diff options
author | Remi NGUYEN VAN <reminv@google.com> | 2021-05-11 13:37:06 +0000 |
---|---|---|
committer | Remi NGUYEN VAN <reminv@google.com> | 2021-05-13 05:55:44 +0000 |
commit | 007a886baf9f4e6737f2b4378f68c023dc7e7b31 (patch) | |
tree | d2f5cf57127acb12112234e8c841f58805862dc9 /tests | |
parent | 8bee21a405b140c9969c40925d5e4c8e7228dbe1 (diff) |
Move net unit tests to packages/Connectivity
Move the tests together with packages/Connectivity code, so both can be
moved to packages/modules/Connectivity together.
Also reorganize unit tests in a unit/ directory, as other tests
(integration/, common/ etc.) have been added in tests/net since they
were created. This makes the directory structure consistent.
Test: atest FrameworksNetTests
Bug: 187814163
Ignore-AOSP-First: needs per-branch move for merge conflicts
Change-Id: I254ffd1c08ec058d594b4ea55cbae5505f8497cc
Diffstat (limited to 'tests')
146 files changed, 0 insertions, 42957 deletions
diff --git a/tests/net/Android.bp b/tests/net/Android.bp deleted file mode 100644 index 6f503ace037f..000000000000 --- a/tests/net/Android.bp +++ /dev/null @@ -1,89 +0,0 @@ -//######################################################################## -// Build FrameworksNetTests package -//######################################################################## -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -java_defaults { - name: "FrameworksNetTests-jni-defaults", - jni_libs: [ - "ld-android", - "libbacktrace", - "libbase", - "libbinder", - "libbpf", - "libbpf_android", - "libc++", - "libcgrouprc", - "libcrypto", - "libcutils", - "libdl_android", - "libhidl-gen-utils", - "libhidlbase", - "libjsoncpp", - "liblog", - "liblzma", - "libnativehelper", - "libnetdbpf", - "libnetdutils", - "libnetworkstatsfactorytestjni", - "libpackagelistparser", - "libpcre2", - "libprocessgroup", - "libselinux", - "libtinyxml2", - "libui", - "libunwindstack", - "libutils", - "libutilscallstack", - "libvndksupport", - "libziparchive", - "libz", - "netd_aidl_interface-V5-cpp", - ], -} - -android_test { - name: "FrameworksNetTests", - defaults: [ - "framework-connectivity-test-defaults", - "FrameworksNetTests-jni-defaults", - ], - srcs: [ - "java/**/*.java", - "java/**/*.kt", - ], - test_suites: ["device-tests"], - certificate: "platform", - jarjar_rules: "jarjar-rules.txt", - static_libs: [ - "androidx.test.rules", - "bouncycastle-repackaged-unbundled", - "FrameworksNetCommonTests", - "frameworks-base-testutils", - "frameworks-net-integration-testutils", - "framework-protos", - "mockito-target-minus-junit4", - "net-tests-utils", - "platform-test-annotations", - "service-connectivity-pre-jarjar", - "services.core", - "services.net", - ], - libs: [ - "android.net.ipsec.ike.stubs.module_lib", - "android.test.runner", - "android.test.base", - "android.test.mock", - "ServiceConnectivityResources", - ], - jni_libs: [ - "libservice-connectivity", - ], -} diff --git a/tests/net/AndroidManifest.xml b/tests/net/AndroidManifest.xml deleted file mode 100644 index 4c60ccf60615..000000000000 --- a/tests/net/AndroidManifest.xml +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.frameworks.tests.net"> - - <uses-permission android:name="android.permission.READ_LOGS" /> - <uses-permission android:name="android.permission.WRITE_SETTINGS" /> - <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> - <uses-permission android:name="android.permission.READ_PHONE_STATE" /> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - <uses-permission android:name="android.permission.BROADCAST_STICKY" /> - <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> - <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" /> - <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" /> - <uses-permission android:name="android.permission.WAKE_LOCK" /> - <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" /> - <uses-permission android:name="android.permission.REAL_GET_TASKS" /> - <uses-permission android:name="android.permission.GET_DETAILED_TASKS" /> - <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" /> - <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" /> - <uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" /> - <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> - <uses-permission android:name="android.permission.MANAGE_USERS" /> - <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> - <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" /> - <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> - <uses-permission android:name="android.permission.INTERNET" /> - <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> - <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" /> - <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" /> - <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" /> - <uses-permission android:name="android.permission.INSTALL_PACKAGES" /> - <uses-permission android:name="android.permission.NETWORK_STACK" /> - <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" /> - <uses-permission android:name="android.permission.NETWORK_FACTORY" /> - <uses-permission android:name="android.permission.NETWORK_STATS_PROVIDER" /> - <uses-permission android:name="android.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE" /> - - <application> - <uses-library android:name="android.test.runner" /> - <uses-library android:name="android.net.ipsec.ike" /> - </application> - - <instrumentation - android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="com.android.frameworks.tests.net" - android:label="Frameworks Networking Tests" /> -</manifest> diff --git a/tests/net/AndroidTest.xml b/tests/net/AndroidTest.xml deleted file mode 100644 index 939ae493b280..000000000000 --- a/tests/net/AndroidTest.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<configuration description="Runs Frameworks Networking Tests."> - <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> - <option name="test-file-name" value="FrameworksNetTests.apk" /> - </target_preparer> - - <option name="test-suite-tag" value="apct" /> - <option name="test-tag" value="FrameworksNetTests" /> - <test class="com.android.tradefed.testtype.AndroidJUnitTest" > - <option name="package" value="com.android.frameworks.tests.net" /> - <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> - <option name="hidden-api-checks" value="false"/> - </test> -</configuration> diff --git a/tests/net/OWNERS b/tests/net/OWNERS deleted file mode 100644 index d3836d4c6c57..000000000000 --- a/tests/net/OWNERS +++ /dev/null @@ -1,8 +0,0 @@ -set noparent - -codewiz@google.com -jchalard@google.com -junyulai@google.com -lorenzo@google.com -reminv@google.com -satk@google.com diff --git a/tests/net/TEST_MAPPING b/tests/net/TEST_MAPPING deleted file mode 100644 index 502f885ceb78..000000000000 --- a/tests/net/TEST_MAPPING +++ /dev/null @@ -1,34 +0,0 @@ -{ - "presubmit": [ - { - "name": "FrameworksNetIntegrationTests" - } - ], - "postsubmit": [ - { - "name": "FrameworksNetDeflakeTest" - } - ], - "auto-postsubmit": [ - // Test tag for automotive targets. These are only running in postsubmit so as to harden the - // automotive targets to avoid introducing additional test flake and build time. The plan for - // presubmit testing for auto is to augment the existing tests to cover auto use cases as well. - // Additionally, this tag is used in targeted test suites to limit resource usage on the test - // infra during the hardening phase. - // TODO: this tag to be removed once the above is no longer an issue. - { - "name": "FrameworksNetTests" - }, - { - "name": "FrameworksNetIntegrationTests" - }, - { - "name": "FrameworksNetDeflakeTest" - } - ], - "imports": [ - { - "path": "packages/modules/Connectivity" - } - ] -}
\ No newline at end of file diff --git a/tests/net/common/Android.bp b/tests/net/common/Android.bp deleted file mode 100644 index 439665b67ab7..000000000000 --- a/tests/net/common/Android.bp +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -// Tests in this folder are included both in unit tests and CTS. -// They must be fast and stable, and exercise public or test APIs. -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -java_library { - name: "FrameworksNetCommonTests", - defaults: ["framework-connectivity-test-defaults"], - srcs: [ - "java/**/*.java", - "java/**/*.kt", - ], - static_libs: [ - "androidx.core_core", - "androidx.test.rules", - "junit", - "mockito-target-minus-junit4", - "modules-utils-build", - "net-tests-utils", - "net-utils-framework-common", - "platform-test-annotations", - ], - libs: [ - "android.test.base.stubs", - ], -} diff --git a/tests/net/common/java/ParseExceptionTest.kt b/tests/net/common/java/ParseExceptionTest.kt deleted file mode 100644 index b702d61a9fe1..000000000000 --- a/tests/net/common/java/ParseExceptionTest.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import android.net.ParseException -import android.os.Build -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.SmallTest -import com.android.testutils.DevSdkIgnoreRule -import junit.framework.Assert.assertEquals -import junit.framework.Assert.assertNull -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -@SmallTest -@RunWith(AndroidJUnit4::class) -class ParseExceptionTest { - @get:Rule - val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.R) - - @Test - fun testConstructor_WithCause() { - val testMessage = "Test message" - val base = Exception("Test") - val exception = ParseException(testMessage, base) - - assertEquals(testMessage, exception.response) - assertEquals(base, exception.cause) - } - - @Test - fun testConstructor_NoCause() { - val testMessage = "Test message" - val exception = ParseException(testMessage) - - assertEquals(testMessage, exception.response) - assertNull(exception.cause) - } -}
\ No newline at end of file diff --git a/tests/net/common/java/android/net/CaptivePortalDataTest.kt b/tests/net/common/java/android/net/CaptivePortalDataTest.kt deleted file mode 100644 index 18a93319b271..000000000000 --- a/tests/net/common/java/android/net/CaptivePortalDataTest.kt +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net - -import android.os.Build -import androidx.test.filters.SmallTest -import com.android.modules.utils.build.SdkLevel -import com.android.testutils.assertParcelSane -import com.android.testutils.assertParcelingIsLossless -import com.android.testutils.DevSdkIgnoreRule -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo -import com.android.testutils.DevSdkIgnoreRunner -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import kotlin.test.assertEquals -import kotlin.test.assertNotEquals - -@SmallTest -@RunWith(DevSdkIgnoreRunner::class) -@IgnoreUpTo(Build.VERSION_CODES.Q) -class CaptivePortalDataTest { - @Rule @JvmField - val ignoreRule = DevSdkIgnoreRule() - - private val data = CaptivePortalData.Builder() - .setRefreshTime(123L) - .setUserPortalUrl(Uri.parse("https://portal.example.com/test")) - .setVenueInfoUrl(Uri.parse("https://venue.example.com/test")) - .setSessionExtendable(true) - .setBytesRemaining(456L) - .setExpiryTime(789L) - .setCaptive(true) - .apply { - if (SdkLevel.isAtLeastS()) { - setVenueFriendlyName("venue friendly name") - } - } - .build() - - private val dataFromPasspoint = CaptivePortalData.Builder() - .setCaptive(true) - .apply { - if (SdkLevel.isAtLeastS()) { - setVenueFriendlyName("venue friendly name") - setUserPortalUrl(Uri.parse("https://tc.example.com/passpoint"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) - setVenueInfoUrl(Uri.parse("https://venue.example.com/passpoint"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) - } - } - .build() - - private fun makeBuilder() = CaptivePortalData.Builder(data) - - @Test - fun testParcelUnparcel() { - val fieldCount = if (SdkLevel.isAtLeastS()) 10 else 7 - assertParcelSane(data, fieldCount) - assertParcelSane(dataFromPasspoint, fieldCount) - - assertParcelingIsLossless(makeBuilder().setUserPortalUrl(null).build()) - assertParcelingIsLossless(makeBuilder().setVenueInfoUrl(null).build()) - } - - @Test - fun testEquals() { - assertEquals(data, makeBuilder().build()) - - assertNotEqualsAfterChange { it.setRefreshTime(456L) } - assertNotEqualsAfterChange { it.setUserPortalUrl(Uri.parse("https://example.com/")) } - assertNotEqualsAfterChange { it.setUserPortalUrl(null) } - assertNotEqualsAfterChange { it.setVenueInfoUrl(Uri.parse("https://example.com/")) } - assertNotEqualsAfterChange { it.setVenueInfoUrl(null) } - assertNotEqualsAfterChange { it.setSessionExtendable(false) } - assertNotEqualsAfterChange { it.setBytesRemaining(789L) } - assertNotEqualsAfterChange { it.setExpiryTime(12L) } - assertNotEqualsAfterChange { it.setCaptive(false) } - - if (SdkLevel.isAtLeastS()) { - assertNotEqualsAfterChange { it.setVenueFriendlyName("another friendly name") } - assertNotEqualsAfterChange { it.setVenueFriendlyName(null) } - - assertEquals(dataFromPasspoint, CaptivePortalData.Builder(dataFromPasspoint).build()) - assertNotEqualsAfterChange { it.setUserPortalUrl( - Uri.parse("https://tc.example.com/passpoint")) } - assertNotEqualsAfterChange { it.setUserPortalUrl( - Uri.parse("https://tc.example.com/passpoint"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) } - assertNotEqualsAfterChange { it.setUserPortalUrl( - Uri.parse("https://tc.example.com/other"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) } - assertNotEqualsAfterChange { it.setUserPortalUrl( - Uri.parse("https://tc.example.com/passpoint"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) } - assertNotEqualsAfterChange { it.setVenueInfoUrl( - Uri.parse("https://venue.example.com/passpoint")) } - assertNotEqualsAfterChange { it.setVenueInfoUrl( - Uri.parse("https://venue.example.com/other"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) } - assertNotEqualsAfterChange { it.setVenueInfoUrl( - Uri.parse("https://venue.example.com/passpoint"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) } - } - } - - @Test - fun testUserPortalUrl() { - assertEquals(Uri.parse("https://portal.example.com/test"), data.userPortalUrl) - } - - @Test - fun testVenueInfoUrl() { - assertEquals(Uri.parse("https://venue.example.com/test"), data.venueInfoUrl) - } - - @Test - fun testIsSessionExtendable() { - assertTrue(data.isSessionExtendable) - } - - @Test - fun testByteLimit() { - assertEquals(456L, data.byteLimit) - // Test byteLimit unset. - assertEquals(-1L, CaptivePortalData.Builder(null).build().byteLimit) - } - - @Test - fun testRefreshTimeMillis() { - assertEquals(123L, data.refreshTimeMillis) - } - - @Test - fun testExpiryTimeMillis() { - assertEquals(789L, data.expiryTimeMillis) - // Test expiryTimeMillis unset. - assertEquals(-1L, CaptivePortalData.Builder(null).build().expiryTimeMillis) - } - - @Test - fun testIsCaptive() { - assertTrue(data.isCaptive) - assertFalse(makeBuilder().setCaptive(false).build().isCaptive) - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.R) - fun testVenueFriendlyName() { - assertEquals("venue friendly name", data.venueFriendlyName) - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.R) - fun testGetVenueInfoUrlSource() { - assertEquals(CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER, - data.venueInfoUrlSource) - assertEquals(CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT, - dataFromPasspoint.venueInfoUrlSource) - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.R) - fun testGetUserPortalUrlSource() { - assertEquals(CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER, - data.userPortalUrlSource) - assertEquals(CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT, - dataFromPasspoint.userPortalUrlSource) - } - - private fun CaptivePortalData.mutate(mutator: (CaptivePortalData.Builder) -> Unit) = - CaptivePortalData.Builder(this).apply { mutator(this) }.build() - - private fun assertNotEqualsAfterChange(mutator: (CaptivePortalData.Builder) -> Unit) { - assertNotEquals(data, data.mutate(mutator)) - } -}
\ No newline at end of file diff --git a/tests/net/common/java/android/net/CaptivePortalTest.java b/tests/net/common/java/android/net/CaptivePortalTest.java deleted file mode 100644 index 15d3398d43c0..000000000000 --- a/tests/net/common/java/android/net/CaptivePortalTest.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static org.junit.Assert.assertEquals; - -import android.os.Build; -import android.os.RemoteException; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.testutils.DevSdkIgnoreRule; -import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class CaptivePortalTest { - @Rule - public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); - - private static final int DEFAULT_TIMEOUT_MS = 5000; - private static final String TEST_PACKAGE_NAME = "com.google.android.test"; - - private final class MyCaptivePortalImpl extends ICaptivePortal.Stub { - int mCode = -1; - String mPackageName = null; - - @Override - public void appResponse(final int response) throws RemoteException { - mCode = response; - } - - @Override - public void appRequest(final int request) throws RemoteException { - mCode = request; - } - - // This is only @Override on R- - public void logEvent(int eventId, String packageName) throws RemoteException { - mCode = eventId; - mPackageName = packageName; - } - } - - private interface TestFunctor { - void useCaptivePortal(CaptivePortal o); - } - - private MyCaptivePortalImpl runCaptivePortalTest(TestFunctor f) { - final MyCaptivePortalImpl cp = new MyCaptivePortalImpl(); - f.useCaptivePortal(new CaptivePortal(cp.asBinder())); - return cp; - } - - @Test - public void testReportCaptivePortalDismissed() { - final MyCaptivePortalImpl result = - runCaptivePortalTest(c -> c.reportCaptivePortalDismissed()); - assertEquals(result.mCode, CaptivePortal.APP_RETURN_DISMISSED); - } - - @Test - public void testIgnoreNetwork() { - final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.ignoreNetwork()); - assertEquals(result.mCode, CaptivePortal.APP_RETURN_UNWANTED); - } - - @Test - public void testUseNetwork() { - final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.useNetwork()); - assertEquals(result.mCode, CaptivePortal.APP_RETURN_WANTED_AS_IS); - } - - @IgnoreUpTo(Build.VERSION_CODES.Q) - @Test - public void testReevaluateNetwork() { - final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.reevaluateNetwork()); - assertEquals(result.mCode, CaptivePortal.APP_REQUEST_REEVALUATION_REQUIRED); - } - - @IgnoreUpTo(Build.VERSION_CODES.R) - @Test - public void testLogEvent() { - /** - * From S testLogEvent is expected to do nothing but shouldn't crash (the API - * logEvent has been deprecated). - */ - final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.logEvent( - 0, - TEST_PACKAGE_NAME)); - } - - @IgnoreAfter(Build.VERSION_CODES.R) - @Test - public void testLogEvent_UntilR() { - final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.logEvent( - 42, TEST_PACKAGE_NAME)); - assertEquals(result.mCode, 42); - assertEquals(result.mPackageName, TEST_PACKAGE_NAME); - } -} diff --git a/tests/net/common/java/android/net/DependenciesTest.java b/tests/net/common/java/android/net/DependenciesTest.java deleted file mode 100644 index ac1c28a45462..000000000000 --- a/tests/net/common/java/android/net/DependenciesTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.concurrent.TimeUnit; - -/** - * A simple class that tests dependencies to java standard tools from the - * Network stack. These tests are not meant to be comprehensive tests of - * the relevant APIs : such tests belong in the relevant test suite for - * these dependencies. Instead, this just makes sure coverage is present - * by calling the methods in the exact way (or a representative way of how) - * they are called in the network stack. - */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class DependenciesTest { - // Used to in ipmemorystore's RegularMaintenanceJobService to convert - // 24 hours into seconds - @Test - public void testTimeUnit() { - final int hours = 24; - final long inSeconds = TimeUnit.HOURS.toMillis(hours); - assertEquals(inSeconds, hours * 60 * 60 * 1000); - } - - private byte[] makeTrivialArray(final int size) { - final byte[] src = new byte[size]; - for (int i = 0; i < size; ++i) { - src[i] = (byte) i; - } - return src; - } - - // Used in ApfFilter to find an IP address from a byte array - @Test - public void testArrays() { - final int size = 128; - final byte[] src = makeTrivialArray(size); - - // Test copy - final int copySize = 16; - final int offset = 24; - final byte[] expected = new byte[copySize]; - for (int i = 0; i < copySize; ++i) { - expected[i] = (byte) (offset + i); - } - - final byte[] copy = Arrays.copyOfRange(src, offset, offset + copySize); - assertArrayEquals(expected, copy); - assertArrayEquals(new byte[0], Arrays.copyOfRange(src, size, size)); - } - - // Used mainly in the Dhcp code - @Test - public void testCopyOf() { - final byte[] src = makeTrivialArray(128); - final byte[] copy = Arrays.copyOf(src, src.length); - assertArrayEquals(src, copy); - assertFalse(src == copy); - - assertArrayEquals(new byte[0], Arrays.copyOf(src, 0)); - - final int excess = 16; - final byte[] biggerCopy = Arrays.copyOf(src, src.length + excess); - for (int i = src.length; i < src.length + excess; ++i) { - assertEquals(0, biggerCopy[i]); - } - for (int i = src.length - 1; i >= 0; --i) { - assertEquals(src[i], biggerCopy[i]); - } - } - - // Used mainly in DnsUtils but also various other places - @Test - public void testAsList() { - final int size = 24; - final Object[] src = new Object[size]; - final ArrayList<Object> expected = new ArrayList<>(size); - for (int i = 0; i < size; ++i) { - final Object o = new Object(); - src[i] = o; - expected.add(o); - } - assertEquals(expected, Arrays.asList(src)); - } -} diff --git a/tests/net/common/java/android/net/DhcpInfoTest.java b/tests/net/common/java/android/net/DhcpInfoTest.java deleted file mode 100644 index ab4726bab573..000000000000 --- a/tests/net/common/java/android/net/DhcpInfoTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTL; -import static com.android.testutils.MiscAsserts.assertFieldCountEquals; -import static com.android.testutils.ParcelUtils.parcelingRoundTrip; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.annotation.Nullable; - -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet4Address; -import java.net.InetAddress; - -@RunWith(AndroidJUnit4.class) -public class DhcpInfoTest { - private static final String STR_ADDR1 = "255.255.255.255"; - private static final String STR_ADDR2 = "127.0.0.1"; - private static final String STR_ADDR3 = "192.168.1.1"; - private static final String STR_ADDR4 = "192.168.1.0"; - private static final int LEASE_TIME = 9999; - - private int ipToInteger(String ipString) throws Exception { - return inet4AddressToIntHTL((Inet4Address) InetAddress.getByName(ipString)); - } - - private DhcpInfo createDhcpInfoObject() throws Exception { - final DhcpInfo dhcpInfo = new DhcpInfo(); - dhcpInfo.ipAddress = ipToInteger(STR_ADDR1); - dhcpInfo.gateway = ipToInteger(STR_ADDR2); - dhcpInfo.netmask = ipToInteger(STR_ADDR3); - dhcpInfo.dns1 = ipToInteger(STR_ADDR4); - dhcpInfo.dns2 = ipToInteger(STR_ADDR4); - dhcpInfo.serverAddress = ipToInteger(STR_ADDR2); - dhcpInfo.leaseDuration = LEASE_TIME; - return dhcpInfo; - } - - @Test - public void testConstructor() { - new DhcpInfo(); - } - - @Test - public void testToString() throws Exception { - final String expectedDefault = "ipaddr 0.0.0.0 gateway 0.0.0.0 netmask 0.0.0.0 " - + "dns1 0.0.0.0 dns2 0.0.0.0 DHCP server 0.0.0.0 lease 0 seconds"; - - DhcpInfo dhcpInfo = new DhcpInfo(); - - // Test default string. - assertEquals(expectedDefault, dhcpInfo.toString()); - - dhcpInfo = createDhcpInfoObject(); - - final String expected = "ipaddr " + STR_ADDR1 + " gateway " + STR_ADDR2 + " netmask " - + STR_ADDR3 + " dns1 " + STR_ADDR4 + " dns2 " + STR_ADDR4 + " DHCP server " - + STR_ADDR2 + " lease " + LEASE_TIME + " seconds"; - // Test with new values - assertEquals(expected, dhcpInfo.toString()); - } - - private boolean dhcpInfoEquals(@Nullable DhcpInfo left, @Nullable DhcpInfo right) { - if (left == null && right == null) return true; - - if (left == null || right == null) return false; - - return left.ipAddress == right.ipAddress - && left.gateway == right.gateway - && left.netmask == right.netmask - && left.dns1 == right.dns1 - && left.dns2 == right.dns2 - && left.serverAddress == right.serverAddress - && left.leaseDuration == right.leaseDuration; - } - - @Test - public void testParcelDhcpInfo() throws Exception { - // Cannot use assertParcelSane() here because this requires .equals() to work as - // defined, but DhcpInfo has a different legacy behavior that we cannot change. - final DhcpInfo dhcpInfo = createDhcpInfoObject(); - assertFieldCountEquals(7, DhcpInfo.class); - - final DhcpInfo dhcpInfoRoundTrip = parcelingRoundTrip(dhcpInfo); - assertTrue(dhcpInfoEquals(null, null)); - assertFalse(dhcpInfoEquals(null, dhcpInfoRoundTrip)); - assertFalse(dhcpInfoEquals(dhcpInfo, null)); - assertTrue(dhcpInfoEquals(dhcpInfo, dhcpInfoRoundTrip)); - } -} diff --git a/tests/net/common/java/android/net/IpPrefixTest.java b/tests/net/common/java/android/net/IpPrefixTest.java deleted file mode 100644 index 50ecb428359e..000000000000 --- a/tests/net/common/java/android/net/IpPrefixTest.java +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static com.android.testutils.MiscAsserts.assertEqualBothWays; -import static com.android.testutils.MiscAsserts.assertFieldCountEquals; -import static com.android.testutils.MiscAsserts.assertNotEqualEitherWay; -import static com.android.testutils.ParcelUtils.assertParcelingIsLossless; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.InetAddress; -import java.util.Random; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class IpPrefixTest { - - private static InetAddress address(String addr) { - return InetAddress.parseNumericAddress(addr); - } - - // Explicitly cast everything to byte because "error: possible loss of precision". - private static final byte[] IPV4_BYTES = { (byte) 192, (byte) 0, (byte) 2, (byte) 4}; - private static final byte[] IPV6_BYTES = { - (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, - (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef, - (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xa0 - }; - - @Test - public void testConstructor() { - IpPrefix p; - try { - p = new IpPrefix((byte[]) null, 9); - fail("Expected NullPointerException: null byte array"); - } catch (RuntimeException expected) { } - - try { - p = new IpPrefix((InetAddress) null, 10); - fail("Expected NullPointerException: null InetAddress"); - } catch (RuntimeException expected) { } - - try { - p = new IpPrefix((String) null); - fail("Expected NullPointerException: null String"); - } catch (RuntimeException expected) { } - - - try { - byte[] b2 = {1, 2, 3, 4, 5}; - p = new IpPrefix(b2, 29); - fail("Expected IllegalArgumentException: invalid array length"); - } catch (IllegalArgumentException expected) { } - - try { - p = new IpPrefix("1.2.3.4"); - fail("Expected IllegalArgumentException: no prefix length"); - } catch (IllegalArgumentException expected) { } - - try { - p = new IpPrefix("1.2.3.4/"); - fail("Expected IllegalArgumentException: empty prefix length"); - } catch (IllegalArgumentException expected) { } - - try { - p = new IpPrefix("foo/32"); - fail("Expected IllegalArgumentException: invalid address"); - } catch (IllegalArgumentException expected) { } - - try { - p = new IpPrefix("1/32"); - fail("Expected IllegalArgumentException: deprecated IPv4 format"); - } catch (IllegalArgumentException expected) { } - - try { - p = new IpPrefix("1.2.3.256/32"); - fail("Expected IllegalArgumentException: invalid IPv4 address"); - } catch (IllegalArgumentException expected) { } - - try { - p = new IpPrefix("foo/32"); - fail("Expected IllegalArgumentException: non-address"); - } catch (IllegalArgumentException expected) { } - - try { - p = new IpPrefix("f00:::/32"); - fail("Expected IllegalArgumentException: invalid IPv6 address"); - } catch (IllegalArgumentException expected) { } - - p = new IpPrefix("/64"); - assertEquals("::/64", p.toString()); - - p = new IpPrefix("/128"); - assertEquals("::1/128", p.toString()); - - p = new IpPrefix("[2001:db8::123]/64"); - assertEquals("2001:db8::/64", p.toString()); - } - - @Test - public void testTruncation() { - IpPrefix p; - - p = new IpPrefix(IPV4_BYTES, 32); - assertEquals("192.0.2.4/32", p.toString()); - - p = new IpPrefix(IPV4_BYTES, 29); - assertEquals("192.0.2.0/29", p.toString()); - - p = new IpPrefix(IPV4_BYTES, 8); - assertEquals("192.0.0.0/8", p.toString()); - - p = new IpPrefix(IPV4_BYTES, 0); - assertEquals("0.0.0.0/0", p.toString()); - - try { - p = new IpPrefix(IPV4_BYTES, 33); - fail("Expected IllegalArgumentException: invalid prefix length"); - } catch (RuntimeException expected) { } - - try { - p = new IpPrefix(IPV4_BYTES, 128); - fail("Expected IllegalArgumentException: invalid prefix length"); - } catch (RuntimeException expected) { } - - try { - p = new IpPrefix(IPV4_BYTES, -1); - fail("Expected IllegalArgumentException: negative prefix length"); - } catch (RuntimeException expected) { } - - p = new IpPrefix(IPV6_BYTES, 128); - assertEquals("2001:db8:dead:beef:f00::a0/128", p.toString()); - - p = new IpPrefix(IPV6_BYTES, 122); - assertEquals("2001:db8:dead:beef:f00::80/122", p.toString()); - - p = new IpPrefix(IPV6_BYTES, 64); - assertEquals("2001:db8:dead:beef::/64", p.toString()); - - p = new IpPrefix(IPV6_BYTES, 3); - assertEquals("2000::/3", p.toString()); - - p = new IpPrefix(IPV6_BYTES, 0); - assertEquals("::/0", p.toString()); - - try { - p = new IpPrefix(IPV6_BYTES, -1); - fail("Expected IllegalArgumentException: negative prefix length"); - } catch (RuntimeException expected) { } - - try { - p = new IpPrefix(IPV6_BYTES, 129); - fail("Expected IllegalArgumentException: negative prefix length"); - } catch (RuntimeException expected) { } - - } - - @Test - public void testEquals() { - IpPrefix p1, p2; - - p1 = new IpPrefix("192.0.2.251/23"); - p2 = new IpPrefix(new byte[]{(byte) 192, (byte) 0, (byte) 2, (byte) 251}, 23); - assertEqualBothWays(p1, p2); - - p1 = new IpPrefix("192.0.2.5/23"); - assertEqualBothWays(p1, p2); - - p1 = new IpPrefix("192.0.2.5/24"); - assertNotEqualEitherWay(p1, p2); - - p1 = new IpPrefix("192.0.4.5/23"); - assertNotEqualEitherWay(p1, p2); - - - p1 = new IpPrefix("2001:db8:dead:beef:f00::80/122"); - p2 = new IpPrefix(IPV6_BYTES, 122); - assertEquals("2001:db8:dead:beef:f00::80/122", p2.toString()); - assertEqualBothWays(p1, p2); - - p1 = new IpPrefix("2001:db8:dead:beef:f00::bf/122"); - assertEqualBothWays(p1, p2); - - p1 = new IpPrefix("2001:db8:dead:beef:f00::8:0/123"); - assertNotEqualEitherWay(p1, p2); - - p1 = new IpPrefix("2001:db8:dead:beef::/122"); - assertNotEqualEitherWay(p1, p2); - - // 192.0.2.4/32 != c000:0204::/32. - byte[] ipv6bytes = new byte[16]; - System.arraycopy(IPV4_BYTES, 0, ipv6bytes, 0, IPV4_BYTES.length); - p1 = new IpPrefix(ipv6bytes, 32); - assertEqualBothWays(p1, new IpPrefix("c000:0204::/32")); - - p2 = new IpPrefix(IPV4_BYTES, 32); - assertNotEqualEitherWay(p1, p2); - } - - @Test - public void testContainsInetAddress() { - IpPrefix p = new IpPrefix("2001:db8:f00::ace:d00d/127"); - assertTrue(p.contains(address("2001:db8:f00::ace:d00c"))); - assertTrue(p.contains(address("2001:db8:f00::ace:d00d"))); - assertFalse(p.contains(address("2001:db8:f00::ace:d00e"))); - assertFalse(p.contains(address("2001:db8:f00::bad:d00d"))); - assertFalse(p.contains(address("2001:4868:4860::8888"))); - assertFalse(p.contains(address("8.8.8.8"))); - - p = new IpPrefix("192.0.2.0/23"); - assertTrue(p.contains(address("192.0.2.43"))); - assertTrue(p.contains(address("192.0.3.21"))); - assertFalse(p.contains(address("192.0.0.21"))); - assertFalse(p.contains(address("8.8.8.8"))); - assertFalse(p.contains(address("2001:4868:4860::8888"))); - - IpPrefix ipv6Default = new IpPrefix("::/0"); - assertTrue(ipv6Default.contains(address("2001:db8::f00"))); - assertFalse(ipv6Default.contains(address("192.0.2.1"))); - - IpPrefix ipv4Default = new IpPrefix("0.0.0.0/0"); - assertTrue(ipv4Default.contains(address("255.255.255.255"))); - assertTrue(ipv4Default.contains(address("192.0.2.1"))); - assertFalse(ipv4Default.contains(address("2001:db8::f00"))); - } - - @Test - public void testContainsIpPrefix() { - assertTrue(new IpPrefix("0.0.0.0/0").containsPrefix(new IpPrefix("0.0.0.0/0"))); - assertTrue(new IpPrefix("0.0.0.0/0").containsPrefix(new IpPrefix("1.2.3.4/0"))); - assertTrue(new IpPrefix("0.0.0.0/0").containsPrefix(new IpPrefix("1.2.3.4/8"))); - assertTrue(new IpPrefix("0.0.0.0/0").containsPrefix(new IpPrefix("1.2.3.4/24"))); - assertTrue(new IpPrefix("0.0.0.0/0").containsPrefix(new IpPrefix("1.2.3.4/23"))); - - assertTrue(new IpPrefix("1.2.3.4/8").containsPrefix(new IpPrefix("1.2.3.4/8"))); - assertTrue(new IpPrefix("1.2.3.4/8").containsPrefix(new IpPrefix("1.254.12.9/8"))); - assertTrue(new IpPrefix("1.2.3.4/21").containsPrefix(new IpPrefix("1.2.3.4/21"))); - assertTrue(new IpPrefix("1.2.3.4/32").containsPrefix(new IpPrefix("1.2.3.4/32"))); - - assertTrue(new IpPrefix("1.2.3.4/20").containsPrefix(new IpPrefix("1.2.3.0/24"))); - - assertFalse(new IpPrefix("1.2.3.4/32").containsPrefix(new IpPrefix("1.2.3.5/32"))); - assertFalse(new IpPrefix("1.2.3.4/8").containsPrefix(new IpPrefix("2.2.3.4/8"))); - assertFalse(new IpPrefix("0.0.0.0/16").containsPrefix(new IpPrefix("0.0.0.0/15"))); - assertFalse(new IpPrefix("100.0.0.0/8").containsPrefix(new IpPrefix("99.0.0.0/8"))); - - assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("::/0"))); - assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("2001:db8::f00/1"))); - assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("3d8a:661:a0::770/8"))); - assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("2001:db8::f00/8"))); - assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("2001:db8::f00/64"))); - assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("2001:db8::f00/113"))); - assertTrue(new IpPrefix("::/0").containsPrefix(new IpPrefix("2001:db8::f00/128"))); - - assertTrue(new IpPrefix("2001:db8:f00::ace:d00d/64").containsPrefix( - new IpPrefix("2001:db8:f00::ace:d00d/64"))); - assertTrue(new IpPrefix("2001:db8:f00::ace:d00d/64").containsPrefix( - new IpPrefix("2001:db8:f00::ace:d00d/120"))); - assertFalse(new IpPrefix("2001:db8:f00::ace:d00d/64").containsPrefix( - new IpPrefix("2001:db8:f00::ace:d00d/32"))); - assertFalse(new IpPrefix("2001:db8:f00::ace:d00d/64").containsPrefix( - new IpPrefix("2006:db8:f00::ace:d00d/96"))); - - assertTrue(new IpPrefix("2001:db8:f00::ace:d00d/128").containsPrefix( - new IpPrefix("2001:db8:f00::ace:d00d/128"))); - assertTrue(new IpPrefix("2001:db8:f00::ace:d00d/100").containsPrefix( - new IpPrefix("2001:db8:f00::ace:ccaf/110"))); - - assertFalse(new IpPrefix("2001:db8:f00::ace:d00d/128").containsPrefix( - new IpPrefix("2001:db8:f00::ace:d00e/128"))); - assertFalse(new IpPrefix("::/30").containsPrefix(new IpPrefix("::/29"))); - } - - @Test - public void testHashCode() { - IpPrefix p = new IpPrefix(new byte[4], 0); - Random random = new Random(); - for (int i = 0; i < 100; i++) { - final IpPrefix oldP = p; - if (random.nextBoolean()) { - // IPv4. - byte[] b = new byte[4]; - random.nextBytes(b); - p = new IpPrefix(b, random.nextInt(33)); - } else { - // IPv6. - byte[] b = new byte[16]; - random.nextBytes(b); - p = new IpPrefix(b, random.nextInt(129)); - } - if (p.equals(oldP)) { - assertEquals(p.hashCode(), oldP.hashCode()); - } - if (p.hashCode() != oldP.hashCode()) { - assertNotEquals(p, oldP); - } - } - } - - @Test - public void testHashCodeIsNotConstant() { - IpPrefix[] prefixes = { - new IpPrefix("2001:db8:f00::ace:d00d/127"), - new IpPrefix("192.0.2.0/23"), - new IpPrefix("::/0"), - new IpPrefix("0.0.0.0/0"), - }; - for (int i = 0; i < prefixes.length; i++) { - for (int j = i + 1; j < prefixes.length; j++) { - assertNotEquals(prefixes[i].hashCode(), prefixes[j].hashCode()); - } - } - } - - @Test - public void testMappedAddressesAreBroken() { - // 192.0.2.0/24 != ::ffff:c000:0204/120, but because we use InetAddress, - // we are unable to comprehend that. - byte[] ipv6bytes = { - (byte) 0, (byte) 0, (byte) 0, (byte) 0, - (byte) 0, (byte) 0, (byte) 0, (byte) 0, - (byte) 0, (byte) 0, (byte) 0xff, (byte) 0xff, - (byte) 192, (byte) 0, (byte) 2, (byte) 0}; - IpPrefix p = new IpPrefix(ipv6bytes, 120); - assertEquals(16, p.getRawAddress().length); // Fine. - assertArrayEquals(ipv6bytes, p.getRawAddress()); // Fine. - - // Broken. - assertEquals("192.0.2.0/120", p.toString()); - assertEquals(InetAddress.parseNumericAddress("192.0.2.0"), p.getAddress()); - } - - @Test - public void testParceling() { - IpPrefix p; - - p = new IpPrefix("2001:4860:db8::/64"); - assertParcelingIsLossless(p); - assertTrue(p.isIPv6()); - - p = new IpPrefix("192.0.2.0/25"); - assertParcelingIsLossless(p); - assertTrue(p.isIPv4()); - - assertFieldCountEquals(2, IpPrefix.class); - } -} diff --git a/tests/net/common/java/android/net/KeepalivePacketDataTest.kt b/tests/net/common/java/android/net/KeepalivePacketDataTest.kt deleted file mode 100644 index f464ec6cf0e5..000000000000 --- a/tests/net/common/java/android/net/KeepalivePacketDataTest.kt +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net - -import android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS -import android.net.InvalidPacketException.ERROR_INVALID_PORT -import android.os.Build -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.testutils.DevSdkIgnoreRule -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo -import java.net.InetAddress -import java.util.Arrays -import org.junit.Assert.assertEquals -import org.junit.Assert.assertTrue -import org.junit.Assert.fail -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -@SmallTest -class KeepalivePacketDataTest { - @Rule @JvmField - val ignoreRule: DevSdkIgnoreRule = DevSdkIgnoreRule() - - private val INVALID_PORT = 65537 - private val TEST_DST_PORT = 4244 - private val TEST_SRC_PORT = 4243 - - private val TESTBYTES = byteArrayOf(12, 31, 22, 44) - private val TEST_SRC_ADDRV4 = "198.168.0.2".address() - private val TEST_DST_ADDRV4 = "198.168.0.1".address() - private val TEST_ADDRV6 = "2001:db8::1".address() - - private fun String.address() = InetAddresses.parseNumericAddress(this) - - // Add for test because constructor of KeepalivePacketData is protected. - private inner class TestKeepalivePacketData( - srcAddress: InetAddress? = TEST_SRC_ADDRV4, - srcPort: Int = TEST_SRC_PORT, - dstAddress: InetAddress? = TEST_DST_ADDRV4, - dstPort: Int = TEST_DST_PORT, - data: ByteArray = TESTBYTES - ) : KeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, data) - - @Test - @IgnoreUpTo(Build.VERSION_CODES.Q) - fun testConstructor() { - var data: TestKeepalivePacketData - - try { - data = TestKeepalivePacketData(srcAddress = null) - fail("Null src address should cause exception") - } catch (e: InvalidPacketException) { - assertEquals(e.error, ERROR_INVALID_IP_ADDRESS) - } - - try { - data = TestKeepalivePacketData(dstAddress = null) - fail("Null dst address should cause exception") - } catch (e: InvalidPacketException) { - assertEquals(e.error, ERROR_INVALID_IP_ADDRESS) - } - - try { - data = TestKeepalivePacketData(dstAddress = TEST_ADDRV6) - fail("Ip family mismatched should cause exception") - } catch (e: InvalidPacketException) { - assertEquals(e.error, ERROR_INVALID_IP_ADDRESS) - } - - try { - data = TestKeepalivePacketData(srcPort = INVALID_PORT) - fail("Invalid srcPort should cause exception") - } catch (e: InvalidPacketException) { - assertEquals(e.error, ERROR_INVALID_PORT) - } - - try { - data = TestKeepalivePacketData(dstPort = INVALID_PORT) - fail("Invalid dstPort should cause exception") - } catch (e: InvalidPacketException) { - assertEquals(e.error, ERROR_INVALID_PORT) - } - } - - @Test - @IgnoreUpTo(Build.VERSION_CODES.Q) - fun testSrcAddress() = assertEquals(TEST_SRC_ADDRV4, TestKeepalivePacketData().srcAddress) - - @Test - @IgnoreUpTo(Build.VERSION_CODES.Q) - fun testDstAddress() = assertEquals(TEST_DST_ADDRV4, TestKeepalivePacketData().dstAddress) - - @Test - @IgnoreUpTo(Build.VERSION_CODES.Q) - fun testSrcPort() = assertEquals(TEST_SRC_PORT, TestKeepalivePacketData().srcPort) - - @Test - @IgnoreUpTo(Build.VERSION_CODES.Q) - fun testDstPort() = assertEquals(TEST_DST_PORT, TestKeepalivePacketData().dstPort) - - @Test - @IgnoreUpTo(Build.VERSION_CODES.Q) - fun testPacket() = assertTrue(Arrays.equals(TESTBYTES, TestKeepalivePacketData().packet)) -}
\ No newline at end of file diff --git a/tests/net/common/java/android/net/LinkAddressTest.java b/tests/net/common/java/android/net/LinkAddressTest.java deleted file mode 100644 index 2cf3cf9c11da..000000000000 --- a/tests/net/common/java/android/net/LinkAddressTest.java +++ /dev/null @@ -1,518 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.system.OsConstants.IFA_F_DADFAILED; -import static android.system.OsConstants.IFA_F_DEPRECATED; -import static android.system.OsConstants.IFA_F_OPTIMISTIC; -import static android.system.OsConstants.IFA_F_PERMANENT; -import static android.system.OsConstants.IFA_F_TEMPORARY; -import static android.system.OsConstants.IFA_F_TENTATIVE; -import static android.system.OsConstants.RT_SCOPE_HOST; -import static android.system.OsConstants.RT_SCOPE_LINK; -import static android.system.OsConstants.RT_SCOPE_SITE; -import static android.system.OsConstants.RT_SCOPE_UNIVERSE; - -import static com.android.testutils.MiscAsserts.assertEqualBothWays; -import static com.android.testutils.MiscAsserts.assertFieldCountEquals; -import static com.android.testutils.MiscAsserts.assertNotEqualEitherWay; -import static com.android.testutils.ParcelUtils.assertParcelingIsLossless; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.os.Build; -import android.os.SystemClock; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.testutils.DevSdkIgnoreRule; -import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InterfaceAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.Arrays; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class LinkAddressTest { - @Rule - public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); - - private static final String V4 = "192.0.2.1"; - private static final String V6 = "2001:db8::1"; - private static final InetAddress V4_ADDRESS = InetAddresses.parseNumericAddress(V4); - private static final InetAddress V6_ADDRESS = InetAddresses.parseNumericAddress(V6); - - @Test - public void testConstants() { - // RT_SCOPE_UNIVERSE = 0, but all the other constants should be nonzero. - assertNotEquals(0, RT_SCOPE_HOST); - assertNotEquals(0, RT_SCOPE_LINK); - assertNotEquals(0, RT_SCOPE_SITE); - - assertNotEquals(0, IFA_F_DEPRECATED); - assertNotEquals(0, IFA_F_PERMANENT); - assertNotEquals(0, IFA_F_TENTATIVE); - } - - @Test - public void testConstructors() throws SocketException { - LinkAddress address; - - // Valid addresses work as expected. - address = new LinkAddress(V4_ADDRESS, 25); - assertEquals(V4_ADDRESS, address.getAddress()); - assertEquals(25, address.getPrefixLength()); - assertEquals(0, address.getFlags()); - assertEquals(RT_SCOPE_UNIVERSE, address.getScope()); - assertTrue(address.isIpv4()); - - address = new LinkAddress(V6_ADDRESS, 127); - assertEquals(V6_ADDRESS, address.getAddress()); - assertEquals(127, address.getPrefixLength()); - assertEquals(0, address.getFlags()); - assertEquals(RT_SCOPE_UNIVERSE, address.getScope()); - assertTrue(address.isIpv6()); - - // Nonsensical flags/scopes or combinations thereof are acceptable. - address = new LinkAddress(V6 + "/64", IFA_F_DEPRECATED | IFA_F_PERMANENT, RT_SCOPE_LINK); - assertEquals(V6_ADDRESS, address.getAddress()); - assertEquals(64, address.getPrefixLength()); - assertEquals(IFA_F_DEPRECATED | IFA_F_PERMANENT, address.getFlags()); - assertEquals(RT_SCOPE_LINK, address.getScope()); - assertTrue(address.isIpv6()); - - address = new LinkAddress(V4 + "/23", 123, 456); - assertEquals(V4_ADDRESS, address.getAddress()); - assertEquals(23, address.getPrefixLength()); - assertEquals(123, address.getFlags()); - assertEquals(456, address.getScope()); - assertTrue(address.isIpv4()); - - address = new LinkAddress("/64", 1 /* flags */, 2 /* scope */); - assertEquals(Inet6Address.LOOPBACK, address.getAddress()); - assertEquals(64, address.getPrefixLength()); - assertEquals(1, address.getFlags()); - assertEquals(2, address.getScope()); - assertTrue(address.isIpv6()); - - address = new LinkAddress("[2001:db8::123]/64", 3 /* flags */, 4 /* scope */); - assertEquals(InetAddresses.parseNumericAddress("2001:db8::123"), address.getAddress()); - assertEquals(64, address.getPrefixLength()); - assertEquals(3, address.getFlags()); - assertEquals(4, address.getScope()); - assertTrue(address.isIpv6()); - - // InterfaceAddress doesn't have a constructor. Fetch some from an interface. - List<InterfaceAddress> addrs = NetworkInterface.getByName("lo").getInterfaceAddresses(); - - // We expect to find 127.0.0.1/8 and ::1/128, in any order. - LinkAddress ipv4Loopback, ipv6Loopback; - assertEquals(2, addrs.size()); - if (addrs.get(0).getAddress() instanceof Inet4Address) { - ipv4Loopback = new LinkAddress(addrs.get(0)); - ipv6Loopback = new LinkAddress(addrs.get(1)); - } else { - ipv4Loopback = new LinkAddress(addrs.get(1)); - ipv6Loopback = new LinkAddress(addrs.get(0)); - } - - assertEquals(InetAddresses.parseNumericAddress("127.0.0.1"), ipv4Loopback.getAddress()); - assertEquals(8, ipv4Loopback.getPrefixLength()); - - assertEquals(InetAddresses.parseNumericAddress("::1"), ipv6Loopback.getAddress()); - assertEquals(128, ipv6Loopback.getPrefixLength()); - - // Null addresses are rejected. - try { - address = new LinkAddress(null, 24); - fail("Null InetAddress should cause IllegalArgumentException"); - } catch(IllegalArgumentException expected) {} - - try { - address = new LinkAddress((String) null, IFA_F_PERMANENT, RT_SCOPE_UNIVERSE); - fail("Null string should cause IllegalArgumentException"); - } catch(IllegalArgumentException expected) {} - - try { - address = new LinkAddress((InterfaceAddress) null); - fail("Null string should cause NullPointerException"); - } catch(NullPointerException expected) {} - - // Invalid prefix lengths are rejected. - try { - address = new LinkAddress(V4_ADDRESS, -1); - fail("Negative IPv4 prefix length should cause IllegalArgumentException"); - } catch(IllegalArgumentException expected) {} - - try { - address = new LinkAddress(V6_ADDRESS, -1); - fail("Negative IPv6 prefix length should cause IllegalArgumentException"); - } catch(IllegalArgumentException expected) {} - - try { - address = new LinkAddress(V4_ADDRESS, 33); - fail("/33 IPv4 prefix length should cause IllegalArgumentException"); - } catch(IllegalArgumentException expected) {} - - try { - address = new LinkAddress(V4 + "/33", IFA_F_PERMANENT, RT_SCOPE_UNIVERSE); - fail("/33 IPv4 prefix length should cause IllegalArgumentException"); - } catch(IllegalArgumentException expected) {} - - - try { - address = new LinkAddress(V6_ADDRESS, 129, IFA_F_PERMANENT, RT_SCOPE_UNIVERSE); - fail("/129 IPv6 prefix length should cause IllegalArgumentException"); - } catch(IllegalArgumentException expected) {} - - try { - address = new LinkAddress(V6 + "/129", IFA_F_PERMANENT, RT_SCOPE_UNIVERSE); - fail("/129 IPv6 prefix length should cause IllegalArgumentException"); - } catch(IllegalArgumentException expected) {} - - // Multicast addresses are rejected. - try { - address = new LinkAddress("224.0.0.2/32"); - fail("IPv4 multicast address should cause IllegalArgumentException"); - } catch(IllegalArgumentException expected) {} - - try { - address = new LinkAddress("ff02::1/128"); - fail("IPv6 multicast address should cause IllegalArgumentException"); - } catch(IllegalArgumentException expected) {} - } - - @Test - public void testAddressScopes() { - assertEquals(RT_SCOPE_HOST, new LinkAddress("::/128").getScope()); - assertEquals(RT_SCOPE_HOST, new LinkAddress("0.0.0.0/32").getScope()); - - assertEquals(RT_SCOPE_LINK, new LinkAddress("::1/128").getScope()); - assertEquals(RT_SCOPE_LINK, new LinkAddress("127.0.0.5/8").getScope()); - assertEquals(RT_SCOPE_LINK, new LinkAddress("fe80::ace:d00d/64").getScope()); - assertEquals(RT_SCOPE_LINK, new LinkAddress("169.254.5.12/16").getScope()); - - assertEquals(RT_SCOPE_SITE, new LinkAddress("fec0::dead/64").getScope()); - - assertEquals(RT_SCOPE_UNIVERSE, new LinkAddress("10.1.2.3/21").getScope()); - assertEquals(RT_SCOPE_UNIVERSE, new LinkAddress("192.0.2.1/25").getScope()); - assertEquals(RT_SCOPE_UNIVERSE, new LinkAddress("2001:db8::/64").getScope()); - assertEquals(RT_SCOPE_UNIVERSE, new LinkAddress("5000::/127").getScope()); - } - - private void assertIsSameAddressAs(LinkAddress l1, LinkAddress l2) { - assertTrue(l1 + " unexpectedly does not have same address as " + l2, - l1.isSameAddressAs(l2)); - assertTrue(l2 + " unexpectedly does not have same address as " + l1, - l2.isSameAddressAs(l1)); - } - - private void assertIsNotSameAddressAs(LinkAddress l1, LinkAddress l2) { - assertFalse(l1 + " unexpectedly has same address as " + l2, - l1.isSameAddressAs(l2)); - assertFalse(l2 + " unexpectedly has same address as " + l1, - l1.isSameAddressAs(l2)); - } - - @Test - public void testEqualsAndSameAddressAs() { - LinkAddress l1, l2, l3; - - l1 = new LinkAddress("2001:db8::1/64"); - l2 = new LinkAddress("2001:db8::1/64"); - assertEqualBothWays(l1, l2); - assertIsSameAddressAs(l1, l2); - - l2 = new LinkAddress("2001:db8::1/65"); - assertNotEqualEitherWay(l1, l2); - assertIsNotSameAddressAs(l1, l2); - - l2 = new LinkAddress("2001:db8::2/64"); - assertNotEqualEitherWay(l1, l2); - assertIsNotSameAddressAs(l1, l2); - - - l1 = new LinkAddress("192.0.2.1/24"); - l2 = new LinkAddress("192.0.2.1/24"); - assertEqualBothWays(l1, l2); - assertIsSameAddressAs(l1, l2); - - l2 = new LinkAddress("192.0.2.1/23"); - assertNotEqualEitherWay(l1, l2); - assertIsNotSameAddressAs(l1, l2); - - l2 = new LinkAddress("192.0.2.2/24"); - assertNotEqualEitherWay(l1, l2); - assertIsNotSameAddressAs(l1, l2); - - - // Check equals() and isSameAddressAs() on identical addresses with different flags. - l1 = new LinkAddress(V6_ADDRESS, 64); - l2 = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_UNIVERSE); - assertEqualBothWays(l1, l2); - assertIsSameAddressAs(l1, l2); - - l2 = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED, RT_SCOPE_UNIVERSE); - assertNotEqualEitherWay(l1, l2); - assertIsSameAddressAs(l1, l2); - - // Check equals() and isSameAddressAs() on identical addresses with different scope. - l1 = new LinkAddress(V4_ADDRESS, 24); - l2 = new LinkAddress(V4_ADDRESS, 24, 0, RT_SCOPE_UNIVERSE); - assertEqualBothWays(l1, l2); - assertIsSameAddressAs(l1, l2); - - l2 = new LinkAddress(V4_ADDRESS, 24, 0, RT_SCOPE_HOST); - assertNotEqualEitherWay(l1, l2); - assertIsSameAddressAs(l1, l2); - - // Addresses with the same start or end bytes aren't equal between families. - l1 = new LinkAddress("32.1.13.184/24"); - l2 = new LinkAddress("2001:db8::1/24"); - l3 = new LinkAddress("::2001:db8/24"); - - byte[] ipv4Bytes = l1.getAddress().getAddress(); - byte[] l2FirstIPv6Bytes = Arrays.copyOf(l2.getAddress().getAddress(), 4); - byte[] l3LastIPv6Bytes = Arrays.copyOfRange(l3.getAddress().getAddress(), 12, 16); - assertTrue(Arrays.equals(ipv4Bytes, l2FirstIPv6Bytes)); - assertTrue(Arrays.equals(ipv4Bytes, l3LastIPv6Bytes)); - - assertNotEqualEitherWay(l1, l2); - assertIsNotSameAddressAs(l1, l2); - - assertNotEqualEitherWay(l1, l3); - assertIsNotSameAddressAs(l1, l3); - - // Because we use InetAddress, an IPv4 address is equal to its IPv4-mapped address. - // TODO: Investigate fixing this. - String addressString = V4 + "/24"; - l1 = new LinkAddress(addressString); - l2 = new LinkAddress("::ffff:" + addressString); - assertEqualBothWays(l1, l2); - assertIsSameAddressAs(l1, l2); - } - - @Test - public void testHashCode() { - LinkAddress l1, l2; - - l1 = new LinkAddress(V4_ADDRESS, 23); - l2 = new LinkAddress(V4_ADDRESS, 23, 0, RT_SCOPE_HOST); - assertNotEquals(l1.hashCode(), l2.hashCode()); - - l1 = new LinkAddress(V6_ADDRESS, 128); - l2 = new LinkAddress(V6_ADDRESS, 128, IFA_F_TENTATIVE, RT_SCOPE_UNIVERSE); - assertNotEquals(l1.hashCode(), l2.hashCode()); - } - - @Test - public void testParceling() { - LinkAddress l; - - l = new LinkAddress(V6_ADDRESS, 64, 123, 456); - assertParcelingIsLossless(l); - - l = new LinkAddress(V4 + "/28", IFA_F_PERMANENT, RT_SCOPE_LINK); - assertParcelingIsLossless(l); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testLifetimeParceling() { - final LinkAddress l = new LinkAddress(V6_ADDRESS, 64, 123, 456, 1L, 3600000L); - assertParcelingIsLossless(l); - } - - @Test @IgnoreAfter(Build.VERSION_CODES.Q) - public void testFieldCount_Q() { - assertFieldCountEquals(4, LinkAddress.class); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testFieldCount() { - // Make sure any new field is covered by the above parceling tests when changing this number - assertFieldCountEquals(6, LinkAddress.class); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testDeprecationTime() { - try { - new LinkAddress(V6_ADDRESS, 64, 0, 456, - LinkAddress.LIFETIME_UNKNOWN, 100000L); - fail("Only one time provided should cause exception"); - } catch (IllegalArgumentException expected) { } - - try { - new LinkAddress(V6_ADDRESS, 64, 0, 456, - 200000L, 100000L); - fail("deprecation time later than expiration time should cause exception"); - } catch (IllegalArgumentException expected) { } - - try { - new LinkAddress(V6_ADDRESS, 64, 0, 456, - -2, 100000L); - fail("negative deprecation time should cause exception"); - } catch (IllegalArgumentException expected) { } - - LinkAddress addr = new LinkAddress(V6_ADDRESS, 64, 0, 456, 100000L, 200000L); - assertEquals(100000L, addr.getDeprecationTime()); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testExpirationTime() { - try { - new LinkAddress(V6_ADDRESS, 64, 0, 456, - 200000L, LinkAddress.LIFETIME_UNKNOWN); - fail("Only one time provided should cause exception"); - } catch (IllegalArgumentException expected) { } - - try { - new LinkAddress(V6_ADDRESS, 64, 0, 456, - 100000L, -2); - fail("negative expiration time should cause exception"); - } catch (IllegalArgumentException expected) { } - - LinkAddress addr = new LinkAddress(V6_ADDRESS, 64, 0, 456, 100000L, 200000L); - assertEquals(200000L, addr.getExpirationTime()); - } - - @Test - public void testGetFlags() { - LinkAddress l = new LinkAddress(V6_ADDRESS, 64, 123, RT_SCOPE_HOST); - assertEquals(123, l.getFlags()); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testGetFlags_Deprecation() { - // Test if deprecated bit was added/remove automatically based on the provided deprecation - // time - LinkAddress l = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_HOST, - 1L, LinkAddress.LIFETIME_PERMANENT); - // Check if the flag is added automatically. - assertTrue((l.getFlags() & IFA_F_DEPRECATED) != 0); - - l = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED, RT_SCOPE_HOST, - SystemClock.elapsedRealtime() + 100000L, LinkAddress.LIFETIME_PERMANENT); - // Check if the flag is removed automatically. - assertTrue((l.getFlags() & IFA_F_DEPRECATED) == 0); - - l = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED, RT_SCOPE_HOST, - LinkAddress.LIFETIME_PERMANENT, LinkAddress.LIFETIME_PERMANENT); - // Check if the permanent flag is added. - assertTrue((l.getFlags() & IFA_F_PERMANENT) != 0); - - l = new LinkAddress(V6_ADDRESS, 64, IFA_F_PERMANENT, RT_SCOPE_HOST, - 1000L, SystemClock.elapsedRealtime() + 100000L); - // Check if the permanent flag is removed - assertTrue((l.getFlags() & IFA_F_PERMANENT) == 0); - } - - private void assertGlobalPreferred(LinkAddress l, String msg) { - assertTrue(msg, l.isGlobalPreferred()); - } - - private void assertNotGlobalPreferred(LinkAddress l, String msg) { - assertFalse(msg, l.isGlobalPreferred()); - } - - @Test - public void testIsGlobalPreferred() { - LinkAddress l; - - l = new LinkAddress(V4_ADDRESS, 32, 0, RT_SCOPE_UNIVERSE); - assertGlobalPreferred(l, "v4,global,noflags"); - - l = new LinkAddress("10.10.1.7/23", 0, RT_SCOPE_UNIVERSE); - assertGlobalPreferred(l, "v4-rfc1918,global,noflags"); - - l = new LinkAddress("10.10.1.7/23", 0, RT_SCOPE_SITE); - assertNotGlobalPreferred(l, "v4-rfc1918,site-local,noflags"); - - l = new LinkAddress("127.0.0.7/8", 0, RT_SCOPE_HOST); - assertNotGlobalPreferred(l, "v4-localhost,node-local,noflags"); - - l = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_UNIVERSE); - assertGlobalPreferred(l, "v6,global,noflags"); - - l = new LinkAddress(V6_ADDRESS, 64, IFA_F_PERMANENT, RT_SCOPE_UNIVERSE); - assertGlobalPreferred(l, "v6,global,permanent"); - - // IPv6 ULAs are not acceptable "global preferred" addresses. - l = new LinkAddress("fc12::1/64", 0, RT_SCOPE_UNIVERSE); - assertNotGlobalPreferred(l, "v6,ula1,noflags"); - - l = new LinkAddress("fd34::1/64", 0, RT_SCOPE_UNIVERSE); - assertNotGlobalPreferred(l, "v6,ula2,noflags"); - - l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_UNIVERSE); - assertGlobalPreferred(l, "v6,global,tempaddr"); - - l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_DADFAILED), - RT_SCOPE_UNIVERSE); - assertNotGlobalPreferred(l, "v6,global,tempaddr+dadfailed"); - - l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_DEPRECATED), - RT_SCOPE_UNIVERSE); - assertNotGlobalPreferred(l, "v6,global,tempaddr+deprecated"); - - l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_SITE); - assertNotGlobalPreferred(l, "v6,site-local,tempaddr"); - - l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_LINK); - assertNotGlobalPreferred(l, "v6,link-local,tempaddr"); - - l = new LinkAddress(V6_ADDRESS, 64, IFA_F_TEMPORARY, RT_SCOPE_HOST); - assertNotGlobalPreferred(l, "v6,node-local,tempaddr"); - - l = new LinkAddress("::1/128", IFA_F_PERMANENT, RT_SCOPE_HOST); - assertNotGlobalPreferred(l, "v6-localhost,node-local,permanent"); - - l = new LinkAddress(V6_ADDRESS, 64, (IFA_F_TEMPORARY|IFA_F_TENTATIVE), - RT_SCOPE_UNIVERSE); - assertNotGlobalPreferred(l, "v6,global,tempaddr+tentative"); - - l = new LinkAddress(V6_ADDRESS, 64, - (IFA_F_TEMPORARY|IFA_F_TENTATIVE|IFA_F_OPTIMISTIC), - RT_SCOPE_UNIVERSE); - assertGlobalPreferred(l, "v6,global,tempaddr+optimistic"); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testIsGlobalPreferred_DeprecatedInFuture() { - final LinkAddress l = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED, - RT_SCOPE_UNIVERSE, SystemClock.elapsedRealtime() + 100000, - SystemClock.elapsedRealtime() + 200000); - // Although the deprecated bit is set, but the deprecation time is in the future, test - // if the flag is removed automatically. - assertGlobalPreferred(l, "v6,global,tempaddr+deprecated in the future"); - } -} diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java deleted file mode 100644 index 550953d0612d..000000000000 --- a/tests/net/common/java/android/net/LinkPropertiesTest.java +++ /dev/null @@ -1,1271 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.net.RouteInfo.RTN_THROW; -import static android.net.RouteInfo.RTN_UNICAST; -import static android.net.RouteInfo.RTN_UNREACHABLE; - -import static com.android.testutils.ParcelUtils.assertParcelSane; -import static com.android.testutils.ParcelUtils.assertParcelingIsLossless; -import static com.android.testutils.ParcelUtils.parcelingRoundTrip; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.net.LinkProperties.ProvisioningChange; -import android.os.Build; -import android.system.OsConstants; -import android.util.ArraySet; - -import androidx.core.os.BuildCompat; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.LinkPropertiesUtils.CompareResult; -import com.android.testutils.DevSdkIgnoreRule; -import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class LinkPropertiesTest { - @Rule - public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); - - private static final InetAddress ADDRV4 = address("75.208.6.1"); - private static final InetAddress ADDRV6 = address("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); - private static final InetAddress DNS1 = address("75.208.7.1"); - private static final InetAddress DNS2 = address("69.78.7.1"); - private static final InetAddress DNS6 = address("2001:4860:4860::8888"); - private static final InetAddress PRIVDNS1 = address("1.1.1.1"); - private static final InetAddress PRIVDNS2 = address("1.0.0.1"); - private static final InetAddress PRIVDNS6 = address("2606:4700:4700::1111"); - private static final InetAddress PCSCFV4 = address("10.77.25.37"); - private static final InetAddress PCSCFV6 = address("2001:0db8:85a3:0000:0000:8a2e:0370:1"); - private static final InetAddress GATEWAY1 = address("75.208.8.1"); - private static final InetAddress GATEWAY2 = address("69.78.8.1"); - private static final InetAddress GATEWAY61 = address("fe80::6:0000:613"); - private static final InetAddress GATEWAY62 = address("fe80::6:22%lo"); - private static final InetAddress TESTIPV4ADDR = address("192.168.47.42"); - private static final InetAddress TESTIPV6ADDR = address("fe80::7:33%43"); - private static final Inet4Address DHCPSERVER = (Inet4Address) address("192.0.2.1"); - private static final String NAME = "qmi0"; - private static final String DOMAINS = "google.com"; - private static final String PRIV_DNS_SERVER_NAME = "private.dns.com"; - private static final String TCP_BUFFER_SIZES = "524288,1048576,2097152,262144,524288,1048576"; - private static final int MTU = 1500; - private static final LinkAddress LINKADDRV4 = new LinkAddress(ADDRV4, 32); - private static final LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128); - private static final LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64"); - private static final Uri CAPPORT_API_URL = Uri.parse("https://test.example.com/capportapi"); - - // CaptivePortalData cannot be in a constant as it does not exist on Q. - // The test runner also crashes when scanning for tests if it is a return type. - private static Object getCaptivePortalData() { - return new CaptivePortalData.Builder() - .setVenueInfoUrl(Uri.parse("https://test.example.com/venue")).build(); - } - - private static InetAddress address(String addrString) { - return InetAddresses.parseNumericAddress(addrString); - } - - private static boolean isAtLeastR() { - // BuildCompat.isAtLeastR is documented to return false on release SDKs (including R) - return Build.VERSION.SDK_INT > Build.VERSION_CODES.Q || BuildCompat.isAtLeastR(); - } - - private void checkEmpty(final LinkProperties lp) { - assertEquals(0, lp.getAllInterfaceNames().size()); - assertEquals(0, lp.getAllAddresses().size()); - assertEquals(0, lp.getDnsServers().size()); - assertEquals(0, lp.getValidatedPrivateDnsServers().size()); - assertEquals(0, lp.getPcscfServers().size()); - assertEquals(0, lp.getAllRoutes().size()); - assertEquals(0, lp.getAllLinkAddresses().size()); - assertEquals(0, lp.getStackedLinks().size()); - assertEquals(0, lp.getMtu()); - assertNull(lp.getPrivateDnsServerName()); - assertNull(lp.getDomains()); - assertNull(lp.getHttpProxy()); - assertNull(lp.getTcpBufferSizes()); - assertNull(lp.getNat64Prefix()); - assertFalse(lp.isProvisioned()); - assertFalse(lp.isIpv4Provisioned()); - assertFalse(lp.isIpv6Provisioned()); - assertFalse(lp.isPrivateDnsActive()); - - if (isAtLeastR()) { - assertNull(lp.getDhcpServerAddress()); - assertFalse(lp.isWakeOnLanSupported()); - assertNull(lp.getCaptivePortalApiUrl()); - assertNull(lp.getCaptivePortalData()); - } - } - - private LinkProperties makeTestObject() { - final LinkProperties lp = new LinkProperties(); - lp.setInterfaceName(NAME); - lp.addLinkAddress(LINKADDRV4); - lp.addLinkAddress(LINKADDRV6); - lp.addDnsServer(DNS1); - lp.addDnsServer(DNS2); - lp.addValidatedPrivateDnsServer(PRIVDNS1); - lp.addValidatedPrivateDnsServer(PRIVDNS2); - lp.setUsePrivateDns(true); - lp.setPrivateDnsServerName(PRIV_DNS_SERVER_NAME); - lp.addPcscfServer(PCSCFV6); - lp.setDomains(DOMAINS); - lp.addRoute(new RouteInfo(GATEWAY1)); - lp.addRoute(new RouteInfo(GATEWAY2)); - lp.setHttpProxy(ProxyInfo.buildDirectProxy("test", 8888)); - lp.setMtu(MTU); - lp.setTcpBufferSizes(TCP_BUFFER_SIZES); - lp.setNat64Prefix(new IpPrefix("2001:db8:0:64::/96")); - if (isAtLeastR()) { - lp.setDhcpServerAddress(DHCPSERVER); - lp.setWakeOnLanSupported(true); - lp.setCaptivePortalApiUrl(CAPPORT_API_URL); - lp.setCaptivePortalData((CaptivePortalData) getCaptivePortalData()); - } - return lp; - } - - public void assertLinkPropertiesEqual(LinkProperties source, LinkProperties target) { - // Check implementation of equals(), element by element. - assertTrue(source.isIdenticalInterfaceName(target)); - assertTrue(target.isIdenticalInterfaceName(source)); - - assertTrue(source.isIdenticalAddresses(target)); - assertTrue(target.isIdenticalAddresses(source)); - - assertTrue(source.isIdenticalDnses(target)); - assertTrue(target.isIdenticalDnses(source)); - - assertTrue(source.isIdenticalPrivateDns(target)); - assertTrue(target.isIdenticalPrivateDns(source)); - - assertTrue(source.isIdenticalValidatedPrivateDnses(target)); - assertTrue(target.isIdenticalValidatedPrivateDnses(source)); - - assertTrue(source.isIdenticalPcscfs(target)); - assertTrue(target.isIdenticalPcscfs(source)); - - assertTrue(source.isIdenticalRoutes(target)); - assertTrue(target.isIdenticalRoutes(source)); - - assertTrue(source.isIdenticalHttpProxy(target)); - assertTrue(target.isIdenticalHttpProxy(source)); - - assertTrue(source.isIdenticalStackedLinks(target)); - assertTrue(target.isIdenticalStackedLinks(source)); - - assertTrue(source.isIdenticalMtu(target)); - assertTrue(target.isIdenticalMtu(source)); - - assertTrue(source.isIdenticalTcpBufferSizes(target)); - assertTrue(target.isIdenticalTcpBufferSizes(source)); - - if (isAtLeastR()) { - assertTrue(source.isIdenticalDhcpServerAddress(target)); - assertTrue(source.isIdenticalDhcpServerAddress(source)); - - assertTrue(source.isIdenticalWakeOnLan(target)); - assertTrue(target.isIdenticalWakeOnLan(source)); - - assertTrue(source.isIdenticalCaptivePortalApiUrl(target)); - assertTrue(target.isIdenticalCaptivePortalApiUrl(source)); - - assertTrue(source.isIdenticalCaptivePortalData(target)); - assertTrue(target.isIdenticalCaptivePortalData(source)); - } - - // Check result of equals(). - assertTrue(source.equals(target)); - assertTrue(target.equals(source)); - - // Check hashCode. - assertEquals(source.hashCode(), target.hashCode()); - } - - @Test - public void testEqualsNull() { - LinkProperties source = new LinkProperties(); - LinkProperties target = new LinkProperties(); - - assertFalse(source == target); - assertLinkPropertiesEqual(source, target); - } - - @Test - public void testEqualsSameOrder() throws Exception { - LinkProperties source = new LinkProperties(); - source.setInterfaceName(NAME); - // set 2 link addresses - source.addLinkAddress(LINKADDRV4); - source.addLinkAddress(LINKADDRV6); - // set 2 dnses - source.addDnsServer(DNS1); - source.addDnsServer(DNS2); - // set 1 pcscf - source.addPcscfServer(PCSCFV6); - // set 2 gateways - source.addRoute(new RouteInfo(GATEWAY1)); - source.addRoute(new RouteInfo(GATEWAY2)); - source.setMtu(MTU); - - LinkProperties target = new LinkProperties(); - - // All fields are same - target.setInterfaceName(NAME); - target.addLinkAddress(LINKADDRV4); - target.addLinkAddress(LINKADDRV6); - target.addDnsServer(DNS1); - target.addDnsServer(DNS2); - target.addPcscfServer(PCSCFV6); - target.addRoute(new RouteInfo(GATEWAY1)); - target.addRoute(new RouteInfo(GATEWAY2)); - target.setMtu(MTU); - - assertLinkPropertiesEqual(source, target); - - target.clear(); - // change Interface Name - target.setInterfaceName("qmi1"); - target.addLinkAddress(LINKADDRV4); - target.addLinkAddress(LINKADDRV6); - target.addDnsServer(DNS1); - target.addDnsServer(DNS2); - target.addPcscfServer(PCSCFV6); - target.addRoute(new RouteInfo(GATEWAY1)); - target.addRoute(new RouteInfo(GATEWAY2)); - target.setMtu(MTU); - assertFalse(source.equals(target)); - - target.clear(); - target.setInterfaceName(NAME); - // change link addresses - target.addLinkAddress(new LinkAddress(address("75.208.6.2"), 32)); - target.addLinkAddress(LINKADDRV6); - target.addDnsServer(DNS1); - target.addDnsServer(DNS2); - target.addPcscfServer(PCSCFV6); - target.addRoute(new RouteInfo(GATEWAY1)); - target.addRoute(new RouteInfo(GATEWAY2)); - target.setMtu(MTU); - assertFalse(source.equals(target)); - - target.clear(); - target.setInterfaceName(NAME); - target.addLinkAddress(LINKADDRV4); - target.addLinkAddress(LINKADDRV6); - // change dnses - target.addDnsServer(address("75.208.7.2")); - target.addDnsServer(DNS2); - target.addPcscfServer(PCSCFV6); - target.addRoute(new RouteInfo(GATEWAY1)); - target.addRoute(new RouteInfo(GATEWAY2)); - target.setMtu(MTU); - assertFalse(source.equals(target)); - - target.clear(); - target.setInterfaceName(NAME); - target.addLinkAddress(LINKADDRV4); - target.addLinkAddress(LINKADDRV6); - target.addDnsServer(address("75.208.7.2")); - target.addDnsServer(DNS2); - // change pcscf - target.addPcscfServer(address("2001::1")); - target.addRoute(new RouteInfo(GATEWAY1)); - target.addRoute(new RouteInfo(GATEWAY2)); - target.setMtu(MTU); - assertFalse(source.equals(target)); - - target.clear(); - target.setInterfaceName(NAME); - target.addLinkAddress(LINKADDRV4); - target.addLinkAddress(LINKADDRV6); - target.addDnsServer(DNS1); - target.addDnsServer(DNS2); - // change gateway - target.addRoute(new RouteInfo(address("75.208.8.2"))); - target.setMtu(MTU); - target.addRoute(new RouteInfo(GATEWAY2)); - assertFalse(source.equals(target)); - - target.clear(); - target.setInterfaceName(NAME); - target.addLinkAddress(LINKADDRV4); - target.addLinkAddress(LINKADDRV6); - target.addDnsServer(DNS1); - target.addDnsServer(DNS2); - target.addRoute(new RouteInfo(GATEWAY1)); - target.addRoute(new RouteInfo(GATEWAY2)); - // change mtu - target.setMtu(1440); - assertFalse(source.equals(target)); - } - - @Test - public void testEqualsDifferentOrder() throws Exception { - LinkProperties source = new LinkProperties(); - source.setInterfaceName(NAME); - // set 2 link addresses - source.addLinkAddress(LINKADDRV4); - source.addLinkAddress(LINKADDRV6); - // set 2 dnses - source.addDnsServer(DNS1); - source.addDnsServer(DNS2); - // set 2 gateways - source.addRoute(new RouteInfo(LINKADDRV4, GATEWAY1)); - source.addRoute(new RouteInfo(GATEWAY2)); - source.setMtu(MTU); - - LinkProperties target = new LinkProperties(); - // Exchange order - target.setInterfaceName(NAME); - target.addLinkAddress(LINKADDRV6); - target.addLinkAddress(LINKADDRV4); - target.addDnsServer(DNS2); - target.addDnsServer(DNS1); - target.addRoute(new RouteInfo(GATEWAY2)); - target.addRoute(new RouteInfo(LINKADDRV4, GATEWAY1)); - target.setMtu(MTU); - - assertLinkPropertiesEqual(source, target); - } - - @Test - public void testEqualsDuplicated() throws Exception { - LinkProperties source = new LinkProperties(); - // set 3 link addresses, eg, [A, A, B] - source.addLinkAddress(LINKADDRV4); - source.addLinkAddress(LINKADDRV4); - source.addLinkAddress(LINKADDRV6); - - LinkProperties target = new LinkProperties(); - // set 3 link addresses, eg, [A, B, B] - target.addLinkAddress(LINKADDRV4); - target.addLinkAddress(LINKADDRV6); - target.addLinkAddress(LINKADDRV6); - - assertLinkPropertiesEqual(source, target); - } - - private void assertAllRoutesHaveInterface(String iface, LinkProperties lp) { - for (RouteInfo r : lp.getRoutes()) { - assertEquals(iface, r.getInterface()); - } - } - - private void assertAllRoutesNotHaveInterface(String iface, LinkProperties lp) { - for (RouteInfo r : lp.getRoutes()) { - assertNotEquals(iface, r.getInterface()); - } - } - - @Test - public void testRouteInterfaces() { - LinkAddress prefix1 = new LinkAddress(address("2001:db8:1::"), 48); - LinkAddress prefix2 = new LinkAddress(address("2001:db8:2::"), 48); - InetAddress address = ADDRV6; - - // Add a route with no interface to a LinkProperties with no interface. No errors. - LinkProperties lp = new LinkProperties(); - RouteInfo r = new RouteInfo(prefix1, address, null); - assertTrue(lp.addRoute(r)); - assertEquals(1, lp.getRoutes().size()); - assertAllRoutesHaveInterface(null, lp); - - // Adding the same route twice has no effect. - assertFalse(lp.addRoute(r)); - assertEquals(1, lp.getRoutes().size()); - - // Add a route with an interface. Expect an exception. - r = new RouteInfo(prefix2, address, "wlan0"); - try { - lp.addRoute(r); - fail("Adding wlan0 route to LP with no interface, expect exception"); - } catch (IllegalArgumentException expected) {} - - // Change the interface name. All the routes should change their interface name too. - lp.setInterfaceName("rmnet0"); - assertAllRoutesHaveInterface("rmnet0", lp); - assertAllRoutesNotHaveInterface(null, lp); - assertAllRoutesNotHaveInterface("wlan0", lp); - - // Now add a route with the wrong interface. This causes an exception too. - try { - lp.addRoute(r); - fail("Adding wlan0 route to rmnet0 LP, expect exception"); - } catch (IllegalArgumentException expected) {} - - // If the interface name matches, the route is added. - r = new RouteInfo(prefix2, null, "wlan0"); - lp.setInterfaceName("wlan0"); - lp.addRoute(r); - assertEquals(2, lp.getRoutes().size()); - assertAllRoutesHaveInterface("wlan0", lp); - assertAllRoutesNotHaveInterface("rmnet0", lp); - - // Routes with null interfaces are converted to wlan0. - r = RouteInfo.makeHostRoute(ADDRV6, null); - lp.addRoute(r); - assertEquals(3, lp.getRoutes().size()); - assertAllRoutesHaveInterface("wlan0", lp); - - // Check routes are updated correctly when calling setInterfaceName. - LinkProperties lp2 = new LinkProperties(lp); - assertAllRoutesHaveInterface("wlan0", lp2); - final CompareResult<RouteInfo> cr1 = - new CompareResult<>(lp.getAllRoutes(), lp2.getAllRoutes()); - assertEquals(0, cr1.added.size()); - assertEquals(0, cr1.removed.size()); - - lp2.setInterfaceName("p2p0"); - assertAllRoutesHaveInterface("p2p0", lp2); - assertAllRoutesNotHaveInterface("wlan0", lp2); - final CompareResult<RouteInfo> cr2 = - new CompareResult<>(lp.getAllRoutes(), lp2.getAllRoutes()); - assertEquals(3, cr2.added.size()); - assertEquals(3, cr2.removed.size()); - - // Remove route with incorrect interface, no route removed. - lp.removeRoute(new RouteInfo(prefix2, null, null)); - assertEquals(3, lp.getRoutes().size()); - - // Check remove works when interface is correct. - lp.removeRoute(new RouteInfo(prefix2, null, "wlan0")); - assertEquals(2, lp.getRoutes().size()); - assertAllRoutesHaveInterface("wlan0", lp); - assertAllRoutesNotHaveInterface("p2p0", lp); - } - - @Test - public void testStackedInterfaces() { - LinkProperties rmnet0 = new LinkProperties(); - rmnet0.setInterfaceName("rmnet0"); - rmnet0.addLinkAddress(LINKADDRV6); - - LinkProperties clat4 = new LinkProperties(); - clat4.setInterfaceName("clat4"); - clat4.addLinkAddress(LINKADDRV4); - - assertEquals(0, rmnet0.getStackedLinks().size()); - assertEquals(1, rmnet0.getAddresses().size()); - assertEquals(1, rmnet0.getLinkAddresses().size()); - assertEquals(1, rmnet0.getAllAddresses().size()); - assertEquals(1, rmnet0.getAllLinkAddresses().size()); - assertEquals(1, rmnet0.getAllInterfaceNames().size()); - assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0)); - - rmnet0.addStackedLink(clat4); - assertEquals(1, rmnet0.getStackedLinks().size()); - assertEquals(1, rmnet0.getAddresses().size()); - assertEquals(1, rmnet0.getLinkAddresses().size()); - assertEquals(2, rmnet0.getAllAddresses().size()); - assertEquals(2, rmnet0.getAllLinkAddresses().size()); - assertEquals(2, rmnet0.getAllInterfaceNames().size()); - assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0)); - assertEquals("clat4", rmnet0.getAllInterfaceNames().get(1)); - - rmnet0.addStackedLink(clat4); - assertEquals(1, rmnet0.getStackedLinks().size()); - assertEquals(1, rmnet0.getAddresses().size()); - assertEquals(1, rmnet0.getLinkAddresses().size()); - assertEquals(2, rmnet0.getAllAddresses().size()); - assertEquals(2, rmnet0.getAllLinkAddresses().size()); - assertEquals(2, rmnet0.getAllInterfaceNames().size()); - assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0)); - assertEquals("clat4", rmnet0.getAllInterfaceNames().get(1)); - - assertEquals(0, clat4.getStackedLinks().size()); - - // Modify an item in the returned collection to see what happens. - for (LinkProperties link : rmnet0.getStackedLinks()) { - if (link.getInterfaceName().equals("clat4")) { - link.setInterfaceName("newname"); - } - } - for (LinkProperties link : rmnet0.getStackedLinks()) { - assertFalse("newname".equals(link.getInterfaceName())); - } - - assertTrue(rmnet0.removeStackedLink("clat4")); - assertEquals(0, rmnet0.getStackedLinks().size()); - assertEquals(1, rmnet0.getAddresses().size()); - assertEquals(1, rmnet0.getLinkAddresses().size()); - assertEquals(1, rmnet0.getAllAddresses().size()); - assertEquals(1, rmnet0.getAllLinkAddresses().size()); - assertEquals(1, rmnet0.getAllInterfaceNames().size()); - assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0)); - - assertFalse(rmnet0.removeStackedLink("clat4")); - } - - private LinkAddress getFirstLinkAddress(LinkProperties lp) { - return lp.getLinkAddresses().iterator().next(); - } - - @Test - public void testAddressMethods() { - LinkProperties lp = new LinkProperties(); - - // No addresses. - assertFalse(lp.hasIpv4Address()); - assertFalse(lp.hasGlobalIpv6Address()); - - // Addresses on stacked links don't count. - LinkProperties stacked = new LinkProperties(); - stacked.setInterfaceName("stacked"); - lp.addStackedLink(stacked); - stacked.addLinkAddress(LINKADDRV4); - stacked.addLinkAddress(LINKADDRV6); - assertTrue(stacked.hasIpv4Address()); - assertTrue(stacked.hasGlobalIpv6Address()); - assertFalse(lp.hasIpv4Address()); - assertFalse(lp.hasGlobalIpv6Address()); - lp.removeStackedLink("stacked"); - assertFalse(lp.hasIpv4Address()); - assertFalse(lp.hasGlobalIpv6Address()); - - // Addresses on the base link. - // Check the return values of hasIpvXAddress and ensure the add/remove methods return true - // iff something changes. - assertEquals(0, lp.getLinkAddresses().size()); - assertTrue(lp.addLinkAddress(LINKADDRV6)); - assertEquals(1, lp.getLinkAddresses().size()); - assertFalse(lp.hasIpv4Address()); - assertTrue(lp.hasGlobalIpv6Address()); - - assertTrue(lp.removeLinkAddress(LINKADDRV6)); - assertEquals(0, lp.getLinkAddresses().size()); - - assertTrue(lp.addLinkAddress(LINKADDRV6LINKLOCAL)); - assertEquals(1, lp.getLinkAddresses().size()); - assertFalse(lp.hasGlobalIpv6Address()); - - assertTrue(lp.addLinkAddress(LINKADDRV4)); - assertEquals(2, lp.getLinkAddresses().size()); - assertTrue(lp.hasIpv4Address()); - assertFalse(lp.hasGlobalIpv6Address()); - - assertTrue(lp.addLinkAddress(LINKADDRV6)); - assertEquals(3, lp.getLinkAddresses().size()); - assertTrue(lp.hasIpv4Address()); - assertTrue(lp.hasGlobalIpv6Address()); - - assertTrue(lp.removeLinkAddress(LINKADDRV6LINKLOCAL)); - assertEquals(2, lp.getLinkAddresses().size()); - assertTrue(lp.hasIpv4Address()); - assertTrue(lp.hasGlobalIpv6Address()); - - // Adding an address twice has no effect. - // Removing an address that's not present has no effect. - assertFalse(lp.addLinkAddress(LINKADDRV4)); - assertEquals(2, lp.getLinkAddresses().size()); - assertTrue(lp.hasIpv4Address()); - assertTrue(lp.removeLinkAddress(LINKADDRV4)); - assertEquals(1, lp.getLinkAddresses().size()); - assertFalse(lp.hasIpv4Address()); - assertFalse(lp.removeLinkAddress(LINKADDRV4)); - assertEquals(1, lp.getLinkAddresses().size()); - - // Adding an address that's already present but with different properties causes the - // existing address to be updated and returns true. - // Start with only LINKADDRV6. - assertEquals(1, lp.getLinkAddresses().size()); - assertEquals(LINKADDRV6, getFirstLinkAddress(lp)); - - // Create a LinkAddress object for the same address, but with different flags. - LinkAddress deprecated = new LinkAddress(ADDRV6, 128, - OsConstants.IFA_F_DEPRECATED, OsConstants.RT_SCOPE_UNIVERSE); - assertTrue(deprecated.isSameAddressAs(LINKADDRV6)); - assertFalse(deprecated.equals(LINKADDRV6)); - - // Check that adding it updates the existing address instead of adding a new one. - assertTrue(lp.addLinkAddress(deprecated)); - assertEquals(1, lp.getLinkAddresses().size()); - assertEquals(deprecated, getFirstLinkAddress(lp)); - assertFalse(LINKADDRV6.equals(getFirstLinkAddress(lp))); - - // Removing LINKADDRV6 removes deprecated, because removing addresses ignores properties. - assertTrue(lp.removeLinkAddress(LINKADDRV6)); - assertEquals(0, lp.getLinkAddresses().size()); - } - - @Test - public void testLinkAddresses() { - final LinkProperties lp = new LinkProperties(); - lp.addLinkAddress(LINKADDRV4); - lp.addLinkAddress(LINKADDRV6); - - final LinkProperties lp2 = new LinkProperties(); - lp2.addLinkAddress(LINKADDRV6); - - final LinkProperties lp3 = new LinkProperties(); - final List<LinkAddress> linkAddresses = Arrays.asList(LINKADDRV4); - lp3.setLinkAddresses(linkAddresses); - - assertFalse(lp.equals(lp2)); - assertFalse(lp2.equals(lp3)); - - lp.removeLinkAddress(LINKADDRV4); - assertTrue(lp.equals(lp2)); - - lp2.setLinkAddresses(lp3.getLinkAddresses()); - assertTrue(lp2.equals(lp3)); - } - - @Test - public void testNat64Prefix() throws Exception { - LinkProperties lp = new LinkProperties(); - lp.addLinkAddress(LINKADDRV4); - lp.addLinkAddress(LINKADDRV6); - - assertNull(lp.getNat64Prefix()); - - IpPrefix p = new IpPrefix("64:ff9b::/96"); - lp.setNat64Prefix(p); - assertEquals(p, lp.getNat64Prefix()); - - p = new IpPrefix("2001:db8:a:b:1:2:3::/96"); - lp.setNat64Prefix(p); - assertEquals(p, lp.getNat64Prefix()); - - p = new IpPrefix("2001:db8:a:b:1:2::/80"); - try { - lp.setNat64Prefix(p); - } catch (IllegalArgumentException expected) { - } - - p = new IpPrefix("64:ff9b::/64"); - try { - lp.setNat64Prefix(p); - } catch (IllegalArgumentException expected) { - } - - assertEquals(new IpPrefix("2001:db8:a:b:1:2:3::/96"), lp.getNat64Prefix()); - - lp.setNat64Prefix(null); - assertNull(lp.getNat64Prefix()); - } - - @Test - public void testIsProvisioned() { - LinkProperties lp4 = new LinkProperties(); - assertFalse("v4only:empty", lp4.isProvisioned()); - lp4.addLinkAddress(LINKADDRV4); - assertFalse("v4only:addr-only", lp4.isProvisioned()); - lp4.addDnsServer(DNS1); - assertFalse("v4only:addr+dns", lp4.isProvisioned()); - lp4.addRoute(new RouteInfo(GATEWAY1)); - assertTrue("v4only:addr+dns+route", lp4.isProvisioned()); - assertTrue("v4only:addr+dns+route", lp4.isIpv4Provisioned()); - assertFalse("v4only:addr+dns+route", lp4.isIpv6Provisioned()); - - LinkProperties lp6 = new LinkProperties(); - assertFalse("v6only:empty", lp6.isProvisioned()); - lp6.addLinkAddress(LINKADDRV6LINKLOCAL); - assertFalse("v6only:fe80-only", lp6.isProvisioned()); - lp6.addDnsServer(DNS6); - assertFalse("v6only:fe80+dns", lp6.isProvisioned()); - lp6.addRoute(new RouteInfo(GATEWAY61)); - assertFalse("v6only:fe80+dns+route", lp6.isProvisioned()); - lp6.addLinkAddress(LINKADDRV6); - assertTrue("v6only:fe80+global+dns+route", lp6.isIpv6Provisioned()); - assertTrue("v6only:fe80+global+dns+route", lp6.isProvisioned()); - lp6.removeLinkAddress(LINKADDRV6LINKLOCAL); - assertFalse("v6only:global+dns+route", lp6.isIpv4Provisioned()); - assertTrue("v6only:global+dns+route", lp6.isIpv6Provisioned()); - assertTrue("v6only:global+dns+route", lp6.isProvisioned()); - - LinkProperties lp46 = new LinkProperties(); - lp46.addLinkAddress(LINKADDRV4); - lp46.addLinkAddress(LINKADDRV6); - lp46.addDnsServer(DNS1); - lp46.addDnsServer(DNS6); - assertFalse("dualstack:missing-routes", lp46.isProvisioned()); - lp46.addRoute(new RouteInfo(GATEWAY1)); - assertTrue("dualstack:v4-provisioned", lp46.isIpv4Provisioned()); - assertFalse("dualstack:v4-provisioned", lp46.isIpv6Provisioned()); - assertTrue("dualstack:v4-provisioned", lp46.isProvisioned()); - lp46.addRoute(new RouteInfo(GATEWAY61)); - assertTrue("dualstack:both-provisioned", lp46.isIpv4Provisioned()); - assertTrue("dualstack:both-provisioned", lp46.isIpv6Provisioned()); - assertTrue("dualstack:both-provisioned", lp46.isProvisioned()); - - // A link with an IPv6 address and default route, but IPv4 DNS server. - LinkProperties mixed = new LinkProperties(); - mixed.addLinkAddress(LINKADDRV6); - mixed.addDnsServer(DNS1); - mixed.addRoute(new RouteInfo(GATEWAY61)); - assertFalse("mixed:addr6+route6+dns4", mixed.isIpv4Provisioned()); - assertFalse("mixed:addr6+route6+dns4", mixed.isIpv6Provisioned()); - assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned()); - } - - @Test - public void testCompareProvisioning() { - LinkProperties v4lp = new LinkProperties(); - v4lp.addLinkAddress(LINKADDRV4); - v4lp.addRoute(new RouteInfo(GATEWAY1)); - v4lp.addDnsServer(DNS1); - assertTrue(v4lp.isProvisioned()); - - LinkProperties v4r = new LinkProperties(v4lp); - v4r.removeDnsServer(DNS1); - assertFalse(v4r.isProvisioned()); - - assertEquals(ProvisioningChange.STILL_NOT_PROVISIONED, - LinkProperties.compareProvisioning(v4r, v4r)); - assertEquals(ProvisioningChange.LOST_PROVISIONING, - LinkProperties.compareProvisioning(v4lp, v4r)); - assertEquals(ProvisioningChange.GAINED_PROVISIONING, - LinkProperties.compareProvisioning(v4r, v4lp)); - assertEquals(ProvisioningChange.STILL_PROVISIONED, - LinkProperties.compareProvisioning(v4lp, v4lp)); - - // Check that losing IPv4 provisioning on a dualstack network is - // seen as a total loss of provisioning. - LinkProperties v6lp = new LinkProperties(); - v6lp.addLinkAddress(LINKADDRV6); - v6lp.addRoute(new RouteInfo(GATEWAY61)); - v6lp.addDnsServer(DNS6); - assertFalse(v6lp.isIpv4Provisioned()); - assertTrue(v6lp.isIpv6Provisioned()); - assertTrue(v6lp.isProvisioned()); - - LinkProperties v46lp = new LinkProperties(v6lp); - v46lp.addLinkAddress(LINKADDRV4); - v46lp.addRoute(new RouteInfo(GATEWAY1)); - v46lp.addDnsServer(DNS1); - assertTrue(v46lp.isIpv4Provisioned()); - assertTrue(v46lp.isIpv6Provisioned()); - assertTrue(v46lp.isProvisioned()); - - assertEquals(ProvisioningChange.STILL_PROVISIONED, - LinkProperties.compareProvisioning(v4lp, v46lp)); - assertEquals(ProvisioningChange.STILL_PROVISIONED, - LinkProperties.compareProvisioning(v6lp, v46lp)); - assertEquals(ProvisioningChange.LOST_PROVISIONING, - LinkProperties.compareProvisioning(v46lp, v6lp)); - assertEquals(ProvisioningChange.LOST_PROVISIONING, - LinkProperties.compareProvisioning(v46lp, v4lp)); - - // Check that losing and gaining a secondary router does not change - // the provisioning status. - LinkProperties v6lp2 = new LinkProperties(v6lp); - v6lp2.addRoute(new RouteInfo(GATEWAY62)); - assertTrue(v6lp2.isProvisioned()); - - assertEquals(ProvisioningChange.STILL_PROVISIONED, - LinkProperties.compareProvisioning(v6lp2, v6lp)); - assertEquals(ProvisioningChange.STILL_PROVISIONED, - LinkProperties.compareProvisioning(v6lp, v6lp2)); - } - - @Test - public void testIsReachable() { - final LinkProperties v4lp = new LinkProperties(); - assertFalse(v4lp.isReachable(DNS1)); - assertFalse(v4lp.isReachable(DNS2)); - - // Add an on-link route, making the on-link DNS server reachable, - // but there is still no IPv4 address. - assertTrue(v4lp.addRoute(new RouteInfo(new IpPrefix(address("75.208.0.0"), 16)))); - assertFalse(v4lp.isReachable(DNS1)); - assertFalse(v4lp.isReachable(DNS2)); - - // Adding an IPv4 address (right now, any IPv4 address) means we use - // the routes to compute likely reachability. - assertTrue(v4lp.addLinkAddress(new LinkAddress(ADDRV4, 16))); - assertTrue(v4lp.isReachable(DNS1)); - assertFalse(v4lp.isReachable(DNS2)); - - // Adding a default route makes the off-link DNS server reachable. - assertTrue(v4lp.addRoute(new RouteInfo(GATEWAY1))); - assertTrue(v4lp.isReachable(DNS1)); - assertTrue(v4lp.isReachable(DNS2)); - - final LinkProperties v6lp = new LinkProperties(); - final InetAddress kLinkLocalDns = address("fe80::6:1"); - final InetAddress kLinkLocalDnsWithScope = address("fe80::6:2%43"); - final InetAddress kOnLinkDns = address("2001:db8:85a3::53"); - assertFalse(v6lp.isReachable(kLinkLocalDns)); - assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope)); - assertFalse(v6lp.isReachable(kOnLinkDns)); - assertFalse(v6lp.isReachable(DNS6)); - - // Add a link-local route, making the link-local DNS servers reachable. Because - // we assume the presence of an IPv6 link-local address, link-local DNS servers - // are considered reachable, but only those with a non-zero scope identifier. - assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(address("fe80::"), 64)))); - assertFalse(v6lp.isReachable(kLinkLocalDns)); - assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope)); - assertFalse(v6lp.isReachable(kOnLinkDns)); - assertFalse(v6lp.isReachable(DNS6)); - - // Add a link-local address--nothing changes. - assertTrue(v6lp.addLinkAddress(LINKADDRV6LINKLOCAL)); - assertFalse(v6lp.isReachable(kLinkLocalDns)); - assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope)); - assertFalse(v6lp.isReachable(kOnLinkDns)); - assertFalse(v6lp.isReachable(DNS6)); - - // Add a global route on link, but no global address yet. DNS servers reachable - // via a route that doesn't require a gateway: give them the benefit of the - // doubt and hope the link-local source address suffices for communication. - assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(address("2001:db8:85a3::"), 64)))); - assertFalse(v6lp.isReachable(kLinkLocalDns)); - assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope)); - assertTrue(v6lp.isReachable(kOnLinkDns)); - assertFalse(v6lp.isReachable(DNS6)); - - // Add a global address; the on-link global address DNS server is (still) - // presumed reachable. - assertTrue(v6lp.addLinkAddress(new LinkAddress(ADDRV6, 64))); - assertFalse(v6lp.isReachable(kLinkLocalDns)); - assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope)); - assertTrue(v6lp.isReachable(kOnLinkDns)); - assertFalse(v6lp.isReachable(DNS6)); - - // Adding a default route makes the off-link DNS server reachable. - assertTrue(v6lp.addRoute(new RouteInfo(GATEWAY62))); - assertFalse(v6lp.isReachable(kLinkLocalDns)); - assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope)); - assertTrue(v6lp.isReachable(kOnLinkDns)); - assertTrue(v6lp.isReachable(DNS6)); - - // Check isReachable on stacked links. This requires that the source IP address be assigned - // on the interface returned by the route lookup. - LinkProperties stacked = new LinkProperties(); - - // Can't add a stacked link without an interface name. - stacked.setInterfaceName("v4-test0"); - v6lp.addStackedLink(stacked); - - InetAddress stackedAddress = address("192.0.0.4"); - LinkAddress stackedLinkAddress = new LinkAddress(stackedAddress, 32); - assertFalse(v6lp.isReachable(stackedAddress)); - stacked.addLinkAddress(stackedLinkAddress); - assertFalse(v6lp.isReachable(stackedAddress)); - stacked.addRoute(new RouteInfo(stackedLinkAddress)); - assertTrue(stacked.isReachable(stackedAddress)); - assertTrue(v6lp.isReachable(stackedAddress)); - - assertFalse(v6lp.isReachable(DNS1)); - stacked.addRoute(new RouteInfo((IpPrefix) null, stackedAddress)); - assertTrue(v6lp.isReachable(DNS1)); - } - - @Test - public void testLinkPropertiesEnsureDirectlyConnectedRoutes() { - // IPv4 case: no route added initially - LinkProperties rmnet0 = new LinkProperties(); - rmnet0.setInterfaceName("rmnet0"); - rmnet0.addLinkAddress(new LinkAddress("10.0.0.2/8")); - RouteInfo directRoute0 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null, - rmnet0.getInterfaceName()); - - // Since no routes is added explicitly, getAllRoutes() should return empty. - assertTrue(rmnet0.getAllRoutes().isEmpty()); - rmnet0.ensureDirectlyConnectedRoutes(); - // ensureDirectlyConnectedRoutes() should have added the missing local route. - assertEqualRoutes(Collections.singletonList(directRoute0), rmnet0.getAllRoutes()); - - // IPv4 case: both direct and default routes added initially - LinkProperties rmnet1 = new LinkProperties(); - rmnet1.setInterfaceName("rmnet1"); - rmnet1.addLinkAddress(new LinkAddress("10.0.0.3/8")); - RouteInfo defaultRoute1 = new RouteInfo((IpPrefix) null, address("10.0.0.1"), - rmnet1.getInterfaceName()); - RouteInfo directRoute1 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null, - rmnet1.getInterfaceName()); - rmnet1.addRoute(defaultRoute1); - rmnet1.addRoute(directRoute1); - - // Check added routes - assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes()); - // ensureDirectlyConnectedRoutes() shouldn't change the routes since direct connected - // route is already part of the configuration. - rmnet1.ensureDirectlyConnectedRoutes(); - assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes()); - - // IPv6 case: only default routes added initially - LinkProperties rmnet2 = new LinkProperties(); - rmnet2.setInterfaceName("rmnet2"); - rmnet2.addLinkAddress(new LinkAddress("fe80::cafe/64")); - rmnet2.addLinkAddress(new LinkAddress("2001:db8::2/64")); - RouteInfo defaultRoute2 = new RouteInfo((IpPrefix) null, address("2001:db8::1"), - rmnet2.getInterfaceName()); - RouteInfo directRoute2 = new RouteInfo(new IpPrefix("2001:db8::/64"), null, - rmnet2.getInterfaceName()); - RouteInfo linkLocalRoute2 = new RouteInfo(new IpPrefix("fe80::/64"), null, - rmnet2.getInterfaceName()); - rmnet2.addRoute(defaultRoute2); - - assertEqualRoutes(Arrays.asList(defaultRoute2), rmnet2.getAllRoutes()); - rmnet2.ensureDirectlyConnectedRoutes(); - assertEqualRoutes(Arrays.asList(defaultRoute2, directRoute2, linkLocalRoute2), - rmnet2.getAllRoutes()); - - // Corner case: no interface name - LinkProperties rmnet3 = new LinkProperties(); - rmnet3.addLinkAddress(new LinkAddress("192.168.0.2/24")); - RouteInfo directRoute3 = new RouteInfo(new IpPrefix("192.168.0.0/24"), null, - rmnet3.getInterfaceName()); - - assertTrue(rmnet3.getAllRoutes().isEmpty()); - rmnet3.ensureDirectlyConnectedRoutes(); - assertEqualRoutes(Collections.singletonList(directRoute3), rmnet3.getAllRoutes()); - } - - private void assertEqualRoutes(Collection<RouteInfo> expected, Collection<RouteInfo> actual) { - Set<RouteInfo> expectedSet = new ArraySet<>(expected); - Set<RouteInfo> actualSet = new ArraySet<>(actual); - // Duplicated entries in actual routes are considered failures - assertEquals(actual.size(), actualSet.size()); - - assertEquals(expectedSet, actualSet); - } - - private static LinkProperties makeLinkPropertiesForParceling() { - LinkProperties source = new LinkProperties(); - source.setInterfaceName(NAME); - - source.addLinkAddress(LINKADDRV4); - source.addLinkAddress(LINKADDRV6); - - source.addDnsServer(DNS1); - source.addDnsServer(DNS2); - source.addDnsServer(GATEWAY62); - - source.addPcscfServer(TESTIPV4ADDR); - source.addPcscfServer(TESTIPV6ADDR); - - source.setUsePrivateDns(true); - source.setPrivateDnsServerName(PRIV_DNS_SERVER_NAME); - - source.setDomains(DOMAINS); - - source.addRoute(new RouteInfo(GATEWAY1)); - source.addRoute(new RouteInfo(GATEWAY2)); - - source.addValidatedPrivateDnsServer(DNS6); - source.addValidatedPrivateDnsServer(GATEWAY61); - source.addValidatedPrivateDnsServer(TESTIPV6ADDR); - - source.setHttpProxy(ProxyInfo.buildDirectProxy("test", 8888)); - - source.setMtu(MTU); - - source.setTcpBufferSizes(TCP_BUFFER_SIZES); - - source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96")); - - final LinkProperties stacked = new LinkProperties(); - stacked.setInterfaceName("test-stacked"); - source.addStackedLink(stacked); - - return source; - } - - @Test @IgnoreAfter(Build.VERSION_CODES.Q) - public void testLinkPropertiesParcelable_Q() throws Exception { - final LinkProperties source = makeLinkPropertiesForParceling(); - assertParcelSane(source, 14 /* fieldCount */); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testLinkPropertiesParcelable() throws Exception { - final LinkProperties source = makeLinkPropertiesForParceling(); - - source.setWakeOnLanSupported(true); - source.setCaptivePortalApiUrl(CAPPORT_API_URL); - source.setCaptivePortalData((CaptivePortalData) getCaptivePortalData()); - source.setDhcpServerAddress((Inet4Address) GATEWAY1); - assertParcelSane(new LinkProperties(source, true /* parcelSensitiveFields */), - 18 /* fieldCount */); - - // Verify that without using a sensitiveFieldsParcelingCopy, sensitive fields are cleared. - final LinkProperties sanitized = new LinkProperties(source); - sanitized.setCaptivePortalApiUrl(null); - sanitized.setCaptivePortalData(null); - assertEquals(sanitized, parcelingRoundTrip(source)); - } - - // Parceling of the scope was broken until Q-QPR2 - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testLinkLocalDnsServerParceling() throws Exception { - final String strAddress = "fe80::1%lo"; - final LinkProperties lp = new LinkProperties(); - lp.addDnsServer(address(strAddress)); - final LinkProperties unparceled = parcelingRoundTrip(lp); - // Inet6Address#equals does not test for the scope id - assertEquals(strAddress, unparceled.getDnsServers().get(0).getHostAddress()); - } - - @Test - public void testParcelUninitialized() throws Exception { - LinkProperties empty = new LinkProperties(); - assertParcelingIsLossless(empty); - } - - @Test - public void testConstructor() { - LinkProperties lp = new LinkProperties(); - checkEmpty(lp); - assertLinkPropertiesEqual(lp, new LinkProperties(lp)); - assertLinkPropertiesEqual(lp, new LinkProperties()); - - lp = makeTestObject(); - assertLinkPropertiesEqual(lp, new LinkProperties(lp)); - } - - @Test - public void testDnsServers() { - final LinkProperties lp = new LinkProperties(); - final List<InetAddress> dnsServers = Arrays.asList(DNS1, DNS2); - lp.setDnsServers(dnsServers); - assertEquals(2, lp.getDnsServers().size()); - assertEquals(DNS1, lp.getDnsServers().get(0)); - assertEquals(DNS2, lp.getDnsServers().get(1)); - - lp.removeDnsServer(DNS1); - assertEquals(1, lp.getDnsServers().size()); - assertEquals(DNS2, lp.getDnsServers().get(0)); - - lp.addDnsServer(DNS6); - assertEquals(2, lp.getDnsServers().size()); - assertEquals(DNS2, lp.getDnsServers().get(0)); - assertEquals(DNS6, lp.getDnsServers().get(1)); - } - - @Test - public void testValidatedPrivateDnsServers() { - final LinkProperties lp = new LinkProperties(); - final List<InetAddress> privDnsServers = Arrays.asList(PRIVDNS1, PRIVDNS2); - lp.setValidatedPrivateDnsServers(privDnsServers); - assertEquals(2, lp.getValidatedPrivateDnsServers().size()); - assertEquals(PRIVDNS1, lp.getValidatedPrivateDnsServers().get(0)); - assertEquals(PRIVDNS2, lp.getValidatedPrivateDnsServers().get(1)); - - lp.removeValidatedPrivateDnsServer(PRIVDNS1); - assertEquals(1, lp.getValidatedPrivateDnsServers().size()); - assertEquals(PRIVDNS2, lp.getValidatedPrivateDnsServers().get(0)); - - lp.addValidatedPrivateDnsServer(PRIVDNS6); - assertEquals(2, lp.getValidatedPrivateDnsServers().size()); - assertEquals(PRIVDNS2, lp.getValidatedPrivateDnsServers().get(0)); - assertEquals(PRIVDNS6, lp.getValidatedPrivateDnsServers().get(1)); - } - - @Test - public void testPcscfServers() { - final LinkProperties lp = new LinkProperties(); - final List<InetAddress> pcscfServers = Arrays.asList(PCSCFV4); - lp.setPcscfServers(pcscfServers); - assertEquals(1, lp.getPcscfServers().size()); - assertEquals(PCSCFV4, lp.getPcscfServers().get(0)); - - lp.removePcscfServer(PCSCFV4); - assertEquals(0, lp.getPcscfServers().size()); - - lp.addPcscfServer(PCSCFV6); - assertEquals(1, lp.getPcscfServers().size()); - assertEquals(PCSCFV6, lp.getPcscfServers().get(0)); - } - - @Test - public void testTcpBufferSizes() { - final LinkProperties lp = makeTestObject(); - assertEquals(TCP_BUFFER_SIZES, lp.getTcpBufferSizes()); - - lp.setTcpBufferSizes(null); - assertNull(lp.getTcpBufferSizes()); - } - - @Test - public void testHasIpv6DefaultRoute() { - final LinkProperties lp = makeTestObject(); - assertFalse(lp.hasIPv6DefaultRoute()); - - lp.addRoute(new RouteInfo(GATEWAY61)); - assertTrue(lp.hasIPv6DefaultRoute()); - } - - @Test - public void testHttpProxy() { - final LinkProperties lp = makeTestObject(); - assertTrue(lp.getHttpProxy().equals(ProxyInfo.buildDirectProxy("test", 8888))); - } - - @Test - public void testPrivateDnsServerName() { - final LinkProperties lp = makeTestObject(); - assertEquals(PRIV_DNS_SERVER_NAME, lp.getPrivateDnsServerName()); - - lp.setPrivateDnsServerName(null); - assertNull(lp.getPrivateDnsServerName()); - } - - @Test - public void testUsePrivateDns() { - final LinkProperties lp = makeTestObject(); - assertTrue(lp.isPrivateDnsActive()); - - lp.clear(); - assertFalse(lp.isPrivateDnsActive()); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testDhcpServerAddress() { - final LinkProperties lp = makeTestObject(); - assertEquals(DHCPSERVER, lp.getDhcpServerAddress()); - - lp.clear(); - assertNull(lp.getDhcpServerAddress()); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testWakeOnLanSupported() { - final LinkProperties lp = makeTestObject(); - assertTrue(lp.isWakeOnLanSupported()); - - lp.clear(); - assertFalse(lp.isWakeOnLanSupported()); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testCaptivePortalApiUrl() { - final LinkProperties lp = makeTestObject(); - assertEquals(CAPPORT_API_URL, lp.getCaptivePortalApiUrl()); - - lp.clear(); - assertNull(lp.getCaptivePortalApiUrl()); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testCaptivePortalData() { - final LinkProperties lp = makeTestObject(); - assertEquals(getCaptivePortalData(), lp.getCaptivePortalData()); - - lp.clear(); - assertNull(lp.getCaptivePortalData()); - } - - private LinkProperties makeIpv4LinkProperties() { - final LinkProperties linkProperties = new LinkProperties(); - linkProperties.setInterfaceName(NAME); - linkProperties.addLinkAddress(LINKADDRV4); - linkProperties.addDnsServer(DNS1); - linkProperties.addRoute(new RouteInfo(GATEWAY1)); - linkProperties.addRoute(new RouteInfo(GATEWAY2)); - return linkProperties; - } - - private LinkProperties makeIpv6LinkProperties() { - final LinkProperties linkProperties = new LinkProperties(); - linkProperties.setInterfaceName(NAME); - linkProperties.addLinkAddress(LINKADDRV6); - linkProperties.addDnsServer(DNS6); - linkProperties.addRoute(new RouteInfo(GATEWAY61)); - linkProperties.addRoute(new RouteInfo(GATEWAY62)); - return linkProperties; - } - - @Test - public void testHasIpv4DefaultRoute() { - final LinkProperties Ipv4 = makeIpv4LinkProperties(); - assertTrue(Ipv4.hasIpv4DefaultRoute()); - final LinkProperties Ipv6 = makeIpv6LinkProperties(); - assertFalse(Ipv6.hasIpv4DefaultRoute()); - } - - @Test - public void testHasIpv4DnsServer() { - final LinkProperties Ipv4 = makeIpv4LinkProperties(); - assertTrue(Ipv4.hasIpv4DnsServer()); - final LinkProperties Ipv6 = makeIpv6LinkProperties(); - assertFalse(Ipv6.hasIpv4DnsServer()); - } - - @Test - public void testHasIpv6DnsServer() { - final LinkProperties Ipv4 = makeIpv4LinkProperties(); - assertFalse(Ipv4.hasIpv6DnsServer()); - final LinkProperties Ipv6 = makeIpv6LinkProperties(); - assertTrue(Ipv6.hasIpv6DnsServer()); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testHasIpv4UnreachableDefaultRoute() { - final LinkProperties lp = makeTestObject(); - assertFalse(lp.hasIpv4UnreachableDefaultRoute()); - assertFalse(lp.hasIpv6UnreachableDefaultRoute()); - - lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); - assertTrue(lp.hasIpv4UnreachableDefaultRoute()); - assertFalse(lp.hasIpv6UnreachableDefaultRoute()); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testHasIpv6UnreachableDefaultRoute() { - final LinkProperties lp = makeTestObject(); - assertFalse(lp.hasIpv6UnreachableDefaultRoute()); - assertFalse(lp.hasIpv4UnreachableDefaultRoute()); - - lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); - assertTrue(lp.hasIpv6UnreachableDefaultRoute()); - assertFalse(lp.hasIpv4UnreachableDefaultRoute()); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testRouteAddWithSameKey() throws Exception { - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName("wlan0"); - final IpPrefix v6 = new IpPrefix("64:ff9b::/96"); - lp.addRoute(new RouteInfo(v6, address("fe80::1"), "wlan0", RTN_UNICAST, 1280)); - assertEquals(1, lp.getRoutes().size()); - lp.addRoute(new RouteInfo(v6, address("fe80::1"), "wlan0", RTN_UNICAST, 1500)); - assertEquals(1, lp.getRoutes().size()); - final IpPrefix v4 = new IpPrefix("192.0.2.128/25"); - lp.addRoute(new RouteInfo(v4, address("192.0.2.1"), "wlan0", RTN_UNICAST, 1460)); - assertEquals(2, lp.getRoutes().size()); - lp.addRoute(new RouteInfo(v4, address("192.0.2.1"), "wlan0", RTN_THROW, 1460)); - assertEquals(2, lp.getRoutes().size()); - } -} diff --git a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt deleted file mode 100644 index a5e44d59fcab..000000000000 --- a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net - -import android.net.wifi.aware.DiscoverySession -import android.net.wifi.aware.PeerHandle -import android.net.wifi.aware.WifiAwareNetworkSpecifier -import android.os.Build -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 - -import com.android.testutils.assertParcelSane -import com.android.testutils.DevSdkIgnoreRule -import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo - -import java.lang.IllegalStateException - -import org.junit.Assert.assertFalse -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mockito - -@RunWith(AndroidJUnit4::class) -@SmallTest -class MatchAllNetworkSpecifierTest { - @Rule @JvmField - val ignoreRule: DevSdkIgnoreRule = DevSdkIgnoreRule() - - private val specifier = MatchAllNetworkSpecifier() - private val discoverySession = Mockito.mock(DiscoverySession::class.java) - private val peerHandle = Mockito.mock(PeerHandle::class.java) - private val wifiAwareNetworkSpecifier = WifiAwareNetworkSpecifier.Builder(discoverySession, - peerHandle).build() - - @Test - fun testParcel() { - assertParcelSane(MatchAllNetworkSpecifier(), 0) - } - - @Test - @IgnoreUpTo(Build.VERSION_CODES.Q) - @IgnoreAfter(Build.VERSION_CODES.R) - // Only run this test on Android R. - // The method - satisfiedBy() has changed to canBeSatisfiedBy() starting from Android R, so the - // method - canBeSatisfiedBy() cannot be found when running this test on Android Q. - fun testCanBeSatisfiedBy_OnlyForR() { - // MatchAllNetworkSpecifier didn't follow its parent class to change the satisfiedBy() to - // canBeSatisfiedBy(), so if a caller calls MatchAllNetworkSpecifier#canBeSatisfiedBy(), the - // NetworkSpecifier#canBeSatisfiedBy() will be called actually, and false will be returned. - // Although it's not meeting the expectation, the behavior still needs to be verified. - assertFalse(specifier.canBeSatisfiedBy(wifiAwareNetworkSpecifier)) - } - - @Test(expected = IllegalStateException::class) - @IgnoreUpTo(Build.VERSION_CODES.R) - fun testCanBeSatisfiedBy() { - specifier.canBeSatisfiedBy(wifiAwareNetworkSpecifier) - } -} diff --git a/tests/net/common/java/android/net/NattKeepalivePacketDataTest.kt b/tests/net/common/java/android/net/NattKeepalivePacketDataTest.kt deleted file mode 100644 index 46f39dd016fd..000000000000 --- a/tests/net/common/java/android/net/NattKeepalivePacketDataTest.kt +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net - -import android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS -import android.net.InvalidPacketException.ERROR_INVALID_PORT -import android.net.NattSocketKeepalive.NATT_PORT -import android.os.Build -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.testutils.assertEqualBothWays -import com.android.testutils.assertFieldCountEquals -import com.android.testutils.assertParcelSane -import com.android.testutils.DevSdkIgnoreRule -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo -import com.android.testutils.parcelingRoundTrip -import java.net.InetAddress -import org.junit.Assert.assertEquals -import org.junit.Assert.assertNotEquals -import org.junit.Assert.fail -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -@SmallTest -class NattKeepalivePacketDataTest { - @Rule @JvmField - val ignoreRule: DevSdkIgnoreRule = DevSdkIgnoreRule() - - /* Refer to the definition in {@code NattKeepalivePacketData} */ - private val IPV4_HEADER_LENGTH = 20 - private val UDP_HEADER_LENGTH = 8 - - private val TEST_PORT = 4243 - private val TEST_PORT2 = 4244 - private val TEST_SRC_ADDRV4 = "198.168.0.2".address() - private val TEST_DST_ADDRV4 = "198.168.0.1".address() - private val TEST_ADDRV6 = "2001:db8::1".address() - - private fun String.address() = InetAddresses.parseNumericAddress(this) - private fun nattKeepalivePacket( - srcAddress: InetAddress? = TEST_SRC_ADDRV4, - srcPort: Int = TEST_PORT, - dstAddress: InetAddress? = TEST_DST_ADDRV4, - dstPort: Int = NATT_PORT - ) = NattKeepalivePacketData.nattKeepalivePacket(srcAddress, srcPort, dstAddress, dstPort) - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - fun testConstructor() { - try { - nattKeepalivePacket(dstPort = TEST_PORT) - fail("Dst port is not NATT port should cause exception") - } catch (e: InvalidPacketException) { - assertEquals(e.error, ERROR_INVALID_PORT) - } - - try { - nattKeepalivePacket(srcAddress = TEST_ADDRV6) - fail("A v6 srcAddress should cause exception") - } catch (e: InvalidPacketException) { - assertEquals(e.error, ERROR_INVALID_IP_ADDRESS) - } - - try { - nattKeepalivePacket(dstAddress = TEST_ADDRV6) - fail("A v6 dstAddress should cause exception") - } catch (e: InvalidPacketException) { - assertEquals(e.error, ERROR_INVALID_IP_ADDRESS) - } - - try { - parcelingRoundTrip( - NattKeepalivePacketData(TEST_SRC_ADDRV4, TEST_PORT, TEST_DST_ADDRV4, TEST_PORT, - byteArrayOf(12, 31, 22, 44))) - fail("Invalid data should cause exception") - } catch (e: IllegalArgumentException) { } - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - fun testParcel() { - assertParcelSane(nattKeepalivePacket(), 0) - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - fun testEquals() { - assertEqualBothWays(nattKeepalivePacket(), nattKeepalivePacket()) - assertNotEquals(nattKeepalivePacket(dstAddress = TEST_SRC_ADDRV4), nattKeepalivePacket()) - assertNotEquals(nattKeepalivePacket(srcAddress = TEST_DST_ADDRV4), nattKeepalivePacket()) - // Test src port only because dst port have to be NATT_PORT - assertNotEquals(nattKeepalivePacket(srcPort = TEST_PORT2), nattKeepalivePacket()) - // Make sure the parceling test is updated if fields are added in the base class. - assertFieldCountEquals(5, KeepalivePacketData::class.java) - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - fun testHashCode() { - assertEquals(nattKeepalivePacket().hashCode(), nattKeepalivePacket().hashCode()) - } -}
\ No newline at end of file diff --git a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt deleted file mode 100644 index 2b45b3d69ce9..000000000000 --- a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net - -import android.os.Build -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.modules.utils.build.SdkLevel.isAtLeastS -import com.android.testutils.DevSdkIgnoreRule -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo -import com.android.testutils.assertParcelSane -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -@SmallTest -class NetworkAgentConfigTest { - @Rule @JvmField - val ignoreRule = DevSdkIgnoreRule() - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - fun testParcelNetworkAgentConfig() { - val config = NetworkAgentConfig.Builder().apply { - setExplicitlySelected(true) - setLegacyType(ConnectivityManager.TYPE_ETHERNET) - setSubscriberId("MySubId") - setPartialConnectivityAcceptable(false) - setUnvalidatedConnectivityAcceptable(true) - if (isAtLeastS()) { - setBypassableVpn(true) - } - }.build() - if (isAtLeastS()) { - // From S, the config will have 12 items - assertParcelSane(config, 12) - } else { - // For R or below, the config will have 10 items - assertParcelSane(config, 10) - } - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - fun testBuilder() { - val config = NetworkAgentConfig.Builder().apply { - setExplicitlySelected(true) - setLegacyType(ConnectivityManager.TYPE_ETHERNET) - setSubscriberId("MySubId") - setPartialConnectivityAcceptable(false) - setUnvalidatedConnectivityAcceptable(true) - setLegacyTypeName("TEST_NETWORK") - if (isAtLeastS()) { - setNat64DetectionEnabled(false) - setProvisioningNotificationEnabled(false) - setBypassableVpn(true) - } - }.build() - - assertTrue(config.isExplicitlySelected()) - assertEquals(ConnectivityManager.TYPE_ETHERNET, config.getLegacyType()) - assertEquals("MySubId", config.getSubscriberId()) - assertFalse(config.isPartialConnectivityAcceptable()) - assertTrue(config.isUnvalidatedConnectivityAcceptable()) - assertEquals("TEST_NETWORK", config.getLegacyTypeName()) - if (isAtLeastS()) { - assertFalse(config.isNat64DetectionEnabled()) - assertFalse(config.isProvisioningNotificationEnabled()) - assertTrue(config.isBypassableVpn()) - } else { - assertTrue(config.isNat64DetectionEnabled()) - assertTrue(config.isProvisioningNotificationEnabled()) - } - } -} diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java deleted file mode 100644 index 9efdde4da0c0..000000000000 --- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java +++ /dev/null @@ -1,1158 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; -import static android.net.NetworkCapabilities.MAX_TRANSPORT; -import static android.net.NetworkCapabilities.MIN_TRANSPORT; -import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; -import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS; -import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS; -import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; -import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; -import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; -import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; -import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; -import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; -import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; -import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; -import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS; -import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; -import static android.net.NetworkCapabilities.SIGNAL_STRENGTH_UNSPECIFIED; -import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; -import static android.net.NetworkCapabilities.TRANSPORT_TEST; -import static android.net.NetworkCapabilities.TRANSPORT_VPN; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE; -import static android.os.Process.INVALID_UID; - -import static com.android.modules.utils.build.SdkLevel.isAtLeastR; -import static com.android.modules.utils.build.SdkLevel.isAtLeastS; -import static com.android.net.module.util.NetworkCapabilitiesUtils.TRANSPORT_USB; -import static com.android.testutils.MiscAsserts.assertEmpty; -import static com.android.testutils.MiscAsserts.assertThrows; -import static com.android.testutils.ParcelUtils.assertParcelSane; -import static com.android.testutils.ParcelUtils.assertParcelingIsLossless; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; - -import android.net.wifi.aware.DiscoverySession; -import android.net.wifi.aware.PeerHandle; -import android.net.wifi.aware.WifiAwareNetworkSpecifier; -import android.os.Build; -import android.test.suitebuilder.annotation.SmallTest; -import android.util.ArraySet; -import android.util.Range; - -import androidx.test.runner.AndroidJUnit4; - -import com.android.testutils.CompatUtil; -import com.android.testutils.DevSdkIgnoreRule; -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; - -import java.util.Arrays; -import java.util.Set; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetworkCapabilitiesTest { - private static final String TEST_SSID = "TEST_SSID"; - private static final String DIFFERENT_TEST_SSID = "DIFFERENT_TEST_SSID"; - private static final int TEST_SUBID1 = 1; - private static final int TEST_SUBID2 = 2; - private static final int TEST_SUBID3 = 3; - - @Rule - public DevSdkIgnoreRule mDevSdkIgnoreRule = new DevSdkIgnoreRule(); - - private DiscoverySession mDiscoverySession = Mockito.mock(DiscoverySession.class); - private PeerHandle mPeerHandle = Mockito.mock(PeerHandle.class); - - @Test - public void testMaybeMarkCapabilitiesRestricted() { - // check that internet does not get restricted - NetworkCapabilities netCap = new NetworkCapabilities(); - netCap.addCapability(NET_CAPABILITY_INTERNET); - netCap.maybeMarkCapabilitiesRestricted(); - assertTrue(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - - // metered-ness shouldn't matter - netCap = new NetworkCapabilities(); - netCap.addCapability(NET_CAPABILITY_INTERNET); - netCap.addCapability(NET_CAPABILITY_NOT_METERED); - netCap.maybeMarkCapabilitiesRestricted(); - assertTrue(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - netCap = new NetworkCapabilities(); - netCap.addCapability(NET_CAPABILITY_INTERNET); - netCap.removeCapability(NET_CAPABILITY_NOT_METERED); - netCap.maybeMarkCapabilitiesRestricted(); - assertTrue(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - - // add EIMS - bundled with unrestricted means it's unrestricted - netCap = new NetworkCapabilities(); - netCap.addCapability(NET_CAPABILITY_INTERNET); - netCap.addCapability(NET_CAPABILITY_EIMS); - netCap.addCapability(NET_CAPABILITY_NOT_METERED); - netCap.maybeMarkCapabilitiesRestricted(); - assertTrue(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - netCap = new NetworkCapabilities(); - netCap.addCapability(NET_CAPABILITY_INTERNET); - netCap.addCapability(NET_CAPABILITY_EIMS); - netCap.removeCapability(NET_CAPABILITY_NOT_METERED); - netCap.maybeMarkCapabilitiesRestricted(); - assertTrue(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - - // just a restricted cap should be restricted regardless of meteredness - netCap = new NetworkCapabilities(); - netCap.addCapability(NET_CAPABILITY_EIMS); - netCap.addCapability(NET_CAPABILITY_NOT_METERED); - netCap.maybeMarkCapabilitiesRestricted(); - assertFalse(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - netCap = new NetworkCapabilities(); - netCap.addCapability(NET_CAPABILITY_EIMS); - netCap.removeCapability(NET_CAPABILITY_NOT_METERED); - netCap.maybeMarkCapabilitiesRestricted(); - assertFalse(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - - // try 2 restricted caps - netCap = new NetworkCapabilities(); - netCap.addCapability(NET_CAPABILITY_CBS); - netCap.addCapability(NET_CAPABILITY_EIMS); - netCap.addCapability(NET_CAPABILITY_NOT_METERED); - netCap.maybeMarkCapabilitiesRestricted(); - assertFalse(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - netCap = new NetworkCapabilities(); - netCap.addCapability(NET_CAPABILITY_CBS); - netCap.addCapability(NET_CAPABILITY_EIMS); - netCap.removeCapability(NET_CAPABILITY_NOT_METERED); - netCap.maybeMarkCapabilitiesRestricted(); - assertFalse(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - } - - @Test - public void testDescribeImmutableDifferences() { - NetworkCapabilities nc1; - NetworkCapabilities nc2; - - // Transports changing - nc1 = new NetworkCapabilities().addTransportType(TRANSPORT_CELLULAR); - nc2 = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI); - assertNotEquals("", nc1.describeImmutableDifferences(nc2)); - assertEquals("", nc1.describeImmutableDifferences(nc1)); - - // Mutable capability changing - nc1 = new NetworkCapabilities().addCapability(NET_CAPABILITY_VALIDATED); - nc2 = new NetworkCapabilities(); - assertEquals("", nc1.describeImmutableDifferences(nc2)); - assertEquals("", nc1.describeImmutableDifferences(nc1)); - - // NOT_METERED changing (http://b/63326103) - nc1 = new NetworkCapabilities() - .addCapability(NET_CAPABILITY_NOT_METERED) - .addCapability(NET_CAPABILITY_INTERNET); - nc2 = new NetworkCapabilities().addCapability(NET_CAPABILITY_INTERNET); - assertEquals("", nc1.describeImmutableDifferences(nc2)); - assertEquals("", nc1.describeImmutableDifferences(nc1)); - - // Immutable capability changing - nc1 = new NetworkCapabilities() - .addCapability(NET_CAPABILITY_INTERNET) - .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); - nc2 = new NetworkCapabilities().addCapability(NET_CAPABILITY_INTERNET); - assertNotEquals("", nc1.describeImmutableDifferences(nc2)); - assertEquals("", nc1.describeImmutableDifferences(nc1)); - - // Specifier changing - nc1 = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI); - nc2 = new NetworkCapabilities() - .addTransportType(TRANSPORT_WIFI) - .setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier("eth42")); - assertNotEquals("", nc1.describeImmutableDifferences(nc2)); - assertEquals("", nc1.describeImmutableDifferences(nc1)); - } - - @Test - public void testLinkBandwidthUtils() { - assertEquals(LINK_BANDWIDTH_UNSPECIFIED, NetworkCapabilities - .minBandwidth(LINK_BANDWIDTH_UNSPECIFIED, LINK_BANDWIDTH_UNSPECIFIED)); - assertEquals(10, NetworkCapabilities - .minBandwidth(LINK_BANDWIDTH_UNSPECIFIED, 10)); - assertEquals(10, NetworkCapabilities - .minBandwidth(10, LINK_BANDWIDTH_UNSPECIFIED)); - assertEquals(10, NetworkCapabilities - .minBandwidth(10, 20)); - - assertEquals(LINK_BANDWIDTH_UNSPECIFIED, NetworkCapabilities - .maxBandwidth(LINK_BANDWIDTH_UNSPECIFIED, LINK_BANDWIDTH_UNSPECIFIED)); - assertEquals(10, NetworkCapabilities - .maxBandwidth(LINK_BANDWIDTH_UNSPECIFIED, 10)); - assertEquals(10, NetworkCapabilities - .maxBandwidth(10, LINK_BANDWIDTH_UNSPECIFIED)); - assertEquals(20, NetworkCapabilities - .maxBandwidth(10, 20)); - } - - @Test - public void testSetUids() { - final NetworkCapabilities netCap = new NetworkCapabilities(); - // Null uids match all UIDs - netCap.setUids(null); - assertTrue(netCap.appliesToUid(10)); - assertTrue(netCap.appliesToUid(200)); - assertTrue(netCap.appliesToUid(3000)); - assertTrue(netCap.appliesToUid(10010)); - assertTrue(netCap.appliesToUidRange(new UidRange(50, 100))); - assertTrue(netCap.appliesToUidRange(new UidRange(70, 72))); - assertTrue(netCap.appliesToUidRange(new UidRange(3500, 3912))); - assertTrue(netCap.appliesToUidRange(new UidRange(1, 100000))); - - if (isAtLeastS()) { - final Set<Range<Integer>> uids = new ArraySet<>(); - uids.add(uidRange(50, 100)); - uids.add(uidRange(3000, 4000)); - netCap.setUids(uids); - assertTrue(netCap.appliesToUid(50)); - assertTrue(netCap.appliesToUid(80)); - assertTrue(netCap.appliesToUid(100)); - assertTrue(netCap.appliesToUid(3000)); - assertTrue(netCap.appliesToUid(3001)); - assertFalse(netCap.appliesToUid(10)); - assertFalse(netCap.appliesToUid(25)); - assertFalse(netCap.appliesToUid(49)); - assertFalse(netCap.appliesToUid(101)); - assertFalse(netCap.appliesToUid(2000)); - assertFalse(netCap.appliesToUid(100000)); - - assertTrue(netCap.appliesToUidRange(new UidRange(50, 100))); - assertTrue(netCap.appliesToUidRange(new UidRange(70, 72))); - assertTrue(netCap.appliesToUidRange(new UidRange(3500, 3912))); - assertFalse(netCap.appliesToUidRange(new UidRange(1, 100))); - assertFalse(netCap.appliesToUidRange(new UidRange(49, 100))); - assertFalse(netCap.appliesToUidRange(new UidRange(1, 10))); - assertFalse(netCap.appliesToUidRange(new UidRange(60, 101))); - assertFalse(netCap.appliesToUidRange(new UidRange(60, 3400))); - - NetworkCapabilities netCap2 = new NetworkCapabilities(); - // A new netcap object has null UIDs, so anything will satisfy it. - assertTrue(netCap2.satisfiedByUids(netCap)); - // Still not equal though. - assertFalse(netCap2.equalsUids(netCap)); - netCap2.setUids(uids); - assertTrue(netCap2.satisfiedByUids(netCap)); - assertTrue(netCap.equalsUids(netCap2)); - assertTrue(netCap2.equalsUids(netCap)); - - uids.add(uidRange(600, 700)); - netCap2.setUids(uids); - assertFalse(netCap2.satisfiedByUids(netCap)); - assertFalse(netCap.appliesToUid(650)); - assertTrue(netCap2.appliesToUid(650)); - netCap.combineCapabilities(netCap2); - assertTrue(netCap2.satisfiedByUids(netCap)); - assertTrue(netCap.appliesToUid(650)); - assertFalse(netCap.appliesToUid(500)); - - assertTrue(new NetworkCapabilities().satisfiedByUids(netCap)); - netCap.combineCapabilities(new NetworkCapabilities()); - assertTrue(netCap.appliesToUid(500)); - assertTrue(netCap.appliesToUidRange(new UidRange(1, 100000))); - assertFalse(netCap2.appliesToUid(500)); - assertFalse(netCap2.appliesToUidRange(new UidRange(1, 100000))); - assertTrue(new NetworkCapabilities().satisfiedByUids(netCap)); - - // Null uids satisfies everything. - netCap.setUids(null); - assertTrue(netCap2.satisfiedByUids(netCap)); - assertTrue(netCap.satisfiedByUids(netCap2)); - netCap2.setUids(null); - assertTrue(netCap2.satisfiedByUids(netCap)); - assertTrue(netCap.satisfiedByUids(netCap2)); - } - } - - @Test - public void testParcelNetworkCapabilities() { - final Set<Range<Integer>> uids = new ArraySet<>(); - uids.add(uidRange(50, 100)); - uids.add(uidRange(3000, 4000)); - final NetworkCapabilities netCap = new NetworkCapabilities() - .addCapability(NET_CAPABILITY_INTERNET) - .addCapability(NET_CAPABILITY_EIMS) - .addCapability(NET_CAPABILITY_NOT_METERED); - if (isAtLeastS()) { - netCap.setSubscriptionIds(Set.of(TEST_SUBID1, TEST_SUBID2)); - netCap.setUids(uids); - } - if (isAtLeastR()) { - netCap.setOwnerUid(123); - netCap.setAdministratorUids(new int[] {5, 11}); - } - assertParcelingIsLossless(netCap); - netCap.setSSID(TEST_SSID); - testParcelSane(netCap); - } - - @Test - public void testParcelNetworkCapabilitiesWithRequestorUidAndPackageName() { - final NetworkCapabilities netCap = new NetworkCapabilities() - .addCapability(NET_CAPABILITY_INTERNET) - .addCapability(NET_CAPABILITY_EIMS) - .addCapability(NET_CAPABILITY_NOT_METERED); - if (isAtLeastR()) { - netCap.setRequestorPackageName("com.android.test"); - netCap.setRequestorUid(9304); - } - assertParcelingIsLossless(netCap); - netCap.setSSID(TEST_SSID); - testParcelSane(netCap); - } - - private void testParcelSane(NetworkCapabilities cap) { - if (isAtLeastS()) { - assertParcelSane(cap, 16); - } else if (isAtLeastR()) { - assertParcelSane(cap, 15); - } else { - assertParcelSane(cap, 11); - } - } - - private static NetworkCapabilities createNetworkCapabilitiesWithTransportInfo() { - return new NetworkCapabilities() - .addCapability(NET_CAPABILITY_INTERNET) - .addCapability(NET_CAPABILITY_EIMS) - .addCapability(NET_CAPABILITY_NOT_METERED) - .setSSID(TEST_SSID) - .setTransportInfo(new TestTransportInfo()) - .setRequestorPackageName("com.android.test") - .setRequestorUid(9304); - } - - @Test - public void testNetworkCapabilitiesCopyWithNoRedactions() { - assumeTrue(isAtLeastS()); - - final NetworkCapabilities netCap = createNetworkCapabilitiesWithTransportInfo(); - final NetworkCapabilities netCapWithNoRedactions = - new NetworkCapabilities(netCap, NetworkCapabilities.REDACT_NONE); - TestTransportInfo testTransportInfo = - (TestTransportInfo) netCapWithNoRedactions.getTransportInfo(); - assertFalse(testTransportInfo.locationRedacted); - assertFalse(testTransportInfo.localMacAddressRedacted); - assertFalse(testTransportInfo.settingsRedacted); - } - - @Test - public void testNetworkCapabilitiesCopyWithoutLocationSensitiveFields() { - assumeTrue(isAtLeastS()); - - final NetworkCapabilities netCap = createNetworkCapabilitiesWithTransportInfo(); - final NetworkCapabilities netCapWithNoRedactions = - new NetworkCapabilities(netCap, REDACT_FOR_ACCESS_FINE_LOCATION); - TestTransportInfo testTransportInfo = - (TestTransportInfo) netCapWithNoRedactions.getTransportInfo(); - assertTrue(testTransportInfo.locationRedacted); - assertFalse(testTransportInfo.localMacAddressRedacted); - assertFalse(testTransportInfo.settingsRedacted); - } - - @Test - public void testOemPaid() { - NetworkCapabilities nc = new NetworkCapabilities(); - // By default OEM_PAID is neither in the required or forbidden lists and the network is not - // restricted. - if (isAtLeastS()) { - assertFalse(nc.hasForbiddenCapability(NET_CAPABILITY_OEM_PAID)); - } - assertFalse(nc.hasCapability(NET_CAPABILITY_OEM_PAID)); - nc.maybeMarkCapabilitiesRestricted(); - assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - - // Adding OEM_PAID to capability list should make network restricted. - nc.addCapability(NET_CAPABILITY_OEM_PAID); - nc.addCapability(NET_CAPABILITY_INTERNET); // Combine with unrestricted capability. - nc.maybeMarkCapabilitiesRestricted(); - assertTrue(nc.hasCapability(NET_CAPABILITY_OEM_PAID)); - assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - - // Now let's make request for OEM_PAID network. - NetworkCapabilities nr = new NetworkCapabilities(); - nr.addCapability(NET_CAPABILITY_OEM_PAID); - nr.maybeMarkCapabilitiesRestricted(); - assertTrue(nr.satisfiedByNetworkCapabilities(nc)); - - // Request fails for network with the default capabilities. - assertFalse(nr.satisfiedByNetworkCapabilities(new NetworkCapabilities())); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.R) - public void testOemPrivate() { - NetworkCapabilities nc = new NetworkCapabilities(); - // By default OEM_PRIVATE is neither in the required or forbidden lists and the network is - // not restricted. - assertFalse(nc.hasForbiddenCapability(NET_CAPABILITY_OEM_PRIVATE)); - assertFalse(nc.hasCapability(NET_CAPABILITY_OEM_PRIVATE)); - nc.maybeMarkCapabilitiesRestricted(); - assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - - // Adding OEM_PRIVATE to capability list should make network restricted. - nc.addCapability(NET_CAPABILITY_OEM_PRIVATE); - nc.addCapability(NET_CAPABILITY_INTERNET); // Combine with unrestricted capability. - nc.maybeMarkCapabilitiesRestricted(); - assertTrue(nc.hasCapability(NET_CAPABILITY_OEM_PRIVATE)); - assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - - // Now let's make request for OEM_PRIVATE network. - NetworkCapabilities nr = new NetworkCapabilities(); - nr.addCapability(NET_CAPABILITY_OEM_PRIVATE); - nr.maybeMarkCapabilitiesRestricted(); - assertTrue(nr.satisfiedByNetworkCapabilities(nc)); - - // Request fails for network with the default capabilities. - assertFalse(nr.satisfiedByNetworkCapabilities(new NetworkCapabilities())); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.R) - public void testForbiddenCapabilities() { - NetworkCapabilities network = new NetworkCapabilities(); - - NetworkCapabilities request = new NetworkCapabilities(); - assertTrue("Request: " + request + ", Network:" + network, - request.satisfiedByNetworkCapabilities(network)); - - // Requesting absence of capabilities that network doesn't have. Request should satisfy. - request.addForbiddenCapability(NET_CAPABILITY_WIFI_P2P); - request.addForbiddenCapability(NET_CAPABILITY_NOT_METERED); - assertTrue(request.satisfiedByNetworkCapabilities(network)); - assertArrayEquals(new int[]{NET_CAPABILITY_WIFI_P2P, - NET_CAPABILITY_NOT_METERED}, - request.getForbiddenCapabilities()); - - // This is a default capability, just want to make sure its there because we use it below. - assertTrue(network.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - - // Verify that adding forbidden capability will effectively remove it from capability list. - request.addForbiddenCapability(NET_CAPABILITY_NOT_RESTRICTED); - assertTrue(request.hasForbiddenCapability(NET_CAPABILITY_NOT_RESTRICTED)); - assertFalse(request.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - - // Now this request won't be satisfied because network contains NOT_RESTRICTED. - assertFalse(request.satisfiedByNetworkCapabilities(network)); - network.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); - assertTrue(request.satisfiedByNetworkCapabilities(network)); - - // Verify that adding capability will effectively remove it from forbidden list - request.addCapability(NET_CAPABILITY_NOT_RESTRICTED); - assertTrue(request.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - assertFalse(request.hasForbiddenCapability(NET_CAPABILITY_NOT_RESTRICTED)); - - assertFalse(request.satisfiedByNetworkCapabilities(network)); - network.addCapability(NET_CAPABILITY_NOT_RESTRICTED); - assertTrue(request.satisfiedByNetworkCapabilities(network)); - } - - @Test - public void testConnectivityManagedCapabilities() { - NetworkCapabilities nc = new NetworkCapabilities(); - assertFalse(nc.hasConnectivityManagedCapability()); - // Check every single system managed capability. - nc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL); - assertTrue(nc.hasConnectivityManagedCapability()); - nc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL); - nc.addCapability(NET_CAPABILITY_FOREGROUND); - assertTrue(nc.hasConnectivityManagedCapability()); - nc.removeCapability(NET_CAPABILITY_FOREGROUND); - nc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY); - assertTrue(nc.hasConnectivityManagedCapability()); - nc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY); - nc.addCapability(NET_CAPABILITY_VALIDATED); - assertTrue(nc.hasConnectivityManagedCapability()); - } - - @Test - public void testEqualsNetCapabilities() { - NetworkCapabilities nc1 = new NetworkCapabilities(); - NetworkCapabilities nc2 = new NetworkCapabilities(); - assertTrue(nc1.equalsNetCapabilities(nc2)); - assertEquals(nc1, nc2); - - nc1.addCapability(NET_CAPABILITY_MMS); - assertFalse(nc1.equalsNetCapabilities(nc2)); - assertNotEquals(nc1, nc2); - nc2.addCapability(NET_CAPABILITY_MMS); - assertTrue(nc1.equalsNetCapabilities(nc2)); - assertEquals(nc1, nc2); - - if (isAtLeastS()) { - nc1.addForbiddenCapability(NET_CAPABILITY_INTERNET); - assertFalse(nc1.equalsNetCapabilities(nc2)); - nc2.addForbiddenCapability(NET_CAPABILITY_INTERNET); - assertTrue(nc1.equalsNetCapabilities(nc2)); - - // Remove a required capability doesn't affect forbidden capabilities. - // This is a behaviour change from R to S. - nc1.removeCapability(NET_CAPABILITY_INTERNET); - assertTrue(nc1.equalsNetCapabilities(nc2)); - - nc1.removeForbiddenCapability(NET_CAPABILITY_INTERNET); - assertFalse(nc1.equalsNetCapabilities(nc2)); - nc2.removeForbiddenCapability(NET_CAPABILITY_INTERNET); - assertTrue(nc1.equalsNetCapabilities(nc2)); - } - } - - @Test - public void testSSID() { - NetworkCapabilities nc1 = new NetworkCapabilities(); - NetworkCapabilities nc2 = new NetworkCapabilities(); - assertTrue(nc2.satisfiedBySSID(nc1)); - - nc1.setSSID(TEST_SSID); - assertTrue(nc2.satisfiedBySSID(nc1)); - nc2.setSSID("different " + TEST_SSID); - assertFalse(nc2.satisfiedBySSID(nc1)); - - assertTrue(nc1.satisfiedByImmutableNetworkCapabilities(nc2)); - assertFalse(nc1.satisfiedByNetworkCapabilities(nc2)); - } - - private ArraySet<Range<Integer>> uidRanges(int from, int to) { - final ArraySet<Range<Integer>> range = new ArraySet<>(1); - range.add(uidRange(from, to)); - return range; - } - - private Range<Integer> uidRange(int from, int to) { - return new Range<Integer>(from, to); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testSetAdministratorUids() { - NetworkCapabilities nc = - new NetworkCapabilities().setAdministratorUids(new int[] {2, 1, 3}); - - assertArrayEquals(new int[] {1, 2, 3}, nc.getAdministratorUids()); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testSetAdministratorUidsWithDuplicates() { - try { - new NetworkCapabilities().setAdministratorUids(new int[] {1, 1}); - fail("Expected IllegalArgumentException for duplicate uids"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testCombineCapabilities() { - NetworkCapabilities nc1 = new NetworkCapabilities(); - NetworkCapabilities nc2 = new NetworkCapabilities(); - - if (isAtLeastS()) { - nc1.addForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL); - } - nc1.addCapability(NET_CAPABILITY_NOT_ROAMING); - assertNotEquals(nc1, nc2); - nc2.combineCapabilities(nc1); - assertEquals(nc1, nc2); - assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING)); - if (isAtLeastS()) { - assertTrue(nc2.hasForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); - } - - if (isAtLeastS()) { - // This will effectively move NOT_ROAMING capability from required to forbidden for nc1. - nc1.addForbiddenCapability(NET_CAPABILITY_NOT_ROAMING); - // It is not allowed to have the same capability in both wanted and forbidden list. - assertThrows(IllegalArgumentException.class, () -> nc2.combineCapabilities(nc1)); - // Remove forbidden capability to continue other tests. - nc1.removeForbiddenCapability(NET_CAPABILITY_NOT_ROAMING); - } - - nc1.setSSID(TEST_SSID); - nc2.combineCapabilities(nc1); - if (isAtLeastR()) { - assertTrue(TEST_SSID.equals(nc2.getSsid())); - } - - // Because they now have the same SSID, the following call should not throw - nc2.combineCapabilities(nc1); - - nc1.setSSID(DIFFERENT_TEST_SSID); - try { - nc2.combineCapabilities(nc1); - fail("Expected IllegalStateException: can't combine different SSIDs"); - } catch (IllegalStateException expected) {} - nc1.setSSID(TEST_SSID); - - if (isAtLeastS()) { - nc1.setUids(uidRanges(10, 13)); - assertNotEquals(nc1, nc2); - nc2.combineCapabilities(nc1); // Everything + 10~13 is still everything. - assertNotEquals(nc1, nc2); - nc1.combineCapabilities(nc2); // 10~13 + everything is everything. - assertEquals(nc1, nc2); - nc1.setUids(uidRanges(10, 13)); - nc2.setUids(uidRanges(20, 23)); - assertNotEquals(nc1, nc2); - nc1.combineCapabilities(nc2); - assertTrue(nc1.appliesToUid(12)); - assertFalse(nc2.appliesToUid(12)); - assertTrue(nc1.appliesToUid(22)); - assertTrue(nc2.appliesToUid(22)); - - // Verify the subscription id list can be combined only when they are equal. - nc1.setSubscriptionIds(Set.of(TEST_SUBID1, TEST_SUBID2)); - nc2.setSubscriptionIds(Set.of(TEST_SUBID2)); - assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1)); - - nc2.setSubscriptionIds(Set.of()); - assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1)); - - nc2.setSubscriptionIds(Set.of(TEST_SUBID2, TEST_SUBID1)); - nc2.combineCapabilities(nc1); - assertEquals(Set.of(TEST_SUBID2, TEST_SUBID1), nc2.getSubscriptionIds()); - } - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testCombineCapabilities_AdministratorUids() { - final NetworkCapabilities nc1 = new NetworkCapabilities(); - final NetworkCapabilities nc2 = new NetworkCapabilities(); - - final int[] adminUids = {3, 6, 12}; - nc1.setAdministratorUids(adminUids); - nc2.combineCapabilities(nc1); - assertTrue(nc2.equalsAdministratorUids(nc1)); - assertArrayEquals(nc2.getAdministratorUids(), adminUids); - - final int[] adminUidsOtherOrder = {3, 12, 6}; - nc1.setAdministratorUids(adminUidsOtherOrder); - assertTrue(nc2.equalsAdministratorUids(nc1)); - - final int[] adminUids2 = {11, 1, 12, 3, 6}; - nc1.setAdministratorUids(adminUids2); - assertFalse(nc2.equalsAdministratorUids(nc1)); - assertFalse(Arrays.equals(nc2.getAdministratorUids(), adminUids2)); - try { - nc2.combineCapabilities(nc1); - fail("Shouldn't be able to combine different lists of admin UIDs"); - } catch (IllegalStateException expected) { } - } - - @Test - public void testSetCapabilities() { - final int[] REQUIRED_CAPABILITIES = new int[] { - NET_CAPABILITY_INTERNET, NET_CAPABILITY_NOT_VPN }; - - NetworkCapabilities nc1 = new NetworkCapabilities(); - NetworkCapabilities nc2 = new NetworkCapabilities(); - - nc1.setCapabilities(REQUIRED_CAPABILITIES); - assertArrayEquals(REQUIRED_CAPABILITIES, nc1.getCapabilities()); - - // Verify that setting and adding capabilities leads to the same object state. - nc2.clearAll(); - for (int cap : REQUIRED_CAPABILITIES) { - nc2.addCapability(cap); - } - assertEquals(nc1, nc2); - - if (isAtLeastS()) { - final int[] forbiddenCapabilities = new int[]{ - NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_NOT_RESTRICTED }; - - nc1.setCapabilities(REQUIRED_CAPABILITIES, forbiddenCapabilities); - assertArrayEquals(REQUIRED_CAPABILITIES, nc1.getCapabilities()); - assertArrayEquals(forbiddenCapabilities, nc1.getForbiddenCapabilities()); - - nc2.clearAll(); - for (int cap : REQUIRED_CAPABILITIES) { - nc2.addCapability(cap); - } - for (int cap : forbiddenCapabilities) { - nc2.addForbiddenCapability(cap); - } - assertEquals(nc1, nc2); - } - } - - @Test - public void testSetNetworkSpecifierOnMultiTransportNc() { - // Sequence 1: Transport + Transport + NetworkSpecifier - NetworkCapabilities nc1 = new NetworkCapabilities(); - nc1.addTransportType(TRANSPORT_CELLULAR).addTransportType(TRANSPORT_WIFI); - try { - nc1.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier("eth0")); - fail("Cannot set NetworkSpecifier on a NetworkCapability with multiple transports!"); - } catch (IllegalStateException expected) { - // empty - } - - // Sequence 2: Transport + NetworkSpecifier + Transport - NetworkCapabilities nc2 = new NetworkCapabilities(); - nc2.addTransportType(TRANSPORT_CELLULAR).setNetworkSpecifier( - CompatUtil.makeEthernetNetworkSpecifier("testtap3")); - try { - nc2.addTransportType(TRANSPORT_WIFI); - fail("Cannot set a second TransportType of a network which has a NetworkSpecifier!"); - } catch (IllegalStateException expected) { - // empty - } - } - - @Test - public void testSetTransportInfoOnMultiTransportNc() { - // Sequence 1: Transport + Transport + TransportInfo - NetworkCapabilities nc1 = new NetworkCapabilities(); - nc1.addTransportType(TRANSPORT_CELLULAR).addTransportType(TRANSPORT_WIFI) - .setTransportInfo(new TestTransportInfo()); - - // Sequence 2: Transport + NetworkSpecifier + Transport - NetworkCapabilities nc2 = new NetworkCapabilities(); - nc2.addTransportType(TRANSPORT_CELLULAR).setTransportInfo(new TestTransportInfo()) - .addTransportType(TRANSPORT_WIFI); - } - - @Test - public void testCombineTransportInfo() { - NetworkCapabilities nc1 = new NetworkCapabilities(); - nc1.setTransportInfo(new TestTransportInfo()); - - NetworkCapabilities nc2 = new NetworkCapabilities(); - // new TransportInfo so that object is not #equals to nc1's TransportInfo (that's where - // combine fails) - nc2.setTransportInfo(new TestTransportInfo()); - - try { - nc1.combineCapabilities(nc2); - fail("Should not be able to combine NetworkCabilities which contain TransportInfos"); - } catch (IllegalStateException expected) { - // empty - } - - // verify that can combine with identical TransportInfo objects - NetworkCapabilities nc3 = new NetworkCapabilities(); - nc3.setTransportInfo(nc1.getTransportInfo()); - nc1.combineCapabilities(nc3); - } - - @Test - public void testSet() { - NetworkCapabilities nc1 = new NetworkCapabilities(); - NetworkCapabilities nc2 = new NetworkCapabilities(); - - if (isAtLeastS()) { - nc1.addForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL); - } - nc1.addCapability(NET_CAPABILITY_NOT_ROAMING); - assertNotEquals(nc1, nc2); - nc2.set(nc1); - assertEquals(nc1, nc2); - assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING)); - if (isAtLeastS()) { - assertTrue(nc2.hasForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); - } - - if (isAtLeastS()) { - // This will effectively move NOT_ROAMING capability from required to forbidden for nc1. - nc1.addForbiddenCapability(NET_CAPABILITY_NOT_ROAMING); - } - nc1.setSSID(TEST_SSID); - nc2.set(nc1); - assertEquals(nc1, nc2); - if (isAtLeastS()) { - // Contrary to combineCapabilities, set() will have removed the NOT_ROAMING capability - // from nc2. - assertFalse(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING)); - assertTrue(nc2.hasForbiddenCapability(NET_CAPABILITY_NOT_ROAMING)); - } - - if (isAtLeastR()) { - assertTrue(TEST_SSID.equals(nc2.getSsid())); - } - - nc1.setSSID(DIFFERENT_TEST_SSID); - nc2.set(nc1); - assertEquals(nc1, nc2); - if (isAtLeastR()) { - assertTrue(DIFFERENT_TEST_SSID.equals(nc2.getSsid())); - } - if (isAtLeastS()) { - nc1.setUids(uidRanges(10, 13)); - } else { - nc1.setUids(null); - } - nc2.set(nc1); // Overwrites, as opposed to combineCapabilities - assertEquals(nc1, nc2); - - if (isAtLeastS()) { - assertThrows(NullPointerException.class, () -> nc1.setSubscriptionIds(null)); - nc1.setSubscriptionIds(Set.of()); - nc2.set(nc1); - assertEquals(nc1, nc2); - - nc1.setSubscriptionIds(Set.of(TEST_SUBID1)); - nc2.set(nc1); - assertEquals(nc1, nc2); - - nc2.setSubscriptionIds(Set.of(TEST_SUBID2, TEST_SUBID1)); - nc2.set(nc1); - assertEquals(nc1, nc2); - - nc2.setSubscriptionIds(Set.of(TEST_SUBID3, TEST_SUBID2)); - assertNotEquals(nc1, nc2); - } - } - - @Test - public void testGetTransportTypes() { - final NetworkCapabilities nc = new NetworkCapabilities(); - nc.addTransportType(TRANSPORT_CELLULAR); - nc.addTransportType(TRANSPORT_WIFI); - nc.addTransportType(TRANSPORT_VPN); - nc.addTransportType(TRANSPORT_TEST); - - final int[] transportTypes = nc.getTransportTypes(); - assertEquals(4, transportTypes.length); - assertEquals(TRANSPORT_CELLULAR, transportTypes[0]); - assertEquals(TRANSPORT_WIFI, transportTypes[1]); - assertEquals(TRANSPORT_VPN, transportTypes[2]); - assertEquals(TRANSPORT_TEST, transportTypes[3]); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testTelephonyNetworkSpecifier() { - final TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier(1); - final NetworkCapabilities nc1 = new NetworkCapabilities.Builder() - .addTransportType(TRANSPORT_WIFI) - .setNetworkSpecifier(specifier) - .build(); - assertEquals(specifier, nc1.getNetworkSpecifier()); - try { - final NetworkCapabilities nc2 = new NetworkCapabilities.Builder() - .setNetworkSpecifier(specifier) - .build(); - fail("Must have a single transport type. Without transport type or multiple transport" - + " types is invalid."); - } catch (IllegalStateException expected) { } - } - - @Test - public void testWifiAwareNetworkSpecifier() { - final NetworkCapabilities nc = new NetworkCapabilities() - .addTransportType(TRANSPORT_WIFI_AWARE); - // If NetworkSpecifier is not set, the default value is null. - assertNull(nc.getNetworkSpecifier()); - final WifiAwareNetworkSpecifier specifier = new WifiAwareNetworkSpecifier.Builder( - mDiscoverySession, mPeerHandle).build(); - nc.setNetworkSpecifier(specifier); - assertEquals(specifier, nc.getNetworkSpecifier()); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testAdministratorUidsAndOwnerUid() { - // Test default owner uid. - // If the owner uid is not set, the default value should be Process.INVALID_UID. - final NetworkCapabilities nc1 = new NetworkCapabilities.Builder().build(); - assertEquals(INVALID_UID, nc1.getOwnerUid()); - // Test setAdministratorUids and getAdministratorUids. - final int[] administratorUids = {1001, 10001}; - final NetworkCapabilities nc2 = new NetworkCapabilities.Builder() - .setAdministratorUids(administratorUids) - .build(); - assertTrue(Arrays.equals(administratorUids, nc2.getAdministratorUids())); - // Test setOwnerUid and getOwnerUid. - // The owner UID must be included in administrator UIDs, or throw IllegalStateException. - try { - final NetworkCapabilities nc3 = new NetworkCapabilities.Builder() - .setOwnerUid(1001) - .build(); - fail("The owner UID must be included in administrator UIDs."); - } catch (IllegalStateException expected) { } - final NetworkCapabilities nc4 = new NetworkCapabilities.Builder() - .setAdministratorUids(administratorUids) - .setOwnerUid(1001) - .build(); - assertEquals(1001, nc4.getOwnerUid()); - try { - final NetworkCapabilities nc5 = new NetworkCapabilities.Builder() - .setAdministratorUids(null) - .build(); - fail("Should not set null into setAdministratorUids"); - } catch (NullPointerException expected) { } - } - - private static NetworkCapabilities capsWithSubIds(Integer ... subIds) { - // Since the NetworkRequest would put NOT_VCN_MANAGED capabilities in general, for - // every NetworkCapabilities that simulates networks needs to add it too in order to - // satisfy these requests. - final NetworkCapabilities nc = new NetworkCapabilities.Builder() - .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) - .setSubscriptionIds(new ArraySet<>(subIds)).build(); - assertEquals(new ArraySet<>(subIds), nc.getSubscriptionIds()); - return nc; - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.R) - public void testSubIds() throws Exception { - final NetworkCapabilities ncWithoutId = capsWithSubIds(); - final NetworkCapabilities ncWithId = capsWithSubIds(TEST_SUBID1); - final NetworkCapabilities ncWithOtherIds = capsWithSubIds(TEST_SUBID1, TEST_SUBID3); - final NetworkCapabilities ncWithoutRequestedIds = capsWithSubIds(TEST_SUBID3); - - final NetworkRequest requestWithoutId = new NetworkRequest.Builder().build(); - assertEmpty(requestWithoutId.networkCapabilities.getSubscriptionIds()); - final NetworkRequest requestWithIds = new NetworkRequest.Builder() - .setSubscriptionIds(Set.of(TEST_SUBID1, TEST_SUBID2)).build(); - assertEquals(Set.of(TEST_SUBID1, TEST_SUBID2), - requestWithIds.networkCapabilities.getSubscriptionIds()); - - assertFalse(requestWithIds.canBeSatisfiedBy(ncWithoutId)); - assertTrue(requestWithIds.canBeSatisfiedBy(ncWithOtherIds)); - assertFalse(requestWithIds.canBeSatisfiedBy(ncWithoutRequestedIds)); - assertTrue(requestWithIds.canBeSatisfiedBy(ncWithId)); - assertTrue(requestWithoutId.canBeSatisfiedBy(ncWithoutId)); - assertTrue(requestWithoutId.canBeSatisfiedBy(ncWithId)); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.R) - public void testEqualsSubIds() throws Exception { - assertEquals(capsWithSubIds(), capsWithSubIds()); - assertNotEquals(capsWithSubIds(), capsWithSubIds(TEST_SUBID1)); - assertEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID1)); - assertNotEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID2)); - assertNotEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID2, TEST_SUBID1)); - assertEquals(capsWithSubIds(TEST_SUBID1, TEST_SUBID2), - capsWithSubIds(TEST_SUBID2, TEST_SUBID1)); - } - - @Test - public void testLinkBandwidthKbps() { - final NetworkCapabilities nc = new NetworkCapabilities(); - // The default value of LinkDown/UpstreamBandwidthKbps should be LINK_BANDWIDTH_UNSPECIFIED. - assertEquals(LINK_BANDWIDTH_UNSPECIFIED, nc.getLinkDownstreamBandwidthKbps()); - assertEquals(LINK_BANDWIDTH_UNSPECIFIED, nc.getLinkUpstreamBandwidthKbps()); - nc.setLinkDownstreamBandwidthKbps(512); - nc.setLinkUpstreamBandwidthKbps(128); - assertEquals(512, nc.getLinkDownstreamBandwidthKbps()); - assertNotEquals(128, nc.getLinkDownstreamBandwidthKbps()); - assertEquals(128, nc.getLinkUpstreamBandwidthKbps()); - assertNotEquals(512, nc.getLinkUpstreamBandwidthKbps()); - } - - private int getMaxTransport() { - if (!isAtLeastS() && MAX_TRANSPORT == TRANSPORT_USB) return MAX_TRANSPORT - 1; - return MAX_TRANSPORT; - } - - @Test - public void testSignalStrength() { - final NetworkCapabilities nc = new NetworkCapabilities(); - // The default value of signal strength should be SIGNAL_STRENGTH_UNSPECIFIED. - assertEquals(SIGNAL_STRENGTH_UNSPECIFIED, nc.getSignalStrength()); - nc.setSignalStrength(-80); - assertEquals(-80, nc.getSignalStrength()); - assertNotEquals(-50, nc.getSignalStrength()); - } - - private void assertNoTransport(NetworkCapabilities nc) { - for (int i = MIN_TRANSPORT; i <= getMaxTransport(); i++) { - assertFalse(nc.hasTransport(i)); - } - } - - // Checks that all transport types from MIN_TRANSPORT to maxTransportType are set and all - // transport types from maxTransportType + 1 to MAX_TRANSPORT are not set when positiveSequence - // is true. If positiveSequence is false, then the check sequence is opposite. - private void checkCurrentTransportTypes(NetworkCapabilities nc, int maxTransportType, - boolean positiveSequence) { - for (int i = MIN_TRANSPORT; i <= maxTransportType; i++) { - if (positiveSequence) { - assertTrue(nc.hasTransport(i)); - } else { - assertFalse(nc.hasTransport(i)); - } - } - for (int i = getMaxTransport(); i > maxTransportType; i--) { - if (positiveSequence) { - assertFalse(nc.hasTransport(i)); - } else { - assertTrue(nc.hasTransport(i)); - } - } - } - - @Test - public void testMultipleTransportTypes() { - final NetworkCapabilities nc = new NetworkCapabilities(); - assertNoTransport(nc); - // Test adding multiple transport types. - for (int i = MIN_TRANSPORT; i <= getMaxTransport(); i++) { - nc.addTransportType(i); - checkCurrentTransportTypes(nc, i, true /* positiveSequence */); - } - // Test removing multiple transport types. - for (int i = MIN_TRANSPORT; i <= getMaxTransport(); i++) { - nc.removeTransportType(i); - checkCurrentTransportTypes(nc, i, false /* positiveSequence */); - } - assertNoTransport(nc); - nc.addTransportType(TRANSPORT_WIFI); - assertTrue(nc.hasTransport(TRANSPORT_WIFI)); - assertFalse(nc.hasTransport(TRANSPORT_VPN)); - nc.addTransportType(TRANSPORT_VPN); - assertTrue(nc.hasTransport(TRANSPORT_WIFI)); - assertTrue(nc.hasTransport(TRANSPORT_VPN)); - nc.removeTransportType(TRANSPORT_WIFI); - assertFalse(nc.hasTransport(TRANSPORT_WIFI)); - assertTrue(nc.hasTransport(TRANSPORT_VPN)); - nc.removeTransportType(TRANSPORT_VPN); - assertFalse(nc.hasTransport(TRANSPORT_WIFI)); - assertFalse(nc.hasTransport(TRANSPORT_VPN)); - assertNoTransport(nc); - } - - @Test - public void testAddAndRemoveTransportType() { - final NetworkCapabilities nc = new NetworkCapabilities(); - try { - nc.addTransportType(-1); - fail("Should not set invalid transport type into addTransportType"); - } catch (IllegalArgumentException expected) { } - try { - nc.removeTransportType(-1); - fail("Should not set invalid transport type into removeTransportType"); - } catch (IllegalArgumentException e) { } - } - - /** - * Test TransportInfo to verify redaction mechanism. - */ - private static class TestTransportInfo implements TransportInfo { - public final boolean locationRedacted; - public final boolean localMacAddressRedacted; - public final boolean settingsRedacted; - - TestTransportInfo() { - locationRedacted = false; - localMacAddressRedacted = false; - settingsRedacted = false; - } - - TestTransportInfo(boolean locationRedacted, - boolean localMacAddressRedacted, - boolean settingsRedacted) { - this.locationRedacted = locationRedacted; - this.localMacAddressRedacted = - localMacAddressRedacted; - this.settingsRedacted = settingsRedacted; - } - - @Override - public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) { - return new TestTransportInfo( - (redactions & NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION) != 0, - (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0, - (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0 - ); - } - - @Override - public @NetworkCapabilities.RedactionType long getApplicableRedactions() { - return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS - | REDACT_FOR_NETWORK_SETTINGS; - } - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testBuilder() { - final int ownerUid = 1001; - final int signalStrength = -80; - final int requestUid = 10100; - final int[] administratorUids = {ownerUid, 10001}; - final TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier(1); - final TransportInfo transportInfo = new TransportInfo() {}; - final String ssid = "TEST_SSID"; - final String packageName = "com.google.test.networkcapabilities"; - final NetworkCapabilities nc = new NetworkCapabilities.Builder() - .addTransportType(TRANSPORT_WIFI) - .addTransportType(TRANSPORT_CELLULAR) - .removeTransportType(TRANSPORT_CELLULAR) - .addCapability(NET_CAPABILITY_EIMS) - .addCapability(NET_CAPABILITY_CBS) - .removeCapability(NET_CAPABILITY_CBS) - .setAdministratorUids(administratorUids) - .setOwnerUid(ownerUid) - .setLinkDownstreamBandwidthKbps(512) - .setLinkUpstreamBandwidthKbps(128) - .setNetworkSpecifier(specifier) - .setTransportInfo(transportInfo) - .setSignalStrength(signalStrength) - .setSsid(ssid) - .setRequestorUid(requestUid) - .setRequestorPackageName(packageName) - .build(); - assertEquals(1, nc.getTransportTypes().length); - assertEquals(TRANSPORT_WIFI, nc.getTransportTypes()[0]); - assertTrue(nc.hasCapability(NET_CAPABILITY_EIMS)); - assertFalse(nc.hasCapability(NET_CAPABILITY_CBS)); - assertTrue(Arrays.equals(administratorUids, nc.getAdministratorUids())); - assertEquals(ownerUid, nc.getOwnerUid()); - assertEquals(512, nc.getLinkDownstreamBandwidthKbps()); - assertNotEquals(128, nc.getLinkDownstreamBandwidthKbps()); - assertEquals(128, nc.getLinkUpstreamBandwidthKbps()); - assertNotEquals(512, nc.getLinkUpstreamBandwidthKbps()); - assertEquals(specifier, nc.getNetworkSpecifier()); - assertEquals(transportInfo, nc.getTransportInfo()); - assertEquals(signalStrength, nc.getSignalStrength()); - assertNotEquals(-50, nc.getSignalStrength()); - assertEquals(ssid, nc.getSsid()); - assertEquals(requestUid, nc.getRequestorUid()); - assertEquals(packageName, nc.getRequestorPackageName()); - // Cannot assign null into NetworkCapabilities.Builder - try { - final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder(null); - fail("Should not set null into NetworkCapabilities.Builder"); - } catch (NullPointerException expected) { } - assertEquals(nc, new NetworkCapabilities.Builder(nc).build()); - - if (isAtLeastS()) { - final NetworkCapabilities nc2 = new NetworkCapabilities.Builder() - .setSubscriptionIds(Set.of(TEST_SUBID1)).build(); - assertEquals(Set.of(TEST_SUBID1), nc2.getSubscriptionIds()); - } - } -} diff --git a/tests/net/common/java/android/net/NetworkProviderTest.kt b/tests/net/common/java/android/net/NetworkProviderTest.kt deleted file mode 100644 index 7424157bea74..000000000000 --- a/tests/net/common/java/android/net/NetworkProviderTest.kt +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net - -import android.app.Instrumentation -import android.content.Context -import android.net.NetworkCapabilities.TRANSPORT_TEST -import android.net.NetworkProviderTest.TestNetworkCallback.CallbackEntry.OnUnavailable -import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequestWithdrawn -import android.net.NetworkProviderTest.TestNetworkProvider.CallbackEntry.OnNetworkRequested -import android.os.Build -import android.os.HandlerThread -import android.os.Looper -import androidx.test.InstrumentationRegistry -import com.android.net.module.util.ArrayTrackRecord -import com.android.testutils.CompatUtil -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo -import com.android.testutils.DevSdkIgnoreRunner -import com.android.testutils.isDevSdkInRange -import org.junit.After -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.mock -import org.mockito.Mockito.verifyNoMoreInteractions -import java.util.UUID -import kotlin.test.assertEquals -import kotlin.test.assertNotEquals - -private const val DEFAULT_TIMEOUT_MS = 5000L -private val instrumentation: Instrumentation - get() = InstrumentationRegistry.getInstrumentation() -private val context: Context get() = InstrumentationRegistry.getContext() -private val PROVIDER_NAME = "NetworkProviderTest" - -@RunWith(DevSdkIgnoreRunner::class) -@IgnoreUpTo(Build.VERSION_CODES.Q) -class NetworkProviderTest { - private val mCm = context.getSystemService(ConnectivityManager::class.java) - private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread") - - @Before - fun setUp() { - instrumentation.getUiAutomation().adoptShellPermissionIdentity() - mHandlerThread.start() - } - - @After - fun tearDown() { - mHandlerThread.quitSafely() - instrumentation.getUiAutomation().dropShellPermissionIdentity() - } - - private class TestNetworkProvider(context: Context, looper: Looper) : - NetworkProvider(context, looper, PROVIDER_NAME) { - private val seenEvents = ArrayTrackRecord<CallbackEntry>().newReadHead() - - sealed class CallbackEntry { - data class OnNetworkRequested( - val request: NetworkRequest, - val score: Int, - val id: Int - ) : CallbackEntry() - data class OnNetworkRequestWithdrawn(val request: NetworkRequest) : CallbackEntry() - } - - override fun onNetworkRequested(request: NetworkRequest, score: Int, id: Int) { - seenEvents.add(OnNetworkRequested(request, score, id)) - } - - override fun onNetworkRequestWithdrawn(request: NetworkRequest) { - seenEvents.add(OnNetworkRequestWithdrawn(request)) - } - - inline fun <reified T : CallbackEntry> expectCallback( - crossinline predicate: (T) -> Boolean - ) = seenEvents.poll(DEFAULT_TIMEOUT_MS) { it is T && predicate(it) } - } - - private fun createNetworkProvider(ctx: Context = context): TestNetworkProvider { - return TestNetworkProvider(ctx, mHandlerThread.looper) - } - - @Test - fun testOnNetworkRequested() { - val provider = createNetworkProvider() - assertEquals(provider.getProviderId(), NetworkProvider.ID_NONE) - mCm.registerNetworkProvider(provider) - assertNotEquals(provider.getProviderId(), NetworkProvider.ID_NONE) - - val specifier = CompatUtil.makeTestNetworkSpecifier( - UUID.randomUUID().toString()) - val nr: NetworkRequest = NetworkRequest.Builder() - .addTransportType(TRANSPORT_TEST) - .setNetworkSpecifier(specifier) - .build() - val cb = ConnectivityManager.NetworkCallback() - mCm.requestNetwork(nr, cb) - provider.expectCallback<OnNetworkRequested>() { callback -> - callback.request.getNetworkSpecifier() == specifier && - callback.request.hasTransport(TRANSPORT_TEST) - } - - val initialScore = 40 - val updatedScore = 60 - val nc = NetworkCapabilities().apply { - addTransportType(NetworkCapabilities.TRANSPORT_TEST) - removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) - removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) - addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) - addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) - addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) - setNetworkSpecifier(specifier) - } - val lp = LinkProperties() - val config = NetworkAgentConfig.Builder().build() - val agent = object : NetworkAgent(context, mHandlerThread.looper, "TestAgent", nc, lp, - initialScore, config, provider) {} - - provider.expectCallback<OnNetworkRequested>() { callback -> - callback.request.getNetworkSpecifier() == specifier && - callback.score == initialScore && - callback.id == agent.providerId - } - - agent.sendNetworkScore(updatedScore) - provider.expectCallback<OnNetworkRequested>() { callback -> - callback.request.getNetworkSpecifier() == specifier && - callback.score == updatedScore && - callback.id == agent.providerId - } - - mCm.unregisterNetworkCallback(cb) - provider.expectCallback<OnNetworkRequestWithdrawn>() { callback -> - callback.request.getNetworkSpecifier() == specifier && - callback.request.hasTransport(TRANSPORT_TEST) - } - mCm.unregisterNetworkProvider(provider) - // Provider id should be ID_NONE after unregister network provider - assertEquals(provider.getProviderId(), NetworkProvider.ID_NONE) - // unregisterNetworkProvider should not crash even if it's called on an - // already unregistered provider. - mCm.unregisterNetworkProvider(provider) - } - - private class TestNetworkCallback : ConnectivityManager.NetworkCallback() { - private val seenEvents = ArrayTrackRecord<CallbackEntry>().newReadHead() - sealed class CallbackEntry { - object OnUnavailable : CallbackEntry() - } - - override fun onUnavailable() { - seenEvents.add(OnUnavailable) - } - - inline fun <reified T : CallbackEntry> expectCallback( - crossinline predicate: (T) -> Boolean - ) = seenEvents.poll(DEFAULT_TIMEOUT_MS) { it is T && predicate(it) } - } - - @Test - fun testDeclareNetworkRequestUnfulfillable() { - val mockContext = mock(Context::class.java) - doReturn(mCm).`when`(mockContext).getSystemService(Context.CONNECTIVITY_SERVICE) - val provider = createNetworkProvider(mockContext) - // ConnectivityManager not required at creation time after R - if (!isDevSdkInRange(0, Build.VERSION_CODES.R)) { - verifyNoMoreInteractions(mockContext) - } - - mCm.registerNetworkProvider(provider) - - val specifier = CompatUtil.makeTestNetworkSpecifier( - UUID.randomUUID().toString()) - val nr: NetworkRequest = NetworkRequest.Builder() - .addTransportType(TRANSPORT_TEST) - .setNetworkSpecifier(specifier) - .build() - - val cb = TestNetworkCallback() - mCm.requestNetwork(nr, cb) - provider.declareNetworkRequestUnfulfillable(nr) - cb.expectCallback<OnUnavailable>() { nr.getNetworkSpecifier() == specifier } - mCm.unregisterNetworkProvider(provider) - } -} diff --git a/tests/net/common/java/android/net/NetworkSpecifierTest.kt b/tests/net/common/java/android/net/NetworkSpecifierTest.kt deleted file mode 100644 index f3409f53596f..000000000000 --- a/tests/net/common/java/android/net/NetworkSpecifierTest.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net - -import android.os.Build -import androidx.test.filters.SmallTest -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo -import com.android.testutils.DevSdkIgnoreRunner -import kotlin.test.assertTrue -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertNotEquals -import org.junit.Test -import org.junit.runner.RunWith - -@SmallTest -@RunWith(DevSdkIgnoreRunner::class) -@IgnoreUpTo(Build.VERSION_CODES.Q) -class NetworkSpecifierTest { - private class TestNetworkSpecifier( - val intData: Int = 123, - val stringData: String = "init" - ) : NetworkSpecifier() { - override fun canBeSatisfiedBy(other: NetworkSpecifier?): Boolean = - other != null && - other is TestNetworkSpecifier && - other.intData >= intData && - stringData.equals(other.stringData) - - override fun redact(): NetworkSpecifier = TestNetworkSpecifier(intData, "redact") - } - - @Test - fun testRedact() { - val ns: TestNetworkSpecifier = TestNetworkSpecifier() - val redactNs = ns.redact() - assertTrue(redactNs is TestNetworkSpecifier) - assertEquals(ns.intData, redactNs.intData) - assertNotEquals(ns.stringData, redactNs.stringData) - assertTrue("redact".equals(redactNs.stringData)) - } - - @Test - fun testcanBeSatisfiedBy() { - val target: TestNetworkSpecifier = TestNetworkSpecifier() - assertFalse(target.canBeSatisfiedBy(null)) - assertTrue(target.canBeSatisfiedBy(TestNetworkSpecifier())) - val otherNs = TelephonyNetworkSpecifier.Builder().setSubscriptionId(123).build() - assertFalse(target.canBeSatisfiedBy(otherNs)) - assertTrue(target.canBeSatisfiedBy(TestNetworkSpecifier(intData = 999))) - assertFalse(target.canBeSatisfiedBy(TestNetworkSpecifier(intData = 1))) - assertFalse(target.canBeSatisfiedBy(TestNetworkSpecifier(stringData = "diff"))) - } -}
\ No newline at end of file diff --git a/tests/net/common/java/android/net/NetworkStackTest.java b/tests/net/common/java/android/net/NetworkStackTest.java deleted file mode 100644 index f8f9c72374ad..000000000000 --- a/tests/net/common/java/android/net/NetworkStackTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net; - -import static org.junit.Assert.assertEquals; - -import android.os.Build; -import android.os.IBinder; - -import androidx.test.runner.AndroidJUnit4; - -import com.android.testutils.DevSdkIgnoreRule; -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(AndroidJUnit4.class) -public class NetworkStackTest { - @Rule - public DevSdkIgnoreRule mDevSdkIgnoreRule = new DevSdkIgnoreRule(); - - @Mock private IBinder mConnectorBinder; - - @Before public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testGetService() { - NetworkStack.setServiceForTest(mConnectorBinder); - assertEquals(NetworkStack.getService(), mConnectorBinder); - } -} diff --git a/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt b/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt deleted file mode 100644 index 0ca4d9551f39..000000000000 --- a/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net - -import android.net.ConnectivityManager.TYPE_NONE -import android.net.ConnectivityManager.TYPE_WIFI -import android.net.InetAddresses.parseNumericAddress -import android.net.NetworkCapabilities.TRANSPORT_WIFI -import android.os.Build -import androidx.test.filters.SmallTest -import com.android.testutils.DevSdkIgnoreRule -import com.android.testutils.DevSdkIgnoreRunner -import com.android.testutils.assertParcelSane -import org.junit.Test -import org.junit.runner.RunWith -import java.net.Inet4Address -import java.net.Inet6Address - -private const val TEST_IMSI = "imsi1" -private const val TEST_SSID = "SSID1" -private const val TEST_NETID = 123 - -private val TEST_IPV4_GATEWAY = parseNumericAddress("192.168.222.3") as Inet4Address -private val TEST_IPV6_GATEWAY = parseNumericAddress("2001:db8::1") as Inet6Address -private val TEST_IPV4_LINKADDR = LinkAddress("192.168.222.123/24") -private val TEST_IPV6_LINKADDR = LinkAddress("2001:db8::123/64") -private val TEST_IFACE = "fake0" -private val TEST_LINK_PROPERTIES = LinkProperties().apply { - interfaceName = TEST_IFACE - addLinkAddress(TEST_IPV4_LINKADDR) - addLinkAddress(TEST_IPV6_LINKADDR) - - // Add default routes - addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY)) - addRoute(RouteInfo(IpPrefix(parseNumericAddress("::"), 0), TEST_IPV6_GATEWAY)) -} - -private val TEST_CAPABILITIES = NetworkCapabilities().apply { - addTransportType(TRANSPORT_WIFI) - setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false) - setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true) - setSSID(TEST_SSID) -} - -@SmallTest -@RunWith(DevSdkIgnoreRunner::class) -@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) -class NetworkStateSnapshotTest { - - @Test - fun testParcelUnparcel() { - val emptySnapshot = NetworkStateSnapshot(Network(TEST_NETID), NetworkCapabilities(), - LinkProperties(), null, TYPE_NONE) - val snapshot = NetworkStateSnapshot( - Network(TEST_NETID), TEST_CAPABILITIES, TEST_LINK_PROPERTIES, TEST_IMSI, TYPE_WIFI) - assertParcelSane(emptySnapshot, 5) - assertParcelSane(snapshot, 5) - } -} diff --git a/tests/net/common/java/android/net/NetworkTest.java b/tests/net/common/java/android/net/NetworkTest.java deleted file mode 100644 index 7423c733c6eb..000000000000 --- a/tests/net/common/java/android/net/NetworkTest.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.os.Build; -import android.platform.test.annotations.AppModeFull; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.testutils.DevSdkIgnoreRule; -import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.net.DatagramSocket; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.SocketException; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetworkTest { - final Network mNetwork = new Network(99); - - @Rule - public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule(); - - @Test - public void testBindSocketOfInvalidFdThrows() throws Exception { - - final FileDescriptor fd = new FileDescriptor(); - assertFalse(fd.valid()); - - try { - mNetwork.bindSocket(fd); - fail("SocketException not thrown"); - } catch (SocketException expected) {} - } - - @Test - public void testBindSocketOfNonSocketFdThrows() throws Exception { - final File devNull = new File("/dev/null"); - assertTrue(devNull.canRead()); - - final FileInputStream fis = new FileInputStream(devNull); - assertTrue(null != fis.getFD()); - assertTrue(fis.getFD().valid()); - - try { - mNetwork.bindSocket(fis.getFD()); - fail("SocketException not thrown"); - } catch (SocketException expected) {} - } - - @Test - @AppModeFull(reason = "Socket cannot bind in instant app mode") - public void testBindSocketOfConnectedDatagramSocketThrows() throws Exception { - final DatagramSocket mDgramSocket = new DatagramSocket(0, (InetAddress) Inet6Address.ANY); - mDgramSocket.connect((InetAddress) Inet6Address.LOOPBACK, 53); - assertTrue(mDgramSocket.isConnected()); - - try { - mNetwork.bindSocket(mDgramSocket); - fail("SocketException not thrown"); - } catch (SocketException expected) {} - } - - @Test - public void testBindSocketOfLocalSocketThrows() throws Exception { - final LocalSocket mLocalClient = new LocalSocket(); - mLocalClient.bind(new LocalSocketAddress("testClient")); - assertTrue(mLocalClient.getFileDescriptor().valid()); - - try { - mNetwork.bindSocket(mLocalClient.getFileDescriptor()); - fail("SocketException not thrown"); - } catch (SocketException expected) {} - - final LocalServerSocket mLocalServer = new LocalServerSocket("testServer"); - mLocalClient.connect(mLocalServer.getLocalSocketAddress()); - assertTrue(mLocalClient.isConnected()); - - try { - mNetwork.bindSocket(mLocalClient.getFileDescriptor()); - fail("SocketException not thrown"); - } catch (SocketException expected) {} - } - - @Test - public void testZeroIsObviousForDebugging() { - Network zero = new Network(0); - assertEquals(0, zero.hashCode()); - assertEquals(0, zero.getNetworkHandle()); - assertEquals("0", zero.toString()); - } - - @Test - public void testGetNetworkHandle() { - Network one = new Network(1); - Network two = new Network(2); - Network three = new Network(3); - - // None of the hashcodes are zero. - assertNotEquals(0, one.hashCode()); - assertNotEquals(0, two.hashCode()); - assertNotEquals(0, three.hashCode()); - - // All the hashcodes are distinct. - assertNotEquals(one.hashCode(), two.hashCode()); - assertNotEquals(one.hashCode(), three.hashCode()); - assertNotEquals(two.hashCode(), three.hashCode()); - - // None of the handles are zero. - assertNotEquals(0, one.getNetworkHandle()); - assertNotEquals(0, two.getNetworkHandle()); - assertNotEquals(0, three.getNetworkHandle()); - - // All the handles are distinct. - assertNotEquals(one.getNetworkHandle(), two.getNetworkHandle()); - assertNotEquals(one.getNetworkHandle(), three.getNetworkHandle()); - assertNotEquals(two.getNetworkHandle(), three.getNetworkHandle()); - - // The handles are not equal to the hashcodes. - assertNotEquals(one.hashCode(), one.getNetworkHandle()); - assertNotEquals(two.hashCode(), two.getNetworkHandle()); - assertNotEquals(three.hashCode(), three.getNetworkHandle()); - - // Adjust as necessary to test an implementation's specific constants. - // When running with runtest, "adb logcat -s TestRunner" can be useful. - assertEquals(7700664333L, one.getNetworkHandle()); - assertEquals(11995631629L, two.getNetworkHandle()); - assertEquals(16290598925L, three.getNetworkHandle()); - } - - // getNetId() did not exist in Q - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testGetNetId() { - assertEquals(1234, new Network(1234).getNetId()); - assertEquals(2345, new Network(2345, true).getNetId()); - } - - @Test - public void testFromNetworkHandle() { - final Network network = new Network(1234); - assertEquals(network.netId, Network.fromNetworkHandle(network.getNetworkHandle()).netId); - } - - // Parsing private DNS bypassing handle was not supported until S - @Test @IgnoreUpTo(Build.VERSION_CODES.R) - public void testFromNetworkHandlePrivateDnsBypass_S() { - final Network network = new Network(1234, true); - - final Network recreatedNetwork = Network.fromNetworkHandle(network.getNetworkHandle()); - assertEquals(network.netId, recreatedNetwork.netId); - assertEquals(network.getNetIdForResolv(), recreatedNetwork.getNetIdForResolv()); - } - - @Test @IgnoreAfter(Build.VERSION_CODES.R) - public void testFromNetworkHandlePrivateDnsBypass_R() { - final Network network = new Network(1234, true); - - final Network recreatedNetwork = Network.fromNetworkHandle(network.getNetworkHandle()); - assertEquals(network.netId, recreatedNetwork.netId); - // Until R included, fromNetworkHandle would not parse the private DNS bypass flag - assertEquals(network.netId, recreatedNetwork.getNetIdForResolv()); - } - - @Test - public void testGetPrivateDnsBypassingCopy() { - final Network copy = mNetwork.getPrivateDnsBypassingCopy(); - assertEquals(mNetwork.netId, copy.netId); - assertNotEquals(copy.netId, copy.getNetIdForResolv()); - assertNotEquals(mNetwork.getNetIdForResolv(), copy.getNetIdForResolv()); - } -} diff --git a/tests/net/common/java/android/net/OemNetworkPreferencesTest.java b/tests/net/common/java/android/net/OemNetworkPreferencesTest.java deleted file mode 100644 index fd29a9539de8..000000000000 --- a/tests/net/common/java/android/net/OemNetworkPreferencesTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static com.android.testutils.MiscAsserts.assertThrows; -import static com.android.testutils.ParcelUtils.assertParcelSane; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.os.Build; - -import androidx.test.filters.SmallTest; - -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; -import com.android.testutils.DevSdkIgnoreRunner; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.Map; - -@IgnoreUpTo(Build.VERSION_CODES.R) -@RunWith(DevSdkIgnoreRunner.class) -@SmallTest -public class OemNetworkPreferencesTest { - - private static final int TEST_PREF = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED; - private static final String TEST_PACKAGE = "com.google.apps.contacts"; - - private final OemNetworkPreferences.Builder mBuilder = new OemNetworkPreferences.Builder(); - - @Test - public void testBuilderAddNetworkPreferenceRequiresNonNullPackageName() { - assertThrows(NullPointerException.class, - () -> mBuilder.addNetworkPreference(null, TEST_PREF)); - } - - @Test - public void testBuilderRemoveNetworkPreferenceRequiresNonNullPackageName() { - assertThrows(NullPointerException.class, - () -> mBuilder.clearNetworkPreference(null)); - } - - @Test - public void testGetNetworkPreferenceReturnsCorrectValue() { - final int expectedNumberOfMappings = 1; - mBuilder.addNetworkPreference(TEST_PACKAGE, TEST_PREF); - - final Map<String, Integer> networkPreferences = - mBuilder.build().getNetworkPreferences(); - - assertEquals(expectedNumberOfMappings, networkPreferences.size()); - assertTrue(networkPreferences.containsKey(TEST_PACKAGE)); - } - - @Test - public void testGetNetworkPreferenceReturnsUnmodifiableValue() { - final String newPackage = "new.com.google.apps.contacts"; - mBuilder.addNetworkPreference(TEST_PACKAGE, TEST_PREF); - - final Map<String, Integer> networkPreferences = - mBuilder.build().getNetworkPreferences(); - - assertThrows(UnsupportedOperationException.class, - () -> networkPreferences.put(newPackage, TEST_PREF)); - - assertThrows(UnsupportedOperationException.class, - () -> networkPreferences.remove(TEST_PACKAGE)); - - } - - @Test - public void testToStringReturnsCorrectValue() { - mBuilder.addNetworkPreference(TEST_PACKAGE, TEST_PREF); - - final String networkPreferencesString = mBuilder.build().getNetworkPreferences().toString(); - - assertTrue(networkPreferencesString.contains(Integer.toString(TEST_PREF))); - assertTrue(networkPreferencesString.contains(TEST_PACKAGE)); - } - - @Test - public void testOemNetworkPreferencesParcelable() { - mBuilder.addNetworkPreference(TEST_PACKAGE, TEST_PREF); - - final OemNetworkPreferences prefs = mBuilder.build(); - - assertParcelSane(prefs, 1 /* fieldCount */); - } - - @Test - public void testAddNetworkPreferenceOverwritesPriorPreference() { - final int newPref = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; - mBuilder.addNetworkPreference(TEST_PACKAGE, TEST_PREF); - Map<String, Integer> networkPreferences = - mBuilder.build().getNetworkPreferences(); - - assertTrue(networkPreferences.containsKey(TEST_PACKAGE)); - assertEquals(networkPreferences.get(TEST_PACKAGE).intValue(), TEST_PREF); - - mBuilder.addNetworkPreference(TEST_PACKAGE, newPref); - networkPreferences = mBuilder.build().getNetworkPreferences(); - - assertTrue(networkPreferences.containsKey(TEST_PACKAGE)); - assertEquals(networkPreferences.get(TEST_PACKAGE).intValue(), newPref); - } - - @Test - public void testRemoveNetworkPreferenceRemovesValue() { - mBuilder.addNetworkPreference(TEST_PACKAGE, TEST_PREF); - Map<String, Integer> networkPreferences = - mBuilder.build().getNetworkPreferences(); - - assertTrue(networkPreferences.containsKey(TEST_PACKAGE)); - - mBuilder.clearNetworkPreference(TEST_PACKAGE); - networkPreferences = mBuilder.build().getNetworkPreferences(); - - assertFalse(networkPreferences.containsKey(TEST_PACKAGE)); - } - - @Test - public void testConstructorByOemNetworkPreferencesSetsValue() { - mBuilder.addNetworkPreference(TEST_PACKAGE, TEST_PREF); - OemNetworkPreferences networkPreference = mBuilder.build(); - - final Map<String, Integer> networkPreferences = - new OemNetworkPreferences - .Builder(networkPreference) - .build() - .getNetworkPreferences(); - - assertTrue(networkPreferences.containsKey(TEST_PACKAGE)); - assertEquals(networkPreferences.get(TEST_PACKAGE).intValue(), TEST_PREF); - } -} diff --git a/tests/net/common/java/android/net/RouteInfoTest.java b/tests/net/common/java/android/net/RouteInfoTest.java deleted file mode 100644 index 71689f919726..000000000000 --- a/tests/net/common/java/android/net/RouteInfoTest.java +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.net.RouteInfo.RTN_UNREACHABLE; - -import static com.android.testutils.MiscAsserts.assertEqualBothWays; -import static com.android.testutils.MiscAsserts.assertFieldCountEquals; -import static com.android.testutils.MiscAsserts.assertNotEqualEitherWay; -import static com.android.testutils.ParcelUtils.assertParcelingIsLossless; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.os.Build; - -import androidx.core.os.BuildCompat; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.testutils.DevSdkIgnoreRule; -import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class RouteInfoTest { - @Rule - public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); - - private static final int INVALID_ROUTE_TYPE = -1; - - private InetAddress Address(String addr) { - return InetAddresses.parseNumericAddress(addr); - } - - private IpPrefix Prefix(String prefix) { - return new IpPrefix(prefix); - } - - private static boolean isAtLeastR() { - // BuildCompat.isAtLeastR is documented to return false on release SDKs (including R) - return Build.VERSION.SDK_INT > Build.VERSION_CODES.Q || BuildCompat.isAtLeastR(); - } - - @Test - public void testConstructor() { - RouteInfo r; - // Invalid input. - try { - r = new RouteInfo((IpPrefix) null, null, "rmnet0"); - fail("Expected RuntimeException: destination and gateway null"); - } catch (RuntimeException e) { } - - try { - r = new RouteInfo(Prefix("2001:db8:ace::/49"), Address("2001:db8::1"), "rmnet0", - INVALID_ROUTE_TYPE); - fail("Invalid route type should cause exception"); - } catch (IllegalArgumentException e) { } - - try { - r = new RouteInfo(Prefix("2001:db8:ace::/49"), Address("192.0.2.1"), "rmnet0", - RTN_UNREACHABLE); - fail("Address family mismatch should cause exception"); - } catch (IllegalArgumentException e) { } - - try { - r = new RouteInfo(Prefix("0.0.0.0/0"), Address("2001:db8::1"), "rmnet0", - RTN_UNREACHABLE); - fail("Address family mismatch should cause exception"); - } catch (IllegalArgumentException e) { } - - // Null destination is default route. - r = new RouteInfo((IpPrefix) null, Address("2001:db8::1"), null); - assertEquals(Prefix("::/0"), r.getDestination()); - assertEquals(Address("2001:db8::1"), r.getGateway()); - assertNull(r.getInterface()); - - r = new RouteInfo((IpPrefix) null, Address("192.0.2.1"), "wlan0"); - assertEquals(Prefix("0.0.0.0/0"), r.getDestination()); - assertEquals(Address("192.0.2.1"), r.getGateway()); - assertEquals("wlan0", r.getInterface()); - - // Null gateway sets gateway to unspecified address (why?). - r = new RouteInfo(Prefix("2001:db8:beef:cafe::/48"), null, "lo"); - assertEquals(Prefix("2001:db8:beef::/48"), r.getDestination()); - assertEquals(Address("::"), r.getGateway()); - assertEquals("lo", r.getInterface()); - - r = new RouteInfo(Prefix("192.0.2.5/24"), null); - assertEquals(Prefix("192.0.2.0/24"), r.getDestination()); - assertEquals(Address("0.0.0.0"), r.getGateway()); - assertNull(r.getInterface()); - } - - @Test - public void testMatches() { - class PatchedRouteInfo { - private final RouteInfo mRouteInfo; - - public PatchedRouteInfo(IpPrefix destination, InetAddress gateway, String iface) { - mRouteInfo = new RouteInfo(destination, gateway, iface); - } - - public boolean matches(InetAddress destination) { - return mRouteInfo.matches(destination); - } - } - - PatchedRouteInfo r; - - r = new PatchedRouteInfo(Prefix("2001:db8:f00::ace:d00d/127"), null, "rmnet0"); - assertTrue(r.matches(Address("2001:db8:f00::ace:d00c"))); - assertTrue(r.matches(Address("2001:db8:f00::ace:d00d"))); - assertFalse(r.matches(Address("2001:db8:f00::ace:d00e"))); - assertFalse(r.matches(Address("2001:db8:f00::bad:d00d"))); - assertFalse(r.matches(Address("2001:4868:4860::8888"))); - assertFalse(r.matches(Address("8.8.8.8"))); - - r = new PatchedRouteInfo(Prefix("192.0.2.0/23"), null, "wlan0"); - assertTrue(r.matches(Address("192.0.2.43"))); - assertTrue(r.matches(Address("192.0.3.21"))); - assertFalse(r.matches(Address("192.0.0.21"))); - assertFalse(r.matches(Address("8.8.8.8"))); - - PatchedRouteInfo ipv6Default = new PatchedRouteInfo(Prefix("::/0"), null, "rmnet0"); - assertTrue(ipv6Default.matches(Address("2001:db8::f00"))); - assertFalse(ipv6Default.matches(Address("192.0.2.1"))); - - PatchedRouteInfo ipv4Default = new PatchedRouteInfo(Prefix("0.0.0.0/0"), null, "rmnet0"); - assertTrue(ipv4Default.matches(Address("255.255.255.255"))); - assertTrue(ipv4Default.matches(Address("192.0.2.1"))); - assertFalse(ipv4Default.matches(Address("2001:db8::f00"))); - } - - @Test - public void testEquals() { - // IPv4 - RouteInfo r1 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "wlan0"); - RouteInfo r2 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "wlan0"); - assertEqualBothWays(r1, r2); - - RouteInfo r3 = new RouteInfo(Prefix("2001:db8:ace::/49"), Address("2001:db8::1"), "wlan0"); - RouteInfo r4 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::2"), "wlan0"); - RouteInfo r5 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "rmnet0"); - assertNotEqualEitherWay(r1, r3); - assertNotEqualEitherWay(r1, r4); - assertNotEqualEitherWay(r1, r5); - - // IPv6 - r1 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "wlan0"); - r2 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "wlan0"); - assertEqualBothWays(r1, r2); - - r3 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0"); - r4 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.2"), "wlan0"); - r5 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "rmnet0"); - assertNotEqualEitherWay(r1, r3); - assertNotEqualEitherWay(r1, r4); - assertNotEqualEitherWay(r1, r5); - - // Interfaces (but not destinations or gateways) can be null. - r1 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), null); - r2 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), null); - r3 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0"); - assertEqualBothWays(r1, r2); - assertNotEqualEitherWay(r1, r3); - } - - @Test - public void testHostAndDefaultRoutes() { - RouteInfo r; - - r = new RouteInfo(Prefix("0.0.0.0/0"), Address("0.0.0.0"), "wlan0"); - assertFalse(r.isHostRoute()); - assertTrue(r.isDefaultRoute()); - assertTrue(r.isIPv4Default()); - assertFalse(r.isIPv6Default()); - if (isAtLeastR()) { - assertFalse(r.isIPv4UnreachableDefault()); - assertFalse(r.isIPv6UnreachableDefault()); - } - - r = new RouteInfo(Prefix("::/0"), Address("::"), "wlan0"); - assertFalse(r.isHostRoute()); - assertTrue(r.isDefaultRoute()); - assertFalse(r.isIPv4Default()); - assertTrue(r.isIPv6Default()); - if (isAtLeastR()) { - assertFalse(r.isIPv4UnreachableDefault()); - assertFalse(r.isIPv6UnreachableDefault()); - } - - r = new RouteInfo(Prefix("192.0.2.0/24"), null, "wlan0"); - assertFalse(r.isHostRoute()); - assertFalse(r.isDefaultRoute()); - assertFalse(r.isIPv4Default()); - assertFalse(r.isIPv6Default()); - if (isAtLeastR()) { - assertFalse(r.isIPv4UnreachableDefault()); - assertFalse(r.isIPv6UnreachableDefault()); - } - - r = new RouteInfo(Prefix("2001:db8::/48"), null, "wlan0"); - assertFalse(r.isHostRoute()); - assertFalse(r.isDefaultRoute()); - assertFalse(r.isIPv4Default()); - assertFalse(r.isIPv6Default()); - if (isAtLeastR()) { - assertFalse(r.isIPv4UnreachableDefault()); - assertFalse(r.isIPv6UnreachableDefault()); - } - - r = new RouteInfo(Prefix("192.0.2.0/32"), Address("0.0.0.0"), "wlan0"); - assertTrue(r.isHostRoute()); - assertFalse(r.isDefaultRoute()); - assertFalse(r.isIPv4Default()); - assertFalse(r.isIPv6Default()); - if (isAtLeastR()) { - assertFalse(r.isIPv4UnreachableDefault()); - assertFalse(r.isIPv6UnreachableDefault()); - } - - r = new RouteInfo(Prefix("2001:db8::/128"), Address("::"), "wlan0"); - assertTrue(r.isHostRoute()); - assertFalse(r.isDefaultRoute()); - assertFalse(r.isIPv4Default()); - assertFalse(r.isIPv6Default()); - if (isAtLeastR()) { - assertFalse(r.isIPv4UnreachableDefault()); - assertFalse(r.isIPv6UnreachableDefault()); - } - - r = new RouteInfo(Prefix("192.0.2.0/32"), null, "wlan0"); - assertTrue(r.isHostRoute()); - assertFalse(r.isDefaultRoute()); - assertFalse(r.isIPv4Default()); - assertFalse(r.isIPv6Default()); - if (isAtLeastR()) { - assertFalse(r.isIPv4UnreachableDefault()); - assertFalse(r.isIPv6UnreachableDefault()); - } - - r = new RouteInfo(Prefix("2001:db8::/128"), null, "wlan0"); - assertTrue(r.isHostRoute()); - assertFalse(r.isDefaultRoute()); - assertFalse(r.isIPv4Default()); - assertFalse(r.isIPv6Default()); - if (isAtLeastR()) { - assertFalse(r.isIPv4UnreachableDefault()); - assertFalse(r.isIPv6UnreachableDefault()); - } - - r = new RouteInfo(Prefix("::/128"), Address("fe80::"), "wlan0"); - assertTrue(r.isHostRoute()); - assertFalse(r.isDefaultRoute()); - assertFalse(r.isIPv4Default()); - assertFalse(r.isIPv6Default()); - if (isAtLeastR()) { - assertFalse(r.isIPv4UnreachableDefault()); - assertFalse(r.isIPv6UnreachableDefault()); - } - - r = new RouteInfo(Prefix("0.0.0.0/32"), Address("192.0.2.1"), "wlan0"); - assertTrue(r.isHostRoute()); - assertFalse(r.isDefaultRoute()); - assertFalse(r.isIPv4Default()); - assertFalse(r.isIPv6Default()); - if (isAtLeastR()) { - assertFalse(r.isIPv4UnreachableDefault()); - assertFalse(r.isIPv6UnreachableDefault()); - } - - r = new RouteInfo(Prefix("0.0.0.0/32"), Address("192.0.2.1"), "wlan0"); - assertTrue(r.isHostRoute()); - assertFalse(r.isDefaultRoute()); - assertFalse(r.isIPv4Default()); - assertFalse(r.isIPv6Default()); - if (isAtLeastR()) { - assertFalse(r.isIPv4UnreachableDefault()); - assertFalse(r.isIPv6UnreachableDefault()); - } - - r = new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE); - assertFalse(r.isHostRoute()); - assertFalse(r.isDefaultRoute()); - assertFalse(r.isIPv4Default()); - assertFalse(r.isIPv6Default()); - if (isAtLeastR()) { - assertTrue(r.isIPv4UnreachableDefault()); - assertFalse(r.isIPv6UnreachableDefault()); - } - - r = new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE); - assertFalse(r.isHostRoute()); - assertFalse(r.isDefaultRoute()); - assertFalse(r.isIPv4Default()); - assertFalse(r.isIPv6Default()); - if (isAtLeastR()) { - assertFalse(r.isIPv4UnreachableDefault()); - assertTrue(r.isIPv6UnreachableDefault()); - } - } - - @Test - public void testTruncation() { - LinkAddress l; - RouteInfo r; - - l = new LinkAddress("192.0.2.5/30"); - r = new RouteInfo(l, Address("192.0.2.1"), "wlan0"); - assertEquals("192.0.2.4", r.getDestination().getAddress().getHostAddress()); - - l = new LinkAddress("2001:db8:1:f::5/63"); - r = new RouteInfo(l, Address("2001:db8:5::1"), "wlan0"); - assertEquals("2001:db8:1:e::", r.getDestination().getAddress().getHostAddress()); - } - - // Make sure that creating routes to multicast addresses doesn't throw an exception. Even though - // there's nothing we can do with them, we don't want to crash if, e.g., someone calls - // requestRouteToHostAddress("230.0.0.0", MOBILE_HIPRI); - @Test - public void testMulticastRoute() { - RouteInfo r; - r = new RouteInfo(Prefix("230.0.0.0/32"), Address("192.0.2.1"), "wlan0"); - r = new RouteInfo(Prefix("ff02::1/128"), Address("2001:db8::1"), "wlan0"); - // No exceptions? Good. - } - - @Test - public void testParceling() { - RouteInfo r; - r = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), null); - assertParcelingIsLossless(r); - r = new RouteInfo(Prefix("192.0.2.0/24"), null, "wlan0"); - assertParcelingIsLossless(r); - r = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0", RTN_UNREACHABLE); - assertParcelingIsLossless(r); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testMtuParceling() { - final RouteInfo r = new RouteInfo(Prefix("ff02::1/128"), Address("2001:db8::"), "testiface", - RTN_UNREACHABLE, 1450 /* mtu */); - assertParcelingIsLossless(r); - } - - @Test @IgnoreAfter(Build.VERSION_CODES.Q) - public void testFieldCount_Q() { - assertFieldCountEquals(6, RouteInfo.class); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testFieldCount() { - // Make sure any new field is covered by the above parceling tests when changing this number - assertFieldCountEquals(7, RouteInfo.class); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testMtu() { - RouteInfo r; - r = new RouteInfo(Prefix("0.0.0.0/0"), Address("0.0.0.0"), "wlan0", - RouteInfo.RTN_UNICAST, 1500); - assertEquals(1500, r.getMtu()); - - r = new RouteInfo(Prefix("0.0.0.0/0"), Address("0.0.0.0"), "wlan0"); - assertEquals(0, r.getMtu()); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - public void testRouteKey() { - RouteInfo.RouteKey k1, k2; - // Only prefix, null gateway and null interface - k1 = new RouteInfo(Prefix("2001:db8::/128"), null).getRouteKey(); - k2 = new RouteInfo(Prefix("2001:db8::/128"), null).getRouteKey(); - assertEquals(k1, k2); - assertEquals(k1.hashCode(), k2.hashCode()); - - // With prefix, gateway and interface. Type and MTU does not affect RouteKey equality - k1 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0", - RTN_UNREACHABLE, 1450).getRouteKey(); - k2 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0", - RouteInfo.RTN_UNICAST, 1400).getRouteKey(); - assertEquals(k1, k2); - assertEquals(k1.hashCode(), k2.hashCode()); - - // Different scope IDs are ignored by the kernel, so we consider them equal here too. - k1 = new RouteInfo(Prefix("2001:db8::/64"), Address("fe80::1%1"), "wlan0").getRouteKey(); - k2 = new RouteInfo(Prefix("2001:db8::/64"), Address("fe80::1%2"), "wlan0").getRouteKey(); - assertEquals(k1, k2); - assertEquals(k1.hashCode(), k2.hashCode()); - - // Different prefix - k1 = new RouteInfo(Prefix("192.0.2.0/24"), null).getRouteKey(); - k2 = new RouteInfo(Prefix("192.0.3.0/24"), null).getRouteKey(); - assertNotEquals(k1, k2); - - // Different gateway - k1 = new RouteInfo(Prefix("ff02::1/128"), Address("2001:db8::1"), null).getRouteKey(); - k2 = new RouteInfo(Prefix("ff02::1/128"), Address("2001:db8::2"), null).getRouteKey(); - assertNotEquals(k1, k2); - - // Different interface - k1 = new RouteInfo(Prefix("ff02::1/128"), null, "tun0").getRouteKey(); - k2 = new RouteInfo(Prefix("ff02::1/128"), null, "tun1").getRouteKey(); - assertNotEquals(k1, k2); - } -} diff --git a/tests/net/common/java/android/net/StaticIpConfigurationTest.java b/tests/net/common/java/android/net/StaticIpConfigurationTest.java deleted file mode 100644 index b5f23bf19a3c..000000000000 --- a/tests/net/common/java/android/net/StaticIpConfigurationTest.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import android.os.Parcel; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class StaticIpConfigurationTest { - - private static final String ADDRSTR = "192.0.2.2/25"; - private static final LinkAddress ADDR = new LinkAddress(ADDRSTR); - private static final InetAddress GATEWAY = IpAddress("192.0.2.1"); - private static final InetAddress OFFLINKGATEWAY = IpAddress("192.0.2.129"); - private static final InetAddress DNS1 = IpAddress("8.8.8.8"); - private static final InetAddress DNS2 = IpAddress("8.8.4.4"); - private static final InetAddress DNS3 = IpAddress("4.2.2.2"); - private static final String IFACE = "eth0"; - private static final String FAKE_DOMAINS = "google.com"; - - private static InetAddress IpAddress(String addr) { - return InetAddress.parseNumericAddress(addr); - } - - private void checkEmpty(StaticIpConfiguration s) { - assertNull(s.ipAddress); - assertNull(s.gateway); - assertNull(s.domains); - assertEquals(0, s.dnsServers.size()); - } - - private StaticIpConfiguration makeTestObject() { - StaticIpConfiguration s = new StaticIpConfiguration(); - s.ipAddress = ADDR; - s.gateway = GATEWAY; - s.dnsServers.add(DNS1); - s.dnsServers.add(DNS2); - s.dnsServers.add(DNS3); - s.domains = FAKE_DOMAINS; - return s; - } - - @Test - public void testConstructor() { - StaticIpConfiguration s = new StaticIpConfiguration(); - checkEmpty(s); - } - - @Test - public void testCopyAndClear() { - StaticIpConfiguration empty = new StaticIpConfiguration((StaticIpConfiguration) null); - checkEmpty(empty); - - StaticIpConfiguration s1 = makeTestObject(); - StaticIpConfiguration s2 = new StaticIpConfiguration(s1); - assertEquals(s1, s2); - s2.clear(); - assertEquals(empty, s2); - } - - @Test - public void testHashCodeAndEquals() { - HashSet<Integer> hashCodes = new HashSet(); - hashCodes.add(0); - - StaticIpConfiguration s = new StaticIpConfiguration(); - // Check that this hash code is nonzero and different from all the ones seen so far. - assertTrue(hashCodes.add(s.hashCode())); - - s.ipAddress = ADDR; - assertTrue(hashCodes.add(s.hashCode())); - - s.gateway = GATEWAY; - assertTrue(hashCodes.add(s.hashCode())); - - s.dnsServers.add(DNS1); - assertTrue(hashCodes.add(s.hashCode())); - - s.dnsServers.add(DNS2); - assertTrue(hashCodes.add(s.hashCode())); - - s.dnsServers.add(DNS3); - assertTrue(hashCodes.add(s.hashCode())); - - s.domains = "example.com"; - assertTrue(hashCodes.add(s.hashCode())); - - assertFalse(s.equals(null)); - assertEquals(s, s); - - StaticIpConfiguration s2 = new StaticIpConfiguration(s); - assertEquals(s, s2); - - s.ipAddress = new LinkAddress(DNS1, 32); - assertNotEquals(s, s2); - - s2 = new StaticIpConfiguration(s); - s.domains = "foo"; - assertNotEquals(s, s2); - - s2 = new StaticIpConfiguration(s); - s.gateway = DNS2; - assertNotEquals(s, s2); - - s2 = new StaticIpConfiguration(s); - s.dnsServers.add(DNS3); - assertNotEquals(s, s2); - } - - @Test - public void testToLinkProperties() { - LinkProperties expected = new LinkProperties(); - expected.setInterfaceName(IFACE); - - StaticIpConfiguration s = new StaticIpConfiguration(); - assertEquals(expected, s.toLinkProperties(IFACE)); - - final RouteInfo connectedRoute = new RouteInfo(new IpPrefix(ADDRSTR), null, IFACE); - s.ipAddress = ADDR; - expected.addLinkAddress(ADDR); - expected.addRoute(connectedRoute); - assertEquals(expected, s.toLinkProperties(IFACE)); - - s.gateway = GATEWAY; - RouteInfo defaultRoute = new RouteInfo(new IpPrefix("0.0.0.0/0"), GATEWAY, IFACE); - expected.addRoute(defaultRoute); - assertEquals(expected, s.toLinkProperties(IFACE)); - - s.gateway = OFFLINKGATEWAY; - expected.removeRoute(defaultRoute); - defaultRoute = new RouteInfo(new IpPrefix("0.0.0.0/0"), OFFLINKGATEWAY, IFACE); - expected.addRoute(defaultRoute); - - RouteInfo gatewayRoute = new RouteInfo(new IpPrefix("192.0.2.129/32"), null, IFACE); - expected.addRoute(gatewayRoute); - assertEquals(expected, s.toLinkProperties(IFACE)); - - s.dnsServers.add(DNS1); - expected.addDnsServer(DNS1); - assertEquals(expected, s.toLinkProperties(IFACE)); - - s.dnsServers.add(DNS2); - s.dnsServers.add(DNS3); - expected.addDnsServer(DNS2); - expected.addDnsServer(DNS3); - assertEquals(expected, s.toLinkProperties(IFACE)); - - s.domains = FAKE_DOMAINS; - expected.setDomains(FAKE_DOMAINS); - assertEquals(expected, s.toLinkProperties(IFACE)); - - s.gateway = null; - expected.removeRoute(defaultRoute); - expected.removeRoute(gatewayRoute); - assertEquals(expected, s.toLinkProperties(IFACE)); - - // Without knowing the IP address, we don't have a directly-connected route, so we can't - // tell if the gateway is off-link or not and we don't add a host route. This isn't a real - // configuration, but we should at least not crash. - s.gateway = OFFLINKGATEWAY; - s.ipAddress = null; - expected.removeLinkAddress(ADDR); - expected.removeRoute(connectedRoute); - expected.addRoute(defaultRoute); - assertEquals(expected, s.toLinkProperties(IFACE)); - } - - private StaticIpConfiguration passThroughParcel(StaticIpConfiguration s) { - Parcel p = Parcel.obtain(); - StaticIpConfiguration s2 = null; - try { - s.writeToParcel(p, 0); - p.setDataPosition(0); - s2 = StaticIpConfiguration.readFromParcel(p); - } finally { - p.recycle(); - } - assertNotNull(s2); - return s2; - } - - @Test - public void testParceling() { - StaticIpConfiguration s = makeTestObject(); - StaticIpConfiguration s2 = passThroughParcel(s); - assertEquals(s, s2); - } - - @Test - public void testBuilder() { - final ArrayList<InetAddress> dnsServers = new ArrayList<>(); - dnsServers.add(DNS1); - - final StaticIpConfiguration s = new StaticIpConfiguration.Builder() - .setIpAddress(ADDR) - .setGateway(GATEWAY) - .setDomains(FAKE_DOMAINS) - .setDnsServers(dnsServers) - .build(); - - assertEquals(s.ipAddress, s.getIpAddress()); - assertEquals(ADDR, s.getIpAddress()); - assertEquals(s.gateway, s.getGateway()); - assertEquals(GATEWAY, s.getGateway()); - assertEquals(s.domains, s.getDomains()); - assertEquals(FAKE_DOMAINS, s.getDomains()); - assertTrue(s.dnsServers.equals(s.getDnsServers())); - assertEquals(1, s.getDnsServers().size()); - assertEquals(DNS1, s.getDnsServers().get(0)); - } - - @Test - public void testAddDnsServers() { - final StaticIpConfiguration s = new StaticIpConfiguration((StaticIpConfiguration) null); - checkEmpty(s); - - s.addDnsServer(DNS1); - assertEquals(1, s.getDnsServers().size()); - assertEquals(DNS1, s.getDnsServers().get(0)); - - s.addDnsServer(DNS2); - s.addDnsServer(DNS3); - assertEquals(3, s.getDnsServers().size()); - assertEquals(DNS2, s.getDnsServers().get(1)); - assertEquals(DNS3, s.getDnsServers().get(2)); - } - - @Test - public void testGetRoutes() { - final StaticIpConfiguration s = makeTestObject(); - final List<RouteInfo> routeInfoList = s.getRoutes(IFACE); - - assertEquals(2, routeInfoList.size()); - assertEquals(new RouteInfo(ADDR, (InetAddress) null, IFACE), routeInfoList.get(0)); - assertEquals(new RouteInfo((IpPrefix) null, GATEWAY, IFACE), routeInfoList.get(1)); - } -} diff --git a/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt b/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt deleted file mode 100644 index 7a18bb08faa8..000000000000 --- a/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net - -import android.net.InetAddresses.parseNumericAddress -import android.os.Build -import com.android.testutils.DevSdkIgnoreRule -import com.android.testutils.DevSdkIgnoreRunner -import com.android.testutils.assertFieldCountEquals -import com.android.testutils.assertParcelSane -import org.junit.Test -import org.junit.runner.RunWith -import java.net.InetAddress -import kotlin.test.assertEquals -import kotlin.test.assertNotEquals -import kotlin.test.assertTrue - -@RunWith(DevSdkIgnoreRunner::class) -@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) // TcpKeepalivePacketData added to SDK in S -class TcpKeepalivePacketDataTest { - private fun makeData( - srcAddress: InetAddress = parseNumericAddress("192.0.2.123"), - srcPort: Int = 1234, - dstAddress: InetAddress = parseNumericAddress("192.0.2.231"), - dstPort: Int = 4321, - data: ByteArray = byteArrayOf(1, 2, 3), - tcpSeq: Int = 135, - tcpAck: Int = 246, - tcpWnd: Int = 1234, - tcpWndScale: Int = 2, - ipTos: Int = 0x12, - ipTtl: Int = 10 - ) = TcpKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, data, tcpSeq, tcpAck, - tcpWnd, tcpWndScale, ipTos, ipTtl) - - @Test - fun testEquals() { - val data1 = makeData() - val data2 = makeData() - assertEquals(data1, data2) - assertEquals(data1.hashCode(), data2.hashCode()) - } - - @Test - fun testNotEquals() { - assertNotEquals(makeData(srcAddress = parseNumericAddress("192.0.2.124")), makeData()) - assertNotEquals(makeData(srcPort = 1235), makeData()) - assertNotEquals(makeData(dstAddress = parseNumericAddress("192.0.2.232")), makeData()) - assertNotEquals(makeData(dstPort = 4322), makeData()) - // .equals does not test .packet, as it should be generated from the other fields - assertNotEquals(makeData(tcpSeq = 136), makeData()) - assertNotEquals(makeData(tcpAck = 247), makeData()) - assertNotEquals(makeData(tcpWnd = 1235), makeData()) - assertNotEquals(makeData(tcpWndScale = 3), makeData()) - assertNotEquals(makeData(ipTos = 0x14), makeData()) - assertNotEquals(makeData(ipTtl = 11), makeData()) - - // Update above assertions if field is added - assertFieldCountEquals(5, KeepalivePacketData::class.java) - assertFieldCountEquals(6, TcpKeepalivePacketData::class.java) - } - - @Test - fun testParcelUnparcel() { - assertParcelSane(makeData(), fieldCount = 6) { a, b -> - // .equals() does not verify .packet - a == b && a.packet contentEquals b.packet - } - } - - @Test - fun testToString() { - val data = makeData() - val str = data.toString() - - assertTrue(str.contains(data.srcAddress.hostAddress)) - assertTrue(str.contains(data.srcPort.toString())) - assertTrue(str.contains(data.dstAddress.hostAddress)) - assertTrue(str.contains(data.dstPort.toString())) - // .packet not included in toString() - assertTrue(str.contains(data.getTcpSeq().toString())) - assertTrue(str.contains(data.getTcpAck().toString())) - assertTrue(str.contains(data.getTcpWindow().toString())) - assertTrue(str.contains(data.getTcpWindowScale().toString())) - assertTrue(str.contains(data.getIpTos().toString())) - assertTrue(str.contains(data.getIpTtl().toString())) - - // Update above assertions if field is added - assertFieldCountEquals(5, KeepalivePacketData::class.java) - assertFieldCountEquals(6, TcpKeepalivePacketData::class.java) - } -}
\ No newline at end of file diff --git a/tests/net/common/java/android/net/UidRangeTest.java b/tests/net/common/java/android/net/UidRangeTest.java deleted file mode 100644 index 1b1c95431d6f..000000000000 --- a/tests/net/common/java/android/net/UidRangeTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.os.UserHandle.MIN_SECONDARY_USER_ID; -import static android.os.UserHandle.SYSTEM; -import static android.os.UserHandle.USER_SYSTEM; -import static android.os.UserHandle.getUid; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.os.Build; -import android.os.UserHandle; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.testutils.DevSdkIgnoreRule; -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class UidRangeTest { - - /* - * UidRange is no longer passed to netd. UID ranges between the framework and netd are passed as - * UidRangeParcel objects. - */ - - @Rule - public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule(); - - @Test - public void testSingleItemUidRangeAllowed() { - new UidRange(123, 123); - new UidRange(0, 0); - new UidRange(Integer.MAX_VALUE, Integer.MAX_VALUE); - } - - @Test - public void testNegativeUidsDisallowed() { - try { - new UidRange(-2, 100); - fail("Exception not thrown for negative start UID"); - } catch (IllegalArgumentException expected) { - } - - try { - new UidRange(-200, -100); - fail("Exception not thrown for negative stop UID"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testStopLessThanStartDisallowed() { - final int x = 4195000; - try { - new UidRange(x, x - 1); - fail("Exception not thrown for negative-length UID range"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testGetStartAndEndUser() throws Exception { - final UidRange uidRangeOfPrimaryUser = new UidRange( - getUid(USER_SYSTEM, 10000), getUid(USER_SYSTEM, 10100)); - final UidRange uidRangeOfSecondaryUser = new UidRange( - getUid(MIN_SECONDARY_USER_ID, 10000), getUid(MIN_SECONDARY_USER_ID, 10100)); - assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getStartUser()); - assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getEndUser()); - assertEquals(MIN_SECONDARY_USER_ID, uidRangeOfSecondaryUser.getStartUser()); - assertEquals(MIN_SECONDARY_USER_ID, uidRangeOfSecondaryUser.getEndUser()); - - final UidRange uidRangeForDifferentUsers = new UidRange( - getUid(USER_SYSTEM, 10000), getUid(MIN_SECONDARY_USER_ID, 10100)); - assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getStartUser()); - assertEquals(MIN_SECONDARY_USER_ID, uidRangeOfSecondaryUser.getEndUser()); - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.R) - public void testCreateForUser() throws Exception { - final UidRange uidRangeOfPrimaryUser = UidRange.createForUser(SYSTEM); - final UidRange uidRangeOfSecondaryUser = UidRange.createForUser( - UserHandle.of(USER_SYSTEM + 1)); - assertTrue(uidRangeOfPrimaryUser.stop < uidRangeOfSecondaryUser.start); - assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getStartUser()); - assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getEndUser()); - assertEquals(USER_SYSTEM + 1, uidRangeOfSecondaryUser.getStartUser()); - assertEquals(USER_SYSTEM + 1, uidRangeOfSecondaryUser.getEndUser()); - } -} diff --git a/tests/net/common/java/android/net/UnderlyingNetworkInfoTest.kt b/tests/net/common/java/android/net/UnderlyingNetworkInfoTest.kt deleted file mode 100644 index f23ba26d0039..000000000000 --- a/tests/net/common/java/android/net/UnderlyingNetworkInfoTest.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net - -import android.os.Build -import androidx.test.filters.SmallTest -import com.android.testutils.DevSdkIgnoreRule -import com.android.testutils.DevSdkIgnoreRunner -import com.android.testutils.assertParcelSane -import org.junit.Test -import org.junit.runner.RunWith -import kotlin.test.assertEquals - -private const val TEST_OWNER_UID = 123 -private const val TEST_IFACE = "test_tun0" -private val TEST_IFACE_LIST = listOf("wlan0", "rmnet_data0", "eth0") - -@SmallTest -@RunWith(DevSdkIgnoreRunner::class) -@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) -class UnderlyingNetworkInfoTest { - @Test - fun testParcelUnparcel() { - val testInfo = UnderlyingNetworkInfo(TEST_OWNER_UID, TEST_IFACE, TEST_IFACE_LIST) - assertEquals(TEST_OWNER_UID, testInfo.getOwnerUid()) - assertEquals(TEST_IFACE, testInfo.getInterface()) - assertEquals(TEST_IFACE_LIST, testInfo.getUnderlyingInterfaces()) - assertParcelSane(testInfo, 3) - - val emptyInfo = UnderlyingNetworkInfo(0, String(), listOf()) - assertEquals(0, emptyInfo.getOwnerUid()) - assertEquals(String(), emptyInfo.getInterface()) - assertEquals(listOf(), emptyInfo.getUnderlyingInterfaces()) - assertParcelSane(emptyInfo, 3) - } -}
\ No newline at end of file diff --git a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java deleted file mode 100644 index d50406fd3a1c..000000000000 --- a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.apf; - -import static com.android.testutils.ParcelUtils.assertParcelSane; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import android.content.Context; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.Arrays; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class ApfCapabilitiesTest { - private Context mContext; - - @Before - public void setUp() { - mContext = InstrumentationRegistry.getContext(); - } - - @Test - public void testConstructAndParcel() { - final ApfCapabilities caps = new ApfCapabilities(123, 456, 789); - assertEquals(123, caps.apfVersionSupported); - assertEquals(456, caps.maximumApfProgramSize); - assertEquals(789, caps.apfPacketFormat); - - assertParcelSane(caps, 3); - } - - @Test - public void testEquals() { - assertEquals(new ApfCapabilities(1, 2, 3), new ApfCapabilities(1, 2, 3)); - assertNotEquals(new ApfCapabilities(2, 2, 3), new ApfCapabilities(1, 2, 3)); - assertNotEquals(new ApfCapabilities(1, 3, 3), new ApfCapabilities(1, 2, 3)); - assertNotEquals(new ApfCapabilities(1, 2, 4), new ApfCapabilities(1, 2, 3)); - } - - @Test - public void testHasDataAccess() { - //hasDataAccess is only supported starting at apf version 4. - ApfCapabilities caps = new ApfCapabilities(1 /* apfVersionSupported */, 2, 3); - assertFalse(caps.hasDataAccess()); - - caps = new ApfCapabilities(4 /* apfVersionSupported */, 5, 6); - assertTrue(caps.hasDataAccess()); - } - - @Test - public void testGetApfDrop8023Frames() { - // Get com.android.internal.R.bool.config_apfDrop802_3Frames. The test cannot directly - // use R.bool.config_apfDrop802_3Frames because that is not a stable resource ID. - final int resId = mContext.getResources().getIdentifier("config_apfDrop802_3Frames", - "bool", "android"); - final boolean shouldDrop8023Frames = mContext.getResources().getBoolean(resId); - final boolean actual = ApfCapabilities.getApfDrop8023Frames(); - assertEquals(shouldDrop8023Frames, actual); - } - - @Test - public void testGetApfEtherTypeBlackList() { - // Get com.android.internal.R.array.config_apfEthTypeBlackList. The test cannot directly - // use R.array.config_apfEthTypeBlackList because that is not a stable resource ID. - final int resId = mContext.getResources().getIdentifier("config_apfEthTypeBlackList", - "array", "android"); - final int[] blacklistedEtherTypeArray = mContext.getResources().getIntArray(resId); - final int[] actual = ApfCapabilities.getApfEtherTypeBlackList(); - assertNotNull(actual); - assertTrue(Arrays.equals(blacklistedEtherTypeArray, actual)); - } -} diff --git a/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt b/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt deleted file mode 100644 index 0b7b74097cc6..000000000000 --- a/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.metrics; - -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.testutils.assertParcelSane -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -@SmallTest -class ApfProgramEventTest { - private infix fun Int.hasFlag(flag: Int) = (this and (1 shl flag)) != 0 - - @Test - fun testBuilderAndParcel() { - val apfProgramEvent = ApfProgramEvent.Builder() - .setLifetime(1) - .setActualLifetime(2) - .setFilteredRas(3) - .setCurrentRas(4) - .setProgramLength(5) - .setFlags(true, true) - .build() - - assertEquals(1, apfProgramEvent.lifetime) - assertEquals(2, apfProgramEvent.actualLifetime) - assertEquals(3, apfProgramEvent.filteredRas) - assertEquals(4, apfProgramEvent.currentRas) - assertEquals(5, apfProgramEvent.programLength) - assertEquals(ApfProgramEvent.flagsFor(true, true), apfProgramEvent.flags) - - assertParcelSane(apfProgramEvent, 6) - } - - @Test - fun testFlagsFor() { - var flags = ApfProgramEvent.flagsFor(false, false) - assertFalse(flags hasFlag ApfProgramEvent.FLAG_HAS_IPV4_ADDRESS) - assertFalse(flags hasFlag ApfProgramEvent.FLAG_MULTICAST_FILTER_ON) - - flags = ApfProgramEvent.flagsFor(true, false) - assertTrue(flags hasFlag ApfProgramEvent.FLAG_HAS_IPV4_ADDRESS) - assertFalse(flags hasFlag ApfProgramEvent.FLAG_MULTICAST_FILTER_ON) - - flags = ApfProgramEvent.flagsFor(false, true) - assertFalse(flags hasFlag ApfProgramEvent.FLAG_HAS_IPV4_ADDRESS) - assertTrue(flags hasFlag ApfProgramEvent.FLAG_MULTICAST_FILTER_ON) - - flags = ApfProgramEvent.flagsFor(true, true) - assertTrue(flags hasFlag ApfProgramEvent.FLAG_HAS_IPV4_ADDRESS) - assertTrue(flags hasFlag ApfProgramEvent.FLAG_MULTICAST_FILTER_ON) - } -} diff --git a/tests/net/common/java/android/net/metrics/ApfStatsTest.kt b/tests/net/common/java/android/net/metrics/ApfStatsTest.kt deleted file mode 100644 index 46a8c8e5b509..000000000000 --- a/tests/net/common/java/android/net/metrics/ApfStatsTest.kt +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.metrics - -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.testutils.assertParcelSane -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -@SmallTest -class ApfStatsTest { - @Test - fun testBuilderAndParcel() { - val apfStats = ApfStats.Builder() - .setDurationMs(Long.MAX_VALUE) - .setReceivedRas(1) - .setMatchingRas(2) - .setDroppedRas(3) - .setZeroLifetimeRas(4) - .setParseErrors(5) - .setProgramUpdates(6) - .setProgramUpdatesAll(7) - .setProgramUpdatesAllowingMulticast(8) - .setMaxProgramSize(9) - .build() - - assertEquals(Long.MAX_VALUE, apfStats.durationMs) - assertEquals(1, apfStats.receivedRas) - assertEquals(2, apfStats.matchingRas) - assertEquals(3, apfStats.droppedRas) - assertEquals(4, apfStats.zeroLifetimeRas) - assertEquals(5, apfStats.parseErrors) - assertEquals(6, apfStats.programUpdates) - assertEquals(7, apfStats.programUpdatesAll) - assertEquals(8, apfStats.programUpdatesAllowingMulticast) - assertEquals(9, apfStats.maxProgramSize) - - assertParcelSane(apfStats, 10) - } -} diff --git a/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt b/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt deleted file mode 100644 index 8d7a9c405024..000000000000 --- a/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.metrics - -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.testutils.assertParcelSane -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -private const val FAKE_MESSAGE = "test" - -@RunWith(AndroidJUnit4::class) -@SmallTest -class DhcpClientEventTest { - @Test - fun testBuilderAndParcel() { - val dhcpClientEvent = DhcpClientEvent.Builder() - .setMsg(FAKE_MESSAGE) - .setDurationMs(Integer.MAX_VALUE) - .build() - - assertEquals(FAKE_MESSAGE, dhcpClientEvent.msg) - assertEquals(Integer.MAX_VALUE, dhcpClientEvent.durationMs) - - assertParcelSane(dhcpClientEvent, 2) - } -} diff --git a/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt b/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt deleted file mode 100644 index 236f72eafbdc..000000000000 --- a/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt +++ /dev/null @@ -1,65 +0,0 @@ -package android.net.metrics - -import android.net.metrics.DhcpErrorEvent.DHCP_INVALID_OPTION_LENGTH -import android.net.metrics.DhcpErrorEvent.errorCodeWithOption -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.testutils.parcelingRoundTrip -import java.lang.reflect.Modifier -import org.junit.Assert.assertEquals -import org.junit.Assert.assertNotNull -import org.junit.Assert.assertTrue -import org.junit.Test -import org.junit.runner.RunWith - -private const val TEST_ERROR_CODE = 12345 -//DHCP Optional Type: DHCP Subnet Mask (Copy from DhcpPacket.java due to it's protected) -private const val DHCP_SUBNET_MASK = 1 - -@RunWith(AndroidJUnit4::class) -@SmallTest -class DhcpErrorEventTest { - - @Test - fun testConstructor() { - val event = DhcpErrorEvent(TEST_ERROR_CODE) - assertEquals(TEST_ERROR_CODE, event.errorCode) - } - - @Test - fun testParcelUnparcel() { - val event = DhcpErrorEvent(TEST_ERROR_CODE) - val parceled = parcelingRoundTrip(event) - assertEquals(TEST_ERROR_CODE, parceled.errorCode) - } - - @Test - fun testErrorCodeWithOption() { - val errorCode = errorCodeWithOption(DHCP_INVALID_OPTION_LENGTH, DHCP_SUBNET_MASK); - assertTrue((DHCP_INVALID_OPTION_LENGTH and errorCode) == DHCP_INVALID_OPTION_LENGTH); - assertTrue((DHCP_SUBNET_MASK and errorCode) == DHCP_SUBNET_MASK); - } - - @Test - fun testToString() { - val names = listOf("L2_ERROR", "L3_ERROR", "L4_ERROR", "DHCP_ERROR", "MISC_ERROR") - val errorFields = DhcpErrorEvent::class.java.declaredFields.filter { - it.type == Int::class.javaPrimitiveType - && Modifier.isPublic(it.modifiers) && Modifier.isStatic(it.modifiers) - && it.name !in names - } - - errorFields.forEach { - val intValue = it.getInt(null) - val stringValue = DhcpErrorEvent(intValue).toString() - assertTrue("Invalid string for error 0x%08X (field %s): %s".format(intValue, it.name, - stringValue), - stringValue.contains(it.name)) - } - } - - @Test - fun testToString_InvalidErrorCode() { - assertNotNull(DhcpErrorEvent(TEST_ERROR_CODE).toString()) - } -} diff --git a/tests/net/common/java/android/net/metrics/IpConnectivityLogTest.java b/tests/net/common/java/android/net/metrics/IpConnectivityLogTest.java deleted file mode 100644 index d4780d3a5d7b..000000000000 --- a/tests/net/common/java/android/net/metrics/IpConnectivityLogTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.metrics; - -import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; - -import android.net.ConnectivityMetricsEvent; -import android.net.IIpConnectivityMetrics; -import android.net.Network; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.internal.util.BitUtils; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class IpConnectivityLogTest { - private static final int FAKE_NET_ID = 100; - private static final int[] FAKE_TRANSPORT_TYPES = BitUtils.unpackBits(TRANSPORT_WIFI); - private static final long FAKE_TIME_STAMP = System.currentTimeMillis(); - private static final String FAKE_INTERFACE_NAME = "test"; - private static final IpReachabilityEvent FAKE_EV = - new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED); - - @Mock IIpConnectivityMetrics mMockService; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - } - - @Test - public void testLoggingEvents() throws Exception { - IpConnectivityLog logger = new IpConnectivityLog(mMockService); - - assertTrue(logger.log(FAKE_EV)); - assertTrue(logger.log(FAKE_TIME_STAMP, FAKE_EV)); - assertTrue(logger.log(FAKE_NET_ID, FAKE_TRANSPORT_TYPES, FAKE_EV)); - assertTrue(logger.log(new Network(FAKE_NET_ID), FAKE_TRANSPORT_TYPES, FAKE_EV)); - assertTrue(logger.log(FAKE_INTERFACE_NAME, FAKE_EV)); - assertTrue(logger.log(makeExpectedEvent(FAKE_TIME_STAMP, FAKE_NET_ID, TRANSPORT_WIFI, - FAKE_INTERFACE_NAME))); - - List<ConnectivityMetricsEvent> got = verifyEvents(6); - assertEventsEqual(makeExpectedEvent(got.get(0).timestamp, 0, 0, null), got.get(0)); - assertEventsEqual(makeExpectedEvent(FAKE_TIME_STAMP, 0, 0, null), got.get(1)); - assertEventsEqual(makeExpectedEvent(got.get(2).timestamp, FAKE_NET_ID, - TRANSPORT_WIFI, null), got.get(2)); - assertEventsEqual(makeExpectedEvent(got.get(3).timestamp, FAKE_NET_ID, - TRANSPORT_WIFI, null), got.get(3)); - assertEventsEqual(makeExpectedEvent(got.get(4).timestamp, 0, 0, FAKE_INTERFACE_NAME), - got.get(4)); - assertEventsEqual(makeExpectedEvent(FAKE_TIME_STAMP, FAKE_NET_ID, - TRANSPORT_WIFI, FAKE_INTERFACE_NAME), got.get(5)); - } - - @Test - public void testLoggingEventsWithMultipleCallers() throws Exception { - IpConnectivityLog logger = new IpConnectivityLog(mMockService); - - final int nCallers = 10; - final int nEvents = 10; - for (int n = 0; n < nCallers; n++) { - final int i = n; - new Thread() { - public void run() { - for (int j = 0; j < nEvents; j++) { - assertTrue(logger.log(makeExpectedEvent( - FAKE_TIME_STAMP + i * 100 + j, - FAKE_NET_ID + i * 100 + j, - ((i + j) % 2 == 0) ? TRANSPORT_WIFI : TRANSPORT_CELLULAR, - FAKE_INTERFACE_NAME))); - } - } - }.start(); - } - - List<ConnectivityMetricsEvent> got = verifyEvents(nCallers * nEvents, 200); - Collections.sort(got, EVENT_COMPARATOR); - Iterator<ConnectivityMetricsEvent> iter = got.iterator(); - for (int i = 0; i < nCallers; i++) { - for (int j = 0; j < nEvents; j++) { - final long expectedTimestamp = FAKE_TIME_STAMP + i * 100 + j; - final int expectedNetId = FAKE_NET_ID + i * 100 + j; - final long expectedTransports = - ((i + j) % 2 == 0) ? TRANSPORT_WIFI : TRANSPORT_CELLULAR; - assertEventsEqual(makeExpectedEvent(expectedTimestamp, expectedNetId, - expectedTransports, FAKE_INTERFACE_NAME), iter.next()); - } - } - } - - private List<ConnectivityMetricsEvent> verifyEvents(int n, int timeoutMs) throws Exception { - ArgumentCaptor<ConnectivityMetricsEvent> captor = - ArgumentCaptor.forClass(ConnectivityMetricsEvent.class); - verify(mMockService, timeout(timeoutMs).times(n)).logEvent(captor.capture()); - return captor.getAllValues(); - } - - private List<ConnectivityMetricsEvent> verifyEvents(int n) throws Exception { - return verifyEvents(n, 10); - } - - - private ConnectivityMetricsEvent makeExpectedEvent(long timestamp, int netId, long transports, - String ifname) { - ConnectivityMetricsEvent ev = new ConnectivityMetricsEvent(); - ev.timestamp = timestamp; - ev.data = FAKE_EV; - ev.netId = netId; - ev.transports = transports; - ev.ifname = ifname; - return ev; - } - - /** Outer equality for ConnectivityMetricsEvent to avoid overriding equals() and hashCode(). */ - private void assertEventsEqual(ConnectivityMetricsEvent expected, - ConnectivityMetricsEvent got) { - assertEquals(expected.data, got.data); - assertEquals(expected.timestamp, got.timestamp); - assertEquals(expected.netId, got.netId); - assertEquals(expected.transports, got.transports); - assertEquals(expected.ifname, got.ifname); - } - - static final Comparator<ConnectivityMetricsEvent> EVENT_COMPARATOR = - Comparator.comparingLong((ev) -> ev.timestamp); -} diff --git a/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt b/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt deleted file mode 100644 index 64be50837fc9..000000000000 --- a/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.metrics - -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.testutils.assertParcelSane -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -@SmallTest -class IpManagerEventTest { - @Test - fun testConstructorAndParcel() { - (IpManagerEvent.PROVISIONING_OK..IpManagerEvent.ERROR_INTERFACE_NOT_FOUND).forEach { - val ipManagerEvent = IpManagerEvent(it, Long.MAX_VALUE) - assertEquals(it, ipManagerEvent.eventType) - assertEquals(Long.MAX_VALUE, ipManagerEvent.durationMs) - - assertParcelSane(ipManagerEvent, 2) - } - } -} diff --git a/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt b/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt deleted file mode 100644 index 55b5e492dd47..000000000000 --- a/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.metrics - -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.testutils.assertParcelSane -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -@SmallTest -class IpReachabilityEventTest { - @Test - fun testConstructorAndParcel() { - (IpReachabilityEvent.PROBE..IpReachabilityEvent.PROVISIONING_LOST_ORGANIC).forEach { - val ipReachabilityEvent = IpReachabilityEvent(it) - assertEquals(it, ipReachabilityEvent.eventType) - - assertParcelSane(ipReachabilityEvent, 1) - } - } -} diff --git a/tests/net/common/java/android/net/metrics/NetworkEventTest.kt b/tests/net/common/java/android/net/metrics/NetworkEventTest.kt deleted file mode 100644 index 41430b03a1eb..000000000000 --- a/tests/net/common/java/android/net/metrics/NetworkEventTest.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.metrics - -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.testutils.assertParcelSane -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -@SmallTest -class NetworkEventTest { - @Test - fun testConstructorAndParcel() { - (NetworkEvent.NETWORK_CONNECTED..NetworkEvent.NETWORK_PARTIAL_CONNECTIVITY).forEach { - var networkEvent = NetworkEvent(it) - assertEquals(it, networkEvent.eventType) - assertEquals(0, networkEvent.durationMs) - - networkEvent = NetworkEvent(it, Long.MAX_VALUE) - assertEquals(it, networkEvent.eventType) - assertEquals(Long.MAX_VALUE, networkEvent.durationMs) - - assertParcelSane(networkEvent, 2) - } - } -} diff --git a/tests/net/common/java/android/net/metrics/RaEventTest.kt b/tests/net/common/java/android/net/metrics/RaEventTest.kt deleted file mode 100644 index d9b720332fbe..000000000000 --- a/tests/net/common/java/android/net/metrics/RaEventTest.kt +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.metrics - -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.testutils.assertParcelSane -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -private const val NO_LIFETIME: Long = -1L - -@RunWith(AndroidJUnit4::class) -@SmallTest -class RaEventTest { - @Test - fun testConstructorAndParcel() { - var raEvent = RaEvent.Builder().build() - assertEquals(NO_LIFETIME, raEvent.routerLifetime) - assertEquals(NO_LIFETIME, raEvent.prefixValidLifetime) - assertEquals(NO_LIFETIME, raEvent.prefixPreferredLifetime) - assertEquals(NO_LIFETIME, raEvent.routeInfoLifetime) - assertEquals(NO_LIFETIME, raEvent.rdnssLifetime) - assertEquals(NO_LIFETIME, raEvent.dnsslLifetime) - - raEvent = RaEvent.Builder() - .updateRouterLifetime(1) - .updatePrefixValidLifetime(2) - .updatePrefixPreferredLifetime(3) - .updateRouteInfoLifetime(4) - .updateRdnssLifetime(5) - .updateDnsslLifetime(6) - .build() - assertEquals(1, raEvent.routerLifetime) - assertEquals(2, raEvent.prefixValidLifetime) - assertEquals(3, raEvent.prefixPreferredLifetime) - assertEquals(4, raEvent.routeInfoLifetime) - assertEquals(5, raEvent.rdnssLifetime) - assertEquals(6, raEvent.dnsslLifetime) - - raEvent = RaEvent.Builder() - .updateRouterLifetime(Long.MIN_VALUE) - .updateRouterLifetime(Long.MAX_VALUE) - .build() - assertEquals(Long.MIN_VALUE, raEvent.routerLifetime) - - raEvent = RaEvent(1, 2, 3, 4, 5, 6) - assertEquals(1, raEvent.routerLifetime) - assertEquals(2, raEvent.prefixValidLifetime) - assertEquals(3, raEvent.prefixPreferredLifetime) - assertEquals(4, raEvent.routeInfoLifetime) - assertEquals(5, raEvent.rdnssLifetime) - assertEquals(6, raEvent.dnsslLifetime) - - assertParcelSane(raEvent, 6) - } -} diff --git a/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt b/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt deleted file mode 100644 index 51c0d41bf4d5..000000000000 --- a/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.metrics - -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.testutils.assertParcelSane -import java.lang.reflect.Modifier -import org.junit.Assert.assertEquals -import org.junit.Assert.assertTrue -import org.junit.Test -import org.junit.runner.RunWith - -private const val FIRST_VALIDATION: Int = 1 shl 8 -private const val REVALIDATION: Int = 2 shl 8 - -@RunWith(AndroidJUnit4::class) -@SmallTest -class ValidationProbeEventTest { - private infix fun Int.hasType(type: Int) = (type and this) == type - - @Test - fun testBuilderAndParcel() { - var validationProbeEvent = ValidationProbeEvent.Builder() - .setProbeType(ValidationProbeEvent.PROBE_DNS, false).build() - - assertTrue(validationProbeEvent.probeType hasType REVALIDATION) - - validationProbeEvent = ValidationProbeEvent.Builder() - .setDurationMs(Long.MAX_VALUE) - .setProbeType(ValidationProbeEvent.PROBE_DNS, true) - .setReturnCode(ValidationProbeEvent.DNS_SUCCESS) - .build() - - assertEquals(Long.MAX_VALUE, validationProbeEvent.durationMs) - assertTrue(validationProbeEvent.probeType hasType ValidationProbeEvent.PROBE_DNS) - assertTrue(validationProbeEvent.probeType hasType FIRST_VALIDATION) - assertEquals(ValidationProbeEvent.DNS_SUCCESS, validationProbeEvent.returnCode) - - assertParcelSane(validationProbeEvent, 3) - } - - @Test - fun testGetProbeName() { - val probeFields = ValidationProbeEvent::class.java.declaredFields.filter { - it.type == Int::class.javaPrimitiveType - && Modifier.isPublic(it.modifiers) && Modifier.isStatic(it.modifiers) - && it.name.contains("PROBE") - } - - probeFields.forEach { - val intValue = it.getInt(null) - val stringValue = ValidationProbeEvent.getProbeName(intValue) - assertEquals(it.name, stringValue) - } - - } -} diff --git a/tests/net/common/java/android/net/netstats/NetworkStatsApiTest.kt b/tests/net/common/java/android/net/netstats/NetworkStatsApiTest.kt deleted file mode 100644 index 7b22e45db90a..000000000000 --- a/tests/net/common/java/android/net/netstats/NetworkStatsApiTest.kt +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.netstats - -import android.net.NetworkStats -import android.net.NetworkStats.DEFAULT_NETWORK_NO -import android.net.NetworkStats.DEFAULT_NETWORK_YES -import android.net.NetworkStats.Entry -import android.net.NetworkStats.IFACE_VT -import android.net.NetworkStats.METERED_NO -import android.net.NetworkStats.METERED_YES -import android.net.NetworkStats.ROAMING_NO -import android.net.NetworkStats.ROAMING_YES -import android.net.NetworkStats.SET_DEFAULT -import android.net.NetworkStats.SET_FOREGROUND -import android.net.NetworkStats.TAG_NONE -import android.os.Build -import androidx.test.filters.SmallTest -import com.android.testutils.DevSdkIgnoreRule -import com.android.testutils.assertFieldCountEquals -import com.android.testutils.assertNetworkStatsEquals -import com.android.testutils.assertParcelingIsLossless -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import kotlin.test.assertEquals - -@RunWith(JUnit4::class) -@SmallTest -class NetworkStatsApiTest { - @Rule - @JvmField - val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.Q) - - private val testStatsEmpty = NetworkStats(0L, 0) - - // Note that these variables need to be initialized outside of constructor, initialize - // here with methods that don't exist in Q devices will result in crash. - - // stats1 and stats2 will have some entries with common keys, which are expected to - // be merged if performing add on these 2 stats. - private lateinit var testStats1: NetworkStats - private lateinit var testStats2: NetworkStats - - // This is a result of adding stats1 and stats2, while the merging of common key items is - // subject to test later, this should not be initialized with for a loop to add stats1 - // and stats2 above. - private lateinit var testStats3: NetworkStats - - companion object { - private const val TEST_IFACE = "test0" - private const val TEST_UID1 = 1001 - private const val TEST_UID2 = 1002 - } - - @Before - fun setUp() { - testStats1 = NetworkStats(0L, 0) - // Entries which only appear in set1. - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 20, 3, 57, 40, 3)) - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_YES, DEFAULT_NETWORK_NO, 31, 7, 24, 5, 8)) - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 25, 3, 47, 8, 2)) - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 37, 52, 1, 10, 4)) - // Entries which are common for set1 and set2. - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 101, 2, 103, 4, 5)) - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 17, 2, 11, 1, 0)) - .addEntry(Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 40, 1, 0, 0, 8)) - .addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 3, 1, 6, 2, 0)) - assertEquals(8, testStats1.size()) - - testStats2 = NetworkStats(0L, 0) - // Entries which are common for set1 and set2. - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 3, 15, 2, 31, 1)) - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 13, 61, 10, 1, 45)) - .addEntry(Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 11, 2, 3, 4, 7)) - .addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 4, 3, 2, 1, 0)) - // Entry which only appears in set2. - .addEntry(Entry(IFACE_VT, TEST_UID2, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 2, 3, 7, 8, 0)) - assertEquals(5, testStats2.size()) - - testStats3 = NetworkStats(0L, 9) - // Entries which are unique either in stats1 or stats2. - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 101, 2, 103, 4, 5)) - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_YES, DEFAULT_NETWORK_NO, 31, 7, 24, 5, 8)) - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 25, 3, 47, 8, 2)) - .addEntry(Entry(IFACE_VT, TEST_UID2, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 2, 3, 7, 8, 0)) - // Entries which are common for stats1 and stats2 are being merged. - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 20, 3, 57, 40, 3)) - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 20, 17, 13, 32, 1)) - .addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 50, 113, 11, 11, 49)) - .addEntry(Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 51, 3, 3, 4, 15)) - .addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 7, 4, 8, 3, 0)) - assertEquals(9, testStats3.size()) - } - - @Test - fun testAddEntry() { - val expectedEntriesInStats2 = arrayOf( - Entry(TEST_IFACE, TEST_UID1, SET_DEFAULT, 0x80, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 3, 15, 2, 31, 1), - Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 13, 61, 10, 1, 45), - Entry(TEST_IFACE, TEST_UID2, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 11, 2, 3, 4, 7), - Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 4, 3, 2, 1, 0), - Entry(IFACE_VT, TEST_UID2, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 2, 3, 7, 8, 0)) - - // While testStats* are already initialized with addEntry, verify content added - // matches expectation. - for (i in expectedEntriesInStats2.indices) { - val entry = testStats2.getValues(i, null) - assertEquals(expectedEntriesInStats2[i], entry) - } - - // Verify entry updated with addEntry. - val stats = testStats2.addEntry(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12, -5, 7, 0, 9)) - assertEquals(Entry(IFACE_VT, TEST_UID1, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 16, -2, 9, 1, 9), - stats.getValues(3, null)) - } - - @Test - fun testAdd() { - var stats = NetworkStats(0L, 0) - assertNetworkStatsEquals(testStatsEmpty, stats) - stats = stats.add(testStats2) - assertNetworkStatsEquals(testStats2, stats) - stats = stats.add(testStats1) - // EMPTY + STATS2 + STATS1 = STATS3 - assertNetworkStatsEquals(testStats3, stats) - } - - @Test - fun testParcelUnparcel() { - assertParcelingIsLossless(testStatsEmpty) - assertParcelingIsLossless(testStats1) - assertParcelingIsLossless(testStats2) - assertFieldCountEquals(15, NetworkStats::class.java) - } - - @Test - fun testDescribeContents() { - assertEquals(0, testStatsEmpty.describeContents()) - assertEquals(0, testStats1.describeContents()) - assertEquals(0, testStats2.describeContents()) - assertEquals(0, testStats3.describeContents()) - } - - @Test - fun testSubtract() { - // STATS3 - STATS2 = STATS1 - assertNetworkStatsEquals(testStats1, testStats3.subtract(testStats2)) - // STATS3 - STATS1 = STATS2 - assertNetworkStatsEquals(testStats2, testStats3.subtract(testStats1)) - } - - @Test - fun testMethodsDontModifyReceiver() { - listOf(testStatsEmpty, testStats1, testStats2, testStats3).forEach { - val origStats = it.clone() - it.addEntry(Entry(TEST_IFACE, TEST_UID1, SET_FOREGROUND, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 13, 61, 10, 1, 45)) - it.add(testStats3) - it.subtract(testStats1) - assertNetworkStatsEquals(origStats, it) - } - } -}
\ No newline at end of file diff --git a/tests/net/common/java/android/net/util/SocketUtilsTest.kt b/tests/net/common/java/android/net/util/SocketUtilsTest.kt deleted file mode 100644 index aaf97f36889b..000000000000 --- a/tests/net/common/java/android/net/util/SocketUtilsTest.kt +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.util - -import android.os.Build -import android.system.NetlinkSocketAddress -import android.system.Os -import android.system.OsConstants.AF_INET -import android.system.OsConstants.ETH_P_ALL -import android.system.OsConstants.IPPROTO_UDP -import android.system.OsConstants.RTMGRP_NEIGH -import android.system.OsConstants.SOCK_DGRAM -import android.system.PacketSocketAddress -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.testutils.DevSdkIgnoreRule -import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Assert.fail -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -private const val TEST_INDEX = 123 -private const val TEST_PORT = 555 -private const val FF_BYTE = 0xff.toByte() - -@RunWith(AndroidJUnit4::class) -@SmallTest -class SocketUtilsTest { - @Rule @JvmField - val ignoreRule = DevSdkIgnoreRule() - - @Test - fun testMakeNetlinkSocketAddress() { - val nlAddress = SocketUtils.makeNetlinkSocketAddress(TEST_PORT, RTMGRP_NEIGH) - if (nlAddress is NetlinkSocketAddress) { - assertEquals(TEST_PORT, nlAddress.getPortId()) - assertEquals(RTMGRP_NEIGH, nlAddress.getGroupsMask()) - } else { - fail("Not NetlinkSocketAddress object") - } - } - - @Test - fun testMakePacketSocketAddress_Q() { - val pkAddress = SocketUtils.makePacketSocketAddress(ETH_P_ALL, TEST_INDEX) - assertTrue("Not PacketSocketAddress object", pkAddress is PacketSocketAddress) - - val pkAddress2 = SocketUtils.makePacketSocketAddress(TEST_INDEX, ByteArray(6) { FF_BYTE }) - assertTrue("Not PacketSocketAddress object", pkAddress2 is PacketSocketAddress) - } - - @Test @IgnoreUpTo(Build.VERSION_CODES.Q) - fun testMakePacketSocketAddress() { - val pkAddress = SocketUtils.makePacketSocketAddress( - ETH_P_ALL, TEST_INDEX, ByteArray(6) { FF_BYTE }) - assertTrue("Not PacketSocketAddress object", pkAddress is PacketSocketAddress) - } - - @Test - fun testCloseSocket() { - // Expect no exception happening with null object. - SocketUtils.closeSocket(null) - - val fd = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) - assertTrue(fd.valid()) - SocketUtils.closeSocket(fd) - assertFalse(fd.valid()) - // Expecting socket should be still invalid even closed socket again. - SocketUtils.closeSocket(fd) - assertFalse(fd.valid()) - } -} diff --git a/tests/net/deflake/Android.bp b/tests/net/deflake/Android.bp deleted file mode 100644 index 58ece37ef647..000000000000 --- a/tests/net/deflake/Android.bp +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -java_test_host { - name: "FrameworksNetDeflakeTest", - srcs: ["src/**/*.kt"], - libs: [ - "junit", - "tradefed", - ], - static_libs: [ - "kotlin-test", - "net-host-tests-utils", - ], - data: [":FrameworksNetTests"], - test_suites: ["device-tests"], -} diff --git a/tests/net/deflake/src/com/android/server/net/FrameworksNetDeflakeTest.kt b/tests/net/deflake/src/com/android/server/net/FrameworksNetDeflakeTest.kt deleted file mode 100644 index 62855255fec2..000000000000 --- a/tests/net/deflake/src/com/android/server/net/FrameworksNetDeflakeTest.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server.net - -import com.android.testutils.host.DeflakeHostTestBase -import com.android.tradefed.testtype.DeviceJUnit4ClassRunner -import org.junit.runner.RunWith - -@RunWith(DeviceJUnit4ClassRunner::class) -class FrameworksNetDeflakeTest: DeflakeHostTestBase() { - override val runCount = 20 - override val testApkFilename = "FrameworksNetTests.apk" - override val testClasses = listOf("com.android.server.ConnectivityServiceTest") -}
\ No newline at end of file diff --git a/tests/net/integration/Android.bp b/tests/net/integration/Android.bp deleted file mode 100644 index 39c424e31f0e..000000000000 --- a/tests/net/integration/Android.bp +++ /dev/null @@ -1,78 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -android_test { - name: "FrameworksNetIntegrationTests", - defaults: ["framework-connectivity-test-defaults"], - platform_apis: true, - certificate: "platform", - srcs: [ - "src/**/*.kt", - "src/**/*.aidl", - ], - libs: [ - "android.test.mock", - ], - static_libs: [ - "NetworkStackApiStableLib", - "androidx.test.ext.junit", - "frameworks-net-integration-testutils", - "kotlin-reflect", - "mockito-target-extended-minus-junit4", - "net-tests-utils", - "service-connectivity", - "services.core", - "services.net", - "testables", - ], - test_suites: ["device-tests"], - use_embedded_native_libs: true, - jni_libs: [ - // For mockito extended - "libdexmakerjvmtiagent", - "libstaticjvmtiagent", - // android_library does not include JNI libs: include NetworkStack dependencies here - "libnativehelper_compat_libc++", - "libnetworkstackutilsjni", - ], -} - -// Utilities for testing framework code both in integration and unit tests. -java_library { - name: "frameworks-net-integration-testutils", - defaults: ["framework-connectivity-test-defaults"], - srcs: ["util/**/*.java", "util/**/*.kt"], - static_libs: [ - "androidx.annotation_annotation", - "androidx.test.rules", - "junit", - "net-tests-utils", - ], - libs: [ - "service-connectivity", - "services.core", - "services.net", - ], -} diff --git a/tests/net/integration/AndroidManifest.xml b/tests/net/integration/AndroidManifest.xml deleted file mode 100644 index 2e1368935759..000000000000 --- a/tests/net/integration/AndroidManifest.xml +++ /dev/null @@ -1,73 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.server.net.integrationtests"> - - <!-- For ConnectivityService registerReceiverAsUser (receiving broadcasts) --> - <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/> - <!-- PermissionMonitor sets network permissions for each user --> - <uses-permission android:name="android.permission.MANAGE_USERS"/> - <!-- ConnectivityService sends notifications to BatteryStats --> - <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"/> - <!-- Reading network status --> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> - <uses-permission android:name="android.permission.NETWORK_FACTORY"/> - <!-- Obtain LinkProperties callbacks with sensitive fields --> - <uses-permission android:name="android.permission.NETWORK_SETTINGS" /> - <uses-permission android:name="android.permission.NETWORK_STACK"/> - <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY"/> - <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> - <!-- Reading DeviceConfig flags --> - <uses-permission android:name="android.permission.READ_DEVICE_CONFIG"/> - <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> - <!-- Querying the resources package --> - <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/> - <application android:debuggable="true"> - <uses-library android:name="android.test.runner"/> - - <!-- This manifest is merged with the base manifest of the real NetworkStack app. - Remove the NetworkStackService from the base (real) manifest, and replace with a test - service that responds to the same intent --> - <service android:name=".TestNetworkStackService" - android:process="com.android.server.net.integrationtests.testnetworkstack" - android:exported="true"> - <intent-filter> - <action android:name="android.net.INetworkStackConnector.Test"/> - </intent-filter> - </service> - <service android:name=".NetworkStackInstrumentationService" - android:process="com.android.server.net.integrationtests.testnetworkstack" - android:exported="true"> - <intent-filter> - <action android:name=".INetworkStackInstrumentation"/> - </intent-filter> - </service> - <service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService" - android:process="com.android.server.net.integrationtests.testnetworkstack" - android:permission="android.permission.BIND_JOB_SERVICE"/> - - </application> - - <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="com.android.server.net.integrationtests" - android:label="Frameworks Net Integration Tests"/> - -</manifest> diff --git a/tests/net/integration/res/values/config.xml b/tests/net/integration/res/values/config.xml deleted file mode 100644 index 2c8046ffd781..000000000000 --- a/tests/net/integration/res/values/config.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <!-- - Override configuration for testing. The below settings use the config_ variants, which are - normally used by RROs to override the setting with highest priority. --> - <integer name="config_captive_portal_dns_probe_timeout">12500</integer> - <string name="config_captive_portal_http_url" translatable="false">http://test.android.com</string> - <string name="config_captive_portal_https_url" translatable="false">https://secure.test.android.com</string> - <string-array name="config_captive_portal_fallback_urls" translatable="false"> - <item>http://fallback1.android.com</item> - <item>http://fallback2.android.com</item> - </string-array> - <string-array name="config_captive_portal_fallback_probe_specs" translatable="false"> - </string-array> -</resources> diff --git a/tests/net/integration/src/android/net/TestNetworkStackClient.kt b/tests/net/integration/src/android/net/TestNetworkStackClient.kt deleted file mode 100644 index 61ef5bdca487..000000000000 --- a/tests/net/integration/src/android/net/TestNetworkStackClient.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package android.net - -import android.content.ComponentName -import android.content.Context -import android.content.Intent -import android.net.networkstack.NetworkStackClientBase -import android.os.IBinder -import com.android.server.net.integrationtests.TestNetworkStackService -import org.mockito.Mockito.any -import org.mockito.Mockito.spy -import org.mockito.Mockito.timeout -import org.mockito.Mockito.verify -import kotlin.test.fail - -const val TEST_ACTION_SUFFIX = ".Test" - -class TestNetworkStackClient(private val context: Context) : NetworkStackClientBase() { - // TODO: consider switching to TrackRecord for more expressive checks - private val lastCallbacks = HashMap<Network, INetworkMonitorCallbacks>() - private val moduleConnector = ConnectivityModuleConnector { _, action, _, _ -> - val intent = Intent(action) - val serviceName = TestNetworkStackService::class.qualifiedName - ?: fail("TestNetworkStackService name not found") - intent.component = ComponentName(context.packageName, serviceName) - return@ConnectivityModuleConnector intent - }.also { it.init(context) } - - fun start() { - moduleConnector.startModuleService( - INetworkStackConnector::class.qualifiedName + TEST_ACTION_SUFFIX, - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) { connector -> - onNetworkStackConnected(INetworkStackConnector.Stub.asInterface(connector)) - } - } - - // base may be an instance of an inaccessible subclass, so non-spyable. - // Use a known open class that delegates to the original instance for all methods except - // asBinder. asBinder needs to use its own non-delegated implementation as otherwise it would - // return a binder token to a class that is not spied on. - open class NetworkMonitorCallbacksWrapper(private val base: INetworkMonitorCallbacks) : - INetworkMonitorCallbacks.Stub(), INetworkMonitorCallbacks by base { - // asBinder is implemented by both base class and delegate: specify explicitly - override fun asBinder(): IBinder { - return super.asBinder() - } - } - - override fun makeNetworkMonitor(network: Network, name: String?, cb: INetworkMonitorCallbacks) { - val cbSpy = spy(NetworkMonitorCallbacksWrapper(cb)) - lastCallbacks[network] = cbSpy - super.makeNetworkMonitor(network, name, cbSpy) - } - - fun verifyNetworkMonitorCreated(network: Network, timeoutMs: Long) { - val cb = lastCallbacks[network] - ?: fail("NetworkMonitor for network $network not requested") - verify(cb, timeout(timeoutMs)).onNetworkMonitorCreated(any()) - } -}
\ No newline at end of file diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt deleted file mode 100644 index e039ef072542..000000000000 --- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server.net.integrationtests - -import android.app.usage.NetworkStatsManager -import android.content.ComponentName -import android.content.Context -import android.content.Context.BIND_AUTO_CREATE -import android.content.Context.BIND_IMPORTANT -import android.content.Intent -import android.content.ServiceConnection -import android.net.ConnectivityManager -import android.net.IDnsResolver -import android.net.INetd -import android.net.LinkProperties -import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL -import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET -import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED -import android.net.NetworkCapabilities.TRANSPORT_CELLULAR -import android.net.NetworkRequest -import android.net.TestNetworkStackClient -import android.net.Uri -import android.net.metrics.IpConnectivityLog -import android.os.ConditionVariable -import android.os.IBinder -import android.os.SystemConfigManager -import android.os.UserHandle -import android.testing.TestableContext -import android.util.Log -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import com.android.server.ConnectivityService -import com.android.server.NetworkAgentWrapper -import com.android.server.TestNetIdManager -import com.android.server.connectivity.MockableSystemProperties -import com.android.server.connectivity.ProxyTracker -import com.android.testutils.TestableNetworkCallback -import org.junit.After -import org.junit.Before -import org.junit.BeforeClass -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.AdditionalAnswers -import org.mockito.ArgumentMatchers.anyString -import org.mockito.Mock -import org.mockito.Mockito.any -import org.mockito.Mockito.anyInt -import org.mockito.Mockito.doNothing -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.eq -import org.mockito.Mockito.mock -import org.mockito.Mockito.spy -import org.mockito.MockitoAnnotations -import org.mockito.Spy -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertNotNull -import kotlin.test.assertTrue -import kotlin.test.fail - -const val SERVICE_BIND_TIMEOUT_MS = 5_000L -const val TEST_TIMEOUT_MS = 10_000L - -/** - * Test that exercises an instrumented version of ConnectivityService against an instrumented - * NetworkStack in a different test process. - */ -@RunWith(AndroidJUnit4::class) -class ConnectivityServiceIntegrationTest { - // lateinit used here for mocks as they need to be reinitialized between each test and the test - // should crash if they are used before being initialized. - @Mock - private lateinit var statsManager: NetworkStatsManager - @Mock - private lateinit var log: IpConnectivityLog - @Mock - private lateinit var netd: INetd - @Mock - private lateinit var dnsResolver: IDnsResolver - @Mock - private lateinit var systemConfigManager: SystemConfigManager - @Spy - private var context = TestableContext(realContext) - - // lateinit for these three classes under test, as they should be reset to a different instance - // for every test but should always be initialized before use (or the test should crash). - private lateinit var networkStackClient: TestNetworkStackClient - private lateinit var service: ConnectivityService - private lateinit var cm: ConnectivityManager - - companion object { - // lateinit for this binder token, as it must be initialized before any test code is run - // and use of it before init should crash the test. - private lateinit var nsInstrumentation: INetworkStackInstrumentation - private val bindingCondition = ConditionVariable(false) - - private val realContext get() = InstrumentationRegistry.getInstrumentation().context - private val httpProbeUrl get() = - realContext.getResources().getString(R.string.config_captive_portal_http_url) - private val httpsProbeUrl get() = - realContext.getResources().getString(R.string.config_captive_portal_https_url) - - private class InstrumentationServiceConnection : ServiceConnection { - override fun onServiceConnected(name: ComponentName?, service: IBinder?) { - Log.i("TestNetworkStack", "Service connected") - try { - if (service == null) fail("Error binding to NetworkStack instrumentation") - if (::nsInstrumentation.isInitialized) fail("Service already connected") - nsInstrumentation = INetworkStackInstrumentation.Stub.asInterface(service) - } finally { - bindingCondition.open() - } - } - - override fun onServiceDisconnected(name: ComponentName?) = Unit - } - - @BeforeClass - @JvmStatic - fun setUpClass() { - val intent = Intent(realContext, NetworkStackInstrumentationService::class.java) - intent.action = INetworkStackInstrumentation::class.qualifiedName - assertTrue(realContext.bindService(intent, InstrumentationServiceConnection(), - BIND_AUTO_CREATE or BIND_IMPORTANT), - "Error binding to instrumentation service") - assertTrue(bindingCondition.block(SERVICE_BIND_TIMEOUT_MS), - "Timed out binding to instrumentation service " + - "after $SERVICE_BIND_TIMEOUT_MS ms") - } - } - - @Before - fun setUp() { - MockitoAnnotations.initMocks(this) - val asUserCtx = mock(Context::class.java, AdditionalAnswers.delegatesTo<Context>(context)) - doReturn(UserHandle.ALL).`when`(asUserCtx).user - doReturn(asUserCtx).`when`(context).createContextAsUser(eq(UserHandle.ALL), anyInt()) - doNothing().`when`(context).sendStickyBroadcast(any(), any()) - doReturn(Context.SYSTEM_CONFIG_SERVICE).`when`(context) - .getSystemServiceName(SystemConfigManager::class.java) - doReturn(systemConfigManager).`when`(context) - .getSystemService(Context.SYSTEM_CONFIG_SERVICE) - doReturn(IntArray(0)).`when`(systemConfigManager).getSystemPermissionUids(anyString()) - - networkStackClient = TestNetworkStackClient(realContext) - networkStackClient.start() - - service = TestConnectivityService(makeDependencies()) - cm = ConnectivityManager(context, service) - context.addMockSystemService(Context.CONNECTIVITY_SERVICE, cm) - context.addMockSystemService(Context.NETWORK_STATS_SERVICE, statsManager) - - service.systemReadyInternal() - } - - private inner class TestConnectivityService(deps: Dependencies) : ConnectivityService( - context, dnsResolver, log, netd, deps) - - private fun makeDependencies(): ConnectivityService.Dependencies { - val deps = spy(ConnectivityService.Dependencies()) - doReturn(networkStackClient).`when`(deps).networkStack - doReturn(mock(ProxyTracker::class.java)).`when`(deps).makeProxyTracker(any(), any()) - doReturn(mock(MockableSystemProperties::class.java)).`when`(deps).systemProperties - doReturn(TestNetIdManager()).`when`(deps).makeNetIdManager() - return deps - } - - @After - fun tearDown() { - nsInstrumentation.clearAllState() - } - - @Test - fun testValidation() { - val request = NetworkRequest.Builder() - .clearCapabilities() - .addCapability(NET_CAPABILITY_INTERNET) - .build() - val testCallback = TestableNetworkCallback() - - cm.registerNetworkCallback(request, testCallback) - nsInstrumentation.addHttpResponse(HttpResponse(httpProbeUrl, responseCode = 204)) - nsInstrumentation.addHttpResponse(HttpResponse(httpsProbeUrl, responseCode = 204)) - - val na = NetworkAgentWrapper(TRANSPORT_CELLULAR, LinkProperties(), null /* ncTemplate */, - context) - networkStackClient.verifyNetworkMonitorCreated(na.network, TEST_TIMEOUT_MS) - - na.addCapability(NET_CAPABILITY_INTERNET) - na.connect() - - testCallback.expectAvailableThenValidatedCallbacks(na.network, TEST_TIMEOUT_MS) - assertEquals(2, nsInstrumentation.getRequestUrls().size) - } - - @Test - fun testCapportApi() { - val request = NetworkRequest.Builder() - .clearCapabilities() - .addCapability(NET_CAPABILITY_INTERNET) - .build() - val testCb = TestableNetworkCallback() - val apiUrl = "https://capport.android.com" - - cm.registerNetworkCallback(request, testCb) - nsInstrumentation.addHttpResponse(HttpResponse( - apiUrl, - """ - |{ - | "captive": true, - | "user-portal-url": "https://login.capport.android.com", - | "venue-info-url": "https://venueinfo.capport.android.com" - |} - """.trimMargin())) - - // Tests will fail if a non-mocked query is received: mock the HTTPS probe, but not the - // HTTP probe as it should not be sent. - // Even if the HTTPS probe succeeds, a portal should be detected as the API takes precedence - // in that case. - nsInstrumentation.addHttpResponse(HttpResponse(httpsProbeUrl, responseCode = 204)) - - val lp = LinkProperties() - lp.captivePortalApiUrl = Uri.parse(apiUrl) - val na = NetworkAgentWrapper(TRANSPORT_CELLULAR, lp, null /* ncTemplate */, context) - networkStackClient.verifyNetworkMonitorCreated(na.network, TEST_TIMEOUT_MS) - - na.addCapability(NET_CAPABILITY_INTERNET) - na.connect() - - testCb.expectAvailableCallbacks(na.network, validated = false, tmt = TEST_TIMEOUT_MS) - - val capportData = testCb.expectLinkPropertiesThat(na, TEST_TIMEOUT_MS) { - it.captivePortalData != null - }.lp.captivePortalData - assertNotNull(capportData) - assertTrue(capportData.isCaptive) - assertEquals(Uri.parse("https://login.capport.android.com"), capportData.userPortalUrl) - assertEquals(Uri.parse("https://venueinfo.capport.android.com"), capportData.venueInfoUrl) - - val nc = testCb.expectCapabilitiesWith(NET_CAPABILITY_CAPTIVE_PORTAL, na, TEST_TIMEOUT_MS) - assertFalse(nc.hasCapability(NET_CAPABILITY_VALIDATED)) - } -}
\ No newline at end of file diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.aidl b/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.aidl deleted file mode 100644 index 9a2bcfea7641..000000000000 --- a/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server.net.integrationtests; - -parcelable HttpResponse;
\ No newline at end of file diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt b/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt deleted file mode 100644 index e2063138fef1..000000000000 --- a/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server.net.integrationtests - -import android.os.Parcel -import android.os.Parcelable - -data class HttpResponse( - val requestUrl: String, - val responseCode: Int, - val content: String = "", - val redirectUrl: String? = null -) : Parcelable { - constructor(p: Parcel): this(p.readString(), p.readInt(), p.readString(), p.readString()) - constructor(requestUrl: String, contentBody: String): this( - requestUrl, - responseCode = 200, - content = contentBody, - redirectUrl = null) - - override fun writeToParcel(dest: Parcel, flags: Int) { - with(dest) { - writeString(requestUrl) - writeInt(responseCode) - writeString(content) - writeString(redirectUrl) - } - } - - override fun describeContents() = 0 - companion object CREATOR : Parcelable.Creator<HttpResponse> { - override fun createFromParcel(source: Parcel) = HttpResponse(source) - override fun newArray(size: Int) = arrayOfNulls<HttpResponse?>(size) - } -}
\ No newline at end of file diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/INetworkStackInstrumentation.aidl b/tests/net/integration/src/com/android/server/net/integrationtests/INetworkStackInstrumentation.aidl deleted file mode 100644 index efc58add9cf5..000000000000 --- a/tests/net/integration/src/com/android/server/net/integrationtests/INetworkStackInstrumentation.aidl +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server.net.integrationtests; - -import com.android.server.net.integrationtests.HttpResponse; - -interface INetworkStackInstrumentation { - void clearAllState(); - void addHttpResponse(in HttpResponse response); - List<String> getRequestUrls(); -}
\ No newline at end of file diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt b/tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt deleted file mode 100644 index e807952cec11..000000000000 --- a/tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server.net.integrationtests - -import android.app.Service -import android.content.Intent -import java.net.URL -import java.util.Collections -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.ConcurrentLinkedQueue -import kotlin.collections.ArrayList -import kotlin.test.fail - -/** - * An instrumentation interface for the NetworkStack that allows controlling behavior to - * facilitate integration tests. - */ -class NetworkStackInstrumentationService : Service() { - override fun onBind(intent: Intent) = InstrumentationConnector.asBinder() - - object InstrumentationConnector : INetworkStackInstrumentation.Stub() { - private val httpResponses = ConcurrentHashMap<String, ConcurrentLinkedQueue<HttpResponse>>() - .run { - withDefault { key -> getOrPut(key) { ConcurrentLinkedQueue() } } - } - private val httpRequestUrls = Collections.synchronizedList(ArrayList<String>()) - - /** - * Called when an HTTP request is being processed by NetworkMonitor. Returns the response - * that should be simulated. - */ - fun processRequest(url: URL): HttpResponse { - val strUrl = url.toString() - httpRequestUrls.add(strUrl) - return httpResponses[strUrl]?.poll() - ?: fail("No mocked response for request: $strUrl. " + - "Mocked URL keys are: ${httpResponses.keys}") - } - - /** - * Clear all state of this connector. This is intended for use between two tests, so all - * state should be reset as if the connector was just created. - */ - override fun clearAllState() { - httpResponses.clear() - httpRequestUrls.clear() - } - - /** - * Add a response to a future HTTP request. - * - * <p>For any subsequent HTTP/HTTPS query, the first response with a matching URL will be - * used to mock the query response. - * - * <p>All requests that are expected to be sent must have a mock response: if an unexpected - * request is seen, the test will fail. - */ - override fun addHttpResponse(response: HttpResponse) { - httpResponses.getValue(response.requestUrl).add(response) - } - - /** - * Get the ordered list of request URLs that have been sent by NetworkMonitor, and were - * answered based on mock responses. - */ - override fun getRequestUrls(): List<String> { - return ArrayList(httpRequestUrls) - } - } -}
\ No newline at end of file diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt b/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt deleted file mode 100644 index eff66584d6c1..000000000000 --- a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server.net.integrationtests - -import android.app.Service -import android.content.Context -import android.content.Intent -import android.net.INetworkMonitorCallbacks -import android.net.Network -import android.net.metrics.IpConnectivityLog -import android.net.util.SharedLog -import android.os.IBinder -import com.android.networkstack.netlink.TcpSocketTracker -import com.android.server.NetworkStackService -import com.android.server.NetworkStackService.NetworkMonitorConnector -import com.android.server.NetworkStackService.NetworkStackConnector -import com.android.server.connectivity.NetworkMonitor -import com.android.server.net.integrationtests.NetworkStackInstrumentationService.InstrumentationConnector -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.mock -import org.mockito.Mockito.spy -import java.io.ByteArrayInputStream -import java.net.HttpURLConnection -import java.net.URL -import java.net.URLConnection -import java.nio.charset.StandardCharsets - -private const val TEST_NETID = 42 - -/** - * Android service that can return an [android.net.INetworkStackConnector] which can be instrumented - * through [NetworkStackInstrumentationService]. - * Useful in tests to create test instrumented NetworkStack components that can receive - * instrumentation commands through [NetworkStackInstrumentationService]. - */ -class TestNetworkStackService : Service() { - override fun onBind(intent: Intent): IBinder = TestNetworkStackConnector(makeTestContext()) - - private fun makeTestContext() = spy(applicationContext).also { - doReturn(mock(IBinder::class.java)).`when`(it).getSystemService(Context.NETD_SERVICE) - } - - private class TestPermissionChecker : NetworkStackService.PermissionChecker() { - override fun enforceNetworkStackCallingPermission() = Unit - } - - private class NetworkMonitorDeps(private val privateDnsBypassNetwork: Network) : - NetworkMonitor.Dependencies() { - override fun getPrivateDnsBypassNetwork(network: Network?) = privateDnsBypassNetwork - } - - private inner class TestNetworkStackConnector(context: Context) : NetworkStackConnector( - context, TestPermissionChecker(), NetworkStackService.Dependencies()) { - - private val network = Network(TEST_NETID) - private val privateDnsBypassNetwork = TestNetwork(TEST_NETID) - - private inner class TestNetwork(netId: Int) : Network(netId) { - override fun openConnection(url: URL): URLConnection { - val response = InstrumentationConnector.processRequest(url) - val responseBytes = response.content.toByteArray(StandardCharsets.UTF_8) - - val connection = mock(HttpURLConnection::class.java) - doReturn(response.responseCode).`when`(connection).responseCode - doReturn(responseBytes.size.toLong()).`when`(connection).contentLengthLong - doReturn(response.redirectUrl).`when`(connection).getHeaderField("location") - doReturn(ByteArrayInputStream(responseBytes)).`when`(connection).inputStream - return connection - } - } - - override fun makeNetworkMonitor( - network: Network, - name: String?, - cb: INetworkMonitorCallbacks - ) { - val nm = NetworkMonitor(this@TestNetworkStackService, cb, - this.network, - mock(IpConnectivityLog::class.java), mock(SharedLog::class.java), - mock(NetworkStackService.NetworkStackServiceManager::class.java), - NetworkMonitorDeps(privateDnsBypassNetwork), - mock(TcpSocketTracker::class.java)) - cb.onNetworkMonitorCreated(NetworkMonitorConnector(nm, TestPermissionChecker())) - } - } -} diff --git a/tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt b/tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt deleted file mode 100644 index 165fd3728281..000000000000 --- a/tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -@file:JvmName("ConnectivityServiceTestUtils") - -package com.android.server - -import android.net.ConnectivityManager.TYPE_BLUETOOTH -import android.net.ConnectivityManager.TYPE_ETHERNET -import android.net.ConnectivityManager.TYPE_MOBILE -import android.net.ConnectivityManager.TYPE_NONE -import android.net.ConnectivityManager.TYPE_TEST -import android.net.ConnectivityManager.TYPE_VPN -import android.net.ConnectivityManager.TYPE_WIFI -import android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH -import android.net.NetworkCapabilities.TRANSPORT_CELLULAR -import android.net.NetworkCapabilities.TRANSPORT_ETHERNET -import android.net.NetworkCapabilities.TRANSPORT_TEST -import android.net.NetworkCapabilities.TRANSPORT_VPN -import android.net.NetworkCapabilities.TRANSPORT_WIFI - -fun transportToLegacyType(transport: Int) = when (transport) { - TRANSPORT_BLUETOOTH -> TYPE_BLUETOOTH - TRANSPORT_CELLULAR -> TYPE_MOBILE - TRANSPORT_ETHERNET -> TYPE_ETHERNET - TRANSPORT_TEST -> TYPE_TEST - TRANSPORT_VPN -> TYPE_VPN - TRANSPORT_WIFI -> TYPE_WIFI - else -> TYPE_NONE -}
\ No newline at end of file diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java deleted file mode 100644 index 17db17923f4d..000000000000 --- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server; - -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; -import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; -import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; -import static android.net.NetworkCapabilities.TRANSPORT_VPN; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE; - -import static com.android.server.ConnectivityServiceTestUtils.transportToLegacyType; - -import static junit.framework.Assert.assertTrue; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import android.annotation.NonNull; -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.LinkProperties; -import android.net.Network; -import android.net.NetworkAgent; -import android.net.NetworkAgentConfig; -import android.net.NetworkCapabilities; -import android.net.NetworkProvider; -import android.net.NetworkScore; -import android.net.NetworkSpecifier; -import android.net.QosFilter; -import android.net.SocketKeepalive; -import android.os.ConditionVariable; -import android.os.HandlerThread; -import android.os.Message; -import android.util.Log; -import android.util.Range; - -import com.android.net.module.util.ArrayTrackRecord; -import com.android.testutils.HandlerUtils; -import com.android.testutils.TestableNetworkCallback; - -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - -public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork { - private final NetworkCapabilities mNetworkCapabilities; - private final HandlerThread mHandlerThread; - private final Context mContext; - private final String mLogTag; - private final NetworkAgentConfig mNetworkAgentConfig; - - private final ConditionVariable mDisconnected = new ConditionVariable(); - private final ConditionVariable mPreventReconnectReceived = new ConditionVariable(); - private final AtomicBoolean mConnected = new AtomicBoolean(false); - private NetworkScore mScore; - private NetworkAgent mNetworkAgent; - private int mStartKeepaliveError = SocketKeepalive.ERROR_UNSUPPORTED; - private int mStopKeepaliveError = SocketKeepalive.NO_KEEPALIVE; - // Controls how test network agent is going to wait before responding to keepalive - // start/stop. Useful when simulate KeepaliveTracker is waiting for response from modem. - private long mKeepaliveResponseDelay = 0L; - private Integer mExpectedKeepaliveSlot = null; - private final ArrayTrackRecord<CallbackType>.ReadHead mCallbackHistory = - new ArrayTrackRecord<CallbackType>().newReadHead(); - - public NetworkAgentWrapper(int transport, LinkProperties linkProperties, - NetworkCapabilities ncTemplate, Context context) throws Exception { - final int type = transportToLegacyType(transport); - final String typeName = ConnectivityManager.getNetworkTypeName(type); - mNetworkCapabilities = (ncTemplate != null) ? ncTemplate : new NetworkCapabilities(); - mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_SUSPENDED); - mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); - mNetworkCapabilities.addTransportType(transport); - switch (transport) { - case TRANSPORT_ETHERNET: - mScore = new NetworkScore.Builder().setLegacyInt(70).build(); - break; - case TRANSPORT_WIFI: - mScore = new NetworkScore.Builder().setLegacyInt(60).build(); - break; - case TRANSPORT_CELLULAR: - mScore = new NetworkScore.Builder().setLegacyInt(50).build(); - break; - case TRANSPORT_WIFI_AWARE: - mScore = new NetworkScore.Builder().setLegacyInt(20).build(); - break; - case TRANSPORT_VPN: - mNetworkCapabilities.removeCapability(NET_CAPABILITY_NOT_VPN); - // VPNs deduce the SUSPENDED capability from their underlying networks and there - // is no public API to let VPN services set it. - mNetworkCapabilities.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); - mScore = new NetworkScore.Builder().setLegacyInt(101).build(); - break; - default: - throw new UnsupportedOperationException("unimplemented network type"); - } - mContext = context; - mLogTag = "Mock-" + typeName; - mHandlerThread = new HandlerThread(mLogTag); - mHandlerThread.start(); - - // extraInfo is set to "" by default in NetworkAgentConfig. - final String extraInfo = (transport == TRANSPORT_CELLULAR) ? "internet.apn" : ""; - mNetworkAgentConfig = new NetworkAgentConfig.Builder() - .setLegacyType(type) - .setLegacyTypeName(typeName) - .setLegacyExtraInfo(extraInfo) - .build(); - mNetworkAgent = makeNetworkAgent(linkProperties, mNetworkAgentConfig); - } - - protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties, - final NetworkAgentConfig nac) throws Exception { - return new InstrumentedNetworkAgent(this, linkProperties, nac); - } - - public static class InstrumentedNetworkAgent extends NetworkAgent { - private final NetworkAgentWrapper mWrapper; - private static final String PROVIDER_NAME = "InstrumentedNetworkAgentProvider"; - - public InstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp, - NetworkAgentConfig nac) { - super(wrapper.mContext, wrapper.mHandlerThread.getLooper(), wrapper.mLogTag, - wrapper.mNetworkCapabilities, lp, wrapper.mScore, nac, - new NetworkProvider(wrapper.mContext, wrapper.mHandlerThread.getLooper(), - PROVIDER_NAME)); - mWrapper = wrapper; - register(); - } - - @Override - public void unwanted() { - mWrapper.mDisconnected.open(); - } - - @Override - public void startSocketKeepalive(Message msg) { - int slot = msg.arg1; - if (mWrapper.mExpectedKeepaliveSlot != null) { - assertEquals((int) mWrapper.mExpectedKeepaliveSlot, slot); - } - mWrapper.mHandlerThread.getThreadHandler().postDelayed( - () -> onSocketKeepaliveEvent(slot, mWrapper.mStartKeepaliveError), - mWrapper.mKeepaliveResponseDelay); - } - - @Override - public void stopSocketKeepalive(Message msg) { - final int slot = msg.arg1; - mWrapper.mHandlerThread.getThreadHandler().postDelayed( - () -> onSocketKeepaliveEvent(slot, mWrapper.mStopKeepaliveError), - mWrapper.mKeepaliveResponseDelay); - } - - @Override - public void onQosCallbackRegistered(final int qosCallbackId, - final @NonNull QosFilter filter) { - Log.i(mWrapper.mLogTag, "onQosCallbackRegistered"); - mWrapper.mCallbackHistory.add( - new CallbackType.OnQosCallbackRegister(qosCallbackId, filter)); - } - - @Override - public void onQosCallbackUnregistered(final int qosCallbackId) { - Log.i(mWrapper.mLogTag, "onQosCallbackUnregistered"); - mWrapper.mCallbackHistory.add(new CallbackType.OnQosCallbackUnregister(qosCallbackId)); - } - - @Override - protected void preventAutomaticReconnect() { - mWrapper.mPreventReconnectReceived.open(); - } - - @Override - protected void addKeepalivePacketFilter(Message msg) { - Log.i(mWrapper.mLogTag, "Add keepalive packet filter."); - } - - @Override - protected void removeKeepalivePacketFilter(Message msg) { - Log.i(mWrapper.mLogTag, "Remove keepalive packet filter."); - } - } - - public void setScore(@NonNull final NetworkScore score) { - mScore = score; - mNetworkAgent.sendNetworkScore(score); - } - - public void adjustScore(int change) { - final int newLegacyScore = mScore.getLegacyInt() + change; - final NetworkScore.Builder builder = new NetworkScore.Builder() - .setLegacyInt(newLegacyScore); - if (mNetworkCapabilities.hasTransport(TRANSPORT_WIFI) && newLegacyScore < 50) { - builder.setExiting(true); - } - mScore = builder.build(); - mNetworkAgent.sendNetworkScore(mScore); - } - - public NetworkScore getScore() { - return mScore; - } - - public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) { - mNetworkAgent.explicitlySelected(explicitlySelected, acceptUnvalidated); - } - - public void addCapability(int capability) { - mNetworkCapabilities.addCapability(capability); - mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); - } - - public void removeCapability(int capability) { - mNetworkCapabilities.removeCapability(capability); - mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); - } - - public void setUids(Set<Range<Integer>> uids) { - mNetworkCapabilities.setUids(uids); - mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); - } - - public void setSignalStrength(int signalStrength) { - mNetworkCapabilities.setSignalStrength(signalStrength); - mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); - } - - public void setNetworkSpecifier(NetworkSpecifier networkSpecifier) { - mNetworkCapabilities.setNetworkSpecifier(networkSpecifier); - mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); - } - - public void setNetworkCapabilities(NetworkCapabilities nc, boolean sendToConnectivityService) { - mNetworkCapabilities.set(nc); - if (sendToConnectivityService) { - mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); - } - } - - public void connect() { - if (!mConnected.compareAndSet(false /* expect */, true /* update */)) { - // compareAndSet returns false when the value couldn't be updated because it did not - // match the expected value. - fail("Test NetworkAgents can only be connected once"); - } - mNetworkAgent.markConnected(); - } - - public void suspend() { - removeCapability(NET_CAPABILITY_NOT_SUSPENDED); - } - - public void resume() { - addCapability(NET_CAPABILITY_NOT_SUSPENDED); - } - - public void disconnect() { - mNetworkAgent.unregister(); - } - - @Override - public Network getNetwork() { - return mNetworkAgent.getNetwork(); - } - - public void expectPreventReconnectReceived(long timeoutMs) { - assertTrue(mPreventReconnectReceived.block(timeoutMs)); - } - - public void expectDisconnected(long timeoutMs) { - assertTrue(mDisconnected.block(timeoutMs)); - } - - public void sendLinkProperties(LinkProperties lp) { - mNetworkAgent.sendLinkProperties(lp); - } - - public void setStartKeepaliveEvent(int reason) { - mStartKeepaliveError = reason; - } - - public void setStopKeepaliveEvent(int reason) { - mStopKeepaliveError = reason; - } - - public void setKeepaliveResponseDelay(long delay) { - mKeepaliveResponseDelay = delay; - } - - public void setExpectedKeepaliveSlot(Integer slot) { - mExpectedKeepaliveSlot = slot; - } - - public NetworkAgent getNetworkAgent() { - return mNetworkAgent; - } - - public NetworkCapabilities getNetworkCapabilities() { - return mNetworkCapabilities; - } - - public int getLegacyType() { - return mNetworkAgentConfig.getLegacyType(); - } - - public String getExtraInfo() { - return mNetworkAgentConfig.getLegacyExtraInfo(); - } - - public @NonNull ArrayTrackRecord<CallbackType>.ReadHead getCallbackHistory() { - return mCallbackHistory; - } - - public void waitForIdle(long timeoutMs) { - HandlerUtils.waitForIdle(mHandlerThread, timeoutMs); - } - - abstract static class CallbackType { - final int mQosCallbackId; - - protected CallbackType(final int qosCallbackId) { - mQosCallbackId = qosCallbackId; - } - - static class OnQosCallbackRegister extends CallbackType { - final QosFilter mFilter; - OnQosCallbackRegister(final int qosCallbackId, final QosFilter filter) { - super(qosCallbackId); - mFilter = filter; - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final OnQosCallbackRegister that = (OnQosCallbackRegister) o; - return mQosCallbackId == that.mQosCallbackId - && Objects.equals(mFilter, that.mFilter); - } - - @Override - public int hashCode() { - return Objects.hash(mQosCallbackId, mFilter); - } - } - - static class OnQosCallbackUnregister extends CallbackType { - OnQosCallbackUnregister(final int qosCallbackId) { - super(qosCallbackId); - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final OnQosCallbackUnregister that = (OnQosCallbackUnregister) o; - return mQosCallbackId == that.mQosCallbackId; - } - - @Override - public int hashCode() { - return Objects.hash(mQosCallbackId); - } - } - } - - public boolean isBypassableVpn() { - return mNetworkAgentConfig.isBypassableVpn(); - } -} diff --git a/tests/net/integration/util/com/android/server/TestNetIdManager.kt b/tests/net/integration/util/com/android/server/TestNetIdManager.kt deleted file mode 100644 index 938a694e8ba9..000000000000 --- a/tests/net/integration/util/com/android/server/TestNetIdManager.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server - -import java.util.concurrent.atomic.AtomicInteger - -/** - * A [NetIdManager] that generates ID starting from [NetIdManager.MAX_NET_ID] and decreasing, rather - * than starting from [NetIdManager.MIN_NET_ID] and increasing. - * - * Useful for testing ConnectivityService, to minimize the risk of test ConnectivityService netIDs - * overlapping with netIDs used by the real ConnectivityService on the device. - * - * IDs may still overlap if many networks have been used on the device (so the "real" netIDs - * are close to MAX_NET_ID), but this is typically not the case when running unit tests. Also, there - * is no way to fully solve the overlap issue without altering ID allocation in non-test code, as - * the real ConnectivityService could start using netIds that have been used by the test in the - * past. - */ -class TestNetIdManager : NetIdManager() { - private val nextId = AtomicInteger(MAX_NET_ID) - override fun reserveNetId() = nextId.decrementAndGet() - override fun releaseNetId(id: Int) = Unit - fun peekNextNetId() = nextId.get() - 1 -} diff --git a/tests/net/jarjar-rules.txt b/tests/net/jarjar-rules.txt deleted file mode 100644 index ca8867206dda..000000000000 --- a/tests/net/jarjar-rules.txt +++ /dev/null @@ -1,2 +0,0 @@ -# Module library in frameworks/libs/net -rule com.android.net.module.util.** android.net.frameworktests.util.@1 diff --git a/tests/net/java/android/app/usage/NetworkStatsManagerTest.java b/tests/net/java/android/app/usage/NetworkStatsManagerTest.java deleted file mode 100644 index 899295a019d2..000000000000 --- a/tests/net/java/android/app/usage/NetworkStatsManagerTest.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.usage; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.net.ConnectivityManager; -import android.net.INetworkStatsService; -import android.net.INetworkStatsSession; -import android.net.NetworkStats.Entry; -import android.net.NetworkStatsHistory; -import android.net.NetworkTemplate; -import android.os.RemoteException; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetworkStatsManagerTest { - - private @Mock INetworkStatsService mService; - private @Mock INetworkStatsSession mStatsSession; - - private NetworkStatsManager mManager; - - // TODO: change to NetworkTemplate.MATCH_MOBILE once internal constant rename is merged to aosp. - private static final int MATCH_MOBILE_ALL = 1; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mManager = new NetworkStatsManager(InstrumentationRegistry.getContext(), mService); - } - - @Test - public void testQueryDetails() throws RemoteException { - final String subscriberId = "subid"; - final long startTime = 1; - final long endTime = 100; - final int uid1 = 10001; - final int uid2 = 10002; - final int uid3 = 10003; - - Entry uid1Entry1 = new Entry("if1", uid1, - android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE, - 100, 10, 200, 20, 0); - - Entry uid1Entry2 = new Entry( - "if2", uid1, - android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE, - 100, 10, 200, 20, 0); - - Entry uid2Entry1 = new Entry("if1", uid2, - android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE, - 150, 10, 250, 20, 0); - - Entry uid2Entry2 = new Entry( - "if2", uid2, - android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE, - 150, 10, 250, 20, 0); - - NetworkStatsHistory history1 = new NetworkStatsHistory(10, 2); - history1.recordData(10, 20, uid1Entry1); - history1.recordData(20, 30, uid1Entry2); - - NetworkStatsHistory history2 = new NetworkStatsHistory(10, 2); - history1.recordData(30, 40, uid2Entry1); - history1.recordData(35, 45, uid2Entry2); - - - when(mService.openSessionForUsageStats(anyInt(), anyString())).thenReturn(mStatsSession); - when(mStatsSession.getRelevantUids()).thenReturn(new int[] { uid1, uid2, uid3 }); - - when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class), - eq(uid1), eq(android.net.NetworkStats.SET_ALL), - eq(android.net.NetworkStats.TAG_NONE), - eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime))) - .then((InvocationOnMock inv) -> { - NetworkTemplate template = inv.getArgument(0); - assertEquals(MATCH_MOBILE_ALL, template.getMatchRule()); - assertEquals(subscriberId, template.getSubscriberId()); - return history1; - }); - - when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class), - eq(uid2), eq(android.net.NetworkStats.SET_ALL), - eq(android.net.NetworkStats.TAG_NONE), - eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime))) - .then((InvocationOnMock inv) -> { - NetworkTemplate template = inv.getArgument(0); - assertEquals(MATCH_MOBILE_ALL, template.getMatchRule()); - assertEquals(subscriberId, template.getSubscriberId()); - return history2; - }); - - - NetworkStats stats = mManager.queryDetails( - ConnectivityManager.TYPE_MOBILE, subscriberId, startTime, endTime); - - NetworkStats.Bucket bucket = new NetworkStats.Bucket(); - - // First 2 buckets exactly match entry timings - assertTrue(stats.getNextBucket(bucket)); - assertEquals(10, bucket.getStartTimeStamp()); - assertEquals(20, bucket.getEndTimeStamp()); - assertBucketMatches(uid1Entry1, bucket); - - assertTrue(stats.getNextBucket(bucket)); - assertEquals(20, bucket.getStartTimeStamp()); - assertEquals(30, bucket.getEndTimeStamp()); - assertBucketMatches(uid1Entry2, bucket); - - // 30 -> 40: contains uid2Entry1 and half of uid2Entry2 - assertTrue(stats.getNextBucket(bucket)); - assertEquals(30, bucket.getStartTimeStamp()); - assertEquals(40, bucket.getEndTimeStamp()); - assertEquals(225, bucket.getRxBytes()); - assertEquals(15, bucket.getRxPackets()); - assertEquals(375, bucket.getTxBytes()); - assertEquals(30, bucket.getTxPackets()); - - // 40 -> 50: contains half of uid2Entry2 - assertTrue(stats.getNextBucket(bucket)); - assertEquals(40, bucket.getStartTimeStamp()); - assertEquals(50, bucket.getEndTimeStamp()); - assertEquals(75, bucket.getRxBytes()); - assertEquals(5, bucket.getRxPackets()); - assertEquals(125, bucket.getTxBytes()); - assertEquals(10, bucket.getTxPackets()); - - assertFalse(stats.hasNextBucket()); - } - - @Test - public void testQueryDetails_NoSubscriberId() throws RemoteException { - final long startTime = 1; - final long endTime = 100; - final int uid1 = 10001; - final int uid2 = 10002; - - when(mService.openSessionForUsageStats(anyInt(), anyString())).thenReturn(mStatsSession); - when(mStatsSession.getRelevantUids()).thenReturn(new int[] { uid1, uid2 }); - - NetworkStats stats = mManager.queryDetails( - ConnectivityManager.TYPE_MOBILE, null, startTime, endTime); - - when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class), - anyInt(), anyInt(), anyInt(), anyInt(), anyLong(), anyLong())) - .thenReturn(new NetworkStatsHistory(10, 0)); - - verify(mStatsSession, times(1)).getHistoryIntervalForUid( - argThat((NetworkTemplate t) -> - // No subscriberId: MATCH_MOBILE_WILDCARD template - t.getMatchRule() == NetworkTemplate.MATCH_MOBILE_WILDCARD), - eq(uid1), eq(android.net.NetworkStats.SET_ALL), - eq(android.net.NetworkStats.TAG_NONE), - eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime)); - - verify(mStatsSession, times(1)).getHistoryIntervalForUid( - argThat((NetworkTemplate t) -> - // No subscriberId: MATCH_MOBILE_WILDCARD template - t.getMatchRule() == NetworkTemplate.MATCH_MOBILE_WILDCARD), - eq(uid2), eq(android.net.NetworkStats.SET_ALL), - eq(android.net.NetworkStats.TAG_NONE), - eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime)); - - assertFalse(stats.hasNextBucket()); - } - - private void assertBucketMatches(Entry expected, NetworkStats.Bucket actual) { - assertEquals(expected.uid, actual.getUid()); - assertEquals(expected.rxBytes, actual.getRxBytes()); - assertEquals(expected.rxPackets, actual.getRxPackets()); - assertEquals(expected.txBytes, actual.getTxBytes()); - assertEquals(expected.txPackets, actual.getTxPackets()); - } -} diff --git a/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java b/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java deleted file mode 100644 index 06e9405a6a79..000000000000 --- a/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsBinder; -import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback; -import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport; -import static android.net.ConnectivityDiagnosticsManager.DataStallReport; - -import static com.android.testutils.ParcelUtils.assertParcelSane; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -import android.content.Context; -import android.os.PersistableBundle; - -import androidx.test.InstrumentationRegistry; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.mockito.Mock; - -import java.util.concurrent.Executor; - -@RunWith(JUnit4.class) -public class ConnectivityDiagnosticsManagerTest { - private static final int NET_ID = 1; - private static final int DETECTION_METHOD = 2; - private static final long TIMESTAMP = 10L; - private static final String INTERFACE_NAME = "interface"; - private static final String BUNDLE_KEY = "key"; - private static final String BUNDLE_VALUE = "value"; - - private static final Executor INLINE_EXECUTOR = x -> x.run(); - - @Mock private IConnectivityManager mService; - @Mock private ConnectivityDiagnosticsCallback mCb; - - private Context mContext; - private ConnectivityDiagnosticsBinder mBinder; - private ConnectivityDiagnosticsManager mManager; - - private String mPackageName; - - @Before - public void setUp() { - mContext = InstrumentationRegistry.getContext(); - - mService = mock(IConnectivityManager.class); - mCb = mock(ConnectivityDiagnosticsCallback.class); - - mBinder = new ConnectivityDiagnosticsBinder(mCb, INLINE_EXECUTOR); - mManager = new ConnectivityDiagnosticsManager(mContext, mService); - - mPackageName = mContext.getOpPackageName(); - } - - @After - public void tearDown() { - // clear ConnectivityDiagnosticsManager callbacks map - ConnectivityDiagnosticsManager.sCallbacks.clear(); - } - - private ConnectivityReport createSampleConnectivityReport() { - final LinkProperties linkProperties = new LinkProperties(); - linkProperties.setInterfaceName(INTERFACE_NAME); - - final NetworkCapabilities networkCapabilities = new NetworkCapabilities(); - networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS); - - final PersistableBundle bundle = new PersistableBundle(); - bundle.putString(BUNDLE_KEY, BUNDLE_VALUE); - - return new ConnectivityReport( - new Network(NET_ID), TIMESTAMP, linkProperties, networkCapabilities, bundle); - } - - private ConnectivityReport createDefaultConnectivityReport() { - return new ConnectivityReport( - new Network(0), - 0L, - new LinkProperties(), - new NetworkCapabilities(), - PersistableBundle.EMPTY); - } - - @Test - public void testPersistableBundleEquals() { - assertFalse( - ConnectivityDiagnosticsManager.persistableBundleEquals( - null, PersistableBundle.EMPTY)); - assertFalse( - ConnectivityDiagnosticsManager.persistableBundleEquals( - PersistableBundle.EMPTY, null)); - assertTrue( - ConnectivityDiagnosticsManager.persistableBundleEquals( - PersistableBundle.EMPTY, PersistableBundle.EMPTY)); - - final PersistableBundle a = new PersistableBundle(); - a.putString(BUNDLE_KEY, BUNDLE_VALUE); - - final PersistableBundle b = new PersistableBundle(); - b.putString(BUNDLE_KEY, BUNDLE_VALUE); - - final PersistableBundle c = new PersistableBundle(); - c.putString(BUNDLE_KEY, null); - - assertFalse( - ConnectivityDiagnosticsManager.persistableBundleEquals(PersistableBundle.EMPTY, a)); - assertFalse( - ConnectivityDiagnosticsManager.persistableBundleEquals(a, PersistableBundle.EMPTY)); - - assertTrue(ConnectivityDiagnosticsManager.persistableBundleEquals(a, b)); - assertTrue(ConnectivityDiagnosticsManager.persistableBundleEquals(b, a)); - - assertFalse(ConnectivityDiagnosticsManager.persistableBundleEquals(a, c)); - assertFalse(ConnectivityDiagnosticsManager.persistableBundleEquals(c, a)); - } - - @Test - public void testConnectivityReportEquals() { - final ConnectivityReport defaultReport = createDefaultConnectivityReport(); - final ConnectivityReport sampleReport = createSampleConnectivityReport(); - assertEquals(sampleReport, createSampleConnectivityReport()); - assertEquals(defaultReport, createDefaultConnectivityReport()); - - final LinkProperties linkProperties = sampleReport.getLinkProperties(); - final NetworkCapabilities networkCapabilities = sampleReport.getNetworkCapabilities(); - final PersistableBundle bundle = sampleReport.getAdditionalInfo(); - - assertNotEquals( - createDefaultConnectivityReport(), - new ConnectivityReport( - new Network(NET_ID), - 0L, - new LinkProperties(), - new NetworkCapabilities(), - PersistableBundle.EMPTY)); - assertNotEquals( - createDefaultConnectivityReport(), - new ConnectivityReport( - new Network(0), - TIMESTAMP, - new LinkProperties(), - new NetworkCapabilities(), - PersistableBundle.EMPTY)); - assertNotEquals( - createDefaultConnectivityReport(), - new ConnectivityReport( - new Network(0), - 0L, - linkProperties, - new NetworkCapabilities(), - PersistableBundle.EMPTY)); - assertNotEquals( - createDefaultConnectivityReport(), - new ConnectivityReport( - new Network(0), - TIMESTAMP, - new LinkProperties(), - networkCapabilities, - PersistableBundle.EMPTY)); - assertNotEquals( - createDefaultConnectivityReport(), - new ConnectivityReport( - new Network(0), - TIMESTAMP, - new LinkProperties(), - new NetworkCapabilities(), - bundle)); - } - - @Test - public void testConnectivityReportParcelUnparcel() { - assertParcelSane(createSampleConnectivityReport(), 5); - } - - private DataStallReport createSampleDataStallReport() { - final LinkProperties linkProperties = new LinkProperties(); - linkProperties.setInterfaceName(INTERFACE_NAME); - - final PersistableBundle bundle = new PersistableBundle(); - bundle.putString(BUNDLE_KEY, BUNDLE_VALUE); - - final NetworkCapabilities networkCapabilities = new NetworkCapabilities(); - networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS); - - return new DataStallReport( - new Network(NET_ID), - TIMESTAMP, - DETECTION_METHOD, - linkProperties, - networkCapabilities, - bundle); - } - - private DataStallReport createDefaultDataStallReport() { - return new DataStallReport( - new Network(0), - 0L, - 0, - new LinkProperties(), - new NetworkCapabilities(), - PersistableBundle.EMPTY); - } - - @Test - public void testDataStallReportEquals() { - final DataStallReport defaultReport = createDefaultDataStallReport(); - final DataStallReport sampleReport = createSampleDataStallReport(); - assertEquals(sampleReport, createSampleDataStallReport()); - assertEquals(defaultReport, createDefaultDataStallReport()); - - final LinkProperties linkProperties = sampleReport.getLinkProperties(); - final NetworkCapabilities networkCapabilities = sampleReport.getNetworkCapabilities(); - final PersistableBundle bundle = sampleReport.getStallDetails(); - - assertNotEquals( - defaultReport, - new DataStallReport( - new Network(NET_ID), - 0L, - 0, - new LinkProperties(), - new NetworkCapabilities(), - PersistableBundle.EMPTY)); - assertNotEquals( - defaultReport, - new DataStallReport( - new Network(0), - TIMESTAMP, - 0, - new LinkProperties(), - new NetworkCapabilities(), - PersistableBundle.EMPTY)); - assertNotEquals( - defaultReport, - new DataStallReport( - new Network(0), - 0L, - DETECTION_METHOD, - new LinkProperties(), - new NetworkCapabilities(), - PersistableBundle.EMPTY)); - assertNotEquals( - defaultReport, - new DataStallReport( - new Network(0), - 0L, - 0, - linkProperties, - new NetworkCapabilities(), - PersistableBundle.EMPTY)); - assertNotEquals( - defaultReport, - new DataStallReport( - new Network(0), - 0L, - 0, - new LinkProperties(), - networkCapabilities, - PersistableBundle.EMPTY)); - assertNotEquals( - defaultReport, - new DataStallReport( - new Network(0), - 0L, - 0, - new LinkProperties(), - new NetworkCapabilities(), - bundle)); - } - - @Test - public void testDataStallReportParcelUnparcel() { - assertParcelSane(createSampleDataStallReport(), 6); - } - - @Test - public void testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable() { - mBinder.onConnectivityReportAvailable(createSampleConnectivityReport()); - - // The callback will be invoked synchronously by inline executor. Immediately check the - // latch without waiting. - verify(mCb).onConnectivityReportAvailable(eq(createSampleConnectivityReport())); - } - - @Test - public void testConnectivityDiagnosticsCallbackOnDataStallSuspected() { - mBinder.onDataStallSuspected(createSampleDataStallReport()); - - // The callback will be invoked synchronously by inline executor. Immediately check the - // latch without waiting. - verify(mCb).onDataStallSuspected(eq(createSampleDataStallReport())); - } - - @Test - public void testConnectivityDiagnosticsCallbackOnNetworkConnectivityReported() { - final Network n = new Network(NET_ID); - final boolean connectivity = true; - - mBinder.onNetworkConnectivityReported(n, connectivity); - - // The callback will be invoked synchronously by inline executor. Immediately check the - // latch without waiting. - verify(mCb).onNetworkConnectivityReported(eq(n), eq(connectivity)); - } - - @Test - public void testRegisterConnectivityDiagnosticsCallback() throws Exception { - final NetworkRequest request = new NetworkRequest.Builder().build(); - - mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); - - verify(mService).registerConnectivityDiagnosticsCallback( - any(ConnectivityDiagnosticsBinder.class), eq(request), eq(mPackageName)); - assertTrue(ConnectivityDiagnosticsManager.sCallbacks.containsKey(mCb)); - } - - @Test - public void testRegisterDuplicateConnectivityDiagnosticsCallback() throws Exception { - final NetworkRequest request = new NetworkRequest.Builder().build(); - - mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); - - try { - mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); - fail("Duplicate callback registration should fail"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testUnregisterConnectivityDiagnosticsCallback() throws Exception { - final NetworkRequest request = new NetworkRequest.Builder().build(); - mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); - - mManager.unregisterConnectivityDiagnosticsCallback(mCb); - - verify(mService).unregisterConnectivityDiagnosticsCallback( - any(ConnectivityDiagnosticsBinder.class)); - assertFalse(ConnectivityDiagnosticsManager.sCallbacks.containsKey(mCb)); - - // verify that re-registering is successful - mManager.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, mCb); - verify(mService, times(2)).registerConnectivityDiagnosticsCallback( - any(ConnectivityDiagnosticsBinder.class), eq(request), eq(mPackageName)); - assertTrue(ConnectivityDiagnosticsManager.sCallbacks.containsKey(mCb)); - } - - @Test - public void testUnregisterUnknownConnectivityDiagnosticsCallback() throws Exception { - mManager.unregisterConnectivityDiagnosticsCallback(mCb); - - verifyNoMoreInteractions(mService); - } -} diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java deleted file mode 100644 index 591e0cc3504e..000000000000 --- a/tests/net/java/android/net/ConnectivityManagerTest.java +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.net.ConnectivityManager.TYPE_NONE; -import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS; -import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; -import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA; -import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; -import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; -import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; -import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL; -import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; -import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH; -import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; -import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI; -import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST; -import static android.net.NetworkRequest.Type.REQUEST; -import static android.net.NetworkRequest.Type.TRACK_DEFAULT; -import static android.net.NetworkRequest.Type.TRACK_SYSTEM_DEFAULT; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.PendingIntent; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.net.ConnectivityManager.NetworkCallback; -import android.os.Build.VERSION_CODES; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.Messenger; -import android.os.Process; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class ConnectivityManagerTest { - - @Mock Context mCtx; - @Mock IConnectivityManager mService; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - } - - static NetworkCapabilities verifyNetworkCapabilities( - int legacyType, int transportType, int... capabilities) { - final NetworkCapabilities nc = ConnectivityManager.networkCapabilitiesForType(legacyType); - assertNotNull(nc); - assertTrue(nc.hasTransport(transportType)); - for (int capability : capabilities) { - assertTrue(nc.hasCapability(capability)); - } - - return nc; - } - - static void verifyUnrestrictedNetworkCapabilities(int legacyType, int transportType) { - verifyNetworkCapabilities( - legacyType, - transportType, - NET_CAPABILITY_INTERNET, - NET_CAPABILITY_NOT_RESTRICTED, - NET_CAPABILITY_NOT_VPN, - NET_CAPABILITY_TRUSTED); - } - - static void verifyRestrictedMobileNetworkCapabilities(int legacyType, int capability) { - final NetworkCapabilities nc = verifyNetworkCapabilities( - legacyType, - TRANSPORT_CELLULAR, - capability, - NET_CAPABILITY_NOT_VPN, - NET_CAPABILITY_TRUSTED); - - assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET)); - assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - } - - @Test - public void testNetworkCapabilitiesForTypeMobile() { - verifyUnrestrictedNetworkCapabilities( - ConnectivityManager.TYPE_MOBILE, TRANSPORT_CELLULAR); - } - - @Test - public void testNetworkCapabilitiesForTypeMobileCbs() { - verifyRestrictedMobileNetworkCapabilities( - ConnectivityManager.TYPE_MOBILE_CBS, NET_CAPABILITY_CBS); - } - - @Test - public void testNetworkCapabilitiesForTypeMobileDun() { - verifyRestrictedMobileNetworkCapabilities( - ConnectivityManager.TYPE_MOBILE_DUN, NET_CAPABILITY_DUN); - } - - @Test - public void testNetworkCapabilitiesForTypeMobileFota() { - verifyRestrictedMobileNetworkCapabilities( - ConnectivityManager.TYPE_MOBILE_FOTA, NET_CAPABILITY_FOTA); - } - - @Test - public void testNetworkCapabilitiesForTypeMobileHipri() { - verifyUnrestrictedNetworkCapabilities( - ConnectivityManager.TYPE_MOBILE_HIPRI, TRANSPORT_CELLULAR); - } - - @Test - public void testNetworkCapabilitiesForTypeMobileIms() { - verifyRestrictedMobileNetworkCapabilities( - ConnectivityManager.TYPE_MOBILE_IMS, NET_CAPABILITY_IMS); - } - - @Test - public void testNetworkCapabilitiesForTypeMobileMms() { - final NetworkCapabilities nc = verifyNetworkCapabilities( - ConnectivityManager.TYPE_MOBILE_MMS, - TRANSPORT_CELLULAR, - NET_CAPABILITY_MMS, - NET_CAPABILITY_NOT_VPN, - NET_CAPABILITY_TRUSTED); - - assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET)); - } - - @Test - public void testNetworkCapabilitiesForTypeMobileSupl() { - final NetworkCapabilities nc = verifyNetworkCapabilities( - ConnectivityManager.TYPE_MOBILE_SUPL, - TRANSPORT_CELLULAR, - NET_CAPABILITY_SUPL, - NET_CAPABILITY_NOT_VPN, - NET_CAPABILITY_TRUSTED); - - assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET)); - } - - @Test - public void testNetworkCapabilitiesForTypeWifi() { - verifyUnrestrictedNetworkCapabilities( - ConnectivityManager.TYPE_WIFI, TRANSPORT_WIFI); - } - - @Test - public void testNetworkCapabilitiesForTypeWifiP2p() { - final NetworkCapabilities nc = verifyNetworkCapabilities( - ConnectivityManager.TYPE_WIFI_P2P, - TRANSPORT_WIFI, - NET_CAPABILITY_NOT_RESTRICTED, NET_CAPABILITY_NOT_VPN, - NET_CAPABILITY_TRUSTED, NET_CAPABILITY_WIFI_P2P); - - assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET)); - } - - @Test - public void testNetworkCapabilitiesForTypeBluetooth() { - verifyUnrestrictedNetworkCapabilities( - ConnectivityManager.TYPE_BLUETOOTH, TRANSPORT_BLUETOOTH); - } - - @Test - public void testNetworkCapabilitiesForTypeEthernet() { - verifyUnrestrictedNetworkCapabilities( - ConnectivityManager.TYPE_ETHERNET, TRANSPORT_ETHERNET); - } - - @Test - public void testCallbackRelease() throws Exception { - ConnectivityManager manager = new ConnectivityManager(mCtx, mService); - NetworkRequest request = makeRequest(1); - NetworkCallback callback = mock(ConnectivityManager.NetworkCallback.class); - Handler handler = new Handler(Looper.getMainLooper()); - ArgumentCaptor<Messenger> captor = ArgumentCaptor.forClass(Messenger.class); - - // register callback - when(mService.requestNetwork(anyInt(), any(), anyInt(), captor.capture(), anyInt(), any(), - anyInt(), anyInt(), any(), nullable(String.class))).thenReturn(request); - manager.requestNetwork(request, callback, handler); - - // callback triggers - captor.getValue().send(makeMessage(request, ConnectivityManager.CALLBACK_AVAILABLE)); - verify(callback, timeout(500).times(1)).onAvailable(any(Network.class), - any(NetworkCapabilities.class), any(LinkProperties.class), anyBoolean()); - - // unregister callback - manager.unregisterNetworkCallback(callback); - verify(mService, times(1)).releaseNetworkRequest(request); - - // callback does not trigger anymore. - captor.getValue().send(makeMessage(request, ConnectivityManager.CALLBACK_LOSING)); - verify(callback, timeout(500).times(0)).onLosing(any(), anyInt()); - } - - @Test - public void testCallbackRecycling() throws Exception { - ConnectivityManager manager = new ConnectivityManager(mCtx, mService); - NetworkRequest req1 = makeRequest(1); - NetworkRequest req2 = makeRequest(2); - NetworkCallback callback = mock(ConnectivityManager.NetworkCallback.class); - Handler handler = new Handler(Looper.getMainLooper()); - ArgumentCaptor<Messenger> captor = ArgumentCaptor.forClass(Messenger.class); - - // register callback - when(mService.requestNetwork(anyInt(), any(), anyInt(), captor.capture(), anyInt(), any(), - anyInt(), anyInt(), any(), nullable(String.class))).thenReturn(req1); - manager.requestNetwork(req1, callback, handler); - - // callback triggers - captor.getValue().send(makeMessage(req1, ConnectivityManager.CALLBACK_AVAILABLE)); - verify(callback, timeout(100).times(1)).onAvailable(any(Network.class), - any(NetworkCapabilities.class), any(LinkProperties.class), anyBoolean()); - - // unregister callback - manager.unregisterNetworkCallback(callback); - verify(mService, times(1)).releaseNetworkRequest(req1); - - // callback does not trigger anymore. - captor.getValue().send(makeMessage(req1, ConnectivityManager.CALLBACK_LOSING)); - verify(callback, timeout(100).times(0)).onLosing(any(), anyInt()); - - // callback can be registered again - when(mService.requestNetwork(anyInt(), any(), anyInt(), captor.capture(), anyInt(), any(), - anyInt(), anyInt(), any(), nullable(String.class))).thenReturn(req2); - manager.requestNetwork(req2, callback, handler); - - // callback triggers - captor.getValue().send(makeMessage(req2, ConnectivityManager.CALLBACK_LOST)); - verify(callback, timeout(100).times(1)).onLost(any()); - - // unregister callback - manager.unregisterNetworkCallback(callback); - verify(mService, times(1)).releaseNetworkRequest(req2); - } - - // TODO: turn on this test when request callback 1:1 mapping is enforced - //@Test - private void noDoubleCallbackRegistration() throws Exception { - ConnectivityManager manager = new ConnectivityManager(mCtx, mService); - NetworkRequest request = makeRequest(1); - NetworkCallback callback = new ConnectivityManager.NetworkCallback(); - ApplicationInfo info = new ApplicationInfo(); - // TODO: update version when starting to enforce 1:1 mapping - info.targetSdkVersion = VERSION_CODES.N_MR1 + 1; - - when(mCtx.getApplicationInfo()).thenReturn(info); - when(mService.requestNetwork(anyInt(), any(), anyInt(), any(), anyInt(), any(), anyInt(), - anyInt(), any(), nullable(String.class))).thenReturn(request); - - Handler handler = new Handler(Looper.getMainLooper()); - manager.requestNetwork(request, callback, handler); - - // callback is already registered, reregistration should fail. - Class<IllegalArgumentException> wantException = IllegalArgumentException.class; - expectThrowable(() -> manager.requestNetwork(request, callback), wantException); - - manager.unregisterNetworkCallback(callback); - verify(mService, times(1)).releaseNetworkRequest(request); - - // unregistering the callback should make it registrable again. - manager.requestNetwork(request, callback); - } - - @Test - public void testArgumentValidation() throws Exception { - ConnectivityManager manager = new ConnectivityManager(mCtx, mService); - - NetworkRequest request = mock(NetworkRequest.class); - NetworkCallback callback = mock(NetworkCallback.class); - Handler handler = mock(Handler.class); - NetworkCallback nullCallback = null; - PendingIntent nullIntent = null; - - mustFail(() -> { manager.requestNetwork(null, callback); }); - mustFail(() -> { manager.requestNetwork(request, nullCallback); }); - mustFail(() -> { manager.requestNetwork(request, callback, null); }); - mustFail(() -> { manager.requestNetwork(request, callback, -1); }); - mustFail(() -> { manager.requestNetwork(request, nullIntent); }); - - mustFail(() -> { manager.registerNetworkCallback(null, callback, handler); }); - mustFail(() -> { manager.registerNetworkCallback(request, null, handler); }); - mustFail(() -> { manager.registerNetworkCallback(request, callback, null); }); - mustFail(() -> { manager.registerNetworkCallback(request, nullIntent); }); - - mustFail(() -> { manager.registerDefaultNetworkCallback(null, handler); }); - mustFail(() -> { manager.registerDefaultNetworkCallback(callback, null); }); - - mustFail(() -> { manager.registerSystemDefaultNetworkCallback(null, handler); }); - mustFail(() -> { manager.registerSystemDefaultNetworkCallback(callback, null); }); - - mustFail(() -> { manager.unregisterNetworkCallback(nullCallback); }); - mustFail(() -> { manager.unregisterNetworkCallback(nullIntent); }); - mustFail(() -> { manager.releaseNetworkRequest(nullIntent); }); - } - - static void mustFail(Runnable fn) { - try { - fn.run(); - fail(); - } catch (Exception expected) { - } - } - - @Test - public void testRequestType() throws Exception { - final String testPkgName = "MyPackage"; - final String testAttributionTag = "MyTag"; - final ConnectivityManager manager = new ConnectivityManager(mCtx, mService); - when(mCtx.getOpPackageName()).thenReturn(testPkgName); - when(mCtx.getAttributionTag()).thenReturn(testAttributionTag); - final NetworkRequest request = makeRequest(1); - final NetworkCallback callback = new ConnectivityManager.NetworkCallback(); - - manager.requestNetwork(request, callback); - verify(mService).requestNetwork(eq(Process.INVALID_UID), eq(request.networkCapabilities), - eq(REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(), - eq(testPkgName), eq(testAttributionTag)); - reset(mService); - - // Verify that register network callback does not calls requestNetwork at all. - manager.registerNetworkCallback(request, callback); - verify(mService, never()).requestNetwork(anyInt(), any(), anyInt(), any(), anyInt(), any(), - anyInt(), anyInt(), any(), any()); - verify(mService).listenForNetwork(eq(request.networkCapabilities), any(), any(), anyInt(), - eq(testPkgName), eq(testAttributionTag)); - reset(mService); - - Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); - - manager.registerDefaultNetworkCallback(callback); - verify(mService).requestNetwork(eq(Process.INVALID_UID), eq(null), - eq(TRACK_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(), - eq(testPkgName), eq(testAttributionTag)); - reset(mService); - - manager.registerDefaultNetworkCallbackForUid(42, callback, handler); - verify(mService).requestNetwork(eq(42), eq(null), - eq(TRACK_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(), - eq(testPkgName), eq(testAttributionTag)); - - manager.requestBackgroundNetwork(request, callback, handler); - verify(mService).requestNetwork(eq(Process.INVALID_UID), eq(request.networkCapabilities), - eq(BACKGROUND_REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(), - eq(testPkgName), eq(testAttributionTag)); - reset(mService); - - manager.registerSystemDefaultNetworkCallback(callback, handler); - verify(mService).requestNetwork(eq(Process.INVALID_UID), eq(null), - eq(TRACK_SYSTEM_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(), - eq(testPkgName), eq(testAttributionTag)); - reset(mService); - } - - static Message makeMessage(NetworkRequest req, int messageType) { - Bundle bundle = new Bundle(); - bundle.putParcelable(NetworkRequest.class.getSimpleName(), req); - // Pass default objects as we don't care which get passed here - bundle.putParcelable(Network.class.getSimpleName(), new Network(1)); - bundle.putParcelable(NetworkCapabilities.class.getSimpleName(), new NetworkCapabilities()); - bundle.putParcelable(LinkProperties.class.getSimpleName(), new LinkProperties()); - Message msg = Message.obtain(); - msg.what = messageType; - msg.setData(bundle); - return msg; - } - - static NetworkRequest makeRequest(int requestId) { - NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); - return new NetworkRequest(request.networkCapabilities, ConnectivityManager.TYPE_NONE, - requestId, NetworkRequest.Type.NONE); - } - - static void expectThrowable(Runnable block, Class<? extends Throwable> throwableType) { - try { - block.run(); - } catch (Throwable t) { - if (t.getClass().equals(throwableType)) { - return; - } - fail("expected exception of type " + throwableType + ", but was " + t.getClass()); - } - fail("expected exception of type " + throwableType); - } -} diff --git a/tests/net/java/android/net/Ikev2VpnProfileTest.java b/tests/net/java/android/net/Ikev2VpnProfileTest.java deleted file mode 100644 index 1abd39a32bdf..000000000000 --- a/tests/net/java/android/net/Ikev2VpnProfileTest.java +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.test.mock.MockContext; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.internal.net.VpnProfile; -import com.android.net.module.util.ProxyUtils; -import com.android.internal.org.bouncycastle.x509.X509V1CertificateGenerator; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.math.BigInteger; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PrivateKey; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import javax.security.auth.x500.X500Principal; - -/** Unit tests for {@link Ikev2VpnProfile.Builder}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class Ikev2VpnProfileTest { - private static final String SERVER_ADDR_STRING = "1.2.3.4"; - private static final String IDENTITY_STRING = "Identity"; - private static final String USERNAME_STRING = "username"; - private static final String PASSWORD_STRING = "pa55w0rd"; - private static final String EXCL_LIST = "exclList"; - private static final byte[] PSK_BYTES = "preSharedKey".getBytes(); - private static final int TEST_MTU = 1300; - - private final MockContext mMockContext = - new MockContext() { - @Override - public String getOpPackageName() { - return "fooPackage"; - } - }; - private final ProxyInfo mProxy = ProxyInfo.buildDirectProxy( - SERVER_ADDR_STRING, -1, ProxyUtils.exclusionStringAsList(EXCL_LIST)); - - private X509Certificate mUserCert; - private X509Certificate mServerRootCa; - private PrivateKey mPrivateKey; - - @Before - public void setUp() throws Exception { - mServerRootCa = generateRandomCertAndKeyPair().cert; - - final CertificateAndKey userCertKey = generateRandomCertAndKeyPair(); - mUserCert = userCertKey.cert; - mPrivateKey = userCertKey.key; - } - - private Ikev2VpnProfile.Builder getBuilderWithDefaultOptions() { - final Ikev2VpnProfile.Builder builder = - new Ikev2VpnProfile.Builder(SERVER_ADDR_STRING, IDENTITY_STRING); - - builder.setBypassable(true); - builder.setProxy(mProxy); - builder.setMaxMtu(TEST_MTU); - builder.setMetered(true); - - return builder; - } - - @Test - public void testBuildValidProfileWithOptions() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa); - final Ikev2VpnProfile profile = builder.build(); - assertNotNull(profile); - - // Check non-auth parameters correctly stored - assertEquals(SERVER_ADDR_STRING, profile.getServerAddr()); - assertEquals(IDENTITY_STRING, profile.getUserIdentity()); - assertEquals(mProxy, profile.getProxyInfo()); - assertTrue(profile.isBypassable()); - assertTrue(profile.isMetered()); - assertEquals(TEST_MTU, profile.getMaxMtu()); - assertEquals(Ikev2VpnProfile.DEFAULT_ALGORITHMS, profile.getAllowedAlgorithms()); - } - - @Test - public void testBuildUsernamePasswordProfile() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa); - final Ikev2VpnProfile profile = builder.build(); - assertNotNull(profile); - - assertEquals(USERNAME_STRING, profile.getUsername()); - assertEquals(PASSWORD_STRING, profile.getPassword()); - assertEquals(mServerRootCa, profile.getServerRootCaCert()); - - assertNull(profile.getPresharedKey()); - assertNull(profile.getRsaPrivateKey()); - assertNull(profile.getUserCert()); - } - - @Test - public void testBuildDigitalSignatureProfile() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa); - final Ikev2VpnProfile profile = builder.build(); - assertNotNull(profile); - - assertEquals(profile.getUserCert(), mUserCert); - assertEquals(mPrivateKey, profile.getRsaPrivateKey()); - assertEquals(profile.getServerRootCaCert(), mServerRootCa); - - assertNull(profile.getPresharedKey()); - assertNull(profile.getUsername()); - assertNull(profile.getPassword()); - } - - @Test - public void testBuildPresharedKeyProfile() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - builder.setAuthPsk(PSK_BYTES); - final Ikev2VpnProfile profile = builder.build(); - assertNotNull(profile); - - assertArrayEquals(PSK_BYTES, profile.getPresharedKey()); - - assertNull(profile.getServerRootCaCert()); - assertNull(profile.getUsername()); - assertNull(profile.getPassword()); - assertNull(profile.getRsaPrivateKey()); - assertNull(profile.getUserCert()); - } - - @Test - public void testBuildWithAllowedAlgorithmsAead() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - builder.setAuthPsk(PSK_BYTES); - - List<String> allowedAlgorithms = Arrays.asList(IpSecAlgorithm.AUTH_CRYPT_AES_GCM); - builder.setAllowedAlgorithms(allowedAlgorithms); - - final Ikev2VpnProfile profile = builder.build(); - assertEquals(allowedAlgorithms, profile.getAllowedAlgorithms()); - } - - @Test - public void testBuildWithAllowedAlgorithmsNormal() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - builder.setAuthPsk(PSK_BYTES); - - List<String> allowedAlgorithms = - Arrays.asList(IpSecAlgorithm.AUTH_HMAC_SHA512, IpSecAlgorithm.CRYPT_AES_CBC); - builder.setAllowedAlgorithms(allowedAlgorithms); - - final Ikev2VpnProfile profile = builder.build(); - assertEquals(allowedAlgorithms, profile.getAllowedAlgorithms()); - } - - @Test - public void testSetAllowedAlgorithmsEmptyList() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - try { - builder.setAllowedAlgorithms(new ArrayList<>()); - fail("Expected exception due to no valid algorithm set"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testSetAllowedAlgorithmsInvalidList() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - List<String> allowedAlgorithms = new ArrayList<>(); - - try { - builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.AUTH_HMAC_SHA256)); - fail("Expected exception due to missing encryption"); - } catch (IllegalArgumentException expected) { - } - - try { - builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.CRYPT_AES_CBC)); - fail("Expected exception due to missing authentication"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testSetAllowedAlgorithmsInsecureAlgorithm() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - List<String> allowedAlgorithms = new ArrayList<>(); - - try { - builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.AUTH_HMAC_MD5)); - fail("Expected exception due to insecure algorithm"); - } catch (IllegalArgumentException expected) { - } - - try { - builder.setAllowedAlgorithms(Arrays.asList(IpSecAlgorithm.AUTH_HMAC_SHA1)); - fail("Expected exception due to insecure algorithm"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testBuildNoAuthMethodSet() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - try { - builder.build(); - fail("Expected exception due to lack of auth method"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testBuildInvalidMtu() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - try { - builder.setMaxMtu(500); - fail("Expected exception due to too-small MTU"); - } catch (IllegalArgumentException expected) { - } - } - - private void verifyVpnProfileCommon(VpnProfile profile) { - assertEquals(SERVER_ADDR_STRING, profile.server); - assertEquals(IDENTITY_STRING, profile.ipsecIdentifier); - assertEquals(mProxy, profile.proxy); - assertTrue(profile.isBypassable); - assertTrue(profile.isMetered); - assertEquals(TEST_MTU, profile.maxMtu); - } - - @Test - public void testPskConvertToVpnProfile() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - builder.setAuthPsk(PSK_BYTES); - final VpnProfile profile = builder.build().toVpnProfile(); - - verifyVpnProfileCommon(profile); - assertEquals(Ikev2VpnProfile.encodeForIpsecSecret(PSK_BYTES), profile.ipsecSecret); - - // Check nothing else is set - assertEquals("", profile.username); - assertEquals("", profile.password); - assertEquals("", profile.ipsecUserCert); - assertEquals("", profile.ipsecCaCert); - } - - @Test - public void testUsernamePasswordConvertToVpnProfile() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa); - final VpnProfile profile = builder.build().toVpnProfile(); - - verifyVpnProfileCommon(profile); - assertEquals(USERNAME_STRING, profile.username); - assertEquals(PASSWORD_STRING, profile.password); - assertEquals(Ikev2VpnProfile.certificateToPemString(mServerRootCa), profile.ipsecCaCert); - - // Check nothing else is set - assertEquals("", profile.ipsecUserCert); - assertEquals("", profile.ipsecSecret); - } - - @Test - public void testRsaConvertToVpnProfile() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa); - final VpnProfile profile = builder.build().toVpnProfile(); - - final String expectedSecret = Ikev2VpnProfile.PREFIX_INLINE - + Ikev2VpnProfile.encodeForIpsecSecret(mPrivateKey.getEncoded()); - verifyVpnProfileCommon(profile); - assertEquals(Ikev2VpnProfile.certificateToPemString(mUserCert), profile.ipsecUserCert); - assertEquals( - expectedSecret, - profile.ipsecSecret); - assertEquals(Ikev2VpnProfile.certificateToPemString(mServerRootCa), profile.ipsecCaCert); - - // Check nothing else is set - assertEquals("", profile.username); - assertEquals("", profile.password); - } - - @Test - public void testPskFromVpnProfileDiscardsIrrelevantValues() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - builder.setAuthPsk(PSK_BYTES); - final VpnProfile profile = builder.build().toVpnProfile(); - profile.username = USERNAME_STRING; - profile.password = PASSWORD_STRING; - profile.ipsecCaCert = Ikev2VpnProfile.certificateToPemString(mServerRootCa); - profile.ipsecUserCert = Ikev2VpnProfile.certificateToPemString(mUserCert); - - final Ikev2VpnProfile result = Ikev2VpnProfile.fromVpnProfile(profile); - assertNull(result.getUsername()); - assertNull(result.getPassword()); - assertNull(result.getUserCert()); - assertNull(result.getRsaPrivateKey()); - assertNull(result.getServerRootCaCert()); - } - - @Test - public void testUsernamePasswordFromVpnProfileDiscardsIrrelevantValues() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa); - final VpnProfile profile = builder.build().toVpnProfile(); - profile.ipsecSecret = new String(PSK_BYTES); - profile.ipsecUserCert = Ikev2VpnProfile.certificateToPemString(mUserCert); - - final Ikev2VpnProfile result = Ikev2VpnProfile.fromVpnProfile(profile); - assertNull(result.getPresharedKey()); - assertNull(result.getUserCert()); - assertNull(result.getRsaPrivateKey()); - } - - @Test - public void testRsaFromVpnProfileDiscardsIrrelevantValues() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa); - final VpnProfile profile = builder.build().toVpnProfile(); - profile.username = USERNAME_STRING; - profile.password = PASSWORD_STRING; - - final Ikev2VpnProfile result = Ikev2VpnProfile.fromVpnProfile(profile); - assertNull(result.getUsername()); - assertNull(result.getPassword()); - assertNull(result.getPresharedKey()); - } - - @Test - public void testPskConversionIsLossless() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - builder.setAuthPsk(PSK_BYTES); - final Ikev2VpnProfile ikeProfile = builder.build(); - - assertEquals(ikeProfile, Ikev2VpnProfile.fromVpnProfile(ikeProfile.toVpnProfile())); - } - - @Test - public void testUsernamePasswordConversionIsLossless() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - builder.setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa); - final Ikev2VpnProfile ikeProfile = builder.build(); - - assertEquals(ikeProfile, Ikev2VpnProfile.fromVpnProfile(ikeProfile.toVpnProfile())); - } - - @Test - public void testRsaConversionIsLossless() throws Exception { - final Ikev2VpnProfile.Builder builder = getBuilderWithDefaultOptions(); - - builder.setAuthDigitalSignature(mUserCert, mPrivateKey, mServerRootCa); - final Ikev2VpnProfile ikeProfile = builder.build(); - - assertEquals(ikeProfile, Ikev2VpnProfile.fromVpnProfile(ikeProfile.toVpnProfile())); - } - - private static class CertificateAndKey { - public final X509Certificate cert; - public final PrivateKey key; - - CertificateAndKey(X509Certificate cert, PrivateKey key) { - this.cert = cert; - this.key = key; - } - } - - private static CertificateAndKey generateRandomCertAndKeyPair() throws Exception { - final Date validityBeginDate = - new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1L)); - final Date validityEndDate = - new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1L)); - - // Generate a keypair - final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); - keyPairGenerator.initialize(512); - final KeyPair keyPair = keyPairGenerator.generateKeyPair(); - - final X500Principal dnName = new X500Principal("CN=test.android.com"); - final X509V1CertificateGenerator certGen = new X509V1CertificateGenerator(); - certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis())); - certGen.setSubjectDN(dnName); - certGen.setIssuerDN(dnName); - certGen.setNotBefore(validityBeginDate); - certGen.setNotAfter(validityEndDate); - certGen.setPublicKey(keyPair.getPublic()); - certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); - - final X509Certificate cert = certGen.generate(keyPair.getPrivate(), "AndroidOpenSSL"); - return new CertificateAndKey(cert, keyPair.getPrivate()); - } -} diff --git a/tests/net/java/android/net/IpMemoryStoreTest.java b/tests/net/java/android/net/IpMemoryStoreTest.java deleted file mode 100644 index 0b13800bc5c9..000000000000 --- a/tests/net/java/android/net/IpMemoryStoreTest.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import android.content.Context; -import android.net.ipmemorystore.Blob; -import android.net.ipmemorystore.IOnStatusListener; -import android.net.ipmemorystore.NetworkAttributes; -import android.net.ipmemorystore.NetworkAttributesParcelable; -import android.net.ipmemorystore.Status; -import android.net.networkstack.ModuleNetworkStackClient; -import android.os.RemoteException; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.net.UnknownHostException; -import java.util.Arrays; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class IpMemoryStoreTest { - private static final String TAG = IpMemoryStoreTest.class.getSimpleName(); - private static final String TEST_CLIENT_ID = "testClientId"; - private static final String TEST_DATA_NAME = "testData"; - private static final String TEST_OTHER_DATA_NAME = TEST_DATA_NAME + "Other"; - private static final byte[] TEST_BLOB_DATA = new byte[] { -3, 6, 8, -9, 12, - -128, 0, 89, 112, 91, -34 }; - private static final NetworkAttributes TEST_NETWORK_ATTRIBUTES = buildTestNetworkAttributes( - "hint", 219); - - @Mock - Context mMockContext; - @Mock - ModuleNetworkStackClient mModuleNetworkStackClient; - @Mock - IIpMemoryStore mMockService; - @Mock - IOnStatusListener mIOnStatusListener; - IpMemoryStore mStore; - - @Captor - ArgumentCaptor<IIpMemoryStoreCallbacks> mCbCaptor; - @Captor - ArgumentCaptor<NetworkAttributesParcelable> mNapCaptor; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - } - - private void startIpMemoryStore(boolean supplyService) { - if (supplyService) { - doAnswer(invocation -> { - ((IIpMemoryStoreCallbacks) invocation.getArgument(0)) - .onIpMemoryStoreFetched(mMockService); - return null; - }).when(mModuleNetworkStackClient).fetchIpMemoryStore(any()); - } else { - doNothing().when(mModuleNetworkStackClient).fetchIpMemoryStore(mCbCaptor.capture()); - } - mStore = new IpMemoryStore(mMockContext) { - @Override - protected ModuleNetworkStackClient getModuleNetworkStackClient(Context ctx) { - return mModuleNetworkStackClient; - } - }; - } - - private static NetworkAttributes buildTestNetworkAttributes(String hint, int mtu) { - return new NetworkAttributes.Builder() - .setCluster(hint) - .setMtu(mtu) - .build(); - } - - @Test - public void testNetworkAttributes() throws Exception { - startIpMemoryStore(true /* supplyService */); - final String l2Key = "fakeKey"; - - mStore.storeNetworkAttributes(l2Key, TEST_NETWORK_ATTRIBUTES, - status -> assertTrue("Store not successful : " + status.resultCode, - status.isSuccess())); - verify(mMockService, times(1)).storeNetworkAttributes(eq(l2Key), - mNapCaptor.capture(), any()); - assertEquals(TEST_NETWORK_ATTRIBUTES, new NetworkAttributes(mNapCaptor.getValue())); - - mStore.retrieveNetworkAttributes(l2Key, - (status, key, attr) -> { - assertTrue("Retrieve network attributes not successful : " - + status.resultCode, status.isSuccess()); - assertEquals(l2Key, key); - assertEquals(TEST_NETWORK_ATTRIBUTES, attr); - }); - - verify(mMockService, times(1)).retrieveNetworkAttributes(eq(l2Key), any()); - } - - @Test - public void testPrivateData() throws RemoteException { - startIpMemoryStore(true /* supplyService */); - final Blob b = new Blob(); - b.data = TEST_BLOB_DATA; - final String l2Key = "fakeKey"; - - mStore.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, b, - status -> { - assertTrue("Store not successful : " + status.resultCode, status.isSuccess()); - }); - verify(mMockService, times(1)).storeBlob(eq(l2Key), eq(TEST_CLIENT_ID), eq(TEST_DATA_NAME), - eq(b), any()); - - mStore.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_OTHER_DATA_NAME, - (status, key, name, data) -> { - assertTrue("Retrieve blob status not successful : " + status.resultCode, - status.isSuccess()); - assertEquals(l2Key, key); - assertEquals(name, TEST_DATA_NAME); - assertTrue(Arrays.equals(b.data, data.data)); - }); - verify(mMockService, times(1)).retrieveBlob(eq(l2Key), eq(TEST_CLIENT_ID), - eq(TEST_OTHER_DATA_NAME), any()); - } - - @Test - public void testFindL2Key() - throws UnknownHostException, RemoteException, Exception { - startIpMemoryStore(true /* supplyService */); - final String l2Key = "fakeKey"; - - mStore.findL2Key(TEST_NETWORK_ATTRIBUTES, - (status, key) -> { - assertTrue("Retrieve network sameness not successful : " + status.resultCode, - status.isSuccess()); - assertEquals(l2Key, key); - }); - verify(mMockService, times(1)).findL2Key(mNapCaptor.capture(), any()); - assertEquals(TEST_NETWORK_ATTRIBUTES, new NetworkAttributes(mNapCaptor.getValue())); - } - - @Test - public void testIsSameNetwork() throws UnknownHostException, RemoteException { - startIpMemoryStore(true /* supplyService */); - final String l2Key1 = "fakeKey1"; - final String l2Key2 = "fakeKey2"; - - mStore.isSameNetwork(l2Key1, l2Key2, - (status, answer) -> { - assertFalse("Retrieve network sameness suspiciously successful : " - + status.resultCode, status.isSuccess()); - assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode); - assertNull(answer); - }); - verify(mMockService, times(1)).isSameNetwork(eq(l2Key1), eq(l2Key2), any()); - } - - @Test - public void testEnqueuedIpMsRequests() throws Exception { - startIpMemoryStore(false /* supplyService */); - - final Blob b = new Blob(); - b.data = TEST_BLOB_DATA; - final String l2Key = "fakeKey"; - - // enqueue multiple ipms requests - mStore.storeNetworkAttributes(l2Key, TEST_NETWORK_ATTRIBUTES, - status -> assertTrue("Store not successful : " + status.resultCode, - status.isSuccess())); - mStore.retrieveNetworkAttributes(l2Key, - (status, key, attr) -> { - assertTrue("Retrieve network attributes not successful : " - + status.resultCode, status.isSuccess()); - assertEquals(l2Key, key); - assertEquals(TEST_NETWORK_ATTRIBUTES, attr); - }); - mStore.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, b, - status -> assertTrue("Store not successful : " + status.resultCode, - status.isSuccess())); - mStore.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_OTHER_DATA_NAME, - (status, key, name, data) -> { - assertTrue("Retrieve blob status not successful : " + status.resultCode, - status.isSuccess()); - assertEquals(l2Key, key); - assertEquals(name, TEST_DATA_NAME); - assertTrue(Arrays.equals(b.data, data.data)); - }); - - // get ipms service ready - mCbCaptor.getValue().onIpMemoryStoreFetched(mMockService); - - InOrder inOrder = inOrder(mMockService); - - inOrder.verify(mMockService).storeNetworkAttributes(eq(l2Key), mNapCaptor.capture(), any()); - inOrder.verify(mMockService).retrieveNetworkAttributes(eq(l2Key), any()); - inOrder.verify(mMockService).storeBlob(eq(l2Key), eq(TEST_CLIENT_ID), eq(TEST_DATA_NAME), - eq(b), any()); - inOrder.verify(mMockService).retrieveBlob(eq(l2Key), eq(TEST_CLIENT_ID), - eq(TEST_OTHER_DATA_NAME), any()); - assertEquals(TEST_NETWORK_ATTRIBUTES, new NetworkAttributes(mNapCaptor.getValue())); - } - - @Test - public void testEnqueuedIpMsRequestsWithException() throws Exception { - startIpMemoryStore(true /* supplyService */); - doThrow(RemoteException.class).when(mMockService).retrieveNetworkAttributes(any(), any()); - - final Blob b = new Blob(); - b.data = TEST_BLOB_DATA; - final String l2Key = "fakeKey"; - - // enqueue multiple ipms requests - mStore.storeNetworkAttributes(l2Key, TEST_NETWORK_ATTRIBUTES, - status -> assertTrue("Store not successful : " + status.resultCode, - status.isSuccess())); - mStore.retrieveNetworkAttributes(l2Key, - (status, key, attr) -> { - assertTrue("Retrieve network attributes not successful : " - + status.resultCode, status.isSuccess()); - assertEquals(l2Key, key); - assertEquals(TEST_NETWORK_ATTRIBUTES, attr); - }); - mStore.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, b, - status -> assertTrue("Store not successful : " + status.resultCode, - status.isSuccess())); - mStore.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_OTHER_DATA_NAME, - (status, key, name, data) -> { - assertTrue("Retrieve blob status not successful : " + status.resultCode, - status.isSuccess()); - assertEquals(l2Key, key); - assertEquals(name, TEST_DATA_NAME); - assertTrue(Arrays.equals(b.data, data.data)); - }); - - // verify the rest of the queue is still processed in order even if the remote exception - // occurs when calling one or more requests - InOrder inOrder = inOrder(mMockService); - - inOrder.verify(mMockService).storeNetworkAttributes(eq(l2Key), mNapCaptor.capture(), any()); - inOrder.verify(mMockService).storeBlob(eq(l2Key), eq(TEST_CLIENT_ID), eq(TEST_DATA_NAME), - eq(b), any()); - inOrder.verify(mMockService).retrieveBlob(eq(l2Key), eq(TEST_CLIENT_ID), - eq(TEST_OTHER_DATA_NAME), any()); - assertEquals(TEST_NETWORK_ATTRIBUTES, new NetworkAttributes(mNapCaptor.getValue())); - } - - @Test - public void testEnqueuedIpMsRequestsCallbackFunctionWithException() throws Exception { - startIpMemoryStore(true /* supplyService */); - - final Blob b = new Blob(); - b.data = TEST_BLOB_DATA; - final String l2Key = "fakeKey"; - - // enqueue multiple ipms requests - mStore.storeNetworkAttributes(l2Key, TEST_NETWORK_ATTRIBUTES, - status -> assertTrue("Store not successful : " + status.resultCode, - status.isSuccess())); - mStore.retrieveNetworkAttributes(l2Key, - (status, key, attr) -> { - throw new RuntimeException("retrieveNetworkAttributes test"); - }); - mStore.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, b, - status -> { - throw new RuntimeException("storeBlob test"); - }); - mStore.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_OTHER_DATA_NAME, - (status, key, name, data) -> { - assertTrue("Retrieve blob status not successful : " + status.resultCode, - status.isSuccess()); - assertEquals(l2Key, key); - assertEquals(name, TEST_DATA_NAME); - assertTrue(Arrays.equals(b.data, data.data)); - }); - - // verify the rest of the queue is still processed in order even if when one or more - // callback throw the remote exception - InOrder inOrder = inOrder(mMockService); - - inOrder.verify(mMockService).storeNetworkAttributes(eq(l2Key), mNapCaptor.capture(), - any()); - inOrder.verify(mMockService).retrieveNetworkAttributes(eq(l2Key), any()); - inOrder.verify(mMockService).storeBlob(eq(l2Key), eq(TEST_CLIENT_ID), eq(TEST_DATA_NAME), - eq(b), any()); - inOrder.verify(mMockService).retrieveBlob(eq(l2Key), eq(TEST_CLIENT_ID), - eq(TEST_OTHER_DATA_NAME), any()); - assertEquals(TEST_NETWORK_ATTRIBUTES, new NetworkAttributes(mNapCaptor.getValue())); - } - - @Test - public void testFactoryReset() throws RemoteException { - startIpMemoryStore(true /* supplyService */); - mStore.factoryReset(); - verify(mMockService, times(1)).factoryReset(); - } -} diff --git a/tests/net/java/android/net/IpSecAlgorithmTest.java b/tests/net/java/android/net/IpSecAlgorithmTest.java deleted file mode 100644 index 5bd221477412..000000000000 --- a/tests/net/java/android/net/IpSecAlgorithmTest.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.net.IpSecAlgorithm.ALGO_TO_REQUIRED_FIRST_SDK; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -import android.content.res.Resources; -import android.os.Build; -import android.os.Parcel; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.internal.util.CollectionUtils; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.AbstractMap.SimpleEntry; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Map.Entry; -import java.util.Random; -import java.util.Set; - -/** Unit tests for {@link IpSecAlgorithm}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class IpSecAlgorithmTest { - private static final byte[] KEY_MATERIAL; - - private final Resources mMockResources = mock(Resources.class); - - static { - KEY_MATERIAL = new byte[128]; - new Random().nextBytes(KEY_MATERIAL); - }; - - private static byte[] generateKey(int keyLenInBits) { - return Arrays.copyOf(KEY_MATERIAL, keyLenInBits / 8); - } - - @Test - public void testNoTruncLen() throws Exception { - Entry<String, Integer>[] authAndAeadList = - new Entry[] { - new SimpleEntry<>(IpSecAlgorithm.AUTH_HMAC_MD5, 128), - new SimpleEntry<>(IpSecAlgorithm.AUTH_HMAC_SHA1, 160), - new SimpleEntry<>(IpSecAlgorithm.AUTH_HMAC_SHA256, 256), - new SimpleEntry<>(IpSecAlgorithm.AUTH_HMAC_SHA384, 384), - new SimpleEntry<>(IpSecAlgorithm.AUTH_HMAC_SHA512, 512), - new SimpleEntry<>(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, 224), - }; - - // Expect auth and aead algorithms to throw errors if trunclen is omitted. - for (Entry<String, Integer> algData : authAndAeadList) { - try { - new IpSecAlgorithm( - algData.getKey(), Arrays.copyOf(KEY_MATERIAL, algData.getValue() / 8)); - fail("Expected exception on unprovided auth trunclen"); - } catch (IllegalArgumentException expected) { - } - } - - // Ensure crypt works with no truncation length supplied. - new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, Arrays.copyOf(KEY_MATERIAL, 256 / 8)); - } - - private void checkAuthKeyAndTruncLenValidation(String algoName, int keyLen, int truncLen) - throws Exception { - new IpSecAlgorithm(algoName, generateKey(keyLen), truncLen); - - try { - new IpSecAlgorithm(algoName, generateKey(keyLen)); - fail("Expected exception on unprovided auth trunclen"); - } catch (IllegalArgumentException pass) { - } - - try { - new IpSecAlgorithm(algoName, generateKey(keyLen + 8), truncLen); - fail("Invalid key length not validated"); - } catch (IllegalArgumentException pass) { - } - - try { - new IpSecAlgorithm(algoName, generateKey(keyLen), truncLen + 1); - fail("Invalid truncation length not validated"); - } catch (IllegalArgumentException pass) { - } - } - - private void checkCryptKeyLenValidation(String algoName, int keyLen) throws Exception { - new IpSecAlgorithm(algoName, generateKey(keyLen)); - - try { - new IpSecAlgorithm(algoName, generateKey(keyLen + 8)); - fail("Invalid key length not validated"); - } catch (IllegalArgumentException pass) { - } - } - - @Test - public void testValidationForAlgosAddedInS() throws Exception { - if (Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.R) { - return; - } - - for (int len : new int[] {160, 224, 288}) { - checkCryptKeyLenValidation(IpSecAlgorithm.CRYPT_AES_CTR, len); - } - checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_AES_XCBC, 128, 96); - checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_AES_CMAC, 128, 96); - checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305, 288, 128); - } - - @Test - public void testTruncLenValidation() throws Exception { - for (int truncLen : new int[] {256, 512}) { - new IpSecAlgorithm( - IpSecAlgorithm.AUTH_HMAC_SHA512, - Arrays.copyOf(KEY_MATERIAL, 512 / 8), - truncLen); - } - - for (int truncLen : new int[] {255, 513}) { - try { - new IpSecAlgorithm( - IpSecAlgorithm.AUTH_HMAC_SHA512, - Arrays.copyOf(KEY_MATERIAL, 512 / 8), - truncLen); - fail("Invalid truncation length not validated"); - } catch (IllegalArgumentException pass) { - } - } - } - - @Test - public void testLenValidation() throws Exception { - for (int len : new int[] {128, 192, 256}) { - new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, Arrays.copyOf(KEY_MATERIAL, len / 8)); - } - try { - new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, Arrays.copyOf(KEY_MATERIAL, 384 / 8)); - fail("Invalid key length not validated"); - } catch (IllegalArgumentException pass) { - } - } - - @Test - public void testAlgoNameValidation() throws Exception { - try { - new IpSecAlgorithm("rot13", Arrays.copyOf(KEY_MATERIAL, 128 / 8)); - fail("Invalid algorithm name not validated"); - } catch (IllegalArgumentException pass) { - } - } - - @Test - public void testParcelUnparcel() throws Exception { - IpSecAlgorithm init = - new IpSecAlgorithm( - IpSecAlgorithm.AUTH_HMAC_SHA512, Arrays.copyOf(KEY_MATERIAL, 512 / 8), 256); - - Parcel p = Parcel.obtain(); - p.setDataPosition(0); - init.writeToParcel(p, 0); - - p.setDataPosition(0); - IpSecAlgorithm fin = IpSecAlgorithm.CREATOR.createFromParcel(p); - assertTrue("Parcel/Unparcel failed!", IpSecAlgorithm.equals(init, fin)); - p.recycle(); - } - - private static Set<String> getMandatoryAlgos() { - return CollectionUtils.filter( - ALGO_TO_REQUIRED_FIRST_SDK.keySet(), - i -> Build.VERSION.DEVICE_INITIAL_SDK_INT >= ALGO_TO_REQUIRED_FIRST_SDK.get(i)); - } - - private static Set<String> getOptionalAlgos() { - return CollectionUtils.filter( - ALGO_TO_REQUIRED_FIRST_SDK.keySet(), - i -> Build.VERSION.DEVICE_INITIAL_SDK_INT < ALGO_TO_REQUIRED_FIRST_SDK.get(i)); - } - - @Test - public void testGetSupportedAlgorithms() throws Exception { - assertTrue(IpSecAlgorithm.getSupportedAlgorithms().containsAll(getMandatoryAlgos())); - assertTrue(ALGO_TO_REQUIRED_FIRST_SDK.keySet().containsAll( - IpSecAlgorithm.getSupportedAlgorithms())); - } - - @Test - public void testLoadAlgos() throws Exception { - final Set<String> optionalAlgoSet = getOptionalAlgos(); - final String[] optionalAlgos = optionalAlgoSet.toArray(new String[0]); - - doReturn(optionalAlgos).when(mMockResources) - .getStringArray(com.android.internal.R.array.config_optionalIpSecAlgorithms); - - final Set<String> enabledAlgos = new HashSet<>(IpSecAlgorithm.loadAlgos(mMockResources)); - final Set<String> expectedAlgos = ALGO_TO_REQUIRED_FIRST_SDK.keySet(); - - assertEquals(expectedAlgos, enabledAlgos); - } -} diff --git a/tests/net/java/android/net/IpSecConfigTest.java b/tests/net/java/android/net/IpSecConfigTest.java deleted file mode 100644 index 25e225ef303a..000000000000 --- a/tests/net/java/android/net/IpSecConfigTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static com.android.testutils.ParcelUtils.assertParcelSane; -import static com.android.testutils.ParcelUtils.assertParcelingIsLossless; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for {@link IpSecConfig}. */ -@SmallTest -@RunWith(JUnit4.class) -public class IpSecConfigTest { - - @Test - public void testDefaults() throws Exception { - IpSecConfig c = new IpSecConfig(); - assertEquals(IpSecTransform.MODE_TRANSPORT, c.getMode()); - assertEquals("", c.getSourceAddress()); - assertEquals("", c.getDestinationAddress()); - assertNull(c.getNetwork()); - assertEquals(IpSecTransform.ENCAP_NONE, c.getEncapType()); - assertEquals(IpSecManager.INVALID_RESOURCE_ID, c.getEncapSocketResourceId()); - assertEquals(0, c.getEncapRemotePort()); - assertEquals(0, c.getNattKeepaliveInterval()); - assertNull(c.getEncryption()); - assertNull(c.getAuthentication()); - assertEquals(IpSecManager.INVALID_RESOURCE_ID, c.getSpiResourceId()); - assertEquals(0, c.getXfrmInterfaceId()); - } - - private IpSecConfig getSampleConfig() { - IpSecConfig c = new IpSecConfig(); - c.setMode(IpSecTransform.MODE_TUNNEL); - c.setSourceAddress("0.0.0.0"); - c.setDestinationAddress("1.2.3.4"); - c.setSpiResourceId(1984); - c.setEncryption( - new IpSecAlgorithm( - IpSecAlgorithm.CRYPT_AES_CBC, - new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF})); - c.setAuthentication( - new IpSecAlgorithm( - IpSecAlgorithm.AUTH_HMAC_MD5, - new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0}, - 128)); - c.setAuthenticatedEncryption( - new IpSecAlgorithm( - IpSecAlgorithm.AUTH_CRYPT_AES_GCM, - new byte[] { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0, 1, 2, 3, 4 - }, - 128)); - c.setEncapType(android.system.OsConstants.UDP_ENCAP_ESPINUDP); - c.setEncapSocketResourceId(7); - c.setEncapRemotePort(22); - c.setNattKeepaliveInterval(42); - c.setMarkValue(12); - c.setMarkMask(23); - c.setXfrmInterfaceId(34); - - return c; - } - - @Test - public void testCopyConstructor() { - IpSecConfig original = getSampleConfig(); - IpSecConfig copy = new IpSecConfig(original); - - assertEquals(original, copy); - assertNotSame(original, copy); - } - - @Test - public void testParcelUnparcel() { - assertParcelingIsLossless(new IpSecConfig()); - - IpSecConfig c = getSampleConfig(); - assertParcelSane(c, 15); - } -} diff --git a/tests/net/java/android/net/IpSecManagerTest.java b/tests/net/java/android/net/IpSecManagerTest.java deleted file mode 100644 index 730e2d56bd78..000000000000 --- a/tests/net/java/android/net/IpSecManagerTest.java +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.system.OsConstants.AF_INET; -import static android.system.OsConstants.IPPROTO_UDP; -import static android.system.OsConstants.SOCK_DGRAM; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.system.Os; -import android.test.mock.MockContext; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.server.IpSecService; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; - -/** Unit tests for {@link IpSecManager}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class IpSecManagerTest { - - private static final int TEST_UDP_ENCAP_PORT = 34567; - private static final int DROID_SPI = 0xD1201D; - private static final int DUMMY_RESOURCE_ID = 0x1234; - - private static final InetAddress GOOGLE_DNS_4; - private static final String VTI_INTF_NAME = "ipsec_test"; - private static final InetAddress VTI_LOCAL_ADDRESS; - private static final LinkAddress VTI_INNER_ADDRESS = new LinkAddress("10.0.1.1/24"); - - static { - try { - // Google Public DNS Addresses; - GOOGLE_DNS_4 = InetAddress.getByName("8.8.8.8"); - VTI_LOCAL_ADDRESS = InetAddress.getByName("8.8.4.4"); - } catch (UnknownHostException e) { - throw new RuntimeException("Could not resolve DNS Addresses", e); - } - } - - private IpSecService mMockIpSecService; - private IpSecManager mIpSecManager; - private MockContext mMockContext = new MockContext() { - @Override - public String getOpPackageName() { - return "fooPackage"; - } - }; - - @Before - public void setUp() throws Exception { - mMockIpSecService = mock(IpSecService.class); - mIpSecManager = new IpSecManager(mMockContext, mMockIpSecService); - } - - /* - * Allocate a specific SPI - * Close SPIs - */ - @Test - public void testAllocSpi() throws Exception { - IpSecSpiResponse spiResp = - new IpSecSpiResponse(IpSecManager.Status.OK, DUMMY_RESOURCE_ID, DROID_SPI); - when(mMockIpSecService.allocateSecurityParameterIndex( - eq(GOOGLE_DNS_4.getHostAddress()), - eq(DROID_SPI), - anyObject())) - .thenReturn(spiResp); - - IpSecManager.SecurityParameterIndex droidSpi = - mIpSecManager.allocateSecurityParameterIndex(GOOGLE_DNS_4, DROID_SPI); - assertEquals(DROID_SPI, droidSpi.getSpi()); - - droidSpi.close(); - - verify(mMockIpSecService).releaseSecurityParameterIndex(DUMMY_RESOURCE_ID); - } - - @Test - public void testAllocRandomSpi() throws Exception { - IpSecSpiResponse spiResp = - new IpSecSpiResponse(IpSecManager.Status.OK, DUMMY_RESOURCE_ID, DROID_SPI); - when(mMockIpSecService.allocateSecurityParameterIndex( - eq(GOOGLE_DNS_4.getHostAddress()), - eq(IpSecManager.INVALID_SECURITY_PARAMETER_INDEX), - anyObject())) - .thenReturn(spiResp); - - IpSecManager.SecurityParameterIndex randomSpi = - mIpSecManager.allocateSecurityParameterIndex(GOOGLE_DNS_4); - - assertEquals(DROID_SPI, randomSpi.getSpi()); - - randomSpi.close(); - - verify(mMockIpSecService).releaseSecurityParameterIndex(DUMMY_RESOURCE_ID); - } - - /* - * Throws resource unavailable exception - */ - @Test - public void testAllocSpiResUnavailableException() throws Exception { - IpSecSpiResponse spiResp = - new IpSecSpiResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE, 0, 0); - when(mMockIpSecService.allocateSecurityParameterIndex( - anyString(), anyInt(), anyObject())) - .thenReturn(spiResp); - - try { - mIpSecManager.allocateSecurityParameterIndex(GOOGLE_DNS_4); - fail("ResourceUnavailableException was not thrown"); - } catch (IpSecManager.ResourceUnavailableException e) { - } - } - - /* - * Throws spi unavailable exception - */ - @Test - public void testAllocSpiSpiUnavailableException() throws Exception { - IpSecSpiResponse spiResp = new IpSecSpiResponse(IpSecManager.Status.SPI_UNAVAILABLE, 0, 0); - when(mMockIpSecService.allocateSecurityParameterIndex( - anyString(), anyInt(), anyObject())) - .thenReturn(spiResp); - - try { - mIpSecManager.allocateSecurityParameterIndex(GOOGLE_DNS_4); - fail("ResourceUnavailableException was not thrown"); - } catch (IpSecManager.ResourceUnavailableException e) { - } - } - - /* - * Should throw exception when request spi 0 in IpSecManager - */ - @Test - public void testRequestAllocInvalidSpi() throws Exception { - try { - mIpSecManager.allocateSecurityParameterIndex(GOOGLE_DNS_4, 0); - fail("Able to allocate invalid spi"); - } catch (IllegalArgumentException e) { - } - } - - @Test - public void testOpenEncapsulationSocket() throws Exception { - IpSecUdpEncapResponse udpEncapResp = - new IpSecUdpEncapResponse( - IpSecManager.Status.OK, - DUMMY_RESOURCE_ID, - TEST_UDP_ENCAP_PORT, - Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)); - when(mMockIpSecService.openUdpEncapsulationSocket(eq(TEST_UDP_ENCAP_PORT), anyObject())) - .thenReturn(udpEncapResp); - - IpSecManager.UdpEncapsulationSocket encapSocket = - mIpSecManager.openUdpEncapsulationSocket(TEST_UDP_ENCAP_PORT); - assertNotNull(encapSocket.getFileDescriptor()); - assertEquals(TEST_UDP_ENCAP_PORT, encapSocket.getPort()); - - encapSocket.close(); - - verify(mMockIpSecService).closeUdpEncapsulationSocket(DUMMY_RESOURCE_ID); - } - - @Test - public void testApplyTransportModeTransformEnsuresSocketCreation() throws Exception { - Socket socket = new Socket(); - IpSecConfig dummyConfig = new IpSecConfig(); - IpSecTransform dummyTransform = new IpSecTransform(null, dummyConfig); - - // Even if underlying SocketImpl is not initalized, this should force the init, and - // thereby succeed. - mIpSecManager.applyTransportModeTransform( - socket, IpSecManager.DIRECTION_IN, dummyTransform); - - // Check to make sure the FileDescriptor is non-null - assertNotNull(socket.getFileDescriptor$()); - } - - @Test - public void testRemoveTransportModeTransformsForcesSocketCreation() throws Exception { - Socket socket = new Socket(); - - // Even if underlying SocketImpl is not initalized, this should force the init, and - // thereby succeed. - mIpSecManager.removeTransportModeTransforms(socket); - - // Check to make sure the FileDescriptor is non-null - assertNotNull(socket.getFileDescriptor$()); - } - - @Test - public void testOpenEncapsulationSocketOnRandomPort() throws Exception { - IpSecUdpEncapResponse udpEncapResp = - new IpSecUdpEncapResponse( - IpSecManager.Status.OK, - DUMMY_RESOURCE_ID, - TEST_UDP_ENCAP_PORT, - Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)); - - when(mMockIpSecService.openUdpEncapsulationSocket(eq(0), anyObject())) - .thenReturn(udpEncapResp); - - IpSecManager.UdpEncapsulationSocket encapSocket = - mIpSecManager.openUdpEncapsulationSocket(); - - assertNotNull(encapSocket.getFileDescriptor()); - assertEquals(TEST_UDP_ENCAP_PORT, encapSocket.getPort()); - - encapSocket.close(); - - verify(mMockIpSecService).closeUdpEncapsulationSocket(DUMMY_RESOURCE_ID); - } - - @Test - public void testOpenEncapsulationSocketWithInvalidPort() throws Exception { - try { - mIpSecManager.openUdpEncapsulationSocket(IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); - fail("IllegalArgumentException was not thrown"); - } catch (IllegalArgumentException e) { - } - } - - // TODO: add test when applicable transform builder interface is available - - private IpSecManager.IpSecTunnelInterface createAndValidateVti(int resourceId, String intfName) - throws Exception { - IpSecTunnelInterfaceResponse dummyResponse = - new IpSecTunnelInterfaceResponse(IpSecManager.Status.OK, resourceId, intfName); - when(mMockIpSecService.createTunnelInterface( - eq(VTI_LOCAL_ADDRESS.getHostAddress()), eq(GOOGLE_DNS_4.getHostAddress()), - anyObject(), anyObject(), anyString())) - .thenReturn(dummyResponse); - - IpSecManager.IpSecTunnelInterface tunnelIntf = mIpSecManager.createIpSecTunnelInterface( - VTI_LOCAL_ADDRESS, GOOGLE_DNS_4, mock(Network.class)); - - assertNotNull(tunnelIntf); - return tunnelIntf; - } - - @Test - public void testCreateVti() throws Exception { - IpSecManager.IpSecTunnelInterface tunnelIntf = - createAndValidateVti(DUMMY_RESOURCE_ID, VTI_INTF_NAME); - - assertEquals(VTI_INTF_NAME, tunnelIntf.getInterfaceName()); - - tunnelIntf.close(); - verify(mMockIpSecService).deleteTunnelInterface(eq(DUMMY_RESOURCE_ID), anyString()); - } - - @Test - public void testAddRemoveAddressesFromVti() throws Exception { - IpSecManager.IpSecTunnelInterface tunnelIntf = - createAndValidateVti(DUMMY_RESOURCE_ID, VTI_INTF_NAME); - - tunnelIntf.addAddress(VTI_INNER_ADDRESS.getAddress(), - VTI_INNER_ADDRESS.getPrefixLength()); - verify(mMockIpSecService) - .addAddressToTunnelInterface( - eq(DUMMY_RESOURCE_ID), eq(VTI_INNER_ADDRESS), anyString()); - - tunnelIntf.removeAddress(VTI_INNER_ADDRESS.getAddress(), - VTI_INNER_ADDRESS.getPrefixLength()); - verify(mMockIpSecService) - .addAddressToTunnelInterface( - eq(DUMMY_RESOURCE_ID), eq(VTI_INNER_ADDRESS), anyString()); - } -} diff --git a/tests/net/java/android/net/IpSecTransformTest.java b/tests/net/java/android/net/IpSecTransformTest.java deleted file mode 100644 index 424f23dbbaf6..000000000000 --- a/tests/net/java/android/net/IpSecTransformTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for {@link IpSecTransform}. */ -@SmallTest -@RunWith(JUnit4.class) -public class IpSecTransformTest { - - @Test - public void testCreateTransformCopiesConfig() { - // Create a config with a few parameters to make sure it's not empty - IpSecConfig config = new IpSecConfig(); - config.setSourceAddress("0.0.0.0"); - config.setDestinationAddress("1.2.3.4"); - config.setSpiResourceId(1984); - - IpSecTransform preModification = new IpSecTransform(null, config); - - config.setSpiResourceId(1985); - IpSecTransform postModification = new IpSecTransform(null, config); - - assertNotEquals(preModification, postModification); - } - - @Test - public void testCreateTransformsWithSameConfigEqual() { - // Create a config with a few parameters to make sure it's not empty - IpSecConfig config = new IpSecConfig(); - config.setSourceAddress("0.0.0.0"); - config.setDestinationAddress("1.2.3.4"); - config.setSpiResourceId(1984); - - IpSecTransform config1 = new IpSecTransform(null, config); - IpSecTransform config2 = new IpSecTransform(null, config); - - assertEquals(config1, config2); - } -} diff --git a/tests/net/java/android/net/KeepalivePacketDataUtilTest.java b/tests/net/java/android/net/KeepalivePacketDataUtilTest.java deleted file mode 100644 index fc739fbfac61..000000000000 --- a/tests/net/java/android/net/KeepalivePacketDataUtilTest.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static com.android.testutils.ParcelUtils.assertParcelingIsLossless; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.net.util.KeepalivePacketDataUtil; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.net.InetAddress; -import java.nio.ByteBuffer; - -@RunWith(JUnit4.class) -public final class KeepalivePacketDataUtilTest { - private static final byte[] IPV4_KEEPALIVE_SRC_ADDR = {10, 0, 0, 1}; - private static final byte[] IPV4_KEEPALIVE_DST_ADDR = {10, 0, 0, 5}; - - @Before - public void setUp() {} - - @Test - public void testFromTcpKeepaliveStableParcelable() throws Exception { - final int srcPort = 1234; - final int dstPort = 4321; - final int seq = 0x11111111; - final int ack = 0x22222222; - final int wnd = 8000; - final int wndScale = 2; - final int tos = 4; - final int ttl = 64; - TcpKeepalivePacketData resultData = null; - final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable(); - testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR; - testInfo.srcPort = srcPort; - testInfo.dstAddress = IPV4_KEEPALIVE_DST_ADDR; - testInfo.dstPort = dstPort; - testInfo.seq = seq; - testInfo.ack = ack; - testInfo.rcvWnd = wnd; - testInfo.rcvWndScale = wndScale; - testInfo.tos = tos; - testInfo.ttl = ttl; - try { - resultData = KeepalivePacketDataUtil.fromStableParcelable(testInfo); - } catch (InvalidPacketException e) { - fail("InvalidPacketException: " + e); - } - - assertEquals(InetAddress.getByAddress(testInfo.srcAddress), resultData.getSrcAddress()); - assertEquals(InetAddress.getByAddress(testInfo.dstAddress), resultData.getDstAddress()); - assertEquals(testInfo.srcPort, resultData.getSrcPort()); - assertEquals(testInfo.dstPort, resultData.getDstPort()); - assertEquals(testInfo.seq, resultData.tcpSeq); - assertEquals(testInfo.ack, resultData.tcpAck); - assertEquals(testInfo.rcvWnd, resultData.tcpWindow); - assertEquals(testInfo.rcvWndScale, resultData.tcpWindowScale); - assertEquals(testInfo.tos, resultData.ipTos); - assertEquals(testInfo.ttl, resultData.ipTtl); - - assertParcelingIsLossless(resultData); - - final byte[] packet = resultData.getPacket(); - // IP version and IHL - assertEquals(packet[0], 0x45); - // TOS - assertEquals(packet[1], tos); - // TTL - assertEquals(packet[8], ttl); - // Source IP address. - byte[] ip = new byte[4]; - ByteBuffer buf = ByteBuffer.wrap(packet, 12, 4); - buf.get(ip); - assertArrayEquals(ip, IPV4_KEEPALIVE_SRC_ADDR); - // Destination IP address. - buf = ByteBuffer.wrap(packet, 16, 4); - buf.get(ip); - assertArrayEquals(ip, IPV4_KEEPALIVE_DST_ADDR); - - buf = ByteBuffer.wrap(packet, 20, 12); - // Source port. - assertEquals(buf.getShort(), srcPort); - // Destination port. - assertEquals(buf.getShort(), dstPort); - // Sequence number. - assertEquals(buf.getInt(), seq); - // Ack. - assertEquals(buf.getInt(), ack); - // Window size. - buf = ByteBuffer.wrap(packet, 34, 2); - assertEquals(buf.getShort(), wnd >> wndScale); - } - - //TODO: add ipv6 test when ipv6 supported - - @Test - public void testToTcpKeepaliveStableParcelable() throws Exception { - final int srcPort = 1234; - final int dstPort = 4321; - final int sequence = 0x11111111; - final int ack = 0x22222222; - final int wnd = 48_000; - final int wndScale = 2; - final int tos = 4; - final int ttl = 64; - final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable(); - testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR; - testInfo.srcPort = srcPort; - testInfo.dstAddress = IPV4_KEEPALIVE_DST_ADDR; - testInfo.dstPort = dstPort; - testInfo.seq = sequence; - testInfo.ack = ack; - testInfo.rcvWnd = wnd; - testInfo.rcvWndScale = wndScale; - testInfo.tos = tos; - testInfo.ttl = ttl; - TcpKeepalivePacketData testData = null; - TcpKeepalivePacketDataParcelable resultData = null; - testData = KeepalivePacketDataUtil.fromStableParcelable(testInfo); - resultData = KeepalivePacketDataUtil.toStableParcelable(testData); - assertArrayEquals(resultData.srcAddress, IPV4_KEEPALIVE_SRC_ADDR); - assertArrayEquals(resultData.dstAddress, IPV4_KEEPALIVE_DST_ADDR); - assertEquals(resultData.srcPort, srcPort); - assertEquals(resultData.dstPort, dstPort); - assertEquals(resultData.seq, sequence); - assertEquals(resultData.ack, ack); - assertEquals(resultData.rcvWnd, wnd); - assertEquals(resultData.rcvWndScale, wndScale); - assertEquals(resultData.tos, tos); - assertEquals(resultData.ttl, ttl); - - final String expected = "" - + "android.net.TcpKeepalivePacketDataParcelable{srcAddress: [10, 0, 0, 1]," - + " srcPort: 1234, dstAddress: [10, 0, 0, 5], dstPort: 4321, seq: 286331153," - + " ack: 572662306, rcvWnd: 48000, rcvWndScale: 2, tos: 4, ttl: 64}"; - assertEquals(expected, resultData.toString()); - } - - @Test - public void testParseTcpKeepalivePacketData() throws Exception { - final int srcPort = 1234; - final int dstPort = 4321; - final int sequence = 0x11111111; - final int ack = 0x22222222; - final int wnd = 4800; - final int wndScale = 2; - final int tos = 4; - final int ttl = 64; - final TcpKeepalivePacketDataParcelable testParcel = new TcpKeepalivePacketDataParcelable(); - testParcel.srcAddress = IPV4_KEEPALIVE_SRC_ADDR; - testParcel.srcPort = srcPort; - testParcel.dstAddress = IPV4_KEEPALIVE_DST_ADDR; - testParcel.dstPort = dstPort; - testParcel.seq = sequence; - testParcel.ack = ack; - testParcel.rcvWnd = wnd; - testParcel.rcvWndScale = wndScale; - testParcel.tos = tos; - testParcel.ttl = ttl; - - final KeepalivePacketData testData = - KeepalivePacketDataUtil.fromStableParcelable(testParcel); - final TcpKeepalivePacketDataParcelable parsedParcelable = - KeepalivePacketDataUtil.parseTcpKeepalivePacketData(testData); - final TcpKeepalivePacketData roundTripData = - KeepalivePacketDataUtil.fromStableParcelable(parsedParcelable); - - // Generated packet is the same, but rcvWnd / wndScale will differ if scale is non-zero - assertTrue(testData.getPacket().length > 0); - assertArrayEquals(testData.getPacket(), roundTripData.getPacket()); - - testParcel.rcvWndScale = 0; - final KeepalivePacketData noScaleTestData = - KeepalivePacketDataUtil.fromStableParcelable(testParcel); - final TcpKeepalivePacketDataParcelable noScaleParsedParcelable = - KeepalivePacketDataUtil.parseTcpKeepalivePacketData(noScaleTestData); - final TcpKeepalivePacketData noScaleRoundTripData = - KeepalivePacketDataUtil.fromStableParcelable(noScaleParsedParcelable); - assertEquals(noScaleTestData, noScaleRoundTripData); - assertTrue(noScaleTestData.getPacket().length > 0); - assertArrayEquals(noScaleTestData.getPacket(), noScaleRoundTripData.getPacket()); - } -} diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java deleted file mode 100644 index 6de31f6b4be1..000000000000 --- a/tests/net/java/android/net/MacAddressTest.java +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.MacAddressUtils; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet6Address; -import java.util.Arrays; -import java.util.Random; - -@SmallTest -@RunWith(AndroidJUnit4.class) -public class MacAddressTest { - - static class AddrTypeTestCase { - byte[] addr; - int expectedType; - - static AddrTypeTestCase of(int expectedType, int... addr) { - AddrTypeTestCase t = new AddrTypeTestCase(); - t.expectedType = expectedType; - t.addr = toByteArray(addr); - return t; - } - } - - @Test - public void testMacAddrTypes() { - AddrTypeTestCase[] testcases = { - AddrTypeTestCase.of(MacAddress.TYPE_UNKNOWN), - AddrTypeTestCase.of(MacAddress.TYPE_UNKNOWN, 0), - AddrTypeTestCase.of(MacAddress.TYPE_UNKNOWN, 1, 2, 3, 4, 5), - AddrTypeTestCase.of(MacAddress.TYPE_UNKNOWN, 1, 2, 3, 4, 5, 6, 7), - AddrTypeTestCase.of(MacAddress.TYPE_UNICAST, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0), - AddrTypeTestCase.of(MacAddress.TYPE_BROADCAST, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff), - AddrTypeTestCase.of(MacAddress.TYPE_MULTICAST, 1, 2, 3, 4, 5, 6), - AddrTypeTestCase.of(MacAddress.TYPE_MULTICAST, 11, 22, 33, 44, 55, 66), - AddrTypeTestCase.of(MacAddress.TYPE_MULTICAST, 33, 33, 0xaa, 0xbb, 0xcc, 0xdd) - }; - - for (AddrTypeTestCase t : testcases) { - int got = MacAddress.macAddressType(t.addr); - String msg = String.format("expected type of %s to be %s, but got %s", - Arrays.toString(t.addr), t.expectedType, got); - assertEquals(msg, t.expectedType, got); - - if (got != MacAddress.TYPE_UNKNOWN) { - assertEquals(got, MacAddress.fromBytes(t.addr).getAddressType()); - } - } - } - - @Test - public void testToOuiString() { - String[][] macs = { - {"07:00:d3:56:8a:c4", "07:00:d3"}, - {"33:33:aa:bb:cc:dd", "33:33:aa"}, - {"06:00:00:00:00:00", "06:00:00"}, - {"07:00:d3:56:8a:c4", "07:00:d3"} - }; - - for (String[] pair : macs) { - String mac = pair[0]; - String expected = pair[1]; - assertEquals(expected, MacAddress.fromString(mac).toOuiString()); - } - } - - @Test - public void testHexPaddingWhenPrinting() { - String[] macs = { - "07:00:d3:56:8a:c4", - "33:33:aa:bb:cc:dd", - "06:00:00:00:00:00", - "07:00:d3:56:8a:c4" - }; - - for (String mac : macs) { - assertEquals(mac, MacAddress.fromString(mac).toString()); - assertEquals(mac, - MacAddress.stringAddrFromByteAddr(MacAddress.byteAddrFromStringAddr(mac))); - } - } - - @Test - public void testIsMulticastAddress() { - MacAddress[] multicastAddresses = { - MacAddress.BROADCAST_ADDRESS, - MacAddress.fromString("07:00:d3:56:8a:c4"), - MacAddress.fromString("33:33:aa:bb:cc:dd"), - }; - MacAddress[] unicastAddresses = { - MacAddress.ALL_ZEROS_ADDRESS, - MacAddress.fromString("00:01:44:55:66:77"), - MacAddress.fromString("08:00:22:33:44:55"), - MacAddress.fromString("06:00:00:00:00:00"), - }; - - for (MacAddress mac : multicastAddresses) { - String msg = mac.toString() + " expected to be a multicast address"; - assertTrue(msg, MacAddressUtils.isMulticastAddress(mac)); - } - for (MacAddress mac : unicastAddresses) { - String msg = mac.toString() + " expected not to be a multicast address"; - assertFalse(msg, MacAddressUtils.isMulticastAddress(mac)); - } - } - - @Test - public void testIsLocallyAssignedAddress() { - MacAddress[] localAddresses = { - MacAddress.fromString("06:00:00:00:00:00"), - MacAddress.fromString("07:00:d3:56:8a:c4"), - MacAddress.fromString("33:33:aa:bb:cc:dd"), - }; - MacAddress[] universalAddresses = { - MacAddress.fromString("00:01:44:55:66:77"), - MacAddress.fromString("08:00:22:33:44:55"), - }; - - for (MacAddress mac : localAddresses) { - String msg = mac.toString() + " expected to be a locally assigned address"; - assertTrue(msg, mac.isLocallyAssigned()); - } - for (MacAddress mac : universalAddresses) { - String msg = mac.toString() + " expected not to be globally unique address"; - assertFalse(msg, mac.isLocallyAssigned()); - } - } - - @Test - public void testMacAddressConversions() { - final int iterations = 10000; - for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddressUtils.createRandomUnicastAddress(); - - String stringRepr = mac.toString(); - byte[] bytesRepr = mac.toByteArray(); - - assertEquals(mac, MacAddress.fromString(stringRepr)); - assertEquals(mac, MacAddress.fromBytes(bytesRepr)); - - assertEquals(mac, MacAddress.fromString(MacAddress.stringAddrFromByteAddr(bytesRepr))); - assertEquals(mac, MacAddress.fromBytes(MacAddress.byteAddrFromStringAddr(stringRepr))); - } - } - - @Test - public void testMacAddressRandomGeneration() { - final int iterations = 1000; - final String expectedAndroidOui = "da:a1:19"; - for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddress.createRandomUnicastAddressWithGoogleBase(); - String stringRepr = mac.toString(); - - assertTrue(stringRepr + " expected to be a locally assigned address", - mac.isLocallyAssigned()); - assertTrue(stringRepr + " expected to begin with " + expectedAndroidOui, - stringRepr.startsWith(expectedAndroidOui)); - } - - final Random r = new Random(); - final String anotherOui = "24:5f:78"; - final String expectedLocalOui = "26:5f:78"; - final MacAddress base = MacAddress.fromString(anotherOui + ":0:0:0"); - for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddressUtils.createRandomUnicastAddress(base, r); - String stringRepr = mac.toString(); - - assertTrue(stringRepr + " expected to be a locally assigned address", - mac.isLocallyAssigned()); - assertEquals(MacAddress.TYPE_UNICAST, mac.getAddressType()); - assertTrue(stringRepr + " expected to begin with " + expectedLocalOui, - stringRepr.startsWith(expectedLocalOui)); - } - - for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddressUtils.createRandomUnicastAddress(); - String stringRepr = mac.toString(); - - assertTrue(stringRepr + " expected to be a locally assigned address", - mac.isLocallyAssigned()); - assertEquals(MacAddress.TYPE_UNICAST, mac.getAddressType()); - } - } - - @Test - public void testConstructorInputValidation() { - String[] invalidStringAddresses = { - "", - "abcd", - "1:2:3:4:5", - "1:2:3:4:5:6:7", - "10000:2:3:4:5:6", - }; - - for (String s : invalidStringAddresses) { - try { - MacAddress mac = MacAddress.fromString(s); - fail("MacAddress.fromString(" + s + ") should have failed, but returned " + mac); - } catch (IllegalArgumentException excepted) { - } - } - - try { - MacAddress mac = MacAddress.fromString(null); - fail("MacAddress.fromString(null) should have failed, but returned " + mac); - } catch (NullPointerException excepted) { - } - - byte[][] invalidBytesAddresses = { - {}, - {1,2,3,4,5}, - {1,2,3,4,5,6,7}, - }; - - for (byte[] b : invalidBytesAddresses) { - try { - MacAddress mac = MacAddress.fromBytes(b); - fail("MacAddress.fromBytes(" + Arrays.toString(b) - + ") should have failed, but returned " + mac); - } catch (IllegalArgumentException excepted) { - } - } - - try { - MacAddress mac = MacAddress.fromBytes(null); - fail("MacAddress.fromBytes(null) should have failed, but returned " + mac); - } catch (NullPointerException excepted) { - } - } - - @Test - public void testMatches() { - // match 4 bytes prefix - assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches( - MacAddress.fromString("aa:bb:cc:dd:00:00"), - MacAddress.fromString("ff:ff:ff:ff:00:00"))); - - // match bytes 0,1,2 and 5 - assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches( - MacAddress.fromString("aa:bb:cc:00:00:11"), - MacAddress.fromString("ff:ff:ff:00:00:ff"))); - - // match 34 bit prefix - assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches( - MacAddress.fromString("aa:bb:cc:dd:c0:00"), - MacAddress.fromString("ff:ff:ff:ff:c0:00"))); - - // fail to match 36 bit prefix - assertFalse(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches( - MacAddress.fromString("aa:bb:cc:dd:40:00"), - MacAddress.fromString("ff:ff:ff:ff:f0:00"))); - - // match all 6 bytes - assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches( - MacAddress.fromString("aa:bb:cc:dd:ee:11"), - MacAddress.fromString("ff:ff:ff:ff:ff:ff"))); - - // match none of 6 bytes - assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches( - MacAddress.fromString("00:00:00:00:00:00"), - MacAddress.fromString("00:00:00:00:00:00"))); - } - - /** - * Tests that link-local address generation from MAC is valid. - */ - @Test - public void testLinkLocalFromMacGeneration() { - MacAddress mac = MacAddress.fromString("52:74:f2:b1:a8:7f"); - byte[] inet6ll = {(byte) 0xfe, (byte) 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x74, - (byte) 0xf2, (byte) 0xff, (byte) 0xfe, (byte) 0xb1, (byte) 0xa8, 0x7f}; - Inet6Address llv6 = mac.getLinkLocalIpv6FromEui48Mac(); - assertTrue(llv6.isLinkLocalAddress()); - assertArrayEquals(inet6ll, llv6.getAddress()); - } - - static byte[] toByteArray(int... in) { - byte[] out = new byte[in.length]; - for (int i = 0; i < in.length; i++) { - out[i] = (byte) in[i]; - } - return out; - } -} diff --git a/tests/net/java/android/net/NetworkIdentityTest.kt b/tests/net/java/android/net/NetworkIdentityTest.kt deleted file mode 100644 index eb2b85c14578..000000000000 --- a/tests/net/java/android/net/NetworkIdentityTest.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net - -import android.net.NetworkIdentity.OEM_NONE -import android.net.NetworkIdentity.OEM_PAID -import android.net.NetworkIdentity.OEM_PRIVATE -import android.net.NetworkIdentity.getOemBitfield -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import kotlin.test.assertEquals - -@RunWith(JUnit4::class) -class NetworkIdentityTest { - @Test - fun testGetOemBitfield() { - val oemNone = NetworkCapabilities().apply { - setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, false) - setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, false) - } - val oemPaid = NetworkCapabilities().apply { - setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, true) - setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, false) - } - val oemPrivate = NetworkCapabilities().apply { - setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, false) - setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, true) - } - val oemAll = NetworkCapabilities().apply { - setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, true) - setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, true) - } - - assertEquals(getOemBitfield(oemNone), OEM_NONE) - assertEquals(getOemBitfield(oemPaid), OEM_PAID) - assertEquals(getOemBitfield(oemPrivate), OEM_PRIVATE) - assertEquals(getOemBitfield(oemAll), OEM_PAID or OEM_PRIVATE) - } -} diff --git a/tests/net/java/android/net/NetworkStatsHistoryTest.java b/tests/net/java/android/net/NetworkStatsHistoryTest.java deleted file mode 100644 index 13558cd51c28..000000000000 --- a/tests/net/java/android/net/NetworkStatsHistoryTest.java +++ /dev/null @@ -1,599 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.net.NetworkStatsHistory.DataStreamUtils.readVarLong; -import static android.net.NetworkStatsHistory.DataStreamUtils.writeVarLong; -import static android.net.NetworkStatsHistory.Entry.UNKNOWN; -import static android.net.NetworkStatsHistory.FIELD_ALL; -import static android.net.NetworkStatsHistory.FIELD_OPERATIONS; -import static android.net.NetworkStatsHistory.FIELD_RX_BYTES; -import static android.net.NetworkStatsHistory.FIELD_RX_PACKETS; -import static android.net.NetworkStatsHistory.FIELD_TX_BYTES; -import static android.net.TrafficStats.GB_IN_BYTES; -import static android.net.TrafficStats.MB_IN_BYTES; -import static android.text.format.DateUtils.DAY_IN_MILLIS; -import static android.text.format.DateUtils.HOUR_IN_MILLIS; -import static android.text.format.DateUtils.MINUTE_IN_MILLIS; -import static android.text.format.DateUtils.SECOND_IN_MILLIS; -import static android.text.format.DateUtils.WEEK_IN_MILLIS; -import static android.text.format.DateUtils.YEAR_IN_MILLIS; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.content.Context; -import android.util.Log; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.frameworks.tests.net.R; - -import org.junit.After; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.util.Random; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetworkStatsHistoryTest { - private static final String TAG = "NetworkStatsHistoryTest"; - - private static final long TEST_START = 1194220800000L; - - private NetworkStatsHistory stats; - - @After - public void tearDown() throws Exception { - if (stats != null) { - assertConsistent(stats); - } - } - - @Test - public void testReadOriginalVersion() throws Exception { - final Context context = InstrumentationRegistry.getContext(); - final DataInputStream in = - new DataInputStream(context.getResources().openRawResource(R.raw.history_v1)); - - NetworkStatsHistory.Entry entry = null; - try { - final NetworkStatsHistory history = new NetworkStatsHistory(in); - assertEquals(15 * SECOND_IN_MILLIS, history.getBucketDuration()); - - entry = history.getValues(0, entry); - assertEquals(29143L, entry.rxBytes); - assertEquals(6223L, entry.txBytes); - - entry = history.getValues(history.size() - 1, entry); - assertEquals(1476L, entry.rxBytes); - assertEquals(838L, entry.txBytes); - - entry = history.getValues(Long.MIN_VALUE, Long.MAX_VALUE, entry); - assertEquals(332401L, entry.rxBytes); - assertEquals(64314L, entry.txBytes); - - } finally { - in.close(); - } - } - - @Test - public void testRecordSingleBucket() throws Exception { - final long BUCKET_SIZE = HOUR_IN_MILLIS; - stats = new NetworkStatsHistory(BUCKET_SIZE); - - // record data into narrow window to get single bucket - stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS, - new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); - - assertEquals(1, stats.size()); - assertValues(stats, 0, SECOND_IN_MILLIS, 1024L, 10L, 2048L, 20L, 2L); - } - - @Test - public void testRecordEqualBuckets() throws Exception { - final long bucketDuration = HOUR_IN_MILLIS; - stats = new NetworkStatsHistory(bucketDuration); - - // split equally across two buckets - final long recordStart = TEST_START + (bucketDuration / 2); - stats.recordData(recordStart, recordStart + bucketDuration, - new NetworkStats.Entry(1024L, 10L, 128L, 2L, 2L)); - - assertEquals(2, stats.size()); - assertValues(stats, 0, HOUR_IN_MILLIS / 2, 512L, 5L, 64L, 1L, 1L); - assertValues(stats, 1, HOUR_IN_MILLIS / 2, 512L, 5L, 64L, 1L, 1L); - } - - @Test - public void testRecordTouchingBuckets() throws Exception { - final long BUCKET_SIZE = 15 * MINUTE_IN_MILLIS; - stats = new NetworkStatsHistory(BUCKET_SIZE); - - // split almost completely into middle bucket, but with a few minutes - // overlap into neighboring buckets. total record is 20 minutes. - final long recordStart = (TEST_START + BUCKET_SIZE) - MINUTE_IN_MILLIS; - final long recordEnd = (TEST_START + (BUCKET_SIZE * 2)) + (MINUTE_IN_MILLIS * 4); - stats.recordData(recordStart, recordEnd, - new NetworkStats.Entry(1000L, 2000L, 5000L, 10000L, 100L)); - - assertEquals(3, stats.size()); - // first bucket should have (1/20 of value) - assertValues(stats, 0, MINUTE_IN_MILLIS, 50L, 100L, 250L, 500L, 5L); - // second bucket should have (15/20 of value) - assertValues(stats, 1, 15 * MINUTE_IN_MILLIS, 750L, 1500L, 3750L, 7500L, 75L); - // final bucket should have (4/20 of value) - assertValues(stats, 2, 4 * MINUTE_IN_MILLIS, 200L, 400L, 1000L, 2000L, 20L); - } - - @Test - public void testRecordGapBuckets() throws Exception { - final long BUCKET_SIZE = HOUR_IN_MILLIS; - stats = new NetworkStatsHistory(BUCKET_SIZE); - - // record some data today and next week with large gap - final long firstStart = TEST_START; - final long lastStart = TEST_START + WEEK_IN_MILLIS; - stats.recordData(firstStart, firstStart + SECOND_IN_MILLIS, - new NetworkStats.Entry(128L, 2L, 256L, 4L, 1L)); - stats.recordData(lastStart, lastStart + SECOND_IN_MILLIS, - new NetworkStats.Entry(64L, 1L, 512L, 8L, 2L)); - - // we should have two buckets, far apart from each other - assertEquals(2, stats.size()); - assertValues(stats, 0, SECOND_IN_MILLIS, 128L, 2L, 256L, 4L, 1L); - assertValues(stats, 1, SECOND_IN_MILLIS, 64L, 1L, 512L, 8L, 2L); - - // now record something in middle, spread across two buckets - final long middleStart = TEST_START + DAY_IN_MILLIS; - final long middleEnd = middleStart + (HOUR_IN_MILLIS * 2); - stats.recordData(middleStart, middleEnd, - new NetworkStats.Entry(2048L, 4L, 2048L, 4L, 2L)); - - // now should have four buckets, with new record in middle two buckets - assertEquals(4, stats.size()); - assertValues(stats, 0, SECOND_IN_MILLIS, 128L, 2L, 256L, 4L, 1L); - assertValues(stats, 1, HOUR_IN_MILLIS, 1024L, 2L, 1024L, 2L, 1L); - assertValues(stats, 2, HOUR_IN_MILLIS, 1024L, 2L, 1024L, 2L, 1L); - assertValues(stats, 3, SECOND_IN_MILLIS, 64L, 1L, 512L, 8L, 2L); - } - - @Test - public void testRecordOverlapBuckets() throws Exception { - final long BUCKET_SIZE = HOUR_IN_MILLIS; - stats = new NetworkStatsHistory(BUCKET_SIZE); - - // record some data in one bucket, and another overlapping buckets - stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS, - new NetworkStats.Entry(256L, 2L, 256L, 2L, 1L)); - final long midStart = TEST_START + (HOUR_IN_MILLIS / 2); - stats.recordData(midStart, midStart + HOUR_IN_MILLIS, - new NetworkStats.Entry(1024L, 10L, 1024L, 10L, 10L)); - - // should have two buckets, with some data mixed together - assertEquals(2, stats.size()); - assertValues(stats, 0, SECOND_IN_MILLIS + (HOUR_IN_MILLIS / 2), 768L, 7L, 768L, 7L, 6L); - assertValues(stats, 1, (HOUR_IN_MILLIS / 2), 512L, 5L, 512L, 5L, 5L); - } - - @Test - public void testRecordEntireGapIdentical() throws Exception { - // first, create two separate histories far apart - final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS); - stats1.recordData(TEST_START, TEST_START + 2 * HOUR_IN_MILLIS, 2000L, 1000L); - - final long TEST_START_2 = TEST_START + DAY_IN_MILLIS; - final NetworkStatsHistory stats2 = new NetworkStatsHistory(HOUR_IN_MILLIS); - stats2.recordData(TEST_START_2, TEST_START_2 + 2 * HOUR_IN_MILLIS, 1000L, 500L); - - // combine together with identical bucket size - stats = new NetworkStatsHistory(HOUR_IN_MILLIS); - stats.recordEntireHistory(stats1); - stats.recordEntireHistory(stats2); - - // first verify that totals match up - assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 3000L, 1500L); - - // now inspect internal buckets - assertValues(stats, 0, 1000L, 500L); - assertValues(stats, 1, 1000L, 500L); - assertValues(stats, 2, 500L, 250L); - assertValues(stats, 3, 500L, 250L); - } - - @Test - public void testRecordEntireOverlapVaryingBuckets() throws Exception { - // create history just over hour bucket boundary - final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS); - stats1.recordData(TEST_START, TEST_START + MINUTE_IN_MILLIS * 60, 600L, 600L); - - final long TEST_START_2 = TEST_START + MINUTE_IN_MILLIS; - final NetworkStatsHistory stats2 = new NetworkStatsHistory(MINUTE_IN_MILLIS); - stats2.recordData(TEST_START_2, TEST_START_2 + MINUTE_IN_MILLIS * 5, 50L, 50L); - - // combine together with minute bucket size - stats = new NetworkStatsHistory(MINUTE_IN_MILLIS); - stats.recordEntireHistory(stats1); - stats.recordEntireHistory(stats2); - - // first verify that totals match up - assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 650L, 650L); - - // now inspect internal buckets - assertValues(stats, 0, 10L, 10L); - assertValues(stats, 1, 20L, 20L); - assertValues(stats, 2, 20L, 20L); - assertValues(stats, 3, 20L, 20L); - assertValues(stats, 4, 20L, 20L); - assertValues(stats, 5, 20L, 20L); - assertValues(stats, 6, 10L, 10L); - - // now combine using 15min buckets - stats = new NetworkStatsHistory(HOUR_IN_MILLIS / 4); - stats.recordEntireHistory(stats1); - stats.recordEntireHistory(stats2); - - // first verify that totals match up - assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 650L, 650L); - - // and inspect buckets - assertValues(stats, 0, 200L, 200L); - assertValues(stats, 1, 150L, 150L); - assertValues(stats, 2, 150L, 150L); - assertValues(stats, 3, 150L, 150L); - } - - @Test - public void testRemove() throws Exception { - stats = new NetworkStatsHistory(HOUR_IN_MILLIS); - - // record some data across 24 buckets - stats.recordData(TEST_START, TEST_START + DAY_IN_MILLIS, 24L, 24L); - assertEquals(24, stats.size()); - - // try removing invalid data; should be no change - stats.removeBucketsBefore(0 - DAY_IN_MILLIS); - assertEquals(24, stats.size()); - - // try removing far before buckets; should be no change - stats.removeBucketsBefore(TEST_START - YEAR_IN_MILLIS); - assertEquals(24, stats.size()); - - // try removing just moments into first bucket; should be no change - // since that bucket contains data beyond the cutoff - stats.removeBucketsBefore(TEST_START + SECOND_IN_MILLIS); - assertEquals(24, stats.size()); - - // try removing single bucket - stats.removeBucketsBefore(TEST_START + HOUR_IN_MILLIS); - assertEquals(23, stats.size()); - - // try removing multiple buckets - stats.removeBucketsBefore(TEST_START + (4 * HOUR_IN_MILLIS)); - assertEquals(20, stats.size()); - - // try removing all buckets - stats.removeBucketsBefore(TEST_START + YEAR_IN_MILLIS); - assertEquals(0, stats.size()); - } - - @Test - public void testTotalData() throws Exception { - final long BUCKET_SIZE = HOUR_IN_MILLIS; - stats = new NetworkStatsHistory(BUCKET_SIZE); - - // record uniform data across day - stats.recordData(TEST_START, TEST_START + DAY_IN_MILLIS, 2400L, 4800L); - - // verify that total outside range is 0 - assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START - DAY_IN_MILLIS, 0L, 0L); - - // verify total in first hour - assertValues(stats, TEST_START, TEST_START + HOUR_IN_MILLIS, 100L, 200L); - - // verify total across 1.5 hours - assertValues(stats, TEST_START, TEST_START + (long) (1.5 * HOUR_IN_MILLIS), 150L, 300L); - - // verify total beyond end - assertValues(stats, TEST_START + (23 * HOUR_IN_MILLIS), TEST_START + WEEK_IN_MILLIS, 100L, 200L); - - // verify everything total - assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 2400L, 4800L); - - } - - @Test - public void testFuzzing() throws Exception { - try { - // fuzzing with random events, looking for crashes - final NetworkStats.Entry entry = new NetworkStats.Entry(); - final Random r = new Random(); - for (int i = 0; i < 500; i++) { - stats = new NetworkStatsHistory(r.nextLong()); - for (int j = 0; j < 10000; j++) { - if (r.nextBoolean()) { - // add range - final long start = r.nextLong(); - final long end = start + r.nextInt(); - entry.rxBytes = nextPositiveLong(r); - entry.rxPackets = nextPositiveLong(r); - entry.txBytes = nextPositiveLong(r); - entry.txPackets = nextPositiveLong(r); - entry.operations = nextPositiveLong(r); - stats.recordData(start, end, entry); - } else { - // trim something - stats.removeBucketsBefore(r.nextLong()); - } - } - assertConsistent(stats); - } - } catch (Throwable e) { - Log.e(TAG, String.valueOf(stats)); - throw new RuntimeException(e); - } - } - - private static long nextPositiveLong(Random r) { - final long value = r.nextLong(); - return value < 0 ? -value : value; - } - - @Test - public void testIgnoreFields() throws Exception { - final NetworkStatsHistory history = new NetworkStatsHistory( - MINUTE_IN_MILLIS, 0, FIELD_RX_BYTES | FIELD_TX_BYTES); - - history.recordData(0, MINUTE_IN_MILLIS, - new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L)); - history.recordData(0, 2 * MINUTE_IN_MILLIS, - new NetworkStats.Entry(2L, 2L, 2L, 2L, 2L)); - - assertFullValues(history, UNKNOWN, 1026L, UNKNOWN, 2050L, UNKNOWN, UNKNOWN); - } - - @Test - public void testIgnoreFieldsRecordIn() throws Exception { - final NetworkStatsHistory full = new NetworkStatsHistory(MINUTE_IN_MILLIS, 0, FIELD_ALL); - final NetworkStatsHistory partial = new NetworkStatsHistory( - MINUTE_IN_MILLIS, 0, FIELD_RX_PACKETS | FIELD_OPERATIONS); - - full.recordData(0, MINUTE_IN_MILLIS, - new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L)); - partial.recordEntireHistory(full); - - assertFullValues(partial, UNKNOWN, UNKNOWN, 10L, UNKNOWN, UNKNOWN, 4L); - } - - @Test - public void testIgnoreFieldsRecordOut() throws Exception { - final NetworkStatsHistory full = new NetworkStatsHistory(MINUTE_IN_MILLIS, 0, FIELD_ALL); - final NetworkStatsHistory partial = new NetworkStatsHistory( - MINUTE_IN_MILLIS, 0, FIELD_RX_PACKETS | FIELD_OPERATIONS); - - partial.recordData(0, MINUTE_IN_MILLIS, - new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L)); - full.recordEntireHistory(partial); - - assertFullValues(full, MINUTE_IN_MILLIS, 0L, 10L, 0L, 0L, 4L); - } - - @Test - public void testSerialize() throws Exception { - final NetworkStatsHistory before = new NetworkStatsHistory(MINUTE_IN_MILLIS, 40, FIELD_ALL); - before.recordData(0, 4 * MINUTE_IN_MILLIS, - new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L)); - before.recordData(DAY_IN_MILLIS, DAY_IN_MILLIS + MINUTE_IN_MILLIS, - new NetworkStats.Entry(10L, 20L, 30L, 40L, 50L)); - - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - before.writeToStream(new DataOutputStream(out)); - out.close(); - - final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - final NetworkStatsHistory after = new NetworkStatsHistory(new DataInputStream(in)); - - // must have identical totals before and after - assertFullValues(before, 5 * MINUTE_IN_MILLIS, 1034L, 30L, 2078L, 60L, 54L); - assertFullValues(after, 5 * MINUTE_IN_MILLIS, 1034L, 30L, 2078L, 60L, 54L); - } - - @Test - public void testVarLong() throws Exception { - assertEquals(0L, performVarLong(0L)); - assertEquals(-1L, performVarLong(-1L)); - assertEquals(1024L, performVarLong(1024L)); - assertEquals(-1024L, performVarLong(-1024L)); - assertEquals(40 * MB_IN_BYTES, performVarLong(40 * MB_IN_BYTES)); - assertEquals(512 * GB_IN_BYTES, performVarLong(512 * GB_IN_BYTES)); - assertEquals(Long.MIN_VALUE, performVarLong(Long.MIN_VALUE)); - assertEquals(Long.MAX_VALUE, performVarLong(Long.MAX_VALUE)); - assertEquals(Long.MIN_VALUE + 40, performVarLong(Long.MIN_VALUE + 40)); - assertEquals(Long.MAX_VALUE - 40, performVarLong(Long.MAX_VALUE - 40)); - } - - @Test - public void testIndexBeforeAfter() throws Exception { - final long BUCKET_SIZE = HOUR_IN_MILLIS; - stats = new NetworkStatsHistory(BUCKET_SIZE); - - final long FIRST_START = TEST_START; - final long FIRST_END = FIRST_START + (2 * HOUR_IN_MILLIS); - final long SECOND_START = TEST_START + WEEK_IN_MILLIS; - final long SECOND_END = SECOND_START + HOUR_IN_MILLIS; - final long THIRD_START = TEST_START + (2 * WEEK_IN_MILLIS); - final long THIRD_END = THIRD_START + (2 * HOUR_IN_MILLIS); - - stats.recordData(FIRST_START, FIRST_END, - new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); - stats.recordData(SECOND_START, SECOND_END, - new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); - stats.recordData(THIRD_START, THIRD_END, - new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); - - // should have buckets: 2+1+2 - assertEquals(5, stats.size()); - - assertIndexBeforeAfter(stats, 0, 0, Long.MIN_VALUE); - assertIndexBeforeAfter(stats, 0, 1, FIRST_START); - assertIndexBeforeAfter(stats, 0, 1, FIRST_START + MINUTE_IN_MILLIS); - assertIndexBeforeAfter(stats, 0, 2, FIRST_START + HOUR_IN_MILLIS); - assertIndexBeforeAfter(stats, 1, 2, FIRST_START + HOUR_IN_MILLIS + MINUTE_IN_MILLIS); - assertIndexBeforeAfter(stats, 1, 2, FIRST_END - MINUTE_IN_MILLIS); - assertIndexBeforeAfter(stats, 1, 2, FIRST_END); - assertIndexBeforeAfter(stats, 1, 2, FIRST_END + MINUTE_IN_MILLIS); - assertIndexBeforeAfter(stats, 1, 2, SECOND_START - MINUTE_IN_MILLIS); - assertIndexBeforeAfter(stats, 1, 3, SECOND_START); - assertIndexBeforeAfter(stats, 2, 3, SECOND_END); - assertIndexBeforeAfter(stats, 2, 3, SECOND_END + MINUTE_IN_MILLIS); - assertIndexBeforeAfter(stats, 2, 3, THIRD_START - MINUTE_IN_MILLIS); - assertIndexBeforeAfter(stats, 2, 4, THIRD_START); - assertIndexBeforeAfter(stats, 3, 4, THIRD_START + MINUTE_IN_MILLIS); - assertIndexBeforeAfter(stats, 3, 4, THIRD_START + HOUR_IN_MILLIS); - assertIndexBeforeAfter(stats, 4, 4, THIRD_END); - assertIndexBeforeAfter(stats, 4, 4, THIRD_END + MINUTE_IN_MILLIS); - assertIndexBeforeAfter(stats, 4, 4, Long.MAX_VALUE); - } - - @Test - public void testIntersects() throws Exception { - final long BUCKET_SIZE = HOUR_IN_MILLIS; - stats = new NetworkStatsHistory(BUCKET_SIZE); - - final long FIRST_START = TEST_START; - final long FIRST_END = FIRST_START + (2 * HOUR_IN_MILLIS); - final long SECOND_START = TEST_START + WEEK_IN_MILLIS; - final long SECOND_END = SECOND_START + HOUR_IN_MILLIS; - final long THIRD_START = TEST_START + (2 * WEEK_IN_MILLIS); - final long THIRD_END = THIRD_START + (2 * HOUR_IN_MILLIS); - - stats.recordData(FIRST_START, FIRST_END, - new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); - stats.recordData(SECOND_START, SECOND_END, - new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); - stats.recordData(THIRD_START, THIRD_END, - new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); - - assertFalse(stats.intersects(10, 20)); - assertFalse(stats.intersects(TEST_START + YEAR_IN_MILLIS, TEST_START + YEAR_IN_MILLIS + 1)); - assertFalse(stats.intersects(Long.MAX_VALUE, Long.MIN_VALUE)); - - assertTrue(stats.intersects(Long.MIN_VALUE, Long.MAX_VALUE)); - assertTrue(stats.intersects(10, TEST_START + YEAR_IN_MILLIS)); - assertTrue(stats.intersects(TEST_START, TEST_START)); - assertTrue(stats.intersects(TEST_START + DAY_IN_MILLIS, TEST_START + DAY_IN_MILLIS + 1)); - assertTrue(stats.intersects(TEST_START + DAY_IN_MILLIS, Long.MAX_VALUE)); - assertTrue(stats.intersects(TEST_START + 1, Long.MAX_VALUE)); - - assertFalse(stats.intersects(Long.MIN_VALUE, TEST_START - 1)); - assertTrue(stats.intersects(Long.MIN_VALUE, TEST_START)); - assertTrue(stats.intersects(Long.MIN_VALUE, TEST_START + 1)); - } - - @Test - public void testSetValues() throws Exception { - stats = new NetworkStatsHistory(HOUR_IN_MILLIS); - stats.recordData(TEST_START, TEST_START + 1, - new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); - - assertEquals(1024L + 2048L, stats.getTotalBytes()); - - final NetworkStatsHistory.Entry entry = stats.getValues(0, null); - entry.rxBytes /= 2; - entry.txBytes *= 2; - stats.setValues(0, entry); - - assertEquals(512L + 4096L, stats.getTotalBytes()); - } - - private static void assertIndexBeforeAfter( - NetworkStatsHistory stats, int before, int after, long time) { - assertEquals("unexpected before", before, stats.getIndexBefore(time)); - assertEquals("unexpected after", after, stats.getIndexAfter(time)); - } - - private static long performVarLong(long before) throws Exception { - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - writeVarLong(new DataOutputStream(out), before); - - final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - return readVarLong(new DataInputStream(in)); - } - - private static void assertConsistent(NetworkStatsHistory stats) { - // verify timestamps are monotonic - long lastStart = Long.MIN_VALUE; - NetworkStatsHistory.Entry entry = null; - for (int i = 0; i < stats.size(); i++) { - entry = stats.getValues(i, entry); - assertTrue(lastStart < entry.bucketStart); - lastStart = entry.bucketStart; - } - } - - private static void assertValues( - NetworkStatsHistory stats, int index, long rxBytes, long txBytes) { - final NetworkStatsHistory.Entry entry = stats.getValues(index, null); - assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); - assertEquals("unexpected txBytes", txBytes, entry.txBytes); - } - - private static void assertValues( - NetworkStatsHistory stats, long start, long end, long rxBytes, long txBytes) { - final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null); - assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); - assertEquals("unexpected txBytes", txBytes, entry.txBytes); - } - - private static void assertValues(NetworkStatsHistory stats, int index, long activeTime, - long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { - final NetworkStatsHistory.Entry entry = stats.getValues(index, null); - assertEquals("unexpected activeTime", activeTime, entry.activeTime); - assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); - assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets); - assertEquals("unexpected txBytes", txBytes, entry.txBytes); - assertEquals("unexpected txPackets", txPackets, entry.txPackets); - assertEquals("unexpected operations", operations, entry.operations); - } - - private static void assertFullValues(NetworkStatsHistory stats, long activeTime, long rxBytes, - long rxPackets, long txBytes, long txPackets, long operations) { - assertValues(stats, Long.MIN_VALUE, Long.MAX_VALUE, activeTime, rxBytes, rxPackets, txBytes, - txPackets, operations); - } - - private static void assertValues(NetworkStatsHistory stats, long start, long end, - long activeTime, long rxBytes, long rxPackets, long txBytes, long txPackets, - long operations) { - final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null); - assertEquals("unexpected activeTime", activeTime, entry.activeTime); - assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); - assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets); - assertEquals("unexpected txBytes", txBytes, entry.txBytes); - assertEquals("unexpected txPackets", txPackets, entry.txPackets); - assertEquals("unexpected operations", operations, entry.operations); - } -} diff --git a/tests/net/java/android/net/NetworkStatsTest.java b/tests/net/java/android/net/NetworkStatsTest.java deleted file mode 100644 index 23d5a7e5d5f8..000000000000 --- a/tests/net/java/android/net/NetworkStatsTest.java +++ /dev/null @@ -1,1024 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; -import static android.net.NetworkStats.DEFAULT_NETWORK_NO; -import static android.net.NetworkStats.DEFAULT_NETWORK_YES; -import static android.net.NetworkStats.IFACE_ALL; -import static android.net.NetworkStats.INTERFACES_ALL; -import static android.net.NetworkStats.METERED_ALL; -import static android.net.NetworkStats.METERED_NO; -import static android.net.NetworkStats.METERED_YES; -import static android.net.NetworkStats.ROAMING_ALL; -import static android.net.NetworkStats.ROAMING_NO; -import static android.net.NetworkStats.ROAMING_YES; -import static android.net.NetworkStats.SET_ALL; -import static android.net.NetworkStats.SET_DBG_VPN_IN; -import static android.net.NetworkStats.SET_DBG_VPN_OUT; -import static android.net.NetworkStats.SET_DEFAULT; -import static android.net.NetworkStats.SET_FOREGROUND; -import static android.net.NetworkStats.TAG_ALL; -import static android.net.NetworkStats.TAG_NONE; -import static android.net.NetworkStats.UID_ALL; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import android.os.Process; -import android.util.ArrayMap; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.google.android.collect.Sets; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.Arrays; -import java.util.HashSet; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetworkStatsTest { - - private static final String TEST_IFACE = "test0"; - private static final String TEST_IFACE2 = "test2"; - private static final int TEST_UID = 1001; - private static final long TEST_START = 1194220800000L; - - @Test - public void testFindIndex() throws Exception { - final NetworkStats stats = new NetworkStats(TEST_START, 5) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 1024L, 8L, 0L, 0L, 10) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_YES, 0L, 0L, 1024L, 8L, 11) - .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1024L, 8L, 1024L, 8L, 12) - .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, - DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12); - - assertEquals(4, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, - ROAMING_YES, DEFAULT_NETWORK_YES)); - assertEquals(3, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO)); - assertEquals(2, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, - ROAMING_NO, DEFAULT_NETWORK_YES)); - assertEquals(1, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO)); - assertEquals(0, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_YES)); - assertEquals(-1, stats.findIndex(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO)); - assertEquals(-1, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO)); - } - - @Test - public void testFindIndexHinted() { - final NetworkStats stats = new NetworkStats(TEST_START, 3) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 1024L, 8L, 0L, 0L, 10) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11) - .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12) - .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1024L, 8L, 0L, 0L, 10) - .insertEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 0L, 0L, 1024L, 8L, 11) - .insertEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11) - .insertEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12) - .insertEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, - DEFAULT_NETWORK_NO, 1024L, 8L, 1024L, 8L, 12); - - // verify that we correctly find across regardless of hinting - for (int hint = 0; hint < stats.size(); hint++) { - assertEquals(0, stats.findIndexHinted(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, hint)); - assertEquals(1, stats.findIndexHinted(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, hint)); - assertEquals(2, stats.findIndexHinted(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, hint)); - assertEquals(3, stats.findIndexHinted(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, hint)); - assertEquals(4, stats.findIndexHinted(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, hint)); - assertEquals(5, stats.findIndexHinted(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, - METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, hint)); - assertEquals(6, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, hint)); - assertEquals(7, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, - METERED_YES, ROAMING_YES, DEFAULT_NETWORK_NO, hint)); - assertEquals(-1, stats.findIndexHinted(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, - METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, hint)); - assertEquals(-1, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, - METERED_YES, ROAMING_YES, DEFAULT_NETWORK_YES, hint)); - } - } - - @Test - public void testAddEntryGrow() throws Exception { - final NetworkStats stats = new NetworkStats(TEST_START, 4); - - assertEquals(0, stats.size()); - assertEquals(4, stats.internalSize()); - - stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 1L, 1L, 2L, 2L, 3); - stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 2L, 2L, 2L, 2L, 4); - stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, - DEFAULT_NETWORK_YES, 3L, 3L, 2L, 2L, 5); - stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, - DEFAULT_NETWORK_NO, 3L, 3L, 2L, 2L, 5); - - assertEquals(4, stats.size()); - assertEquals(4, stats.internalSize()); - - stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 4L, 40L, 4L, 40L, 7); - stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 5L, 50L, 4L, 40L, 8); - stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 6L, 60L, 5L, 50L, 10); - stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, - DEFAULT_NETWORK_YES, 7L, 70L, 5L, 50L, 11); - stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, - DEFAULT_NETWORK_NO, 7L, 70L, 5L, 50L, 11); - - assertEquals(9, stats.size()); - assertTrue(stats.internalSize() >= 9); - - assertValues(stats, 0, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 1L, 1L, 2L, 2L, 3); - assertValues(stats, 1, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 2L, 2L, 2L, 2L, 4); - assertValues(stats, 2, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, - DEFAULT_NETWORK_YES, 3L, 3L, 2L, 2L, 5); - assertValues(stats, 3, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, - ROAMING_YES, DEFAULT_NETWORK_NO, 3L, 3L, 2L, 2L, 5); - assertValues(stats, 4, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 4L, 40L, 4L, 40L, 7); - assertValues(stats, 5, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 5L, 50L, 4L, 40L, 8); - assertValues(stats, 6, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 6L, 60L, 5L, 50L, 10); - assertValues(stats, 7, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, - DEFAULT_NETWORK_YES, 7L, 70L, 5L, 50L, 11); - assertValues(stats, 8, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, - ROAMING_YES, DEFAULT_NETWORK_NO, 7L, 70L, 5L, 50L, 11); - } - - @Test - public void testCombineExisting() throws Exception { - final NetworkStats stats = new NetworkStats(TEST_START, 10); - - stats.insertEntry(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10); - stats.insertEntry(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2); - stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L, - -128L, -1L, -1); - - assertValues(stats, 0, TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 384L, 3L, 128L, 1L, 9); - assertValues(stats, 1, TEST_IFACE, 1001, SET_DEFAULT, 0xff, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 128L, 1L, 128L, 1L, 2); - - // now try combining that should create row - stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3); - assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 128L, 1L, 128L, 1L, 3); - stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3); - assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 256L, 2L, 256L, 2L, 6); - } - - @Test - public void testSubtractIdenticalData() throws Exception { - final NetworkStats before = new NetworkStats(TEST_START, 2) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); - - final NetworkStats after = new NetworkStats(TEST_START, 2) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); - - final NetworkStats result = after.subtract(before); - - // identical data should result in zero delta - assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0); - assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0); - } - - @Test - public void testSubtractIdenticalRows() throws Exception { - final NetworkStats before = new NetworkStats(TEST_START, 2) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); - - final NetworkStats after = new NetworkStats(TEST_START, 2) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1025L, 9L, 2L, 1L, 15) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 1028L, 9L, 20); - - final NetworkStats result = after.subtract(before); - - // expect delta between measurements - assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1L, 1L, 2L, 1L, 4); - assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 3L, 1L, 4L, 1L, 8); - } - - @Test - public void testSubtractNewRows() throws Exception { - final NetworkStats before = new NetworkStats(TEST_START, 2) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); - - final NetworkStats after = new NetworkStats(TEST_START, 3) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12) - .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20); - - final NetworkStats result = after.subtract(before); - - // its okay to have new rows - assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0); - assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0); - assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1024L, 8L, 1024L, 8L, 20); - } - - @Test - public void testSubtractMissingRows() throws Exception { - final NetworkStats before = new NetworkStats(TEST_START, 2) - .insertEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0) - .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2048L, 0L, 0L, 0L, 0); - - final NetworkStats after = new NetworkStats(TEST_START, 1) - .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2049L, 2L, 3L, 4L, 0); - - final NetworkStats result = after.subtract(before); - - // should silently drop omitted rows - assertEquals(1, result.size()); - assertValues(result, 0, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 1L, 2L, 3L, 4L, 0); - assertEquals(4L, result.getTotalBytes()); - } - - @Test - public void testTotalBytes() throws Exception { - final NetworkStats iface = new NetworkStats(TEST_START, 2) - .insertEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 256L, 0L, 0L, 0L, 0L); - assertEquals(384L, iface.getTotalBytes()); - - final NetworkStats uidSet = new NetworkStats(TEST_START, 3) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L); - assertEquals(96L, uidSet.getTotalBytes()); - - final NetworkStats uidTag = new NetworkStats(TEST_START, 6) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L); - assertEquals(64L, uidTag.getTotalBytes()); - - final NetworkStats uidMetered = new NetworkStats(TEST_START, 3) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L); - assertEquals(96L, uidMetered.getTotalBytes()); - - final NetworkStats uidRoaming = new NetworkStats(TEST_START, 3) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, - DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L); - assertEquals(96L, uidRoaming.getTotalBytes()); - } - - @Test - public void testGroupedByIfaceEmpty() throws Exception { - final NetworkStats uidStats = new NetworkStats(TEST_START, 3); - final NetworkStats grouped = uidStats.groupedByIface(); - - assertEquals(0, uidStats.size()); - assertEquals(0, grouped.size()); - } - - @Test - public void testGroupedByIfaceAll() throws Exception { - final NetworkStats uidStats = new NetworkStats(TEST_START, 3) - .insertEntry(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L) - .insertEntry(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_NO, 128L, 8L, 0L, 2L, 20L) - .insertEntry(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES, - DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L); - final NetworkStats grouped = uidStats.groupedByIface(); - - assertEquals(3, uidStats.size()); - assertEquals(1, grouped.size()); - - assertValues(grouped, 0, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL, 384L, 24L, 0L, 6L, 0L); - } - - @Test - public void testGroupedByIface() throws Exception { - final NetworkStats uidStats = new NetworkStats(TEST_START, 7) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L) - .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 64L, 4L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, - DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L); - - final NetworkStats grouped = uidStats.groupedByIface(); - - assertEquals(7, uidStats.size()); - - assertEquals(2, grouped.size()); - assertValues(grouped, 0, TEST_IFACE, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL, 384L, 24L, 0L, 2L, 0L); - assertValues(grouped, 1, TEST_IFACE2, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL, 1024L, 64L, 0L, 0L, 0L); - } - - @Test - public void testAddAllValues() { - final NetworkStats first = new NetworkStats(TEST_START, 5) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, - DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L); - - final NetworkStats second = new NetworkStats(TEST_START, 2) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, - DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L); - - first.combineAllValues(second); - - assertEquals(4, first.size()); - assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_YES, 64L, 0L, 0L, 0L, 0L); - assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L); - assertValues(first, 2, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, - DEFAULT_NETWORK_YES, 64L, 0L, 0L, 0L, 0L); - assertValues(first, 3, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L); - } - - @Test - public void testGetTotal() { - final NetworkStats stats = new NetworkStats(TEST_START, 7) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L) - .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 64L, 4L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 512L,32L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, - DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L); - - assertValues(stats.getTotal(null), 1408L, 88L, 0L, 2L, 20L); - assertValues(stats.getTotal(null, 100), 1280L, 80L, 0L, 2L, 20L); - assertValues(stats.getTotal(null, 101), 128L, 8L, 0L, 0L, 0L); - - final HashSet<String> ifaces = Sets.newHashSet(); - assertValues(stats.getTotal(null, ifaces), 0L, 0L, 0L, 0L, 0L); - - ifaces.add(TEST_IFACE2); - assertValues(stats.getTotal(null, ifaces), 1024L, 64L, 0L, 0L, 0L); - } - - @Test - public void testRemoveUids() throws Exception { - final NetworkStats before = new NetworkStats(TEST_START, 3); - - // Test 0 item stats. - NetworkStats after = before.clone(); - after.removeUids(new int[0]); - assertEquals(0, after.size()); - after.removeUids(new int[] {100}); - assertEquals(0, after.size()); - - // Test 1 item stats. - before.insertEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, 1L, 128L, 0L, 2L, 20L); - after = before.clone(); - after.removeUids(new int[0]); - assertEquals(1, after.size()); - assertValues(after, 0, TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1L, 128L, 0L, 2L, 20L); - after.removeUids(new int[] {99}); - assertEquals(0, after.size()); - - // Append remaining test items. - before.insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 2L, 64L, 0L, 2L, 20L) - .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 4L, 32L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 16L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 8L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 4L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 64L, 2L, 0L, 0L, 0L); - assertEquals(7, before.size()); - - // Test remove with empty uid list. - after = before.clone(); - after.removeUids(new int[0]); - assertValues(after.getTotalIncludingTags(null), 127L, 254L, 0L, 4L, 40L); - - // Test remove uids don't exist in stats. - after.removeUids(new int[] {98, 0, Integer.MIN_VALUE, Integer.MAX_VALUE}); - assertValues(after.getTotalIncludingTags(null), 127L, 254L, 0L, 4L, 40L); - - // Test remove all uids. - after.removeUids(new int[] {99, 100, 100, 101}); - assertEquals(0, after.size()); - - // Test remove in the middle. - after = before.clone(); - after.removeUids(new int[] {100}); - assertEquals(3, after.size()); - assertValues(after, 0, TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1L, 128L, 0L, 2L, 20L); - assertValues(after, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 32L, 4L, 0L, 0L, 0L); - assertValues(after, 2, TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 64L, 2L, 0L, 0L, 0L); - } - - @Test - public void testRemoveEmptyEntries() throws Exception { - // Test empty stats. - final NetworkStats statsEmpty = new NetworkStats(TEST_START, 3); - assertEquals(0, statsEmpty.removeEmptyEntries().size()); - - // Test stats with non-zero entry. - final NetworkStats statsNonZero = new NetworkStats(TEST_START, 1) - .insertEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 1L, 128L, 0L, 2L, 20L); - assertEquals(1, statsNonZero.size()); - final NetworkStats expectedNonZero = statsNonZero.removeEmptyEntries(); - assertEquals(1, expectedNonZero.size()); - assertValues(expectedNonZero, 0, TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 1L, 128L, 0L, 2L, 20L); - - // Test stats with empty entry. - final NetworkStats statsZero = new NetworkStats(TEST_START, 1) - .insertEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L); - assertEquals(1, statsZero.size()); - final NetworkStats expectedZero = statsZero.removeEmptyEntries(); - assertEquals(1, statsZero.size()); // Assert immutable. - assertEquals(0, expectedZero.size()); - - // Test stats with multiple entries. - final NetworkStats statsMultiple = new NetworkStats(TEST_START, 0) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 2L, 64L, 0L, 2L, 20L) - .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 4L, 32L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 0L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 0L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 0L, 8L, 0L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 4L, 0L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 0L, 0L, 0L, 2L, 0L) - .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 0L, 0L, 0L, 0L, 1L); - assertEquals(9, statsMultiple.size()); - final NetworkStats expectedMultiple = statsMultiple.removeEmptyEntries(); - assertEquals(9, statsMultiple.size()); // Assert immutable. - assertEquals(7, expectedMultiple.size()); - assertValues(expectedMultiple.getTotalIncludingTags(null), 14L, 104L, 4L, 4L, 21L); - - // Test stats with multiple empty entries. - assertEquals(statsMultiple.size(), statsMultiple.subtract(statsMultiple).size()); - assertEquals(0, statsMultiple.subtract(statsMultiple).removeEmptyEntries().size()); - } - - @Test - public void testClone() throws Exception { - final NetworkStats original = new NetworkStats(TEST_START, 5) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L) - .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L); - - // make clone and mutate original - final NetworkStats clone = original.clone(); - original.insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L); - - assertEquals(3, original.size()); - assertEquals(2, clone.size()); - - assertEquals(128L + 512L + 128L, original.getTotalBytes()); - assertEquals(128L + 512L, clone.getTotalBytes()); - } - - @Test - public void testAddWhenEmpty() throws Exception { - final NetworkStats red = new NetworkStats(TEST_START, -1); - final NetworkStats blue = new NetworkStats(TEST_START, 5) - .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L) - .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L); - - // We're mostly checking that we don't crash - red.combineAllValues(blue); - } - - @Test - public void testMigrateTun() throws Exception { - final int tunUid = 10030; - final String tunIface = "tun0"; - final String underlyingIface = "wlan0"; - final int testTag1 = 8888; - NetworkStats delta = new NetworkStats(TEST_START, 17) - .insertEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 39605L, 46L, 12259L, 55L, 0L) - .insertEntry(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L) - .insertEntry(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 72667L, 197L, 43909L, 241L, 0L) - .insertEntry(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 9297L, 17L, 4128L, 21L, 0L) - // VPN package also uses some traffic through unprotected network. - .insertEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 4983L, 10L, 1801L, 12L, 0L) - .insertEntry(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L) - // Tag entries - .insertEntry(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 21691L, 41L, 13820L, 51L, 0L) - .insertEntry(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1281L, 2L, 665L, 2L, 0L) - // Irrelevant entries - .insertEntry(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1685L, 5L, 2070L, 6L, 0L) - // Underlying Iface entries - .insertEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 5178L, 8L, 2139L, 11L, 0L) - .insertEntry(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L) - .insertEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 149873L, 287L, 59217L /* smaller than sum(tun0) */, - 299L /* smaller than sum(tun0) */, 0L) - .insertEntry(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L); - - delta.migrateTun(tunUid, tunIface, Arrays.asList(underlyingIface)); - assertEquals(20, delta.size()); - - // tunIface and TEST_IFACE entries are not changed. - assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 39605L, 46L, 12259L, 55L, 0L); - assertValues(delta, 1, tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L); - assertValues(delta, 2, tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 72667L, 197L, 43909L, 241L, 0L); - assertValues(delta, 3, tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 9297L, 17L, 4128L, 21L, 0L); - assertValues(delta, 4, tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 4983L, 10L, 1801L, 12L, 0L); - assertValues(delta, 5, tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L); - assertValues(delta, 6, tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 21691L, 41L, 13820L, 51L, 0L); - assertValues(delta, 7, tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1281L, 2L, 665L, 2L, 0L); - assertValues(delta, 8, TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1685L, 5L, 2070L, 6L, 0L); - - // Existing underlying Iface entries are updated - assertValues(delta, 9, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 44783L, 54L, 14178L, 62L, 0L); - assertValues(delta, 10, underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L); - - // VPN underlying Iface entries are updated - assertValues(delta, 11, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 28304L, 27L, 1L, 2L, 0L); - assertValues(delta, 12, underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L); - - // New entries are added for new application's underlying Iface traffic - assertContains(delta, underlyingIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 72667L, 197L, 43123L, 227L, 0L); - assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 9297L, 17L, 4054, 19L, 0L); - assertContains(delta, underlyingIface, 10120, SET_DEFAULT, testTag1, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 21691L, 41L, 13572L, 48L, 0L); - assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 1281L, 2L, 653L, 1L, 0L); - - // New entries are added for debug purpose - assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 39605L, 46L, 12039, 51, 0); - assertContains(delta, underlyingIface, 10120, SET_DBG_VPN_IN, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 81964, 214, 47177, 246, 0); - assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, METERED_ALL, - ROAMING_ALL, DEFAULT_NETWORK_ALL, 121569, 260, 59216, 297, 0); - - } - - // Tests a case where all of the data received by the tun0 interface is echo back into the tun0 - // interface by the vpn app before it's sent out of the underlying interface. The VPN app should - // not be charged for the echoed data but it should still be charged for any extra data it sends - // via the underlying interface. - @Test - public void testMigrateTun_VpnAsLoopback() { - final int tunUid = 10030; - final String tunIface = "tun0"; - final String underlyingIface = "wlan0"; - NetworkStats delta = new NetworkStats(TEST_START, 9) - // 2 different apps sent/receive data via tun0. - .insertEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L) - .insertEntry(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 500L, 2L, 200L, 5L, 0L) - // VPN package resends data through the tunnel (with exaggerated overhead) - .insertEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 240000, 100L, 120000L, 60L, 0L) - // 1 app already has some traffic on the underlying interface, the other doesn't yet - .insertEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 1000L, 10L, 2000L, 20L, 0L) - // Traffic through the underlying interface via the vpn app. - // This test should redistribute this data correctly. - .insertEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 75500L, 37L, 130000L, 70L, 0L); - - delta.migrateTun(tunUid, tunIface, Arrays.asList(underlyingIface)); - assertEquals(9, delta.size()); - - // tunIface entries should not be changed. - assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - assertValues(delta, 1, tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 500L, 2L, 200L, 5L, 0L); - assertValues(delta, 2, tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 240000L, 100L, 120000L, 60L, 0L); - - // Existing underlying Iface entries are updated - assertValues(delta, 3, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 51000L, 35L, 102000L, 70L, 0L); - - // VPN underlying Iface entries are updated - assertValues(delta, 4, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 25000L, 10L, 29800L, 15L, 0L); - - // New entries are added for new application's underlying Iface traffic - assertContains(delta, underlyingIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 500L, 2L, 200L, 5L, 0L); - - // New entries are added for debug purpose - assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - assertContains(delta, underlyingIface, 20100, SET_DBG_VPN_IN, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, 500, 2L, 200L, 5L, 0L); - assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, METERED_ALL, - ROAMING_ALL, DEFAULT_NETWORK_ALL, 50500L, 27L, 100200L, 55, 0); - } - - @Test - public void testFilter_NoFilter() { - NetworkStats.Entry entry1 = new NetworkStats.Entry( - "test1", 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats.Entry entry2 = new NetworkStats.Entry( - "test2", 10101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats.Entry entry3 = new NetworkStats.Entry( - "test2", 10101, SET_DEFAULT, 123, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats stats = new NetworkStats(TEST_START, 3) - .insertEntry(entry1) - .insertEntry(entry2) - .insertEntry(entry3); - - stats.filter(UID_ALL, INTERFACES_ALL, TAG_ALL); - assertEquals(3, stats.size()); - assertEquals(entry1, stats.getValues(0, null)); - assertEquals(entry2, stats.getValues(1, null)); - assertEquals(entry3, stats.getValues(2, null)); - } - - @Test - public void testFilter_UidFilter() { - final int testUid = 10101; - NetworkStats.Entry entry1 = new NetworkStats.Entry( - "test1", 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats.Entry entry2 = new NetworkStats.Entry( - "test2", testUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats.Entry entry3 = new NetworkStats.Entry( - "test2", testUid, SET_DEFAULT, 123, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats stats = new NetworkStats(TEST_START, 3) - .insertEntry(entry1) - .insertEntry(entry2) - .insertEntry(entry3); - - stats.filter(testUid, INTERFACES_ALL, TAG_ALL); - assertEquals(2, stats.size()); - assertEquals(entry2, stats.getValues(0, null)); - assertEquals(entry3, stats.getValues(1, null)); - } - - @Test - public void testFilter_InterfaceFilter() { - final String testIf1 = "testif1"; - final String testIf2 = "testif2"; - NetworkStats.Entry entry1 = new NetworkStats.Entry( - testIf1, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats.Entry entry2 = new NetworkStats.Entry( - "otherif", 10101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats.Entry entry3 = new NetworkStats.Entry( - testIf1, 10101, SET_DEFAULT, 123, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats.Entry entry4 = new NetworkStats.Entry( - testIf2, 10101, SET_DEFAULT, 123, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats stats = new NetworkStats(TEST_START, 4) - .insertEntry(entry1) - .insertEntry(entry2) - .insertEntry(entry3) - .insertEntry(entry4); - - stats.filter(UID_ALL, new String[] { testIf1, testIf2 }, TAG_ALL); - assertEquals(3, stats.size()); - assertEquals(entry1, stats.getValues(0, null)); - assertEquals(entry3, stats.getValues(1, null)); - assertEquals(entry4, stats.getValues(2, null)); - } - - @Test - public void testFilter_EmptyInterfaceFilter() { - NetworkStats.Entry entry1 = new NetworkStats.Entry( - "if1", 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats.Entry entry2 = new NetworkStats.Entry( - "if2", 10101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats stats = new NetworkStats(TEST_START, 3) - .insertEntry(entry1) - .insertEntry(entry2); - - stats.filter(UID_ALL, new String[] { }, TAG_ALL); - assertEquals(0, stats.size()); - } - - @Test - public void testFilter_TagFilter() { - final int testTag = 123; - final int otherTag = 456; - NetworkStats.Entry entry1 = new NetworkStats.Entry( - "test1", 10100, SET_DEFAULT, testTag, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats.Entry entry2 = new NetworkStats.Entry( - "test2", 10101, SET_DEFAULT, testTag, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats.Entry entry3 = new NetworkStats.Entry( - "test2", 10101, SET_DEFAULT, otherTag, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats stats = new NetworkStats(TEST_START, 3) - .insertEntry(entry1) - .insertEntry(entry2) - .insertEntry(entry3); - - stats.filter(UID_ALL, INTERFACES_ALL, testTag); - assertEquals(2, stats.size()); - assertEquals(entry1, stats.getValues(0, null)); - assertEquals(entry2, stats.getValues(1, null)); - } - - @Test - public void testFilterDebugEntries() { - NetworkStats.Entry entry1 = new NetworkStats.Entry( - "test1", 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats.Entry entry2 = new NetworkStats.Entry( - "test2", 10101, SET_DBG_VPN_IN, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats.Entry entry3 = new NetworkStats.Entry( - "test2", 10101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats.Entry entry4 = new NetworkStats.Entry( - "test2", 10101, SET_DBG_VPN_OUT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); - - NetworkStats stats = new NetworkStats(TEST_START, 4) - .insertEntry(entry1) - .insertEntry(entry2) - .insertEntry(entry3) - .insertEntry(entry4); - - stats.filterDebugEntries(); - - assertEquals(2, stats.size()); - assertEquals(entry1, stats.getValues(0, null)); - assertEquals(entry3, stats.getValues(1, null)); - } - - @Test - public void testApply464xlatAdjustments() { - final String v4Iface = "v4-wlan0"; - final String baseIface = "wlan0"; - final String otherIface = "other"; - final int appUid = 10001; - final int rootUid = Process.ROOT_UID; - ArrayMap<String, String> stackedIface = new ArrayMap<>(); - stackedIface.put(v4Iface, baseIface); - - // Ipv4 traffic sent/received by an app on stacked interface. - final NetworkStats.Entry appEntry = new NetworkStats.Entry( - v4Iface, appUid, SET_DEFAULT, TAG_NONE, - 30501490 /* rxBytes */, - 22401 /* rxPackets */, - 876235 /* txBytes */, - 13805 /* txPackets */, - 0 /* operations */); - - // Traffic measured for the root uid on the base interface. - final NetworkStats.Entry rootUidEntry = new NetworkStats.Entry( - baseIface, rootUid, SET_DEFAULT, TAG_NONE, - 163577 /* rxBytes */, - 187 /* rxPackets */, - 17607 /* txBytes */, - 97 /* txPackets */, - 0 /* operations */); - - final NetworkStats.Entry otherEntry = new NetworkStats.Entry( - otherIface, appUid, SET_DEFAULT, TAG_NONE, - 2600 /* rxBytes */, - 2 /* rxPackets */, - 3800 /* txBytes */, - 3 /* txPackets */, - 0 /* operations */); - - final NetworkStats stats = new NetworkStats(TEST_START, 3) - .insertEntry(appEntry) - .insertEntry(rootUidEntry) - .insertEntry(otherEntry); - - stats.apply464xlatAdjustments(stackedIface); - - assertEquals(3, stats.size()); - final NetworkStats.Entry expectedAppUid = new NetworkStats.Entry( - v4Iface, appUid, SET_DEFAULT, TAG_NONE, - 30949510, - 22401, - 1152335, - 13805, - 0); - final NetworkStats.Entry expectedRootUid = new NetworkStats.Entry( - baseIface, 0, SET_DEFAULT, TAG_NONE, - 163577, - 187, - 17607, - 97, - 0); - assertEquals(expectedAppUid, stats.getValues(0, null)); - assertEquals(expectedRootUid, stats.getValues(1, null)); - assertEquals(otherEntry, stats.getValues(2, null)); - } - - @Test - public void testApply464xlatAdjustments_noStackedIface() { - NetworkStats.Entry firstEntry = new NetworkStats.Entry( - "if1", 10002, SET_DEFAULT, TAG_NONE, - 2600 /* rxBytes */, - 2 /* rxPackets */, - 3800 /* txBytes */, - 3 /* txPackets */, - 0 /* operations */); - NetworkStats.Entry secondEntry = new NetworkStats.Entry( - "if2", 10002, SET_DEFAULT, TAG_NONE, - 5000 /* rxBytes */, - 3 /* rxPackets */, - 6000 /* txBytes */, - 4 /* txPackets */, - 0 /* operations */); - - NetworkStats stats = new NetworkStats(TEST_START, 2) - .insertEntry(firstEntry) - .insertEntry(secondEntry); - - // Empty map: no adjustment - stats.apply464xlatAdjustments(new ArrayMap<>()); - - assertEquals(2, stats.size()); - assertEquals(firstEntry, stats.getValues(0, null)); - assertEquals(secondEntry, stats.getValues(1, null)); - } - - private static void assertContains(NetworkStats stats, String iface, int uid, int set, - int tag, int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets, - long txBytes, long txPackets, long operations) { - int index = stats.findIndex(iface, uid, set, tag, metered, roaming, defaultNetwork); - assertTrue(index != -1); - assertValues(stats, index, iface, uid, set, tag, metered, roaming, defaultNetwork, - rxBytes, rxPackets, txBytes, txPackets, operations); - } - - private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set, - int tag, int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets, - long txBytes, long txPackets, long operations) { - final NetworkStats.Entry entry = stats.getValues(index, null); - assertValues(entry, iface, uid, set, tag, metered, roaming, defaultNetwork); - assertValues(entry, rxBytes, rxPackets, txBytes, txPackets, operations); - } - - private static void assertValues( - NetworkStats.Entry entry, String iface, int uid, int set, int tag, int metered, - int roaming, int defaultNetwork) { - assertEquals(iface, entry.iface); - assertEquals(uid, entry.uid); - assertEquals(set, entry.set); - assertEquals(tag, entry.tag); - assertEquals(metered, entry.metered); - assertEquals(roaming, entry.roaming); - assertEquals(defaultNetwork, entry.defaultNetwork); - } - - private static void assertValues(NetworkStats.Entry entry, long rxBytes, long rxPackets, - long txBytes, long txPackets, long operations) { - assertEquals(rxBytes, entry.rxBytes); - assertEquals(rxPackets, entry.rxPackets); - assertEquals(txBytes, entry.txBytes); - assertEquals(txPackets, entry.txPackets); - assertEquals(operations, entry.operations); - } - -} diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/tests/net/java/android/net/NetworkTemplateTest.kt deleted file mode 100644 index ab6b2f409867..000000000000 --- a/tests/net/java/android/net/NetworkTemplateTest.kt +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net - -import android.content.Context -import android.net.ConnectivityManager.TYPE_MOBILE -import android.net.ConnectivityManager.TYPE_WIFI -import android.net.NetworkIdentity.SUBTYPE_COMBINED -import android.net.NetworkIdentity.OEM_NONE -import android.net.NetworkIdentity.OEM_PAID -import android.net.NetworkIdentity.OEM_PRIVATE -import android.net.NetworkIdentity.buildNetworkIdentity -import android.net.NetworkStats.DEFAULT_NETWORK_ALL -import android.net.NetworkStats.METERED_ALL -import android.net.NetworkStats.ROAMING_ALL -import android.net.NetworkTemplate.MATCH_MOBILE -import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD -import android.net.NetworkTemplate.MATCH_WIFI -import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD -import android.net.NetworkTemplate.WIFI_NETWORKID_ALL -import android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA -import android.net.NetworkTemplate.NETWORK_TYPE_ALL -import android.net.NetworkTemplate.OEM_MANAGED_ALL -import android.net.NetworkTemplate.OEM_MANAGED_NO -import android.net.NetworkTemplate.OEM_MANAGED_YES -import android.net.NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT -import android.net.NetworkTemplate.buildTemplateWifi -import android.net.NetworkTemplate.buildTemplateWifiWildcard -import android.net.NetworkTemplate.buildTemplateCarrier -import android.net.NetworkTemplate.buildTemplateMobileWithRatType -import android.telephony.TelephonyManager -import com.android.testutils.assertParcelSane -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import org.mockito.Mockito.mock -import org.mockito.MockitoAnnotations -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertNotEquals -import kotlin.test.assertTrue - -private const val TEST_IMSI1 = "imsi1" -private const val TEST_IMSI2 = "imsi2" -private const val TEST_SSID1 = "ssid1" -private const val TEST_SSID2 = "ssid2" - -@RunWith(JUnit4::class) -class NetworkTemplateTest { - private val mockContext = mock(Context::class.java) - - private fun buildMobileNetworkState(subscriberId: String): NetworkStateSnapshot = - buildNetworkState(TYPE_MOBILE, subscriberId = subscriberId) - private fun buildWifiNetworkState(subscriberId: String?, ssid: String?): NetworkStateSnapshot = - buildNetworkState(TYPE_WIFI, subscriberId = subscriberId, ssid = ssid) - - private fun buildNetworkState( - type: Int, - subscriberId: String? = null, - ssid: String? = null, - oemManaged: Int = OEM_NONE - ): NetworkStateSnapshot { - val lp = LinkProperties() - val caps = NetworkCapabilities().apply { - setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false) - setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true) - setSSID(ssid) - setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, - (oemManaged and OEM_PAID) == OEM_PAID) - setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, - (oemManaged and OEM_PRIVATE) == OEM_PRIVATE) - } - return NetworkStateSnapshot(mock(Network::class.java), caps, lp, subscriberId, type) - } - - private fun NetworkTemplate.assertMatches(ident: NetworkIdentity) = - assertTrue(matches(ident), "$this does not match $ident") - - private fun NetworkTemplate.assertDoesNotMatch(ident: NetworkIdentity) = - assertFalse(matches(ident), "$this should match $ident") - - @Before - fun setup() { - MockitoAnnotations.initMocks(this) - } - - @Test - fun testWifiWildcardMatches() { - val templateWifiWildcard = buildTemplateWifiWildcard() - - val identMobileImsi1 = buildNetworkIdentity(mockContext, - buildMobileNetworkState(TEST_IMSI1), - false, TelephonyManager.NETWORK_TYPE_UMTS) - val identWifiImsiNullSsid1 = buildNetworkIdentity( - mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0) - val identWifiImsi1Ssid1 = buildNetworkIdentity( - mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0) - - templateWifiWildcard.assertDoesNotMatch(identMobileImsi1) - templateWifiWildcard.assertMatches(identWifiImsiNullSsid1) - templateWifiWildcard.assertMatches(identWifiImsi1Ssid1) - } - - @Test - fun testWifiMatches() { - val templateWifiSsid1 = buildTemplateWifi(TEST_SSID1) - val templateWifiSsid1ImsiNull = buildTemplateWifi(TEST_SSID1, null) - val templateWifiSsid1Imsi1 = buildTemplateWifi(TEST_SSID1, TEST_IMSI1) - val templateWifiSsidAllImsi1 = buildTemplateWifi(WIFI_NETWORKID_ALL, TEST_IMSI1) - - val identMobile1 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI1), - false, TelephonyManager.NETWORK_TYPE_UMTS) - val identWifiImsiNullSsid1 = buildNetworkIdentity( - mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0) - val identWifiImsi1Ssid1 = buildNetworkIdentity( - mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0) - val identWifiImsi2Ssid1 = buildNetworkIdentity( - mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_SSID1), true, 0) - val identWifiImsi1Ssid2 = buildNetworkIdentity( - mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID2), true, 0) - - // Verify that template with SSID only matches any subscriberId and specific SSID. - templateWifiSsid1.assertDoesNotMatch(identMobile1) - templateWifiSsid1.assertMatches(identWifiImsiNullSsid1) - templateWifiSsid1.assertMatches(identWifiImsi1Ssid1) - templateWifiSsid1.assertMatches(identWifiImsi2Ssid1) - templateWifiSsid1.assertDoesNotMatch(identWifiImsi1Ssid2) - - // Verify that template with SSID1 and null imsi matches any network with - // SSID1 and null imsi. - templateWifiSsid1ImsiNull.assertDoesNotMatch(identMobile1) - templateWifiSsid1ImsiNull.assertMatches(identWifiImsiNullSsid1) - templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi1Ssid1) - templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi2Ssid1) - templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi1Ssid2) - - // Verify that template with SSID1 and imsi1 matches any network with - // SSID1 and imsi1. - templateWifiSsid1Imsi1.assertDoesNotMatch(identMobile1) - templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsiNullSsid1) - templateWifiSsid1Imsi1.assertMatches(identWifiImsi1Ssid1) - templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsi2Ssid1) - templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsi1Ssid2) - - // Verify that template with SSID all and imsi1 matches any network with - // any SSID and imsi1. - templateWifiSsidAllImsi1.assertDoesNotMatch(identMobile1) - templateWifiSsidAllImsi1.assertDoesNotMatch(identWifiImsiNullSsid1) - templateWifiSsidAllImsi1.assertMatches(identWifiImsi1Ssid1) - templateWifiSsidAllImsi1.assertDoesNotMatch(identWifiImsi2Ssid1) - templateWifiSsidAllImsi1.assertMatches(identWifiImsi1Ssid2) - } - - @Test - fun testCarrierMatches() { - val templateCarrierImsi1 = buildTemplateCarrier(TEST_IMSI1) - - val identMobile1 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI1), - false, TelephonyManager.NETWORK_TYPE_UMTS) - val identMobile2 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI2), - false, TelephonyManager.NETWORK_TYPE_UMTS) - val identWifiSsid1 = buildNetworkIdentity( - mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0) - val identCarrierWifiImsi1 = buildNetworkIdentity( - mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0) - val identCarrierWifiImsi2 = buildNetworkIdentity( - mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_SSID1), true, 0) - - templateCarrierImsi1.assertMatches(identCarrierWifiImsi1) - templateCarrierImsi1.assertDoesNotMatch(identCarrierWifiImsi2) - templateCarrierImsi1.assertDoesNotMatch(identWifiSsid1) - templateCarrierImsi1.assertMatches(identMobile1) - templateCarrierImsi1.assertDoesNotMatch(identMobile2) - } - - @Test - fun testRatTypeGroupMatches() { - val stateMobile = buildMobileNetworkState(TEST_IMSI1) - // Build UMTS template that matches mobile identities with RAT in the same - // group with any IMSI. See {@link NetworkTemplate#getCollapsedRatType}. - val templateUmts = buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UMTS) - // Build normal template that matches mobile identities with any RAT and IMSI. - val templateAll = buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL) - // Build template with UNKNOWN RAT that matches mobile identities with RAT that - // cannot be determined. - val templateUnknown = - buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UNKNOWN) - - val identUmts = buildNetworkIdentity( - mockContext, stateMobile, false, TelephonyManager.NETWORK_TYPE_UMTS) - val identHsdpa = buildNetworkIdentity( - mockContext, stateMobile, false, TelephonyManager.NETWORK_TYPE_HSDPA) - val identLte = buildNetworkIdentity( - mockContext, stateMobile, false, TelephonyManager.NETWORK_TYPE_LTE) - val identCombined = buildNetworkIdentity( - mockContext, stateMobile, false, SUBTYPE_COMBINED) - val identImsi2 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI2), - false, TelephonyManager.NETWORK_TYPE_UMTS) - val identWifi = buildNetworkIdentity( - mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0) - - // Assert that identity with the same RAT matches. - templateUmts.assertMatches(identUmts) - templateAll.assertMatches(identUmts) - templateUnknown.assertDoesNotMatch(identUmts) - // Assert that identity with the RAT within the same group matches. - templateUmts.assertMatches(identHsdpa) - templateAll.assertMatches(identHsdpa) - templateUnknown.assertDoesNotMatch(identHsdpa) - // Assert that identity with the RAT out of the same group only matches template with - // NETWORK_TYPE_ALL. - templateUmts.assertDoesNotMatch(identLte) - templateAll.assertMatches(identLte) - templateUnknown.assertDoesNotMatch(identLte) - // Assert that identity with combined RAT only matches with template with NETWORK_TYPE_ALL - // and NETWORK_TYPE_UNKNOWN. - templateUmts.assertDoesNotMatch(identCombined) - templateAll.assertMatches(identCombined) - templateUnknown.assertMatches(identCombined) - // Assert that identity with different IMSI matches. - templateUmts.assertMatches(identImsi2) - templateAll.assertMatches(identImsi2) - templateUnknown.assertDoesNotMatch(identImsi2) - // Assert that wifi identity does not match. - templateUmts.assertDoesNotMatch(identWifi) - templateAll.assertDoesNotMatch(identWifi) - templateUnknown.assertDoesNotMatch(identWifi) - } - - @Test - fun testParcelUnparcel() { - val templateMobile = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1, null, null, METERED_ALL, - ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE, - OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT) - val templateWifi = NetworkTemplate(MATCH_WIFI, null, null, TEST_SSID1, METERED_ALL, - ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_ALL, - SUBSCRIBER_ID_MATCH_RULE_EXACT) - val templateOem = NetworkTemplate(MATCH_MOBILE, null, null, null, METERED_ALL, - ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_YES, - SUBSCRIBER_ID_MATCH_RULE_EXACT) - assertParcelSane(templateMobile, 10) - assertParcelSane(templateWifi, 10) - assertParcelSane(templateOem, 10) - } - - // Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with - // TelephonyManager#NETWORK_TYPE_* constants. - @Test - fun testNetworkTypeConstants() { - for (ratType in TelephonyManager.getAllNetworkTypes()) { - assertNotEquals(NETWORK_TYPE_ALL, ratType) - assertNotEquals(NETWORK_TYPE_5G_NSA, ratType) - } - } - - @Test - fun testOemNetworkConstants() { - val constantValues = arrayOf(OEM_MANAGED_YES, OEM_MANAGED_ALL, OEM_MANAGED_NO, - OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE) - - // Verify that "not OEM managed network" constants are equal. - assertEquals(OEM_MANAGED_NO, OEM_NONE) - - // Verify the constants don't conflict. - assertEquals(constantValues.size, constantValues.distinct().count()) - } - - /** - * Helper to enumerate and assert OEM managed wifi and mobile {@code NetworkTemplate}s match - * their the appropriate OEM managed {@code NetworkIdentity}s. - * - * @param networkType {@code TYPE_MOBILE} or {@code TYPE_WIFI} - * @param matchType A match rule from {@code NetworkTemplate.MATCH_*} corresponding to the - * networkType. - * @param subscriberId To be populated with {@code TEST_IMSI*} only if networkType is - * {@code TYPE_MOBILE}. May be left as null when matchType is - * {@link NetworkTemplate.MATCH_MOBILE_WILDCARD}. - * @param templateSsid Top be populated with {@code TEST_SSID*} only if networkType is - * {@code TYPE_WIFI}. May be left as null when matchType is - * {@link NetworkTemplate.MATCH_WIFI_WILDCARD}. - * @param identSsid If networkType is {@code TYPE_WIFI}, this value must *NOT* be null. Provide - * one of {@code TEST_SSID*}. - */ - private fun matchOemManagedIdent( - networkType: Int, - matchType: Int, - subscriberId: String? = null, - templateSsid: String? = null, - identSsid: String? = null - ) { - val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE) - val matchSubscriberIds = arrayOf(subscriberId) - - val templateOemYes = NetworkTemplate(matchType, subscriberId, matchSubscriberIds, - templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, - OEM_MANAGED_YES, SUBSCRIBER_ID_MATCH_RULE_EXACT) - val templateOemAll = NetworkTemplate(matchType, subscriberId, matchSubscriberIds, - templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, - OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT) - - for (identityOemManagedState in oemManagedStates) { - val ident = buildNetworkIdentity(mockContext, buildNetworkState(networkType, - subscriberId, identSsid, identityOemManagedState), /*defaultNetwork=*/false, - /*subType=*/0) - - // Create a template with each OEM managed type and match it against the NetworkIdentity - for (templateOemManagedState in oemManagedStates) { - val template = NetworkTemplate(matchType, subscriberId, matchSubscriberIds, - templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, - NETWORK_TYPE_ALL, templateOemManagedState, SUBSCRIBER_ID_MATCH_RULE_EXACT) - if (identityOemManagedState == templateOemManagedState) { - template.assertMatches(ident) - } else { - template.assertDoesNotMatch(ident) - } - } - // OEM_MANAGED_ALL ignores OEM state. - templateOemAll.assertMatches(ident) - if (identityOemManagedState == OEM_NONE) { - // OEM_MANAGED_YES matches everything except OEM_NONE. - templateOemYes.assertDoesNotMatch(ident) - } else { - templateOemYes.assertMatches(ident) - } - } - } - - @Test - fun testOemManagedMatchesIdent() { - matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE, subscriberId = TEST_IMSI1) - matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE_WILDCARD) - matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI, templateSsid = TEST_SSID1, - identSsid = TEST_SSID1) - matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI_WILDCARD, identSsid = TEST_SSID1) - } -} diff --git a/tests/net/java/android/net/NetworkUtilsTest.java b/tests/net/java/android/net/NetworkUtilsTest.java deleted file mode 100644 index 7748288aeb05..000000000000 --- a/tests/net/java/android/net/NetworkUtilsTest.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static junit.framework.Assert.assertEquals; - -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.math.BigInteger; -import java.util.TreeSet; - -@RunWith(AndroidJUnit4.class) -@androidx.test.filters.SmallTest -public class NetworkUtilsTest { - @Test - public void testRoutedIPv4AddressCount() { - final TreeSet<IpPrefix> set = new TreeSet<>(IpPrefix.lengthComparator()); - // No routes routes to no addresses. - assertEquals(0, NetworkUtils.routedIPv4AddressCount(set)); - - set.add(new IpPrefix("0.0.0.0/0")); - assertEquals(1l << 32, NetworkUtils.routedIPv4AddressCount(set)); - - set.add(new IpPrefix("20.18.0.0/16")); - set.add(new IpPrefix("20.18.0.0/24")); - set.add(new IpPrefix("20.18.0.0/8")); - // There is a default route, still covers everything - assertEquals(1l << 32, NetworkUtils.routedIPv4AddressCount(set)); - - set.clear(); - set.add(new IpPrefix("20.18.0.0/24")); - set.add(new IpPrefix("20.18.0.0/8")); - // The 8-length includes the 24-length prefix - assertEquals(1l << 24, NetworkUtils.routedIPv4AddressCount(set)); - - set.add(new IpPrefix("10.10.10.126/25")); - // The 8-length does not include this 25-length prefix - assertEquals((1l << 24) + (1 << 7), NetworkUtils.routedIPv4AddressCount(set)); - - set.clear(); - set.add(new IpPrefix("1.2.3.4/32")); - set.add(new IpPrefix("1.2.3.4/32")); - set.add(new IpPrefix("1.2.3.4/32")); - set.add(new IpPrefix("1.2.3.4/32")); - assertEquals(1l, NetworkUtils.routedIPv4AddressCount(set)); - - set.add(new IpPrefix("1.2.3.5/32")); - set.add(new IpPrefix("1.2.3.6/32")); - - set.add(new IpPrefix("1.2.3.7/32")); - set.add(new IpPrefix("1.2.3.8/32")); - set.add(new IpPrefix("1.2.3.9/32")); - set.add(new IpPrefix("1.2.3.0/32")); - assertEquals(7l, NetworkUtils.routedIPv4AddressCount(set)); - - // 1.2.3.4/30 eats 1.2.3.{4-7}/32 - set.add(new IpPrefix("1.2.3.4/30")); - set.add(new IpPrefix("6.2.3.4/28")); - set.add(new IpPrefix("120.2.3.4/16")); - assertEquals(7l - 4 + 4 + 16 + 65536, NetworkUtils.routedIPv4AddressCount(set)); - } - - @Test - public void testRoutedIPv6AddressCount() { - final TreeSet<IpPrefix> set = new TreeSet<>(IpPrefix.lengthComparator()); - // No routes routes to no addresses. - assertEquals(BigInteger.ZERO, NetworkUtils.routedIPv6AddressCount(set)); - - set.add(new IpPrefix("::/0")); - assertEquals(BigInteger.ONE.shiftLeft(128), NetworkUtils.routedIPv6AddressCount(set)); - - set.add(new IpPrefix("1234:622a::18/64")); - set.add(new IpPrefix("add4:f00:80:f7:1111::6adb/96")); - set.add(new IpPrefix("add4:f00:80:f7:1111::6adb/8")); - // There is a default route, still covers everything - assertEquals(BigInteger.ONE.shiftLeft(128), NetworkUtils.routedIPv6AddressCount(set)); - - set.clear(); - set.add(new IpPrefix("add4:f00:80:f7:1111::6adb/96")); - set.add(new IpPrefix("add4:f00:80:f7:1111::6adb/8")); - // The 8-length includes the 96-length prefix - assertEquals(BigInteger.ONE.shiftLeft(120), NetworkUtils.routedIPv6AddressCount(set)); - - set.add(new IpPrefix("10::26/64")); - // The 8-length does not include this 64-length prefix - assertEquals(BigInteger.ONE.shiftLeft(120).add(BigInteger.ONE.shiftLeft(64)), - NetworkUtils.routedIPv6AddressCount(set)); - - set.clear(); - set.add(new IpPrefix("add4:f00:80:f7:1111::6ad4/128")); - set.add(new IpPrefix("add4:f00:80:f7:1111::6ad4/128")); - set.add(new IpPrefix("add4:f00:80:f7:1111::6ad4/128")); - set.add(new IpPrefix("add4:f00:80:f7:1111::6ad4/128")); - assertEquals(BigInteger.ONE, NetworkUtils.routedIPv6AddressCount(set)); - - set.add(new IpPrefix("add4:f00:80:f7:1111::6ad5/128")); - set.add(new IpPrefix("add4:f00:80:f7:1111::6ad6/128")); - set.add(new IpPrefix("add4:f00:80:f7:1111::6ad7/128")); - set.add(new IpPrefix("add4:f00:80:f7:1111::6ad8/128")); - set.add(new IpPrefix("add4:f00:80:f7:1111::6ad9/128")); - set.add(new IpPrefix("add4:f00:80:f7:1111::6ad0/128")); - assertEquals(BigInteger.valueOf(7), NetworkUtils.routedIPv6AddressCount(set)); - - // add4:f00:80:f7:1111::6ad4/126 eats add4:f00:8[:f7:1111::6ad{4-7}/128 - set.add(new IpPrefix("add4:f00:80:f7:1111::6ad4/126")); - set.add(new IpPrefix("d00d:f00:80:f7:1111::6ade/124")); - set.add(new IpPrefix("f00b:a33::/112")); - assertEquals(BigInteger.valueOf(7l - 4 + 4 + 16 + 65536), - NetworkUtils.routedIPv6AddressCount(set)); - } -} diff --git a/tests/net/java/android/net/QosSocketFilterTest.java b/tests/net/java/android/net/QosSocketFilterTest.java deleted file mode 100644 index ad58960eaadd..000000000000 --- a/tests/net/java/android/net/QosSocketFilterTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; - -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.InetAddress; -import java.net.InetSocketAddress; - -@RunWith(AndroidJUnit4.class) -@androidx.test.filters.SmallTest -public class QosSocketFilterTest { - - @Test - public void testPortExactMatch() { - final InetAddress addressA = InetAddresses.parseNumericAddress("1.2.3.4"); - final InetAddress addressB = InetAddresses.parseNumericAddress("1.2.3.4"); - assertTrue(QosSocketFilter.matchesLocalAddress( - new InetSocketAddress(addressA, 10), addressB, 10, 10)); - - } - - @Test - public void testPortLessThanStart() { - final InetAddress addressA = InetAddresses.parseNumericAddress("1.2.3.4"); - final InetAddress addressB = InetAddresses.parseNumericAddress("1.2.3.4"); - assertFalse(QosSocketFilter.matchesLocalAddress( - new InetSocketAddress(addressA, 8), addressB, 10, 10)); - } - - @Test - public void testPortGreaterThanEnd() { - final InetAddress addressA = InetAddresses.parseNumericAddress("1.2.3.4"); - final InetAddress addressB = InetAddresses.parseNumericAddress("1.2.3.4"); - assertFalse(QosSocketFilter.matchesLocalAddress( - new InetSocketAddress(addressA, 18), addressB, 10, 10)); - } - - @Test - public void testPortBetweenStartAndEnd() { - final InetAddress addressA = InetAddresses.parseNumericAddress("1.2.3.4"); - final InetAddress addressB = InetAddresses.parseNumericAddress("1.2.3.4"); - assertTrue(QosSocketFilter.matchesLocalAddress( - new InetSocketAddress(addressA, 10), addressB, 8, 18)); - } - - @Test - public void testAddressesDontMatch() { - final InetAddress addressA = InetAddresses.parseNumericAddress("1.2.3.4"); - final InetAddress addressB = InetAddresses.parseNumericAddress("1.2.3.5"); - assertFalse(QosSocketFilter.matchesLocalAddress( - new InetSocketAddress(addressA, 10), addressB, 10, 10)); - } -} - diff --git a/tests/net/java/android/net/TelephonyNetworkSpecifierTest.java b/tests/net/java/android/net/TelephonyNetworkSpecifierTest.java deleted file mode 100644 index 6714bb1abbe6..000000000000 --- a/tests/net/java/android/net/TelephonyNetworkSpecifierTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static com.android.testutils.ParcelUtils.assertParcelSane; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.net.wifi.WifiNetworkSpecifier; -import android.telephony.SubscriptionManager; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; - -/** - * Unit test for {@link android.net.TelephonyNetworkSpecifier}. - */ -@SmallTest -public class TelephonyNetworkSpecifierTest { - private static final int TEST_SUBID = 5; - private static final String TEST_SSID = "Test123"; - - /** - * Validate that IllegalArgumentException will be thrown if build TelephonyNetworkSpecifier - * without calling {@link TelephonyNetworkSpecifier.Builder#setSubscriptionId(int)}. - */ - @Test - public void testBuilderBuildWithDefault() { - try { - new TelephonyNetworkSpecifier.Builder().build(); - } catch (IllegalArgumentException iae) { - // expected, test pass - } - } - - /** - * Validate that no exception will be thrown even if pass invalid subscription id to - * {@link TelephonyNetworkSpecifier.Builder#setSubscriptionId(int)}. - */ - @Test - public void testBuilderBuildWithInvalidSubId() { - TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier.Builder() - .setSubscriptionId(SubscriptionManager.INVALID_SUBSCRIPTION_ID) - .build(); - assertEquals(specifier.getSubscriptionId(), SubscriptionManager.INVALID_SUBSCRIPTION_ID); - } - - /** - * Validate the correctness of TelephonyNetworkSpecifier when provide valid subId. - */ - @Test - public void testBuilderBuildWithValidSubId() { - final TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier.Builder() - .setSubscriptionId(TEST_SUBID) - .build(); - assertEquals(TEST_SUBID, specifier.getSubscriptionId()); - } - - /** - * Validate that parcel marshalling/unmarshalling works. - */ - @Test - public void testParcel() { - TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier.Builder() - .setSubscriptionId(TEST_SUBID) - .build(); - assertParcelSane(specifier, 1 /* fieldCount */); - } - - /** - * Validate the behavior of method canBeSatisfiedBy(). - */ - @Test - public void testCanBeSatisfiedBy() { - final TelephonyNetworkSpecifier tns1 = new TelephonyNetworkSpecifier.Builder() - .setSubscriptionId(TEST_SUBID) - .build(); - final TelephonyNetworkSpecifier tns2 = new TelephonyNetworkSpecifier.Builder() - .setSubscriptionId(TEST_SUBID) - .build(); - final WifiNetworkSpecifier wns = new WifiNetworkSpecifier.Builder() - .setSsid(TEST_SSID) - .build(); - final MatchAllNetworkSpecifier mans = new MatchAllNetworkSpecifier(); - - // Test equality - assertEquals(tns1, tns2); - assertTrue(tns1.canBeSatisfiedBy(tns1)); - assertTrue(tns1.canBeSatisfiedBy(tns2)); - - // Test other edge cases. - assertFalse(tns1.canBeSatisfiedBy(null)); - assertFalse(tns1.canBeSatisfiedBy(wns)); - assertTrue(tns1.canBeSatisfiedBy(mans)); - } -} diff --git a/tests/net/java/android/net/VpnManagerTest.java b/tests/net/java/android/net/VpnManagerTest.java deleted file mode 100644 index 3135062138ac..000000000000 --- a/tests/net/java/android/net/VpnManagerTest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.ComponentName; -import android.content.Intent; -import android.test.mock.MockContext; -import android.util.SparseArray; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.internal.net.VpnProfile; -import com.android.internal.util.MessageUtils; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** Unit tests for {@link VpnManager}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class VpnManagerTest { - private static final String PKG_NAME = "fooPackage"; - - private static final String SESSION_NAME_STRING = "testSession"; - private static final String SERVER_ADDR_STRING = "1.2.3.4"; - private static final String IDENTITY_STRING = "Identity"; - private static final byte[] PSK_BYTES = "preSharedKey".getBytes(); - - private IVpnManager mMockService; - private VpnManager mVpnManager; - private final MockContext mMockContext = - new MockContext() { - @Override - public String getOpPackageName() { - return PKG_NAME; - } - }; - - @Before - public void setUp() throws Exception { - mMockService = mock(IVpnManager.class); - mVpnManager = new VpnManager(mMockContext, mMockService); - } - - @Test - public void testProvisionVpnProfilePreconsented() throws Exception { - final PlatformVpnProfile profile = getPlatformVpnProfile(); - when(mMockService.provisionVpnProfile(any(VpnProfile.class), eq(PKG_NAME))) - .thenReturn(true); - - // Expect there to be no intent returned, as consent has already been granted. - assertNull(mVpnManager.provisionVpnProfile(profile)); - verify(mMockService).provisionVpnProfile(eq(profile.toVpnProfile()), eq(PKG_NAME)); - } - - @Test - public void testProvisionVpnProfileNeedsConsent() throws Exception { - final PlatformVpnProfile profile = getPlatformVpnProfile(); - when(mMockService.provisionVpnProfile(any(VpnProfile.class), eq(PKG_NAME))) - .thenReturn(false); - - // Expect intent to be returned, as consent has not already been granted. - final Intent intent = mVpnManager.provisionVpnProfile(profile); - assertNotNull(intent); - - final ComponentName expectedComponentName = - ComponentName.unflattenFromString( - "com.android.vpndialogs/com.android.vpndialogs.PlatformVpnConfirmDialog"); - assertEquals(expectedComponentName, intent.getComponent()); - verify(mMockService).provisionVpnProfile(eq(profile.toVpnProfile()), eq(PKG_NAME)); - } - - @Test - public void testDeleteProvisionedVpnProfile() throws Exception { - mVpnManager.deleteProvisionedVpnProfile(); - verify(mMockService).deleteVpnProfile(eq(PKG_NAME)); - } - - @Test - public void testStartProvisionedVpnProfile() throws Exception { - mVpnManager.startProvisionedVpnProfile(); - verify(mMockService).startVpnProfile(eq(PKG_NAME)); - } - - @Test - public void testStopProvisionedVpnProfile() throws Exception { - mVpnManager.stopProvisionedVpnProfile(); - verify(mMockService).stopVpnProfile(eq(PKG_NAME)); - } - - private Ikev2VpnProfile getPlatformVpnProfile() throws Exception { - return new Ikev2VpnProfile.Builder(SERVER_ADDR_STRING, IDENTITY_STRING) - .setBypassable(true) - .setMaxMtu(1300) - .setMetered(true) - .setAuthPsk(PSK_BYTES) - .build(); - } - - @Test - public void testVpnTypesEqual() throws Exception { - SparseArray<String> vmVpnTypes = MessageUtils.findMessageNames( - new Class[] { VpnManager.class }, new String[]{ "TYPE_VPN_" }); - SparseArray<String> nativeVpnType = MessageUtils.findMessageNames( - new Class[] { NativeVpnType.class }, new String[]{ "" }); - - // TYPE_VPN_NONE = -1 is only defined in VpnManager. - assertEquals(vmVpnTypes.size() - 1, nativeVpnType.size()); - for (int i = VpnManager.TYPE_VPN_SERVICE; i < vmVpnTypes.size(); i++) { - assertEquals(vmVpnTypes.get(i), "TYPE_VPN_" + nativeVpnType.get(i)); - } - } -} diff --git a/tests/net/java/android/net/VpnTransportInfoTest.java b/tests/net/java/android/net/VpnTransportInfoTest.java deleted file mode 100644 index ccaa5cf7e9f7..000000000000 --- a/tests/net/java/android/net/VpnTransportInfoTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; -import static android.net.NetworkCapabilities.REDACT_NONE; - -import static com.android.testutils.ParcelUtils.assertParcelSane; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class VpnTransportInfoTest { - - @Test - public void testParceling() { - VpnTransportInfo v = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345"); - assertParcelSane(v, 2 /* fieldCount */); - } - - @Test - public void testEqualsAndHashCode() { - String session1 = "12345"; - String session2 = "6789"; - VpnTransportInfo v11 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, session1); - VpnTransportInfo v12 = new VpnTransportInfo(VpnManager.TYPE_VPN_SERVICE, session1); - VpnTransportInfo v13 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, session1); - VpnTransportInfo v14 = new VpnTransportInfo(VpnManager.TYPE_VPN_LEGACY, session1); - VpnTransportInfo v15 = new VpnTransportInfo(VpnManager.TYPE_VPN_OEM, session1); - VpnTransportInfo v21 = new VpnTransportInfo(VpnManager.TYPE_VPN_LEGACY, session2); - - VpnTransportInfo v31 = v11.makeCopy(REDACT_FOR_NETWORK_SETTINGS); - VpnTransportInfo v32 = v13.makeCopy(REDACT_FOR_NETWORK_SETTINGS); - - assertNotEquals(v11, v12); - assertNotEquals(v13, v14); - assertNotEquals(v14, v15); - assertNotEquals(v14, v21); - - assertEquals(v11, v13); - assertEquals(v31, v32); - assertEquals(v11.hashCode(), v13.hashCode()); - assertEquals(REDACT_FOR_NETWORK_SETTINGS, v32.getApplicableRedactions()); - assertEquals(session1, v15.makeCopy(REDACT_NONE).getSessionId()); - } -} diff --git a/tests/net/java/android/net/ipmemorystore/ParcelableTests.java b/tests/net/java/android/net/ipmemorystore/ParcelableTests.java deleted file mode 100644 index 603c87519532..000000000000 --- a/tests/net/java/android/net/ipmemorystore/ParcelableTests.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.ipmemorystore; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import android.net.networkstack.aidl.quirks.IPv6ProvisioningLossQuirk; -import android.net.networkstack.aidl.quirks.IPv6ProvisioningLossQuirkParcelable; -import android.os.Parcel; -import android.os.Parcelable; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.lang.reflect.Modifier; -import java.net.Inet4Address; -import java.net.InetAddress; -import java.util.Arrays; -import java.util.Collections; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class ParcelableTests { - @Test - public void testNetworkAttributesParceling() throws Exception { - final NetworkAttributes.Builder builder = new NetworkAttributes.Builder(); - NetworkAttributes in = builder.build(); - assertEquals(in, new NetworkAttributes(parcelingRoundTrip(in.toParcelable()))); - - builder.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4")); - // lease will expire in two hours - builder.setAssignedV4AddressExpiry(System.currentTimeMillis() + 7_200_000); - // cluster stays null this time around - builder.setDnsAddresses(Collections.emptyList()); - builder.setMtu(18); - in = builder.build(); - assertEquals(in, new NetworkAttributes(parcelingRoundTrip(in.toParcelable()))); - - builder.setAssignedV4Address((Inet4Address) Inet4Address.getByName("6.7.8.9")); - builder.setAssignedV4AddressExpiry(System.currentTimeMillis() + 3_600_000); - builder.setCluster("groupHint"); - builder.setDnsAddresses(Arrays.asList( - InetAddress.getByName("ACA1:652B:0911:DE8F:1200:115E:913B:AA2A"), - InetAddress.getByName("6.7.8.9"))); - builder.setMtu(1_000_000); - in = builder.build(); - assertEquals(in, new NetworkAttributes(parcelingRoundTrip(in.toParcelable()))); - - builder.setMtu(null); - in = builder.build(); - assertEquals(in, new NetworkAttributes(parcelingRoundTrip(in.toParcelable()))); - - // Verify that this test does not miss any new field added later. - // If any field is added to NetworkAttributes it must be tested here for parceling - // roundtrip. - assertEquals(6, Arrays.stream(NetworkAttributes.class.getDeclaredFields()) - .filter(f -> !Modifier.isStatic(f.getModifiers())).count()); - } - - @Test - public void testPrivateDataParceling() throws Exception { - final Blob in = new Blob(); - in.data = new byte[] {89, 111, 108, 111}; - final Blob out = parcelingRoundTrip(in); - // Object.equals on byte[] tests the references - assertEquals(in.data.length, out.data.length); - assertTrue(Arrays.equals(in.data, out.data)); - } - - @Test - public void testSameL3NetworkResponseParceling() throws Exception { - final SameL3NetworkResponseParcelable parcelable = new SameL3NetworkResponseParcelable(); - parcelable.l2Key1 = "key 1"; - parcelable.l2Key2 = "key 2"; - parcelable.confidence = 0.43f; - - final SameL3NetworkResponse in = new SameL3NetworkResponse(parcelable); - assertEquals("key 1", in.l2Key1); - assertEquals("key 2", in.l2Key2); - assertEquals(0.43f, in.confidence, 0.01f /* delta */); - - final SameL3NetworkResponse out = - new SameL3NetworkResponse(parcelingRoundTrip(in.toParcelable())); - - assertEquals(in, out); - assertEquals(in.l2Key1, out.l2Key1); - assertEquals(in.l2Key2, out.l2Key2); - assertEquals(in.confidence, out.confidence, 0.01f /* delta */); - } - - @Test - public void testIPv6ProvisioningLossQuirkParceling() throws Exception { - final NetworkAttributes.Builder builder = new NetworkAttributes.Builder(); - final IPv6ProvisioningLossQuirkParcelable parcelable = - new IPv6ProvisioningLossQuirkParcelable(); - final long expiry = System.currentTimeMillis() + 7_200_000; - - parcelable.detectionCount = 3; - parcelable.quirkExpiry = expiry; // quirk info will expire in two hours - builder.setIpv6ProvLossQuirk(IPv6ProvisioningLossQuirk.fromStableParcelable(parcelable)); - final NetworkAttributes in = builder.build(); - - final NetworkAttributes out = new NetworkAttributes(parcelingRoundTrip(in.toParcelable())); - assertEquals(out.ipv6ProvisioningLossQuirk, in.ipv6ProvisioningLossQuirk); - } - - private <T extends Parcelable> T parcelingRoundTrip(final T in) throws Exception { - final Parcel p = Parcel.obtain(); - in.writeToParcel(p, /* flags */ 0); - p.setDataPosition(0); - final byte[] marshalledData = p.marshall(); - p.recycle(); - - final Parcel q = Parcel.obtain(); - q.unmarshall(marshalledData, 0, marshalledData.length); - q.setDataPosition(0); - - final Parcelable.Creator<T> creator = (Parcelable.Creator<T>) - in.getClass().getField("CREATOR").get(null); // static object, so null receiver - final T unmarshalled = (T) creator.createFromParcel(q); - q.recycle(); - return unmarshalled; - } -} diff --git a/tests/net/java/android/net/nsd/NsdManagerTest.java b/tests/net/java/android/net/nsd/NsdManagerTest.java deleted file mode 100644 index b0a9b8a55322..000000000000 --- a/tests/net/java/android/net/nsd/NsdManagerTest.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.nsd; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.os.Messenger; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.internal.util.AsyncChannel; -import com.android.testutils.HandlerUtils; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NsdManagerTest { - - static final int PROTOCOL = NsdManager.PROTOCOL_DNS_SD; - - @Mock Context mContext; - @Mock INsdManager mService; - MockServiceHandler mServiceHandler; - - NsdManager mManager; - - long mTimeoutMs = 200; // non-final so that tests can adjust the value. - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - mServiceHandler = spy(MockServiceHandler.create(mContext)); - when(mService.getMessenger()).thenReturn(new Messenger(mServiceHandler)); - - mManager = makeManager(); - } - - @After - public void tearDown() throws Exception { - HandlerUtils.waitForIdle(mServiceHandler, mTimeoutMs); - mServiceHandler.chan.disconnect(); - mServiceHandler.stop(); - if (mManager != null) { - mManager.disconnect(); - } - } - - @Test - public void testResolveService() { - NsdManager manager = mManager; - - NsdServiceInfo request = new NsdServiceInfo("a_name", "a_type"); - NsdServiceInfo reply = new NsdServiceInfo("resolved_name", "resolved_type"); - NsdManager.ResolveListener listener = mock(NsdManager.ResolveListener.class); - - manager.resolveService(request, listener); - int key1 = verifyRequest(NsdManager.RESOLVE_SERVICE); - int err = 33; - sendResponse(NsdManager.RESOLVE_SERVICE_FAILED, err, key1, null); - verify(listener, timeout(mTimeoutMs).times(1)).onResolveFailed(request, err); - - manager.resolveService(request, listener); - int key2 = verifyRequest(NsdManager.RESOLVE_SERVICE); - sendResponse(NsdManager.RESOLVE_SERVICE_SUCCEEDED, 0, key2, reply); - verify(listener, timeout(mTimeoutMs).times(1)).onServiceResolved(reply); - } - - @Test - public void testParallelResolveService() { - NsdManager manager = mManager; - - NsdServiceInfo request = new NsdServiceInfo("a_name", "a_type"); - NsdServiceInfo reply = new NsdServiceInfo("resolved_name", "resolved_type"); - - NsdManager.ResolveListener listener1 = mock(NsdManager.ResolveListener.class); - NsdManager.ResolveListener listener2 = mock(NsdManager.ResolveListener.class); - - manager.resolveService(request, listener1); - int key1 = verifyRequest(NsdManager.RESOLVE_SERVICE); - - manager.resolveService(request, listener2); - int key2 = verifyRequest(NsdManager.RESOLVE_SERVICE); - - sendResponse(NsdManager.RESOLVE_SERVICE_SUCCEEDED, 0, key2, reply); - sendResponse(NsdManager.RESOLVE_SERVICE_SUCCEEDED, 0, key1, reply); - - verify(listener1, timeout(mTimeoutMs).times(1)).onServiceResolved(reply); - verify(listener2, timeout(mTimeoutMs).times(1)).onServiceResolved(reply); - } - - @Test - public void testRegisterService() { - NsdManager manager = mManager; - - NsdServiceInfo request1 = new NsdServiceInfo("a_name", "a_type"); - NsdServiceInfo request2 = new NsdServiceInfo("another_name", "another_type"); - request1.setPort(2201); - request2.setPort(2202); - NsdManager.RegistrationListener listener1 = mock(NsdManager.RegistrationListener.class); - NsdManager.RegistrationListener listener2 = mock(NsdManager.RegistrationListener.class); - - // Register two services - manager.registerService(request1, PROTOCOL, listener1); - int key1 = verifyRequest(NsdManager.REGISTER_SERVICE); - - manager.registerService(request2, PROTOCOL, listener2); - int key2 = verifyRequest(NsdManager.REGISTER_SERVICE); - - // First reques fails, second request succeeds - sendResponse(NsdManager.REGISTER_SERVICE_SUCCEEDED, 0, key2, request2); - verify(listener2, timeout(mTimeoutMs).times(1)).onServiceRegistered(request2); - - int err = 1; - sendResponse(NsdManager.REGISTER_SERVICE_FAILED, err, key1, request1); - verify(listener1, timeout(mTimeoutMs).times(1)).onRegistrationFailed(request1, err); - - // Client retries first request, it succeeds - manager.registerService(request1, PROTOCOL, listener1); - int key3 = verifyRequest(NsdManager.REGISTER_SERVICE); - - sendResponse(NsdManager.REGISTER_SERVICE_SUCCEEDED, 0, key3, request1); - verify(listener1, timeout(mTimeoutMs).times(1)).onServiceRegistered(request1); - - // First request is unregistered, it succeeds - manager.unregisterService(listener1); - int key3again = verifyRequest(NsdManager.UNREGISTER_SERVICE); - assertEquals(key3, key3again); - - sendResponse(NsdManager.UNREGISTER_SERVICE_SUCCEEDED, 0, key3again, null); - verify(listener1, timeout(mTimeoutMs).times(1)).onServiceUnregistered(request1); - - // Second request is unregistered, it fails - manager.unregisterService(listener2); - int key2again = verifyRequest(NsdManager.UNREGISTER_SERVICE); - assertEquals(key2, key2again); - - sendResponse(NsdManager.UNREGISTER_SERVICE_FAILED, err, key2again, null); - verify(listener2, timeout(mTimeoutMs).times(1)).onUnregistrationFailed(request2, err); - - // TODO: do not unregister listener until service is unregistered - // Client retries unregistration of second request, it succeeds - //manager.unregisterService(listener2); - //int key2yetAgain = verifyRequest(NsdManager.UNREGISTER_SERVICE); - //assertEquals(key2, key2yetAgain); - - //sendResponse(NsdManager.UNREGISTER_SERVICE_SUCCEEDED, 0, key2yetAgain, null); - //verify(listener2, timeout(mTimeoutMs).times(1)).onServiceUnregistered(request2); - } - - @Test - public void testDiscoverService() { - NsdManager manager = mManager; - - NsdServiceInfo reply1 = new NsdServiceInfo("a_name", "a_type"); - NsdServiceInfo reply2 = new NsdServiceInfo("another_name", "a_type"); - NsdServiceInfo reply3 = new NsdServiceInfo("a_third_name", "a_type"); - - NsdManager.DiscoveryListener listener = mock(NsdManager.DiscoveryListener.class); - - // Client registers for discovery, request fails - manager.discoverServices("a_type", PROTOCOL, listener); - int key1 = verifyRequest(NsdManager.DISCOVER_SERVICES); - - int err = 1; - sendResponse(NsdManager.DISCOVER_SERVICES_FAILED, err, key1, null); - verify(listener, timeout(mTimeoutMs).times(1)).onStartDiscoveryFailed("a_type", err); - - // Client retries, request succeeds - manager.discoverServices("a_type", PROTOCOL, listener); - int key2 = verifyRequest(NsdManager.DISCOVER_SERVICES); - - sendResponse(NsdManager.DISCOVER_SERVICES_STARTED, 0, key2, reply1); - verify(listener, timeout(mTimeoutMs).times(1)).onDiscoveryStarted("a_type"); - - - // mdns notifies about services - sendResponse(NsdManager.SERVICE_FOUND, 0, key2, reply1); - verify(listener, timeout(mTimeoutMs).times(1)).onServiceFound(reply1); - - sendResponse(NsdManager.SERVICE_FOUND, 0, key2, reply2); - verify(listener, timeout(mTimeoutMs).times(1)).onServiceFound(reply2); - - sendResponse(NsdManager.SERVICE_LOST, 0, key2, reply2); - verify(listener, timeout(mTimeoutMs).times(1)).onServiceLost(reply2); - - - // Client unregisters its listener - manager.stopServiceDiscovery(listener); - int key2again = verifyRequest(NsdManager.STOP_DISCOVERY); - assertEquals(key2, key2again); - - // TODO: unregister listener immediately and stop notifying it about services - // Notifications are still passed to the client's listener - sendResponse(NsdManager.SERVICE_LOST, 0, key2, reply1); - verify(listener, timeout(mTimeoutMs).times(1)).onServiceLost(reply1); - - // Client is notified of complete unregistration - sendResponse(NsdManager.STOP_DISCOVERY_SUCCEEDED, 0, key2again, "a_type"); - verify(listener, timeout(mTimeoutMs).times(1)).onDiscoveryStopped("a_type"); - - // Notifications are not passed to the client anymore - sendResponse(NsdManager.SERVICE_FOUND, 0, key2, reply3); - verify(listener, timeout(mTimeoutMs).times(0)).onServiceLost(reply3); - - - // Client registers for service discovery - reset(listener); - manager.discoverServices("a_type", PROTOCOL, listener); - int key3 = verifyRequest(NsdManager.DISCOVER_SERVICES); - - sendResponse(NsdManager.DISCOVER_SERVICES_STARTED, 0, key3, reply1); - verify(listener, timeout(mTimeoutMs).times(1)).onDiscoveryStarted("a_type"); - - // Client unregisters immediately, it fails - manager.stopServiceDiscovery(listener); - int key3again = verifyRequest(NsdManager.STOP_DISCOVERY); - assertEquals(key3, key3again); - - err = 2; - sendResponse(NsdManager.STOP_DISCOVERY_FAILED, err, key3again, "a_type"); - verify(listener, timeout(mTimeoutMs).times(1)).onStopDiscoveryFailed("a_type", err); - - // New notifications are not passed to the client anymore - sendResponse(NsdManager.SERVICE_FOUND, 0, key3, reply1); - verify(listener, timeout(mTimeoutMs).times(0)).onServiceFound(reply1); - } - - @Test - public void testInvalidCalls() { - NsdManager manager = mManager; - - NsdManager.RegistrationListener listener1 = mock(NsdManager.RegistrationListener.class); - NsdManager.DiscoveryListener listener2 = mock(NsdManager.DiscoveryListener.class); - NsdManager.ResolveListener listener3 = mock(NsdManager.ResolveListener.class); - - NsdServiceInfo invalidService = new NsdServiceInfo(null, null); - NsdServiceInfo validService = new NsdServiceInfo("a_name", "a_type"); - validService.setPort(2222); - - // Service registration - // - invalid arguments - mustFail(() -> { manager.unregisterService(null); }); - mustFail(() -> { manager.registerService(null, -1, null); }); - mustFail(() -> { manager.registerService(null, PROTOCOL, listener1); }); - mustFail(() -> { manager.registerService(invalidService, PROTOCOL, listener1); }); - mustFail(() -> { manager.registerService(validService, -1, listener1); }); - mustFail(() -> { manager.registerService(validService, PROTOCOL, null); }); - manager.registerService(validService, PROTOCOL, listener1); - // - listener already registered - mustFail(() -> { manager.registerService(validService, PROTOCOL, listener1); }); - manager.unregisterService(listener1); - // TODO: make listener immediately reusable - //mustFail(() -> { manager.unregisterService(listener1); }); - //manager.registerService(validService, PROTOCOL, listener1); - - // Discover service - // - invalid arguments - mustFail(() -> { manager.stopServiceDiscovery(null); }); - mustFail(() -> { manager.discoverServices(null, -1, null); }); - mustFail(() -> { manager.discoverServices(null, PROTOCOL, listener2); }); - mustFail(() -> { manager.discoverServices("a_service", -1, listener2); }); - mustFail(() -> { manager.discoverServices("a_service", PROTOCOL, null); }); - manager.discoverServices("a_service", PROTOCOL, listener2); - // - listener already registered - mustFail(() -> { manager.discoverServices("another_service", PROTOCOL, listener2); }); - manager.stopServiceDiscovery(listener2); - // TODO: make listener immediately reusable - //mustFail(() -> { manager.stopServiceDiscovery(listener2); }); - //manager.discoverServices("another_service", PROTOCOL, listener2); - - // Resolver service - // - invalid arguments - mustFail(() -> { manager.resolveService(null, null); }); - mustFail(() -> { manager.resolveService(null, listener3); }); - mustFail(() -> { manager.resolveService(invalidService, listener3); }); - mustFail(() -> { manager.resolveService(validService, null); }); - manager.resolveService(validService, listener3); - // - listener already registered:w - mustFail(() -> { manager.resolveService(validService, listener3); }); - } - - public void mustFail(Runnable fn) { - try { - fn.run(); - fail(); - } catch (Exception expected) { - } - } - - NsdManager makeManager() { - NsdManager manager = new NsdManager(mContext, mService); - // Acknowledge first two messages connecting the AsyncChannel. - verify(mServiceHandler, timeout(mTimeoutMs).times(2)).handleMessage(any()); - reset(mServiceHandler); - assertNotNull(mServiceHandler.chan); - return manager; - } - - int verifyRequest(int expectedMessageType) { - HandlerUtils.waitForIdle(mServiceHandler, mTimeoutMs); - verify(mServiceHandler, timeout(mTimeoutMs)).handleMessage(any()); - reset(mServiceHandler); - Message received = mServiceHandler.getLastMessage(); - assertEquals(NsdManager.nameOf(expectedMessageType), NsdManager.nameOf(received.what)); - return received.arg2; - } - - void sendResponse(int replyType, int arg, int key, Object obj) { - mServiceHandler.chan.sendMessage(replyType, arg, key, obj); - } - - // Implements the server side of AsyncChannel connection protocol - public static class MockServiceHandler extends Handler { - public final Context context; - public AsyncChannel chan; - public Message lastMessage; - - MockServiceHandler(Looper l, Context c) { - super(l); - context = c; - } - - synchronized Message getLastMessage() { - return lastMessage; - } - - synchronized void setLastMessage(Message msg) { - lastMessage = obtainMessage(); - lastMessage.copyFrom(msg); - } - - @Override - public void handleMessage(Message msg) { - setLastMessage(msg); - if (msg.what == AsyncChannel.CMD_CHANNEL_FULL_CONNECTION) { - chan = new AsyncChannel(); - chan.connect(context, this, msg.replyTo); - chan.sendMessage(AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED); - } - } - - void stop() { - getLooper().quitSafely(); - } - - static MockServiceHandler create(Context context) { - HandlerThread t = new HandlerThread("mock-service-handler"); - t.start(); - return new MockServiceHandler(t.getLooper(), context); - } - } -} diff --git a/tests/net/java/android/net/nsd/NsdServiceInfoTest.java b/tests/net/java/android/net/nsd/NsdServiceInfoTest.java deleted file mode 100644 index 94dfc7515c67..000000000000 --- a/tests/net/java/android/net/nsd/NsdServiceInfoTest.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.nsd; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.os.Bundle; -import android.os.Parcel; -import android.os.StrictMode; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.Map; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NsdServiceInfoTest { - - public final static InetAddress LOCALHOST; - static { - // Because test. - StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); - StrictMode.setThreadPolicy(policy); - - InetAddress _host = null; - try { - _host = InetAddress.getLocalHost(); - } catch (UnknownHostException e) { } - LOCALHOST = _host; - } - - @Test - public void testLimits() throws Exception { - NsdServiceInfo info = new NsdServiceInfo(); - - // Non-ASCII keys. - boolean exceptionThrown = false; - try { - info.setAttribute("猫", "meow"); - } catch (IllegalArgumentException e) { - exceptionThrown = true; - } - assertTrue(exceptionThrown); - assertEmptyServiceInfo(info); - - // ASCII keys with '=' character. - exceptionThrown = false; - try { - info.setAttribute("kitten=", "meow"); - } catch (IllegalArgumentException e) { - exceptionThrown = true; - } - assertTrue(exceptionThrown); - assertEmptyServiceInfo(info); - - // Single key + value length too long. - exceptionThrown = false; - try { - String longValue = "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" + - "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" + - "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" + - "ooooooooooooooooooooooooooooong"; // 248 characters. - info.setAttribute("longcat", longValue); // Key + value == 255 characters. - } catch (IllegalArgumentException e) { - exceptionThrown = true; - } - assertTrue(exceptionThrown); - assertEmptyServiceInfo(info); - - // Total TXT record length too long. - exceptionThrown = false; - int recordsAdded = 0; - try { - for (int i = 100; i < 300; ++i) { - // 6 char key + 5 char value + 2 bytes overhead = 13 byte record length. - String key = String.format("key%d", i); - info.setAttribute(key, "12345"); - recordsAdded++; - } - } catch (IllegalArgumentException e) { - exceptionThrown = true; - } - assertTrue(exceptionThrown); - assertTrue(100 == recordsAdded); - assertTrue(info.getTxtRecord().length == 1300); - } - - @Test - public void testParcel() throws Exception { - NsdServiceInfo emptyInfo = new NsdServiceInfo(); - checkParcelable(emptyInfo); - - NsdServiceInfo fullInfo = new NsdServiceInfo(); - fullInfo.setServiceName("kitten"); - fullInfo.setServiceType("_kitten._tcp"); - fullInfo.setPort(4242); - fullInfo.setHost(LOCALHOST); - checkParcelable(fullInfo); - - NsdServiceInfo noHostInfo = new NsdServiceInfo(); - noHostInfo.setServiceName("kitten"); - noHostInfo.setServiceType("_kitten._tcp"); - noHostInfo.setPort(4242); - checkParcelable(noHostInfo); - - NsdServiceInfo attributedInfo = new NsdServiceInfo(); - attributedInfo.setServiceName("kitten"); - attributedInfo.setServiceType("_kitten._tcp"); - attributedInfo.setPort(4242); - attributedInfo.setHost(LOCALHOST); - attributedInfo.setAttribute("color", "pink"); - attributedInfo.setAttribute("sound", (new String("にゃあ")).getBytes("UTF-8")); - attributedInfo.setAttribute("adorable", (String) null); - attributedInfo.setAttribute("sticky", "yes"); - attributedInfo.setAttribute("siblings", new byte[] {}); - attributedInfo.setAttribute("edge cases", new byte[] {0, -1, 127, -128}); - attributedInfo.removeAttribute("sticky"); - checkParcelable(attributedInfo); - - // Sanity check that we actually wrote attributes to attributedInfo. - assertTrue(attributedInfo.getAttributes().keySet().contains("adorable")); - String sound = new String(attributedInfo.getAttributes().get("sound"), "UTF-8"); - assertTrue(sound.equals("にゃあ")); - byte[] edgeCases = attributedInfo.getAttributes().get("edge cases"); - assertTrue(Arrays.equals(edgeCases, new byte[] {0, -1, 127, -128})); - assertFalse(attributedInfo.getAttributes().keySet().contains("sticky")); - } - - public void checkParcelable(NsdServiceInfo original) { - // Write to parcel. - Parcel p = Parcel.obtain(); - Bundle writer = new Bundle(); - writer.putParcelable("test_info", original); - writer.writeToParcel(p, 0); - - // Extract from parcel. - p.setDataPosition(0); - Bundle reader = p.readBundle(); - reader.setClassLoader(NsdServiceInfo.class.getClassLoader()); - NsdServiceInfo result = reader.getParcelable("test_info"); - - // Assert equality of base fields. - assertEquals(original.getServiceName(), result.getServiceName()); - assertEquals(original.getServiceType(), result.getServiceType()); - assertEquals(original.getHost(), result.getHost()); - assertTrue(original.getPort() == result.getPort()); - - // Assert equality of attribute map. - Map<String, byte[]> originalMap = original.getAttributes(); - Map<String, byte[]> resultMap = result.getAttributes(); - assertEquals(originalMap.keySet(), resultMap.keySet()); - for (String key : originalMap.keySet()) { - assertTrue(Arrays.equals(originalMap.get(key), resultMap.get(key))); - } - } - - public void assertEmptyServiceInfo(NsdServiceInfo shouldBeEmpty) { - byte[] txtRecord = shouldBeEmpty.getTxtRecord(); - if (txtRecord == null || txtRecord.length == 0) { - return; - } - fail("NsdServiceInfo.getTxtRecord did not return null but " + Arrays.toString(txtRecord)); - } -} diff --git a/tests/net/java/android/net/util/DnsUtilsTest.java b/tests/net/java/android/net/util/DnsUtilsTest.java deleted file mode 100644 index b626db8d89e4..000000000000 --- a/tests/net/java/android/net/util/DnsUtilsTest.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.util; - -import static android.net.util.DnsUtils.IPV6_ADDR_SCOPE_GLOBAL; -import static android.net.util.DnsUtils.IPV6_ADDR_SCOPE_LINKLOCAL; -import static android.net.util.DnsUtils.IPV6_ADDR_SCOPE_SITELOCAL; - -import static org.junit.Assert.assertEquals; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.net.InetAddresses; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.InetAddress; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class DnsUtilsTest { - private InetAddress stringToAddress(@NonNull String addr) { - return InetAddresses.parseNumericAddress(addr); - } - - private DnsUtils.SortableAddress makeSortableAddress(@NonNull String addr) { - return makeSortableAddress(addr, null); - } - - private DnsUtils.SortableAddress makeSortableAddress(@NonNull String addr, - @Nullable String srcAddr) { - return new DnsUtils.SortableAddress(stringToAddress(addr), - srcAddr != null ? stringToAddress(srcAddr) : null); - } - - @Test - public void testRfc6724Comparator() { - final List<DnsUtils.SortableAddress> test = Arrays.asList( - // Ipv4 - makeSortableAddress("216.58.200.36", "192.168.1.1"), - // global with different scope src - makeSortableAddress("2404:6800:4008:801::2004", "fe80::1111:2222"), - // global without src addr - makeSortableAddress("2404:6800:cafe:801::1"), - // loop back - makeSortableAddress("::1", "::1"), - // link local - makeSortableAddress("fe80::c46f:1cff:fe04:39b4", "fe80::1"), - // teredo tunneling - makeSortableAddress("2001::47c1", "2001::2"), - // 6bone without src addr - makeSortableAddress("3ffe::1234:5678"), - // IPv4-compatible - makeSortableAddress("::216.58.200.36", "::216.58.200.9"), - // 6bone - makeSortableAddress("3ffe::1234:5678", "3ffe::1234:1"), - // IPv4-mapped IPv6 - makeSortableAddress("::ffff:192.168.95.7", "::ffff:192.168.95.1")); - - final List<InetAddress> expected = Arrays.asList( - stringToAddress("::1"), // loop back - stringToAddress("fe80::c46f:1cff:fe04:39b4"), // link local - stringToAddress("216.58.200.36"), // Ipv4 - stringToAddress("::ffff:192.168.95.7"), // IPv4-mapped IPv6 - stringToAddress("2001::47c1"), // teredo tunneling - stringToAddress("::216.58.200.36"), // IPv4-compatible - stringToAddress("3ffe::1234:5678"), // 6bone - stringToAddress("2404:6800:4008:801::2004"), // global with different scope src - stringToAddress("2404:6800:cafe:801::1"), // global without src addr - stringToAddress("3ffe::1234:5678")); // 6bone without src addr - - Collections.sort(test, new DnsUtils.Rfc6724Comparator()); - - for (int i = 0; i < test.size(); ++i) { - assertEquals(test.get(i).address, expected.get(i)); - } - - // TODO: add more combinations - } - - @Test - public void testV4SortableAddress() { - // Test V4 address - DnsUtils.SortableAddress test = makeSortableAddress("216.58.200.36"); - assertEquals(test.hasSrcAddr, 0); - assertEquals(test.prefixMatchLen, 0); - assertEquals(test.address, stringToAddress("216.58.200.36")); - assertEquals(test.labelMatch, 0); - assertEquals(test.scopeMatch, 0); - assertEquals(test.scope, IPV6_ADDR_SCOPE_GLOBAL); - assertEquals(test.label, 4); - assertEquals(test.precedence, 35); - - // Test V4 loopback address with the same source address - test = makeSortableAddress("127.1.2.3", "127.1.2.3"); - assertEquals(test.hasSrcAddr, 1); - assertEquals(test.prefixMatchLen, 0); - assertEquals(test.address, stringToAddress("127.1.2.3")); - assertEquals(test.labelMatch, 1); - assertEquals(test.scopeMatch, 1); - assertEquals(test.scope, IPV6_ADDR_SCOPE_LINKLOCAL); - assertEquals(test.label, 4); - assertEquals(test.precedence, 35); - } - - @Test - public void testV6SortableAddress() { - // Test global address - DnsUtils.SortableAddress test = makeSortableAddress("2404:6800:4008:801::2004"); - assertEquals(test.address, stringToAddress("2404:6800:4008:801::2004")); - assertEquals(test.scope, IPV6_ADDR_SCOPE_GLOBAL); - assertEquals(test.label, 1); - assertEquals(test.precedence, 40); - - // Test global address with global source address - test = makeSortableAddress("2404:6800:4008:801::2004", - "2401:fa00:fc:fd00:6d6c:7199:b8e7:41d6"); - assertEquals(test.address, stringToAddress("2404:6800:4008:801::2004")); - assertEquals(test.hasSrcAddr, 1); - assertEquals(test.scope, IPV6_ADDR_SCOPE_GLOBAL); - assertEquals(test.labelMatch, 1); - assertEquals(test.scopeMatch, 1); - assertEquals(test.label, 1); - assertEquals(test.precedence, 40); - assertEquals(test.prefixMatchLen, 13); - - // Test global address with linklocal source address - test = makeSortableAddress("2404:6800:4008:801::2004", "fe80::c46f:1cff:fe04:39b4"); - assertEquals(test.hasSrcAddr, 1); - assertEquals(test.scope, IPV6_ADDR_SCOPE_GLOBAL); - assertEquals(test.labelMatch, 1); - assertEquals(test.scopeMatch, 0); - assertEquals(test.label, 1); - assertEquals(test.precedence, 40); - assertEquals(test.prefixMatchLen, 0); - - // Test loopback address with the same source address - test = makeSortableAddress("::1", "::1"); - assertEquals(test.hasSrcAddr, 1); - assertEquals(test.prefixMatchLen, 16 * 8); - assertEquals(test.labelMatch, 1); - assertEquals(test.scopeMatch, 1); - assertEquals(test.scope, IPV6_ADDR_SCOPE_LINKLOCAL); - assertEquals(test.label, 0); - assertEquals(test.precedence, 50); - - // Test linklocal address - test = makeSortableAddress("fe80::c46f:1cff:fe04:39b4"); - assertEquals(test.scope, IPV6_ADDR_SCOPE_LINKLOCAL); - assertEquals(test.label, 1); - assertEquals(test.precedence, 40); - - // Test linklocal address - test = makeSortableAddress("fe80::"); - assertEquals(test.scope, IPV6_ADDR_SCOPE_LINKLOCAL); - assertEquals(test.label, 1); - assertEquals(test.precedence, 40); - - // Test 6to4 address - test = makeSortableAddress("2002:c000:0204::"); - assertEquals(test.scope, IPV6_ADDR_SCOPE_GLOBAL); - assertEquals(test.label, 2); - assertEquals(test.precedence, 30); - - // Test unique local address - test = makeSortableAddress("fc00::c000:13ab"); - assertEquals(test.scope, IPV6_ADDR_SCOPE_GLOBAL); - assertEquals(test.label, 13); - assertEquals(test.precedence, 3); - - // Test teredo tunneling address - test = makeSortableAddress("2001::47c1"); - assertEquals(test.scope, IPV6_ADDR_SCOPE_GLOBAL); - assertEquals(test.label, 5); - assertEquals(test.precedence, 5); - - // Test IPv4-compatible addresses - test = makeSortableAddress("::216.58.200.36"); - assertEquals(test.scope, IPV6_ADDR_SCOPE_GLOBAL); - assertEquals(test.label, 3); - assertEquals(test.precedence, 1); - - // Test site-local address - test = makeSortableAddress("fec0::cafe:3ab2"); - assertEquals(test.scope, IPV6_ADDR_SCOPE_SITELOCAL); - assertEquals(test.label, 11); - assertEquals(test.precedence, 1); - - // Test 6bone address - test = makeSortableAddress("3ffe::1234:5678"); - assertEquals(test.scope, IPV6_ADDR_SCOPE_GLOBAL); - assertEquals(test.label, 12); - assertEquals(test.precedence, 1); - } -} diff --git a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt b/tests/net/java/android/net/util/KeepaliveUtilsTest.kt deleted file mode 100644 index 5006d5345f5f..000000000000 --- a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.util - -import android.content.Context -import android.content.res.Resources -import android.net.ConnectivityResources -import android.net.NetworkCapabilities -import android.net.NetworkCapabilities.MAX_TRANSPORT -import android.net.NetworkCapabilities.TRANSPORT_CELLULAR -import android.net.NetworkCapabilities.TRANSPORT_ETHERNET -import android.net.NetworkCapabilities.TRANSPORT_VPN -import android.net.NetworkCapabilities.TRANSPORT_WIFI -import androidx.test.filters.SmallTest -import com.android.internal.R -import org.junit.After -import org.junit.Assert.assertArrayEquals -import org.junit.Assert.assertEquals -import org.junit.Assert.fail -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import org.mockito.ArgumentMatchers.eq -import org.mockito.Mockito.any -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.mock - -/** - * Tests for [KeepaliveUtils]. - * - * Build, install and run with: - * atest android.net.util.KeepaliveUtilsTest - */ -@RunWith(JUnit4::class) -@SmallTest -class KeepaliveUtilsTest { - - // Prepare mocked context with given resource strings. - private fun getMockedContextWithStringArrayRes( - id: Int, - name: String, - res: Array<out String?>? - ): Context { - val mockRes = mock(Resources::class.java) - doReturn(res).`when`(mockRes).getStringArray(eq(id)) - doReturn(id).`when`(mockRes).getIdentifier(eq(name), any(), any()) - - return mock(Context::class.java).apply { - doReturn(mockRes).`when`(this).getResources() - ConnectivityResources.setResourcesContextForTest(this) - } - } - - @After - fun tearDown() { - ConnectivityResources.setResourcesContextForTest(null) - } - - @Test - fun testGetSupportedKeepalives() { - fun assertRunWithException(res: Array<out String?>?) { - try { - val mockContext = getMockedContextWithStringArrayRes( - R.array.config_networkSupportedKeepaliveCount, - "config_networkSupportedKeepaliveCount", res) - KeepaliveUtils.getSupportedKeepalives(mockContext) - fail("Expected KeepaliveDeviceConfigurationException") - } catch (expected: KeepaliveUtils.KeepaliveDeviceConfigurationException) { - } - } - - // Check resource with various invalid format. - assertRunWithException(null) - assertRunWithException(arrayOf<String?>(null)) - assertRunWithException(arrayOfNulls<String?>(10)) - assertRunWithException(arrayOf("")) - assertRunWithException(arrayOf("3,ABC")) - assertRunWithException(arrayOf("6,3,3")) - assertRunWithException(arrayOf("5")) - - // Check resource with invalid slots value. - assertRunWithException(arrayOf("3,-1")) - - // Check resource with invalid transport type. - assertRunWithException(arrayOf("-1,3")) - assertRunWithException(arrayOf("10,3")) - - // Check valid customization generates expected array. - val validRes = arrayOf("0,3", "1,0", "4,4") - val expectedValidRes = intArrayOf(3, 0, 0, 0, 4, 0, 0, 0, 0) - - val mockContext = getMockedContextWithStringArrayRes( - R.array.config_networkSupportedKeepaliveCount, - "config_networkSupportedKeepaliveCount", validRes) - val actual = KeepaliveUtils.getSupportedKeepalives(mockContext) - assertArrayEquals(expectedValidRes, actual) - } - - @Test - fun testGetSupportedKeepalivesForNetworkCapabilities() { - // Mock customized supported keepalives for each transport type, and assuming: - // 3 for cellular, - // 6 for wifi, - // 0 for others. - val cust = IntArray(MAX_TRANSPORT + 1).apply { - this[TRANSPORT_CELLULAR] = 3 - this[TRANSPORT_WIFI] = 6 - } - - val nc = NetworkCapabilities() - // Check supported keepalives with single transport type. - nc.transportTypes = intArrayOf(TRANSPORT_CELLULAR) - assertEquals(3, KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities(cust, nc)) - - // Check supported keepalives with multiple transport types. - nc.transportTypes = intArrayOf(TRANSPORT_WIFI, TRANSPORT_VPN) - assertEquals(0, KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities(cust, nc)) - - // Check supported keepalives with non-customized transport type. - nc.transportTypes = intArrayOf(TRANSPORT_ETHERNET) - assertEquals(0, KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities(cust, nc)) - - // Check supported keepalives with undefined transport type. - nc.transportTypes = intArrayOf(MAX_TRANSPORT + 1) - try { - KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities(cust, nc) - fail("Expected ArrayIndexOutOfBoundsException") - } catch (expected: ArrayIndexOutOfBoundsException) { - } - } -} diff --git a/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt b/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt deleted file mode 100644 index 25aa6266577e..000000000000 --- a/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.util - -import android.content.Context -import android.content.res.Resources -import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER -import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE -import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY -import android.net.ConnectivityResources -import android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI -import android.net.ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE -import android.net.util.MultinetworkPolicyTracker.ActiveDataSubscriptionIdListener -import android.provider.Settings -import android.telephony.SubscriptionInfo -import android.telephony.SubscriptionManager -import android.telephony.TelephonyManager -import android.test.mock.MockContentResolver -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.connectivity.resources.R -import com.android.internal.util.test.FakeSettingsProvider -import org.junit.After -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.ArgumentCaptor -import org.mockito.ArgumentMatchers.anyInt -import org.mockito.ArgumentMatchers.argThat -import org.mockito.ArgumentMatchers.eq -import org.mockito.Mockito.any -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.mock -import org.mockito.Mockito.times -import org.mockito.Mockito.verify - -/** - * Tests for [MultinetworkPolicyTracker]. - * - * Build, install and run with: - * atest android.net.util.MultinetworkPolicyTrackerTest - */ -@RunWith(AndroidJUnit4::class) -@SmallTest -class MultinetworkPolicyTrackerTest { - private val resources = mock(Resources::class.java).also { - doReturn(R.integer.config_networkAvoidBadWifi).`when`(it).getIdentifier( - eq("config_networkAvoidBadWifi"), eq("integer"), any()) - doReturn(0).`when`(it).getInteger(R.integer.config_networkAvoidBadWifi) - } - private val telephonyManager = mock(TelephonyManager::class.java) - private val subscriptionManager = mock(SubscriptionManager::class.java).also { - doReturn(null).`when`(it).getActiveSubscriptionInfo(anyInt()) - } - private val resolver = MockContentResolver().apply { - addProvider(Settings.AUTHORITY, FakeSettingsProvider()) } - private val context = mock(Context::class.java).also { - doReturn(Context.TELEPHONY_SERVICE).`when`(it) - .getSystemServiceName(TelephonyManager::class.java) - doReturn(telephonyManager).`when`(it).getSystemService(Context.TELEPHONY_SERVICE) - doReturn(subscriptionManager).`when`(it) - .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) - doReturn(resolver).`when`(it).contentResolver - doReturn(resources).`when`(it).resources - doReturn(it).`when`(it).createConfigurationContext(any()) - Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "1") - ConnectivityResources.setResourcesContextForTest(it) - } - private val tracker = MultinetworkPolicyTracker(context, null /* handler */) - - private fun assertMultipathPreference(preference: Int) { - Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE, - preference.toString()) - tracker.updateMeteredMultipathPreference() - assertEquals(preference, tracker.meteredMultipathPreference) - } - - @After - fun tearDown() { - ConnectivityResources.setResourcesContextForTest(null) - } - - @Test - fun testUpdateMeteredMultipathPreference() { - assertMultipathPreference(MULTIPATH_PREFERENCE_HANDOVER) - assertMultipathPreference(MULTIPATH_PREFERENCE_RELIABILITY) - assertMultipathPreference(MULTIPATH_PREFERENCE_PERFORMANCE) - } - - @Test - fun testUpdateAvoidBadWifi() { - Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "0") - assertTrue(tracker.updateAvoidBadWifi()) - assertFalse(tracker.avoidBadWifi) - - doReturn(1).`when`(resources).getInteger(R.integer.config_networkAvoidBadWifi) - assertTrue(tracker.updateAvoidBadWifi()) - assertTrue(tracker.avoidBadWifi) - } - - @Test - fun testOnActiveDataSubscriptionIdChanged() { - val testSubId = 1000 - val subscriptionInfo = SubscriptionInfo(testSubId, ""/* iccId */, 1/* iccId */, - "TMO"/* displayName */, "TMO"/* carrierName */, 1/* nameSource */, 1/* iconTint */, - "123"/* number */, 1/* roaming */, null/* icon */, "310"/* mcc */, "210"/* mnc */, - ""/* countryIso */, false/* isEmbedded */, null/* nativeAccessRules */, - "1"/* cardString */) - doReturn(subscriptionInfo).`when`(subscriptionManager).getActiveSubscriptionInfo(testSubId) - - // Modify avoidBadWifi and meteredMultipathPreference settings value and local variables in - // MultinetworkPolicyTracker should be also updated after subId changed. - Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "0") - Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE, - MULTIPATH_PREFERENCE_PERFORMANCE.toString()) - - val listenerCaptor = ArgumentCaptor.forClass( - ActiveDataSubscriptionIdListener::class.java) - verify(telephonyManager, times(1)) - .registerTelephonyCallback(any(), listenerCaptor.capture()) - val listener = listenerCaptor.value - listener.onActiveDataSubscriptionIdChanged(testSubId) - - // Check it get resource value with test sub id. - verify(subscriptionManager, times(1)).getActiveSubscriptionInfo(testSubId) - verify(context).createConfigurationContext(argThat { it.mcc == 310 && it.mnc == 210 }) - - // Check if avoidBadWifi and meteredMultipathPreference values have been updated. - assertFalse(tracker.avoidBadWifi) - assertEquals(MULTIPATH_PREFERENCE_PERFORMANCE, tracker.meteredMultipathPreference) - } -} diff --git a/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java b/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java deleted file mode 100644 index 3cfecd552967..000000000000 --- a/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.net; - -import static android.system.OsConstants.AF_INET; -import static android.system.OsConstants.AF_INET6; -import static android.system.OsConstants.AF_UNIX; -import static android.system.OsConstants.EPERM; -import static android.system.OsConstants.SOCK_DGRAM; -import static android.system.OsConstants.SOCK_STREAM; - -import static junit.framework.Assert.assertEquals; - -import static org.junit.Assert.fail; - -import android.system.ErrnoException; -import android.system.Os; - -import androidx.test.runner.AndroidJUnit4; - -import libcore.io.IoUtils; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@androidx.test.filters.SmallTest -public class NetworkUtilsInternalTest { - - private static void expectSocketSuccess(String msg, int domain, int type) { - try { - IoUtils.closeQuietly(Os.socket(domain, type, 0)); - } catch (ErrnoException e) { - fail(msg + e.getMessage()); - } - } - - private static void expectSocketPemissionError(String msg, int domain, int type) { - try { - IoUtils.closeQuietly(Os.socket(domain, type, 0)); - fail(msg); - } catch (ErrnoException e) { - assertEquals(msg, e.errno, EPERM); - } - } - - private static void expectHasNetworking() { - expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException", - AF_UNIX, SOCK_STREAM); - expectSocketSuccess("Creating a AF_INET socket shouldn't have thrown ErrnoException", - AF_INET, SOCK_DGRAM); - expectSocketSuccess("Creating a AF_INET6 socket shouldn't have thrown ErrnoException", - AF_INET6, SOCK_DGRAM); - } - - private static void expectNoNetworking() { - expectSocketSuccess("Creating a UNIX socket should not have thrown ErrnoException", - AF_UNIX, SOCK_STREAM); - expectSocketPemissionError( - "Creating a AF_INET socket should have thrown ErrnoException(EPERM)", - AF_INET, SOCK_DGRAM); - expectSocketPemissionError( - "Creating a AF_INET6 socket should have thrown ErrnoException(EPERM)", - AF_INET6, SOCK_DGRAM); - } - - @Test - public void testSetAllowNetworkingForProcess() { - expectHasNetworking(); - NetworkUtilsInternal.setAllowNetworkingForProcess(false); - expectNoNetworking(); - NetworkUtilsInternal.setAllowNetworkingForProcess(true); - expectHasNetworking(); - } -} diff --git a/tests/net/java/com/android/internal/net/VpnProfileTest.java b/tests/net/java/com/android/internal/net/VpnProfileTest.java deleted file mode 100644 index 46597d19ef1b..000000000000 --- a/tests/net/java/com/android/internal/net/VpnProfileTest.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.net; - -import static com.android.testutils.ParcelUtils.assertParcelSane; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.net.IpSecAlgorithm; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** Unit tests for {@link VpnProfile}. */ -@SmallTest -@RunWith(JUnit4.class) -public class VpnProfileTest { - private static final String DUMMY_PROFILE_KEY = "Test"; - - private static final int ENCODED_INDEX_AUTH_PARAMS_INLINE = 23; - private static final int ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS = 24; - - @Test - public void testDefaults() throws Exception { - final VpnProfile p = new VpnProfile(DUMMY_PROFILE_KEY); - - assertEquals(DUMMY_PROFILE_KEY, p.key); - assertEquals("", p.name); - assertEquals(VpnProfile.TYPE_PPTP, p.type); - assertEquals("", p.server); - assertEquals("", p.username); - assertEquals("", p.password); - assertEquals("", p.dnsServers); - assertEquals("", p.searchDomains); - assertEquals("", p.routes); - assertTrue(p.mppe); - assertEquals("", p.l2tpSecret); - assertEquals("", p.ipsecIdentifier); - assertEquals("", p.ipsecSecret); - assertEquals("", p.ipsecUserCert); - assertEquals("", p.ipsecCaCert); - assertEquals("", p.ipsecServerCert); - assertEquals(null, p.proxy); - assertTrue(p.getAllowedAlgorithms() != null && p.getAllowedAlgorithms().isEmpty()); - assertFalse(p.isBypassable); - assertFalse(p.isMetered); - assertEquals(1360, p.maxMtu); - assertFalse(p.areAuthParamsInline); - assertFalse(p.isRestrictedToTestNetworks); - } - - private VpnProfile getSampleIkev2Profile(String key) { - final VpnProfile p = new VpnProfile(key, true /* isRestrictedToTestNetworks */); - - p.name = "foo"; - p.type = VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS; - p.server = "bar"; - p.username = "baz"; - p.password = "qux"; - p.dnsServers = "8.8.8.8"; - p.searchDomains = ""; - p.routes = "0.0.0.0/0"; - p.mppe = false; - p.l2tpSecret = ""; - p.ipsecIdentifier = "quux"; - p.ipsecSecret = "quuz"; - p.ipsecUserCert = "corge"; - p.ipsecCaCert = "grault"; - p.ipsecServerCert = "garply"; - p.proxy = null; - p.setAllowedAlgorithms( - Arrays.asList( - IpSecAlgorithm.AUTH_CRYPT_AES_GCM, - IpSecAlgorithm.AUTH_HMAC_SHA512, - IpSecAlgorithm.CRYPT_AES_CBC)); - p.isBypassable = true; - p.isMetered = true; - p.maxMtu = 1350; - p.areAuthParamsInline = true; - - // Not saved, but also not compared. - p.saveLogin = true; - - return p; - } - - @Test - public void testEquals() { - assertEquals( - getSampleIkev2Profile(DUMMY_PROFILE_KEY), getSampleIkev2Profile(DUMMY_PROFILE_KEY)); - - final VpnProfile modified = getSampleIkev2Profile(DUMMY_PROFILE_KEY); - modified.maxMtu--; - assertNotEquals(getSampleIkev2Profile(DUMMY_PROFILE_KEY), modified); - } - - @Test - public void testParcelUnparcel() { - assertParcelSane(getSampleIkev2Profile(DUMMY_PROFILE_KEY), 23); - } - - @Test - public void testSetInvalidAlgorithmValueDelimiter() { - final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); - - try { - profile.setAllowedAlgorithms( - Arrays.asList("test" + VpnProfile.VALUE_DELIMITER + "test")); - fail("Expected failure due to value separator in algorithm name"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testSetInvalidAlgorithmListDelimiter() { - final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); - - try { - profile.setAllowedAlgorithms( - Arrays.asList("test" + VpnProfile.LIST_DELIMITER + "test")); - fail("Expected failure due to value separator in algorithm name"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testEncodeDecode() { - final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); - final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, profile.encode()); - assertEquals(profile, decoded); - } - - @Test - public void testEncodeDecodeTooManyValues() { - final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); - final byte[] tooManyValues = - (new String(profile.encode()) + VpnProfile.VALUE_DELIMITER + "invalid").getBytes(); - - assertNull(VpnProfile.decode(DUMMY_PROFILE_KEY, tooManyValues)); - } - - private String getEncodedDecodedIkev2ProfileMissingValues(int... missingIndices) { - // Sort to ensure when we remove, we can do it from greatest first. - Arrays.sort(missingIndices); - - final String encoded = new String(getSampleIkev2Profile(DUMMY_PROFILE_KEY).encode()); - final List<String> parts = - new ArrayList<>(Arrays.asList(encoded.split(VpnProfile.VALUE_DELIMITER))); - - // Remove from back first to ensure indexing is consistent. - for (int i = missingIndices.length - 1; i >= 0; i--) { - parts.remove(missingIndices[i]); - } - - return String.join(VpnProfile.VALUE_DELIMITER, parts.toArray(new String[0])); - } - - @Test - public void testEncodeDecodeInvalidNumberOfValues() { - final String tooFewValues = - getEncodedDecodedIkev2ProfileMissingValues( - ENCODED_INDEX_AUTH_PARAMS_INLINE, - ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS /* missingIndices */); - - assertNull(VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes())); - } - - @Test - public void testEncodeDecodeMissingIsRestrictedToTestNetworks() { - final String tooFewValues = - getEncodedDecodedIkev2ProfileMissingValues( - ENCODED_INDEX_RESTRICTED_TO_TEST_NETWORKS /* missingIndices */); - - // Verify decoding without isRestrictedToTestNetworks defaults to false - final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, tooFewValues.getBytes()); - assertFalse(decoded.isRestrictedToTestNetworks); - } - - @Test - public void testEncodeDecodeLoginsNotSaved() { - final VpnProfile profile = getSampleIkev2Profile(DUMMY_PROFILE_KEY); - profile.saveLogin = false; - - final VpnProfile decoded = VpnProfile.decode(DUMMY_PROFILE_KEY, profile.encode()); - assertNotEquals(profile, decoded); - - // Add the username/password back, everything else must be equal. - decoded.username = profile.username; - decoded.password = profile.password; - assertEquals(profile, decoded); - } -} diff --git a/tests/net/java/com/android/internal/util/BitUtilsTest.java b/tests/net/java/com/android/internal/util/BitUtilsTest.java deleted file mode 100644 index d2fbdce9771a..000000000000 --- a/tests/net/java/com/android/internal/util/BitUtilsTest.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.util; - -import static com.android.internal.util.BitUtils.bytesToBEInt; -import static com.android.internal.util.BitUtils.bytesToLEInt; -import static com.android.internal.util.BitUtils.getUint16; -import static com.android.internal.util.BitUtils.getUint32; -import static com.android.internal.util.BitUtils.getUint8; -import static com.android.internal.util.BitUtils.packBits; -import static com.android.internal.util.BitUtils.uint16; -import static com.android.internal.util.BitUtils.uint32; -import static com.android.internal.util.BitUtils.uint8; -import static com.android.internal.util.BitUtils.unpackBits; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Random; - -@SmallTest -@RunWith(AndroidJUnit4.class) -public class BitUtilsTest { - - @Test - public void testUnsignedByteWideningConversions() { - byte b0 = 0; - byte b1 = 1; - byte bm1 = -1; - assertEquals(0, uint8(b0)); - assertEquals(1, uint8(b1)); - assertEquals(127, uint8(Byte.MAX_VALUE)); - assertEquals(128, uint8(Byte.MIN_VALUE)); - assertEquals(255, uint8(bm1)); - assertEquals(255, uint8((byte)255)); - } - - @Test - public void testUnsignedShortWideningConversions() { - short s0 = 0; - short s1 = 1; - short sm1 = -1; - assertEquals(0, uint16(s0)); - assertEquals(1, uint16(s1)); - assertEquals(32767, uint16(Short.MAX_VALUE)); - assertEquals(32768, uint16(Short.MIN_VALUE)); - assertEquals(65535, uint16(sm1)); - assertEquals(65535, uint16((short)65535)); - } - - @Test - public void testUnsignedShortComposition() { - byte b0 = 0; - byte b1 = 1; - byte b2 = 2; - byte b10 = 10; - byte b16 = 16; - byte b128 = -128; - byte b224 = -32; - byte b255 = -1; - assertEquals(0x0000, uint16(b0, b0)); - assertEquals(0xffff, uint16(b255, b255)); - assertEquals(0x0a01, uint16(b10, b1)); - assertEquals(0x8002, uint16(b128, b2)); - assertEquals(0x01ff, uint16(b1, b255)); - assertEquals(0x80ff, uint16(b128, b255)); - assertEquals(0xe010, uint16(b224, b16)); - } - - @Test - public void testUnsignedIntWideningConversions() { - assertEquals(0, uint32(0)); - assertEquals(1, uint32(1)); - assertEquals(2147483647L, uint32(Integer.MAX_VALUE)); - assertEquals(2147483648L, uint32(Integer.MIN_VALUE)); - assertEquals(4294967295L, uint32(-1)); - assertEquals(4294967295L, uint32((int)4294967295L)); - } - - @Test - public void testBytesToInt() { - assertEquals(0x00000000, bytesToBEInt(bytes(0, 0, 0, 0))); - assertEquals(0xffffffff, bytesToBEInt(bytes(255, 255, 255, 255))); - assertEquals(0x0a000001, bytesToBEInt(bytes(10, 0, 0, 1))); - assertEquals(0x0a000002, bytesToBEInt(bytes(10, 0, 0, 2))); - assertEquals(0x0a001fff, bytesToBEInt(bytes(10, 0, 31, 255))); - assertEquals(0xe0000001, bytesToBEInt(bytes(224, 0, 0, 1))); - - assertEquals(0x00000000, bytesToLEInt(bytes(0, 0, 0, 0))); - assertEquals(0x01020304, bytesToLEInt(bytes(4, 3, 2, 1))); - assertEquals(0xffff0000, bytesToLEInt(bytes(0, 0, 255, 255))); - } - - @Test - public void testUnsignedGetters() { - ByteBuffer b = ByteBuffer.allocate(4); - b.putInt(0xffff); - - assertEquals(0x0, getUint8(b, 0)); - assertEquals(0x0, getUint8(b, 1)); - assertEquals(0xff, getUint8(b, 2)); - assertEquals(0xff, getUint8(b, 3)); - - assertEquals(0x0, getUint16(b, 0)); - assertEquals(0xffff, getUint16(b, 2)); - - b.rewind(); - b.putInt(0xffffffff); - assertEquals(0xffffffffL, getUint32(b, 0)); - } - - @Test - public void testBitsPacking() { - BitPackingTestCase[] testCases = { - new BitPackingTestCase(0, ints()), - new BitPackingTestCase(1, ints(0)), - new BitPackingTestCase(2, ints(1)), - new BitPackingTestCase(3, ints(0, 1)), - new BitPackingTestCase(4, ints(2)), - new BitPackingTestCase(6, ints(1, 2)), - new BitPackingTestCase(9, ints(0, 3)), - new BitPackingTestCase(~Long.MAX_VALUE, ints(63)), - new BitPackingTestCase(~Long.MAX_VALUE + 1, ints(0, 63)), - new BitPackingTestCase(~Long.MAX_VALUE + 2, ints(1, 63)), - }; - for (BitPackingTestCase tc : testCases) { - int[] got = unpackBits(tc.packedBits); - assertTrue( - "unpackBits(" - + tc.packedBits - + "): expected " - + Arrays.toString(tc.bits) - + " but got " - + Arrays.toString(got), - Arrays.equals(tc.bits, got)); - } - for (BitPackingTestCase tc : testCases) { - long got = packBits(tc.bits); - assertEquals( - "packBits(" - + Arrays.toString(tc.bits) - + "): expected " - + tc.packedBits - + " but got " - + got, - tc.packedBits, - got); - } - - long[] moreTestCases = { - 0, 1, -1, 23895, -908235, Long.MAX_VALUE, Long.MIN_VALUE, new Random().nextLong(), - }; - for (long l : moreTestCases) { - assertEquals(l, packBits(unpackBits(l))); - } - } - - static byte[] bytes(int b1, int b2, int b3, int b4) { - return new byte[] {b(b1), b(b2), b(b3), b(b4)}; - } - - static byte b(int i) { - return (byte) i; - } - - static int[] ints(int... array) { - return array; - } - - static class BitPackingTestCase { - final int[] bits; - final long packedBits; - - BitPackingTestCase(long packedBits, int[] bits) { - this.bits = bits; - this.packedBits = packedBits; - } - } -} diff --git a/tests/net/java/com/android/internal/util/RingBufferTest.java b/tests/net/java/com/android/internal/util/RingBufferTest.java deleted file mode 100644 index d06095a690cf..000000000000 --- a/tests/net/java/com/android/internal/util/RingBufferTest.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.util; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@SmallTest -@RunWith(AndroidJUnit4.class) -public class RingBufferTest { - - @Test - public void testEmptyRingBuffer() { - RingBuffer<String> buffer = new RingBuffer<>(String.class, 100); - - assertArrayEquals(new String[0], buffer.toArray()); - } - - @Test - public void testIncorrectConstructorArguments() { - try { - RingBuffer<String> buffer = new RingBuffer<>(String.class, -10); - fail("Should not be able to create a negative capacity RingBuffer"); - } catch (IllegalArgumentException expected) { - } - - try { - RingBuffer<String> buffer = new RingBuffer<>(String.class, 0); - fail("Should not be able to create a 0 capacity RingBuffer"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testRingBufferWithNoWrapping() { - RingBuffer<String> buffer = new RingBuffer<>(String.class, 100); - - buffer.append("a"); - buffer.append("b"); - buffer.append("c"); - buffer.append("d"); - buffer.append("e"); - - String[] expected = {"a", "b", "c", "d", "e"}; - assertArrayEquals(expected, buffer.toArray()); - } - - @Test - public void testRingBufferWithCapacity1() { - RingBuffer<String> buffer = new RingBuffer<>(String.class, 1); - - buffer.append("a"); - assertArrayEquals(new String[]{"a"}, buffer.toArray()); - - buffer.append("b"); - assertArrayEquals(new String[]{"b"}, buffer.toArray()); - - buffer.append("c"); - assertArrayEquals(new String[]{"c"}, buffer.toArray()); - - buffer.append("d"); - assertArrayEquals(new String[]{"d"}, buffer.toArray()); - - buffer.append("e"); - assertArrayEquals(new String[]{"e"}, buffer.toArray()); - } - - @Test - public void testRingBufferWithWrapping() { - int capacity = 100; - RingBuffer<String> buffer = new RingBuffer<>(String.class, capacity); - - buffer.append("a"); - buffer.append("b"); - buffer.append("c"); - buffer.append("d"); - buffer.append("e"); - - String[] expected1 = {"a", "b", "c", "d", "e"}; - assertArrayEquals(expected1, buffer.toArray()); - - String[] expected2 = new String[capacity]; - int firstIndex = 0; - int lastIndex = capacity - 1; - - expected2[firstIndex] = "e"; - for (int i = 1; i < capacity; i++) { - buffer.append("x"); - expected2[i] = "x"; - } - assertArrayEquals(expected2, buffer.toArray()); - - buffer.append("x"); - expected2[firstIndex] = "x"; - assertArrayEquals(expected2, buffer.toArray()); - - for (int i = 0; i < 10; i++) { - for (String s : expected2) { - buffer.append(s); - } - } - assertArrayEquals(expected2, buffer.toArray()); - - buffer.append("a"); - expected2[lastIndex] = "a"; - assertArrayEquals(expected2, buffer.toArray()); - } - - @Test - public void testGetNextSlot() { - int capacity = 100; - RingBuffer<DummyClass1> buffer = new RingBuffer<>(DummyClass1.class, capacity); - - final DummyClass1[] actual = new DummyClass1[capacity]; - final DummyClass1[] expected = new DummyClass1[capacity]; - for (int i = 0; i < capacity; ++i) { - final DummyClass1 obj = buffer.getNextSlot(); - obj.x = capacity * i; - actual[i] = obj; - expected[i] = new DummyClass1(); - expected[i].x = capacity * i; - } - assertArrayEquals(expected, buffer.toArray()); - - for (int i = 0; i < capacity; ++i) { - if (actual[i] != buffer.getNextSlot()) { - fail("getNextSlot() should re-use objects if available"); - } - } - - RingBuffer<DummyClass2> buffer2 = new RingBuffer<>(DummyClass2.class, capacity); - assertNull("getNextSlot() should return null if the object can't be initiated " - + "(No nullary constructor)", buffer2.getNextSlot()); - - RingBuffer<DummyClass3> buffer3 = new RingBuffer<>(DummyClass3.class, capacity); - assertNull("getNextSlot() should return null if the object can't be initiated " - + "(Inaccessible class)", buffer3.getNextSlot()); - } - - public static final class DummyClass1 { - int x; - - public boolean equals(Object o) { - if (o instanceof DummyClass1) { - final DummyClass1 other = (DummyClass1) o; - return other.x == this.x; - } - return false; - } - } - - public static final class DummyClass2 { - public DummyClass2(int x) {} - } - - private static final class DummyClass3 {} -} diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java deleted file mode 100644 index 63501d7662ed..000000000000 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ /dev/null @@ -1,12792 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server; - -import static android.Manifest.permission.CHANGE_NETWORK_STATE; -import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; -import static android.Manifest.permission.DUMP; -import static android.Manifest.permission.LOCAL_MAC_ADDRESS; -import static android.Manifest.permission.NETWORK_FACTORY; -import static android.Manifest.permission.NETWORK_SETTINGS; -import static android.app.PendingIntent.FLAG_IMMUTABLE; -import static android.content.Intent.ACTION_PACKAGE_ADDED; -import static android.content.Intent.ACTION_PACKAGE_REMOVED; -import static android.content.Intent.ACTION_PACKAGE_REPLACED; -import static android.content.Intent.ACTION_USER_ADDED; -import static android.content.Intent.ACTION_USER_REMOVED; -import static android.content.Intent.ACTION_USER_UNLOCKED; -import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; -import static android.content.pm.PackageManager.FEATURE_WIFI; -import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT; -import static android.content.pm.PackageManager.GET_PERMISSIONS; -import static android.content.pm.PackageManager.MATCH_ANY_USER; -import static android.content.pm.PackageManager.PERMISSION_DENIED; -import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; -import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER; -import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK; -import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED; -import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER; -import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; -import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; -import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; -import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; -import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT; -import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE; -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_MOBILE_SUPL; -import static android.net.ConnectivityManager.TYPE_PROXY; -import static android.net.ConnectivityManager.TYPE_VPN; -import static android.net.ConnectivityManager.TYPE_WIFI; -import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF; -import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; -import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; -import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS; -import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK; -import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP; -import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS; -import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; -import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; -import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; -import static android.net.NetworkCapabilities.NET_CAPABILITY_BIP; -import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; -import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS; -import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; -import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS; -import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE; -import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; -import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA; -import static android.net.NetworkCapabilities.NET_CAPABILITY_IA; -import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; -import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; -import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; -import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; -import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; -import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; -import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS; -import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL; -import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_VSIM; -import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P; -import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP; -import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; -import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS; -import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; -import static android.net.NetworkCapabilities.REDACT_NONE; -import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; -import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; -import static android.net.NetworkCapabilities.TRANSPORT_VPN; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE; -import static android.net.NetworkScore.KEEP_CONNECTED_FOR_HANDOVER; -import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; -import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; -import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; -import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; -import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED; -import static android.net.RouteInfo.RTN_UNREACHABLE; -import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED; -import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_REMOVED; -import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; -import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; -import static android.os.Process.INVALID_UID; -import static android.system.OsConstants.IPPROTO_TCP; - -import static com.android.server.ConnectivityServiceTestUtils.transportToLegacyType; -import static com.android.testutils.ConcurrentUtils.await; -import static com.android.testutils.ConcurrentUtils.durationOf; -import static com.android.testutils.ExceptionUtils.ignoreExceptions; -import static com.android.testutils.HandlerUtils.waitForIdleSerialExecutor; -import static com.android.testutils.MiscAsserts.assertContainsAll; -import static com.android.testutils.MiscAsserts.assertContainsExactly; -import static com.android.testutils.MiscAsserts.assertEmpty; -import static com.android.testutils.MiscAsserts.assertLength; -import static com.android.testutils.MiscAsserts.assertRunsInAtMost; -import static com.android.testutils.MiscAsserts.assertThrows; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.AdditionalMatchers.aryEq; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isNull; -import static org.mockito.ArgumentMatchers.startsWith; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.Manifest; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.AlarmManager; -import android.app.AppOpsManager; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.usage.NetworkStatsManager; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.ContentProvider; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.pm.ServiceInfo; -import android.content.pm.UserInfo; -import android.content.res.Resources; -import android.location.LocationManager; -import android.net.CaptivePortalData; -import android.net.ConnectionInfo; -import android.net.ConnectivityManager; -import android.net.ConnectivityManager.NetworkCallback; -import android.net.ConnectivityManager.PacketKeepalive; -import android.net.ConnectivityManager.PacketKeepaliveCallback; -import android.net.ConnectivityManager.TooManyRequestsException; -import android.net.ConnectivityResources; -import android.net.ConnectivitySettingsManager; -import android.net.ConnectivityThread; -import android.net.DataStallReportParcelable; -import android.net.EthernetManager; -import android.net.IConnectivityDiagnosticsCallback; -import android.net.IDnsResolver; -import android.net.INetd; -import android.net.INetworkMonitor; -import android.net.INetworkMonitorCallbacks; -import android.net.IOnCompleteListener; -import android.net.IQosCallback; -import android.net.InetAddresses; -import android.net.InterfaceConfigurationParcel; -import android.net.IpPrefix; -import android.net.IpSecManager; -import android.net.IpSecManager.UdpEncapsulationSocket; -import android.net.LinkAddress; -import android.net.LinkProperties; -import android.net.MatchAllNetworkSpecifier; -import android.net.NativeNetworkConfig; -import android.net.NativeNetworkType; -import android.net.Network; -import android.net.NetworkAgent; -import android.net.NetworkAgentConfig; -import android.net.NetworkCapabilities; -import android.net.NetworkFactory; -import android.net.NetworkInfo; -import android.net.NetworkInfo.DetailedState; -import android.net.NetworkPolicyManager; -import android.net.NetworkPolicyManager.NetworkPolicyCallback; -import android.net.NetworkRequest; -import android.net.NetworkScore; -import android.net.NetworkSpecifier; -import android.net.NetworkStack; -import android.net.NetworkStateSnapshot; -import android.net.NetworkTestResultParcelable; -import android.net.OemNetworkPreferences; -import android.net.ProxyInfo; -import android.net.QosCallbackException; -import android.net.QosFilter; -import android.net.QosSession; -import android.net.ResolverParamsParcel; -import android.net.RouteInfo; -import android.net.RouteInfoParcel; -import android.net.SocketKeepalive; -import android.net.TransportInfo; -import android.net.UidRange; -import android.net.UidRangeParcel; -import android.net.UnderlyingNetworkInfo; -import android.net.Uri; -import android.net.VpnManager; -import android.net.VpnTransportInfo; -import android.net.metrics.IpConnectivityLog; -import android.net.networkstack.NetworkStackClientBase; -import android.net.resolv.aidl.Nat64PrefixEventParcel; -import android.net.resolv.aidl.PrivateDnsValidationEventParcel; -import android.net.shared.NetworkMonitorUtils; -import android.net.shared.PrivateDnsConfig; -import android.net.util.MultinetworkPolicyTracker; -import android.os.BadParcelableException; -import android.os.Binder; -import android.os.Build; -import android.os.Bundle; -import android.os.ConditionVariable; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.os.INetworkManagementService; -import android.os.Looper; -import android.os.Parcel; -import android.os.ParcelFileDescriptor; -import android.os.Parcelable; -import android.os.Process; -import android.os.RemoteException; -import android.os.ServiceSpecificException; -import android.os.SystemClock; -import android.os.SystemConfigManager; -import android.os.UserHandle; -import android.os.UserManager; -import android.provider.Settings; -import android.security.Credentials; -import android.system.Os; -import android.telephony.TelephonyManager; -import android.telephony.data.EpsBearerQosSessionAttributes; -import android.telephony.data.NrQosSessionAttributes; -import android.test.mock.MockContentResolver; -import android.text.TextUtils; -import android.util.ArraySet; -import android.util.Log; -import android.util.Pair; -import android.util.Range; -import android.util.SparseArray; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.connectivity.resources.R; -import com.android.internal.net.VpnConfig; -import com.android.internal.net.VpnProfile; -import com.android.internal.util.ArrayUtils; -import com.android.internal.util.WakeupMessage; -import com.android.internal.util.test.BroadcastInterceptingContext; -import com.android.internal.util.test.FakeSettingsProvider; -import com.android.net.module.util.ArrayTrackRecord; -import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo; -import com.android.server.connectivity.MockableSystemProperties; -import com.android.server.connectivity.Nat464Xlat; -import com.android.server.connectivity.NetworkAgentInfo; -import com.android.server.connectivity.NetworkNotificationManager.NotificationType; -import com.android.server.connectivity.ProxyTracker; -import com.android.server.connectivity.QosCallbackTracker; -import com.android.server.connectivity.Vpn; -import com.android.server.connectivity.VpnProfileStore; -import com.android.server.net.NetworkPinner; -import com.android.testutils.ExceptionUtils; -import com.android.testutils.HandlerUtils; -import com.android.testutils.RecorderCallback.CallbackEntry; -import com.android.testutils.TestableNetworkCallback; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.AdditionalAnswers; -import org.mockito.ArgumentCaptor; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.Spy; -import org.mockito.stubbing.Answer; - -import java.io.FileDescriptor; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.net.DatagramSocket; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import kotlin.reflect.KClass; - -/** - * Tests for {@link ConnectivityService}. - * - * Build, install and run with: - * runtest frameworks-net -c com.android.server.ConnectivityServiceTest - */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class ConnectivityServiceTest { - private static final String TAG = "ConnectivityServiceTest"; - - private static final int TIMEOUT_MS = 500; - // Broadcasts can take a long time to be delivered. The test will not wait for that long unless - // there is a failure, so use a long timeout. - private static final int BROADCAST_TIMEOUT_MS = 30_000; - private static final int TEST_LINGER_DELAY_MS = 400; - private static final int TEST_NASCENT_DELAY_MS = 300; - // Chosen to be less than the linger and nascent timeout. This ensures that we can distinguish - // between a LOST callback that arrives immediately and a LOST callback that arrives after - // the linger/nascent timeout. For this, our assertions should run fast enough to leave - // less than (mService.mLingerDelayMs - TEST_CALLBACK_TIMEOUT_MS) between the time callbacks are - // supposedly fired, and the time we call expectCallback. - private static final int TEST_CALLBACK_TIMEOUT_MS = 250; - // Chosen to be less than TEST_CALLBACK_TIMEOUT_MS. This ensures that requests have time to - // complete before callbacks are verified. - private static final int TEST_REQUEST_TIMEOUT_MS = 150; - - private static final int UNREASONABLY_LONG_ALARM_WAIT_MS = 1000; - - private static final long TIMESTAMP = 1234L; - - private static final int NET_ID = 110; - private static final int OEM_PREF_ANY_NET_ID = -1; - // Set a non-zero value to verify the flow to set tcp init rwnd value. - private static final int TEST_TCP_INIT_RWND = 60; - - // Used for testing the per-work-profile default network. - private static final int TEST_APP_ID = 103; - private static final int TEST_WORK_PROFILE_USER_ID = 2; - private static final int TEST_WORK_PROFILE_APP_UID = - UserHandle.getUid(TEST_WORK_PROFILE_USER_ID, TEST_APP_ID); - private static final String CLAT_PREFIX = "v4-"; - private static final String MOBILE_IFNAME = "test_rmnet_data0"; - private static final String WIFI_IFNAME = "test_wlan0"; - private static final String WIFI_WOL_IFNAME = "test_wlan_wol"; - private static final String VPN_IFNAME = "tun10042"; - private static final String TEST_PACKAGE_NAME = "com.android.test.package"; - private static final int TEST_PACKAGE_UID = 123; - private static final String ALWAYS_ON_PACKAGE = "com.android.test.alwaysonvpn"; - - private static final String INTERFACE_NAME = "interface"; - - private static final String TEST_VENUE_URL_NA_PASSPOINT = "https://android.com/"; - private static final String TEST_VENUE_URL_NA_OTHER = "https://example.com/"; - private static final String TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT = - "https://android.com/terms/"; - private static final String TEST_TERMS_AND_CONDITIONS_URL_NA_OTHER = - "https://example.com/terms/"; - private static final String TEST_VENUE_URL_CAPPORT = "https://android.com/capport/"; - private static final String TEST_USER_PORTAL_API_URL_CAPPORT = - "https://android.com/user/api/capport/"; - private static final String TEST_FRIENDLY_NAME = "Network friendly name"; - private static final String TEST_REDIRECT_URL = "http://example.com/firstPath"; - - private MockContext mServiceContext; - private HandlerThread mCsHandlerThread; - private HandlerThread mVMSHandlerThread; - private ConnectivityService.Dependencies mDeps; - private ConnectivityService mService; - private WrappedConnectivityManager mCm; - private TestNetworkAgentWrapper mWiFiNetworkAgent; - private TestNetworkAgentWrapper mCellNetworkAgent; - private TestNetworkAgentWrapper mEthernetNetworkAgent; - private MockVpn mMockVpn; - private Context mContext; - private NetworkPolicyCallback mPolicyCallback; - private WrappedMultinetworkPolicyTracker mPolicyTracker; - private HandlerThread mAlarmManagerThread; - private TestNetIdManager mNetIdManager; - private QosCallbackMockHelper mQosCallbackMockHelper; - private QosCallbackTracker mQosCallbackTracker; - private VpnManagerService mVpnManagerService; - private TestNetworkCallback mDefaultNetworkCallback; - private TestNetworkCallback mSystemDefaultNetworkCallback; - private TestNetworkCallback mProfileDefaultNetworkCallback; - - // State variables required to emulate NetworkPolicyManagerService behaviour. - private int mBlockedReasons = BLOCKED_REASON_NONE; - - @Mock DeviceIdleInternal mDeviceIdleInternal; - @Mock INetworkManagementService mNetworkManagementService; - @Mock NetworkStatsManager mStatsManager; - @Mock IDnsResolver mMockDnsResolver; - @Mock INetd mMockNetd; - @Mock NetworkStackClientBase mNetworkStack; - @Mock PackageManager mPackageManager; - @Mock UserManager mUserManager; - @Mock NotificationManager mNotificationManager; - @Mock AlarmManager mAlarmManager; - @Mock IConnectivityDiagnosticsCallback mConnectivityDiagnosticsCallback; - @Mock IBinder mIBinder; - @Mock LocationManager mLocationManager; - @Mock AppOpsManager mAppOpsManager; - @Mock TelephonyManager mTelephonyManager; - @Mock MockableSystemProperties mSystemProperties; - @Mock EthernetManager mEthernetManager; - @Mock NetworkPolicyManager mNetworkPolicyManager; - @Mock VpnProfileStore mVpnProfileStore; - @Mock SystemConfigManager mSystemConfigManager; - @Mock Resources mResources; - - private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor = - ArgumentCaptor.forClass(ResolverParamsParcel.class); - - // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods - // do not go through ConnectivityService but talk to netd directly, so they don't automatically - // reflect the state of our test ConnectivityService. - private class WrappedConnectivityManager extends ConnectivityManager { - private Network mFakeBoundNetwork; - - public synchronized boolean bindProcessToNetwork(Network network) { - mFakeBoundNetwork = network; - return true; - } - - public synchronized Network getBoundNetworkForProcess() { - return mFakeBoundNetwork; - } - - public WrappedConnectivityManager(Context context, ConnectivityService service) { - super(context, service); - } - } - - private class MockContext extends BroadcastInterceptingContext { - private final MockContentResolver mContentResolver; - - @Spy private Resources mInternalResources; - private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>(); - - // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant - private final HashMap<String, Integer> mMockedPermissions = new HashMap<>(); - - MockContext(Context base, ContentProvider settingsProvider) { - super(base); - - mInternalResources = spy(base.getResources()); - when(mInternalResources.getStringArray(com.android.internal.R.array.networkAttributes)) - .thenReturn(new String[] { - "wifi,1,1,1,-1,true", - "mobile,0,0,0,-1,true", - "mobile_mms,2,0,2,60000,true", - "mobile_supl,3,0,2,60000,true", - }); - - mContentResolver = new MockContentResolver(); - mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider); - } - - @Override - public void startActivityAsUser(Intent intent, UserHandle handle) { - mStartedActivities.offer(intent); - } - - public Intent expectStartActivityIntent(int timeoutMs) { - Intent intent = null; - try { - intent = mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) {} - assertNotNull("Did not receive sign-in intent after " + timeoutMs + "ms", intent); - return intent; - } - - public void expectNoStartActivityIntent(int timeoutMs) { - try { - assertNull("Received unexpected Intent to start activity", - mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS)); - } catch (InterruptedException e) {} - } - - @Override - public ComponentName startService(Intent service) { - final String action = service.getAction(); - if (!VpnConfig.SERVICE_INTERFACE.equals(action)) { - fail("Attempt to start unknown service, action=" + action); - } - return new ComponentName(service.getPackage(), "com.android.test.Service"); - } - - @Override - public Object getSystemService(String name) { - if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; - if (Context.NOTIFICATION_SERVICE.equals(name)) return mNotificationManager; - if (Context.USER_SERVICE.equals(name)) return mUserManager; - if (Context.ALARM_SERVICE.equals(name)) return mAlarmManager; - if (Context.LOCATION_SERVICE.equals(name)) return mLocationManager; - if (Context.APP_OPS_SERVICE.equals(name)) return mAppOpsManager; - if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; - if (Context.ETHERNET_SERVICE.equals(name)) return mEthernetManager; - if (Context.NETWORK_POLICY_SERVICE.equals(name)) return mNetworkPolicyManager; - if (Context.SYSTEM_CONFIG_SERVICE.equals(name)) return mSystemConfigManager; - if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; - return super.getSystemService(name); - } - - final HashMap<UserHandle, UserManager> mUserManagers = new HashMap<>(); - @Override - public Context createContextAsUser(UserHandle user, int flags) { - final Context asUser = mock(Context.class, AdditionalAnswers.delegatesTo(this)); - doReturn(user).when(asUser).getUser(); - doAnswer((inv) -> { - final UserManager um = mUserManagers.computeIfAbsent(user, - u -> mock(UserManager.class, AdditionalAnswers.delegatesTo(mUserManager))); - return um; - }).when(asUser).getSystemService(Context.USER_SERVICE); - return asUser; - } - - public void setWorkProfile(@NonNull final UserHandle userHandle, boolean value) { - // This relies on all contexts for a given user returning the same UM mock - final UserManager umMock = createContextAsUser(userHandle, 0 /* flags */) - .getSystemService(UserManager.class); - doReturn(value).when(umMock).isManagedProfile(); - doReturn(value).when(mUserManager).isManagedProfile(eq(userHandle.getIdentifier())); - } - - @Override - public ContentResolver getContentResolver() { - return mContentResolver; - } - - @Override - public Resources getResources() { - return mInternalResources; - } - - @Override - public PackageManager getPackageManager() { - return mPackageManager; - } - - private int checkMockedPermission(String permission, Supplier<Integer> ifAbsent) { - final Integer granted = mMockedPermissions.get(permission); - return granted != null ? granted : ifAbsent.get(); - } - - @Override - public int checkPermission(String permission, int pid, int uid) { - return checkMockedPermission( - permission, () -> super.checkPermission(permission, pid, uid)); - } - - @Override - public int checkCallingOrSelfPermission(String permission) { - return checkMockedPermission( - permission, () -> super.checkCallingOrSelfPermission(permission)); - } - - @Override - public void enforceCallingOrSelfPermission(String permission, String message) { - final Integer granted = mMockedPermissions.get(permission); - if (granted == null) { - super.enforceCallingOrSelfPermission(permission, message); - return; - } - - if (!granted.equals(PERMISSION_GRANTED)) { - throw new SecurityException("[Test] permission denied: " + permission); - } - } - - /** - * Mock checks for the specified permission, and have them behave as per {@code granted}. - * - * <p>Passing null reverts to default behavior, which does a real permission check on the - * test package. - * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or - * {@link PackageManager#PERMISSION_DENIED}. - */ - public void setPermission(String permission, Integer granted) { - mMockedPermissions.put(permission, granted); - } - } - - private void waitForIdle() { - HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); - waitForIdle(mCellNetworkAgent, TIMEOUT_MS); - waitForIdle(mWiFiNetworkAgent, TIMEOUT_MS); - waitForIdle(mEthernetNetworkAgent, TIMEOUT_MS); - HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); - HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); - } - - private void waitForIdle(TestNetworkAgentWrapper agent, long timeoutMs) { - if (agent == null) { - return; - } - agent.waitForIdle(timeoutMs); - } - - @Test - public void testWaitForIdle() throws Exception { - final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. - - // Tests that waitForIdle returns immediately if the service is already idle. - for (int i = 0; i < attempts; i++) { - waitForIdle(); - } - - // Bring up a network that we can use to send messages to ConnectivityService. - ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - b.expectBroadcast(); - Network n = mWiFiNetworkAgent.getNetwork(); - assertNotNull(n); - - // Tests that calling waitForIdle waits for messages to be processed. - for (int i = 0; i < attempts; i++) { - mWiFiNetworkAgent.setSignalStrength(i); - waitForIdle(); - assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength()); - } - } - - // This test has an inherent race condition in it, and cannot be enabled for continuous testing - // or presubmit tests. It is kept for manual runs and documentation purposes. - @Ignore - public void verifyThatNotWaitingForIdleCausesRaceConditions() throws Exception { - // Bring up a network that we can use to send messages to ConnectivityService. - ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - b.expectBroadcast(); - Network n = mWiFiNetworkAgent.getNetwork(); - assertNotNull(n); - - // Ensure that not calling waitForIdle causes a race condition. - final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. - for (int i = 0; i < attempts; i++) { - mWiFiNetworkAgent.setSignalStrength(i); - if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) { - // We hit a race condition, as expected. Pass the test. - return; - } - } - - // No race? There is a bug in this test. - fail("expected race condition at least once in " + attempts + " attempts"); - } - - private class TestNetworkAgentWrapper extends NetworkAgentWrapper { - private static final int VALIDATION_RESULT_INVALID = 0; - - private static final long DATA_STALL_TIMESTAMP = 10L; - private static final int DATA_STALL_DETECTION_METHOD = 1; - - private INetworkMonitor mNetworkMonitor; - private INetworkMonitorCallbacks mNmCallbacks; - private int mNmValidationResult = VALIDATION_RESULT_INVALID; - private int mProbesCompleted; - private int mProbesSucceeded; - private String mNmValidationRedirectUrl = null; - private boolean mNmProvNotificationRequested = false; - private Runnable mCreatedCallback; - private Runnable mUnwantedCallback; - private Runnable mDisconnectedCallback; - - private final ConditionVariable mNetworkStatusReceived = new ConditionVariable(); - // Contains the redirectUrl from networkStatus(). Before reading, wait for - // mNetworkStatusReceived. - private String mRedirectUrl; - - TestNetworkAgentWrapper(int transport) throws Exception { - this(transport, new LinkProperties(), null); - } - - TestNetworkAgentWrapper(int transport, LinkProperties linkProperties) - throws Exception { - this(transport, linkProperties, null); - } - - private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties, - NetworkCapabilities ncTemplate) throws Exception { - super(transport, linkProperties, ncTemplate, mServiceContext); - - // Waits for the NetworkAgent to be registered, which includes the creation of the - // NetworkMonitor. - waitForIdle(TIMEOUT_MS); - HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); - HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS); - } - - @Override - protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties, - NetworkAgentConfig nac) throws Exception { - mNetworkMonitor = mock(INetworkMonitor.class); - - final Answer validateAnswer = inv -> { - new Thread(ignoreExceptions(this::onValidationRequested)).start(); - return null; - }; - - doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any()); - doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt()); - - final ArgumentCaptor<Network> nmNetworkCaptor = ArgumentCaptor.forClass(Network.class); - final ArgumentCaptor<INetworkMonitorCallbacks> nmCbCaptor = - ArgumentCaptor.forClass(INetworkMonitorCallbacks.class); - doNothing().when(mNetworkStack).makeNetworkMonitor( - nmNetworkCaptor.capture(), - any() /* name */, - nmCbCaptor.capture()); - - final InstrumentedNetworkAgent na = - new InstrumentedNetworkAgent(this, linkProperties, nac) { - @Override - public void networkStatus(int status, String redirectUrl) { - mRedirectUrl = redirectUrl; - mNetworkStatusReceived.open(); - } - - @Override - public void onNetworkCreated() { - super.onNetworkCreated(); - if (mCreatedCallback != null) mCreatedCallback.run(); - } - - @Override - public void onNetworkUnwanted() { - super.onNetworkUnwanted(); - if (mUnwantedCallback != null) mUnwantedCallback.run(); - } - - @Override - public void onNetworkDestroyed() { - super.onNetworkDestroyed(); - if (mDisconnectedCallback != null) mDisconnectedCallback.run(); - } - }; - - assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId); - mNmCallbacks = nmCbCaptor.getValue(); - - mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor); - - return na; - } - - private void onValidationRequested() throws Exception { - if (mNmProvNotificationRequested - && ((mNmValidationResult & NETWORK_VALIDATION_RESULT_VALID) != 0)) { - mNmCallbacks.hideProvisioningNotification(); - mNmProvNotificationRequested = false; - } - - mNmCallbacks.notifyProbeStatusChanged(mProbesCompleted, mProbesSucceeded); - final NetworkTestResultParcelable p = new NetworkTestResultParcelable(); - p.result = mNmValidationResult; - p.probesAttempted = mProbesCompleted; - p.probesSucceeded = mProbesSucceeded; - p.redirectUrl = mNmValidationRedirectUrl; - p.timestampMillis = TIMESTAMP; - mNmCallbacks.notifyNetworkTestedWithExtras(p); - - if (mNmValidationRedirectUrl != null) { - mNmCallbacks.showProvisioningNotification( - "test_provisioning_notif_action", TEST_PACKAGE_NAME); - mNmProvNotificationRequested = true; - } - } - - /** - * Connect without adding any internet capability. - */ - public void connectWithoutInternet() { - super.connect(); - } - - /** - * Transition this NetworkAgent to CONNECTED state with NET_CAPABILITY_INTERNET. - * @param validated Indicate if network should pretend to be validated. - */ - public void connect(boolean validated) { - connect(validated, true, false /* isStrictMode */); - } - - /** - * Transition this NetworkAgent to CONNECTED state. - * @param validated Indicate if network should pretend to be validated. - * @param hasInternet Indicate if network should pretend to have NET_CAPABILITY_INTERNET. - */ - public void connect(boolean validated, boolean hasInternet, boolean isStrictMode) { - assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_INTERNET)); - - ConnectivityManager.NetworkCallback callback = null; - final ConditionVariable validatedCv = new ConditionVariable(); - if (validated) { - setNetworkValid(isStrictMode); - NetworkRequest request = new NetworkRequest.Builder() - .addTransportType(getNetworkCapabilities().getTransportTypes()[0]) - .clearCapabilities() - .build(); - callback = new ConnectivityManager.NetworkCallback() { - public void onCapabilitiesChanged(Network network, - NetworkCapabilities networkCapabilities) { - if (network.equals(getNetwork()) && - networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { - validatedCv.open(); - } - } - }; - mCm.registerNetworkCallback(request, callback); - } - if (hasInternet) { - addCapability(NET_CAPABILITY_INTERNET); - } - - connectWithoutInternet(); - - if (validated) { - // Wait for network to validate. - waitFor(validatedCv); - setNetworkInvalid(isStrictMode); - } - - if (callback != null) mCm.unregisterNetworkCallback(callback); - } - - public void connectWithCaptivePortal(String redirectUrl, boolean isStrictMode) { - setNetworkPortal(redirectUrl, isStrictMode); - connect(false, true /* hasInternet */, isStrictMode); - } - - public void connectWithPartialConnectivity() { - setNetworkPartial(); - connect(false); - } - - public void connectWithPartialValidConnectivity(boolean isStrictMode) { - setNetworkPartialValid(isStrictMode); - connect(false, true /* hasInternet */, isStrictMode); - } - - void setNetworkValid(boolean isStrictMode) { - mNmValidationResult = NETWORK_VALIDATION_RESULT_VALID; - mNmValidationRedirectUrl = null; - int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS; - if (isStrictMode) { - probesSucceeded |= NETWORK_VALIDATION_PROBE_PRIVDNS; - } - // The probesCompleted equals to probesSucceeded for the case of valid network, so put - // the same value into two different parameter of the method. - setProbesStatus(probesSucceeded, probesSucceeded); - } - - void setNetworkInvalid(boolean isStrictMode) { - mNmValidationResult = VALIDATION_RESULT_INVALID; - mNmValidationRedirectUrl = null; - int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS - | NETWORK_VALIDATION_PROBE_HTTP; - int probesSucceeded = 0; - // If the isStrictMode is true, it means the network is invalid when NetworkMonitor - // tried to validate the private DNS but failed. - if (isStrictMode) { - probesCompleted &= ~NETWORK_VALIDATION_PROBE_HTTP; - probesSucceeded = probesCompleted; - probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; - } - setProbesStatus(probesCompleted, probesSucceeded); - } - - void setNetworkPortal(String redirectUrl, boolean isStrictMode) { - setNetworkInvalid(isStrictMode); - mNmValidationRedirectUrl = redirectUrl; - // Suppose the portal is found when NetworkMonitor probes NETWORK_VALIDATION_PROBE_HTTP - // in the beginning, so the NETWORK_VALIDATION_PROBE_HTTPS hasn't probed yet. - int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; - int probesSucceeded = VALIDATION_RESULT_INVALID; - if (isStrictMode) { - probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; - } - setProbesStatus(probesCompleted, probesSucceeded); - } - - void setNetworkPartial() { - mNmValidationResult = NETWORK_VALIDATION_RESULT_PARTIAL; - mNmValidationRedirectUrl = null; - int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS - | NETWORK_VALIDATION_PROBE_FALLBACK; - int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_FALLBACK; - setProbesStatus(probesCompleted, probesSucceeded); - } - - void setNetworkPartialValid(boolean isStrictMode) { - setNetworkPartial(); - mNmValidationResult |= NETWORK_VALIDATION_RESULT_VALID; - int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS - | NETWORK_VALIDATION_PROBE_HTTP; - int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP; - // Suppose the partial network cannot pass the private DNS validation as well, so only - // add NETWORK_VALIDATION_PROBE_DNS in probesCompleted but not probesSucceeded. - if (isStrictMode) { - probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS; - } - setProbesStatus(probesCompleted, probesSucceeded); - } - - void setProbesStatus(int probesCompleted, int probesSucceeded) { - mProbesCompleted = probesCompleted; - mProbesSucceeded = probesSucceeded; - } - - void notifyCapportApiDataChanged(CaptivePortalData data) { - try { - mNmCallbacks.notifyCaptivePortalDataChanged(data); - } catch (RemoteException e) { - throw new AssertionError("This cannot happen", e); - } - } - - public String waitForRedirectUrl() { - assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS)); - return mRedirectUrl; - } - - public void expectDisconnected() { - expectDisconnected(TIMEOUT_MS); - } - - public void expectPreventReconnectReceived() { - expectPreventReconnectReceived(TIMEOUT_MS); - } - - void notifyDataStallSuspected() throws Exception { - final DataStallReportParcelable p = new DataStallReportParcelable(); - p.detectionMethod = DATA_STALL_DETECTION_METHOD; - p.timestampMillis = DATA_STALL_TIMESTAMP; - mNmCallbacks.notifyDataStallSuspected(p); - } - - public void setCreatedCallback(Runnable r) { - mCreatedCallback = r; - } - - public void setUnwantedCallback(Runnable r) { - mUnwantedCallback = r; - } - - public void setDisconnectedCallback(Runnable r) { - mDisconnectedCallback = r; - } - } - - /** - * A NetworkFactory that allows to wait until any in-flight NetworkRequest add or remove - * operations have been processed and test for them. - */ - private static class MockNetworkFactory extends NetworkFactory { - private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false); - - static class RequestEntry { - @NonNull - public final NetworkRequest request; - - RequestEntry(@NonNull final NetworkRequest request) { - this.request = request; - } - - static final class Add extends RequestEntry { - Add(@NonNull final NetworkRequest request) { - super(request); - } - } - - static final class Remove extends RequestEntry { - Remove(@NonNull final NetworkRequest request) { - super(request); - } - } - - @Override - public String toString() { - return "RequestEntry [ " + getClass().getName() + " : " + request + " ]"; - } - } - - // History of received requests adds and removes. - private final ArrayTrackRecord<RequestEntry>.ReadHead mRequestHistory = - new ArrayTrackRecord<RequestEntry>().newReadHead(); - - private static <T> T failIfNull(@Nullable final T obj, @Nullable final String message) { - if (null == obj) fail(null != message ? message : "Must not be null"); - return obj; - } - - public RequestEntry.Add expectRequestAdd() { - return failIfNull((RequestEntry.Add) mRequestHistory.poll(TIMEOUT_MS, - it -> it instanceof RequestEntry.Add), "Expected request add"); - } - - public void expectRequestAdds(final int count) { - for (int i = count; i > 0; --i) { - expectRequestAdd(); - } - } - - public RequestEntry.Remove expectRequestRemove() { - return failIfNull((RequestEntry.Remove) mRequestHistory.poll(TIMEOUT_MS, - it -> it instanceof RequestEntry.Remove), "Expected request remove"); - } - - public void expectRequestRemoves(final int count) { - for (int i = count; i > 0; --i) { - expectRequestRemove(); - } - } - - // Used to collect the networks requests managed by this factory. This is a duplicate of - // the internal information stored in the NetworkFactory (which is private). - private SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>(); - private final HandlerThread mHandlerSendingRequests; - - public MockNetworkFactory(Looper looper, Context context, String logTag, - NetworkCapabilities filter, HandlerThread threadSendingRequests) { - super(looper, context, logTag, filter); - mHandlerSendingRequests = threadSendingRequests; - } - - public int getMyRequestCount() { - return getRequestCount(); - } - - protected void startNetwork() { - mNetworkStarted.set(true); - } - - protected void stopNetwork() { - mNetworkStarted.set(false); - } - - public boolean getMyStartRequested() { - return mNetworkStarted.get(); - } - - - @Override - protected void needNetworkFor(NetworkRequest request) { - mNetworkRequests.put(request.requestId, request); - super.needNetworkFor(request); - mRequestHistory.add(new RequestEntry.Add(request)); - } - - @Override - protected void releaseNetworkFor(NetworkRequest request) { - mNetworkRequests.remove(request.requestId); - super.releaseNetworkFor(request); - mRequestHistory.add(new RequestEntry.Remove(request)); - } - - public void assertRequestCountEquals(final int count) { - assertEquals(count, getMyRequestCount()); - } - - @Override - public void terminate() { - super.terminate(); - // Make sure there are no remaining requests unaccounted for. - HandlerUtils.waitForIdle(mHandlerSendingRequests, TIMEOUT_MS); - assertNull(mRequestHistory.poll(0, r -> true)); - } - - // Trigger releasing the request as unfulfillable - public void triggerUnfulfillable(NetworkRequest r) { - super.releaseRequestAsUnfulfillableByAnyFactory(r); - } - - public void assertNoRequestChanged() { - assertNull(mRequestHistory.poll(0, r -> true)); - } - } - - private Set<UidRange> uidRangesForUids(int... uids) { - final ArraySet<UidRange> ranges = new ArraySet<>(); - for (final int uid : uids) { - ranges.add(new UidRange(uid, uid)); - } - return ranges; - } - - private static Looper startHandlerThreadAndReturnLooper() { - final HandlerThread handlerThread = new HandlerThread("MockVpnThread"); - handlerThread.start(); - return handlerThread.getLooper(); - } - - private class MockVpn extends Vpn implements TestableNetworkCallback.HasNetwork { - // Careful ! This is different from mNetworkAgent, because MockNetworkAgent does - // not inherit from NetworkAgent. - private TestNetworkAgentWrapper mMockNetworkAgent; - private boolean mAgentRegistered = false; - - private int mVpnType = VpnManager.TYPE_VPN_SERVICE; - private UnderlyingNetworkInfo mUnderlyingNetworkInfo; - - // These ConditionVariables allow tests to wait for LegacyVpnRunner to be stopped/started. - // TODO: this scheme is ad-hoc and error-prone because it does not fail if, for example, the - // test expects two starts in a row, or even if the production code calls start twice in a - // row. find a better solution. Simply putting a method to create a LegacyVpnRunner into - // Vpn.Dependencies doesn't work because LegacyVpnRunner is not a static class and has - // extensive access into the internals of Vpn. - private ConditionVariable mStartLegacyVpnCv = new ConditionVariable(); - private ConditionVariable mStopVpnRunnerCv = new ConditionVariable(); - - public MockVpn(int userId) { - super(startHandlerThreadAndReturnLooper(), mServiceContext, - new Dependencies() { - @Override - public boolean isCallerSystem() { - return true; - } - - @Override - public DeviceIdleInternal getDeviceIdleInternal() { - return mDeviceIdleInternal; - } - }, - mNetworkManagementService, mMockNetd, userId, mVpnProfileStore); - } - - public void setUids(Set<UidRange> uids) { - mNetworkCapabilities.setUids(UidRange.toIntRanges(uids)); - if (mAgentRegistered) { - mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities, true); - } - } - - public void setVpnType(int vpnType) { - mVpnType = vpnType; - } - - @Override - public Network getNetwork() { - return (mMockNetworkAgent == null) ? null : mMockNetworkAgent.getNetwork(); - } - - @Override - public int getActiveVpnType() { - return mVpnType; - } - - private LinkProperties makeLinkProperties() { - final LinkProperties lp = new LinkProperties(); - lp.setInterfaceName(VPN_IFNAME); - return lp; - } - - private void registerAgent(boolean isAlwaysMetered, Set<UidRange> uids, LinkProperties lp) - throws Exception { - if (mAgentRegistered) throw new IllegalStateException("already registered"); - updateState(NetworkInfo.DetailedState.CONNECTING, "registerAgent"); - mConfig = new VpnConfig(); - mConfig.session = "MySession12345"; - setUids(uids); - if (!isAlwaysMetered) mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); - mInterface = VPN_IFNAME; - mNetworkCapabilities.setTransportInfo(new VpnTransportInfo(getActiveVpnType(), - mConfig.session)); - mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp, - mNetworkCapabilities); - mMockNetworkAgent.waitForIdle(TIMEOUT_MS); - - verify(mMockNetd, times(1)).networkAddUidRanges(eq(mMockVpn.getNetwork().getNetId()), - eq(toUidRangeStableParcels(uids))); - verify(mMockNetd, never()) - .networkRemoveUidRanges(eq(mMockVpn.getNetwork().getNetId()), any()); - mAgentRegistered = true; - verify(mMockNetd).networkCreate(nativeNetworkConfigVpn(getNetwork().netId, - !mMockNetworkAgent.isBypassableVpn(), mVpnType)); - updateState(NetworkInfo.DetailedState.CONNECTED, "registerAgent"); - mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities()); - mNetworkAgent = mMockNetworkAgent.getNetworkAgent(); - } - - private void registerAgent(Set<UidRange> uids) throws Exception { - registerAgent(false /* isAlwaysMetered */, uids, makeLinkProperties()); - } - - private void connect(boolean validated, boolean hasInternet, boolean isStrictMode) { - mMockNetworkAgent.connect(validated, hasInternet, isStrictMode); - } - - private void connect(boolean validated) { - mMockNetworkAgent.connect(validated); - } - - private TestNetworkAgentWrapper getAgent() { - return mMockNetworkAgent; - } - - public void establish(LinkProperties lp, int uid, Set<UidRange> ranges, boolean validated, - boolean hasInternet, boolean isStrictMode) throws Exception { - mNetworkCapabilities.setOwnerUid(uid); - mNetworkCapabilities.setAdministratorUids(new int[]{uid}); - registerAgent(false, ranges, lp); - connect(validated, hasInternet, isStrictMode); - waitForIdle(); - } - - public void establish(LinkProperties lp, int uid, Set<UidRange> ranges) throws Exception { - establish(lp, uid, ranges, true, true, false); - } - - public void establishForMyUid(LinkProperties lp) throws Exception { - final int uid = Process.myUid(); - establish(lp, uid, uidRangesForUids(uid), true, true, false); - } - - public void establishForMyUid(boolean validated, boolean hasInternet, boolean isStrictMode) - throws Exception { - final int uid = Process.myUid(); - establish(makeLinkProperties(), uid, uidRangesForUids(uid), validated, hasInternet, - isStrictMode); - } - - public void establishForMyUid() throws Exception { - establishForMyUid(makeLinkProperties()); - } - - public void sendLinkProperties(LinkProperties lp) { - mMockNetworkAgent.sendLinkProperties(lp); - } - - public void disconnect() { - if (mMockNetworkAgent != null) { - mMockNetworkAgent.disconnect(); - updateState(NetworkInfo.DetailedState.DISCONNECTED, "disconnect"); - } - mAgentRegistered = false; - setUids(null); - // Remove NET_CAPABILITY_INTERNET or MockNetworkAgent will refuse to connect later on. - mNetworkCapabilities.removeCapability(NET_CAPABILITY_INTERNET); - mInterface = null; - } - - @Override - public void startLegacyVpnRunner() { - mStartLegacyVpnCv.open(); - } - - public void expectStartLegacyVpnRunner() { - assertTrue("startLegacyVpnRunner not called after " + TIMEOUT_MS + " ms", - mStartLegacyVpnCv.block(TIMEOUT_MS)); - - // startLegacyVpn calls stopVpnRunnerPrivileged, which will open mStopVpnRunnerCv, just - // before calling startLegacyVpnRunner. Restore mStopVpnRunnerCv, so the test can expect - // that the VpnRunner is stopped and immediately restarted by calling - // expectStartLegacyVpnRunner() and expectStopVpnRunnerPrivileged() back-to-back. - mStopVpnRunnerCv = new ConditionVariable(); - } - - @Override - public void stopVpnRunnerPrivileged() { - if (mVpnRunner != null) { - super.stopVpnRunnerPrivileged(); - disconnect(); - mStartLegacyVpnCv = new ConditionVariable(); - } - mVpnRunner = null; - mStopVpnRunnerCv.open(); - } - - public void expectStopVpnRunnerPrivileged() { - assertTrue("stopVpnRunnerPrivileged not called after " + TIMEOUT_MS + " ms", - mStopVpnRunnerCv.block(TIMEOUT_MS)); - } - - @Override - public synchronized UnderlyingNetworkInfo getUnderlyingNetworkInfo() { - if (mUnderlyingNetworkInfo != null) return mUnderlyingNetworkInfo; - - return super.getUnderlyingNetworkInfo(); - } - - private synchronized void setUnderlyingNetworkInfo( - UnderlyingNetworkInfo underlyingNetworkInfo) { - mUnderlyingNetworkInfo = underlyingNetworkInfo; - } - } - - private UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { - return ranges.stream().map( - r -> new UidRangeParcel(r.start, r.stop)).toArray(UidRangeParcel[]::new); - } - - private VpnManagerService makeVpnManagerService() { - final VpnManagerService.Dependencies deps = new VpnManagerService.Dependencies() { - public int getCallingUid() { - return mDeps.getCallingUid(); - } - - public HandlerThread makeHandlerThread() { - return mVMSHandlerThread; - } - - @Override - public VpnProfileStore getVpnProfileStore() { - return mVpnProfileStore; - } - - public INetd getNetd() { - return mMockNetd; - } - - public INetworkManagementService getINetworkManagementService() { - return mNetworkManagementService; - } - }; - return new VpnManagerService(mServiceContext, deps); - } - - private void assertVpnTransportInfo(NetworkCapabilities nc, int type) { - assertNotNull(nc); - final TransportInfo ti = nc.getTransportInfo(); - assertTrue("VPN TransportInfo is not a VpnTransportInfo: " + ti, - ti instanceof VpnTransportInfo); - assertEquals(type, ((VpnTransportInfo) ti).getType()); - - } - - private void processBroadcast(Intent intent) { - mServiceContext.sendBroadcast(intent); - HandlerUtils.waitForIdle(mVMSHandlerThread, TIMEOUT_MS); - waitForIdle(); - } - - private void mockVpn(int uid) { - synchronized (mVpnManagerService.mVpns) { - int userId = UserHandle.getUserId(uid); - mMockVpn = new MockVpn(userId); - // Every running user always has a Vpn in the mVpns array, even if no VPN is running. - mVpnManagerService.mVpns.put(userId, mMockVpn); - } - } - - private void mockUidNetworkingBlocked() { - doAnswer(i -> isUidBlocked(mBlockedReasons, i.getArgument(1)) - ).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean()); - } - - private boolean isUidBlocked(int blockedReasons, boolean meteredNetwork) { - final int blockedOnAllNetworksReason = (blockedReasons & ~BLOCKED_METERED_REASON_MASK); - if (blockedOnAllNetworksReason != BLOCKED_REASON_NONE) { - return true; - } - if (meteredNetwork) { - return blockedReasons != BLOCKED_REASON_NONE; - } - return false; - } - - private void setBlockedReasonChanged(int blockedReasons) { - mBlockedReasons = blockedReasons; - mPolicyCallback.onUidBlockedReasonChanged(Process.myUid(), blockedReasons); - } - - private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) { - return mService.getNetworkAgentInfoForNetwork(mna.getNetwork()).clatd; - } - - private static class WrappedMultinetworkPolicyTracker extends MultinetworkPolicyTracker { - volatile boolean mConfigRestrictsAvoidBadWifi; - volatile int mConfigMeteredMultipathPreference; - - WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r) { - super(c, h, r); - } - - @Override - public boolean configRestrictsAvoidBadWifi() { - return mConfigRestrictsAvoidBadWifi; - } - - @Override - public int configMeteredMultipathPreference() { - return mConfigMeteredMultipathPreference; - } - } - - /** - * Wait up to TIMEOUT_MS for {@code conditionVariable} to open. - * Fails if TIMEOUT_MS goes by before {@code conditionVariable} opens. - */ - static private void waitFor(ConditionVariable conditionVariable) { - if (conditionVariable.block(TIMEOUT_MS)) { - return; - } - fail("ConditionVariable was blocked for more than " + TIMEOUT_MS + "ms"); - } - - private <T> T doAsUid(final int uid, @NonNull final Supplier<T> what) { - when(mDeps.getCallingUid()).thenReturn(uid); - try { - return what.get(); - } finally { - returnRealCallingUid(); - } - } - - private void doAsUid(final int uid, @NonNull final Runnable what) { - doAsUid(uid, () -> { - what.run(); return Void.TYPE; - }); - } - - private void registerNetworkCallbackAsUid(NetworkRequest request, NetworkCallback callback, - int uid) { - doAsUid(uid, () -> { - mCm.registerNetworkCallback(request, callback); - }); - } - - private void registerDefaultNetworkCallbackAsUid(@NonNull final NetworkCallback callback, - final int uid) { - doAsUid(uid, () -> { - mCm.registerDefaultNetworkCallback(callback); - waitForIdle(); - }); - } - - private interface ExceptionalRunnable { - void run() throws Exception; - } - - private void withPermission(String permission, ExceptionalRunnable r) throws Exception { - if (mServiceContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) { - r.run(); - return; - } - try { - mServiceContext.setPermission(permission, PERMISSION_GRANTED); - r.run(); - } finally { - mServiceContext.setPermission(permission, PERMISSION_DENIED); - } - } - - private static final int PRIMARY_USER = 0; - private static final UidRange PRIMARY_UIDRANGE = - UidRange.createForUser(UserHandle.of(PRIMARY_USER)); - private static final int APP1_UID = UserHandle.getUid(PRIMARY_USER, 10100); - private static final int APP2_UID = UserHandle.getUid(PRIMARY_USER, 10101); - private static final int VPN_UID = UserHandle.getUid(PRIMARY_USER, 10043); - private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER, "", - UserInfo.FLAG_PRIMARY); - private static final UserHandle PRIMARY_USER_HANDLE = new UserHandle(PRIMARY_USER); - - private static final int RESTRICTED_USER = 1; - private static final UserInfo RESTRICTED_USER_INFO = new UserInfo(RESTRICTED_USER, "", - UserInfo.FLAG_RESTRICTED); - static { - RESTRICTED_USER_INFO.restrictedProfileParentId = PRIMARY_USER; - } - - @Before - public void setUp() throws Exception { - mNetIdManager = new TestNetIdManager(); - - mContext = InstrumentationRegistry.getContext(); - - MockitoAnnotations.initMocks(this); - - when(mUserManager.getAliveUsers()).thenReturn(Arrays.asList(PRIMARY_USER_INFO)); - when(mUserManager.getUserHandles(anyBoolean())).thenReturn( - Arrays.asList(PRIMARY_USER_HANDLE)); - when(mUserManager.getUserInfo(PRIMARY_USER)).thenReturn(PRIMARY_USER_INFO); - // canHaveRestrictedProfile does not take a userId. It applies to the userId of the context - // it was started from, i.e., PRIMARY_USER. - when(mUserManager.canHaveRestrictedProfile()).thenReturn(true); - when(mUserManager.getUserInfo(RESTRICTED_USER)).thenReturn(RESTRICTED_USER_INFO); - - final ApplicationInfo applicationInfo = new ApplicationInfo(); - applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q; - when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any())) - .thenReturn(applicationInfo); - when(mPackageManager.getTargetSdkVersion(anyString())) - .thenReturn(applicationInfo.targetSdkVersion); - when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]); - - // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not. - // http://b/25897652 . - if (Looper.myLooper() == null) { - Looper.prepare(); - } - mockDefaultPackages(); - mockHasSystemFeature(FEATURE_WIFI, true); - mockHasSystemFeature(FEATURE_WIFI_DIRECT, true); - doReturn(true).when(mTelephonyManager).isDataCapable(); - - FakeSettingsProvider.clearSettingsProvider(); - mServiceContext = new MockContext(InstrumentationRegistry.getContext(), - new FakeSettingsProvider()); - mServiceContext.setUseRegisteredHandlers(true); - - mAlarmManagerThread = new HandlerThread("TestAlarmManager"); - mAlarmManagerThread.start(); - initAlarmManager(mAlarmManager, mAlarmManagerThread.getThreadHandler()); - - mCsHandlerThread = new HandlerThread("TestConnectivityService"); - mVMSHandlerThread = new HandlerThread("TestVpnManagerService"); - mDeps = makeDependencies(); - returnRealCallingUid(); - mService = new ConnectivityService(mServiceContext, - mMockDnsResolver, - mock(IpConnectivityLog.class), - mMockNetd, - mDeps); - mService.mLingerDelayMs = TEST_LINGER_DELAY_MS; - mService.mNascentDelayMs = TEST_NASCENT_DELAY_MS; - verify(mDeps).makeMultinetworkPolicyTracker(any(), any(), any()); - - final ArgumentCaptor<NetworkPolicyCallback> policyCallbackCaptor = - ArgumentCaptor.forClass(NetworkPolicyCallback.class); - verify(mNetworkPolicyManager).registerNetworkPolicyCallback(any(), - policyCallbackCaptor.capture()); - mPolicyCallback = policyCallbackCaptor.getValue(); - - // Create local CM before sending system ready so that we can answer - // getSystemService() correctly. - mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService); - mService.systemReadyInternal(); - mVpnManagerService = makeVpnManagerService(); - mVpnManagerService.systemReady(); - mockVpn(Process.myUid()); - mCm.bindProcessToNetwork(null); - mQosCallbackTracker = mock(QosCallbackTracker.class); - - // Ensure that the default setting for Captive Portals is used for most tests - setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT); - setAlwaysOnNetworks(false); - setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); - } - - private void returnRealCallingUid() { - doAnswer((invocationOnMock) -> Binder.getCallingUid()).when(mDeps).getCallingUid(); - } - - private ConnectivityService.Dependencies makeDependencies() { - doReturn(false).when(mSystemProperties).getBoolean("ro.radio.noril", false); - final ConnectivityService.Dependencies deps = mock(ConnectivityService.Dependencies.class); - doReturn(mCsHandlerThread).when(deps).makeHandlerThread(); - doReturn(mNetIdManager).when(deps).makeNetIdManager(); - doReturn(mNetworkStack).when(deps).getNetworkStack(); - doReturn(mSystemProperties).when(deps).getSystemProperties(); - doReturn(mock(ProxyTracker.class)).when(deps).makeProxyTracker(any(), any()); - doReturn(true).when(deps).queryUserAccess(anyInt(), any(), any()); - doAnswer(inv -> { - mPolicyTracker = new WrappedMultinetworkPolicyTracker( - inv.getArgument(0), inv.getArgument(1), inv.getArgument(2)); - return mPolicyTracker; - }).when(deps).makeMultinetworkPolicyTracker(any(), any(), any()); - doReturn(true).when(deps).getCellular464XlatEnabled(); - - doReturn(60000).when(mResources).getInteger(R.integer.config_networkTransitionTimeout); - doReturn("").when(mResources).getString(R.string.config_networkCaptivePortalServerUrl); - doReturn(new String[]{ WIFI_WOL_IFNAME }).when(mResources).getStringArray( - R.array.config_wakeonlan_supported_interfaces); - doReturn(new String[] { "0,1", "1,3" }).when(mResources).getStringArray( - R.array.config_networkSupportedKeepaliveCount); - doReturn(new String[0]).when(mResources).getStringArray( - R.array.config_networkNotifySwitches); - doReturn(new int[]{10, 11, 12, 14, 15}).when(mResources).getIntArray( - R.array.config_protectedNetworks); - // We don't test the actual notification value strings, so just return an empty array. - // It doesn't matter what the values are as long as it's not null. - doReturn(new String[0]).when(mResources).getStringArray(R.array.network_switch_type_name); - - doReturn(R.array.config_networkSupportedKeepaliveCount).when(mResources) - .getIdentifier(eq("config_networkSupportedKeepaliveCount"), eq("array"), any()); - doReturn(R.array.network_switch_type_name).when(mResources) - .getIdentifier(eq("network_switch_type_name"), eq("array"), any()); - - - final ConnectivityResources connRes = mock(ConnectivityResources.class); - doReturn(mResources).when(connRes).get(); - doReturn(connRes).when(deps).getResources(any()); - - final Context mockResContext = mock(Context.class); - doReturn(mResources).when(mockResContext).getResources(); - ConnectivityResources.setResourcesContextForTest(mockResContext); - - return deps; - } - - private static void initAlarmManager(final AlarmManager am, final Handler alarmHandler) { - doAnswer(inv -> { - final long when = inv.getArgument(1); - final WakeupMessage wakeupMsg = inv.getArgument(3); - final Handler handler = inv.getArgument(4); - - long delayMs = when - SystemClock.elapsedRealtime(); - if (delayMs < 0) delayMs = 0; - if (delayMs > UNREASONABLY_LONG_ALARM_WAIT_MS) { - fail("Attempting to send msg more than " + UNREASONABLY_LONG_ALARM_WAIT_MS - + "ms into the future: " + delayMs); - } - alarmHandler.postDelayed(() -> handler.post(wakeupMsg::onAlarm), wakeupMsg /* token */, - delayMs); - - return null; - }).when(am).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), anyLong(), anyString(), - any(WakeupMessage.class), any()); - - doAnswer(inv -> { - final WakeupMessage wakeupMsg = inv.getArgument(0); - alarmHandler.removeCallbacksAndMessages(wakeupMsg /* token */); - return null; - }).when(am).cancel(any(WakeupMessage.class)); - } - - @After - public void tearDown() throws Exception { - unregisterDefaultNetworkCallbacks(); - maybeTearDownEnterpriseNetwork(); - setAlwaysOnNetworks(false); - if (mCellNetworkAgent != null) { - mCellNetworkAgent.disconnect(); - mCellNetworkAgent = null; - } - if (mWiFiNetworkAgent != null) { - mWiFiNetworkAgent.disconnect(); - mWiFiNetworkAgent = null; - } - if (mEthernetNetworkAgent != null) { - mEthernetNetworkAgent.disconnect(); - mEthernetNetworkAgent = null; - } - - if (mQosCallbackMockHelper != null) { - mQosCallbackMockHelper.tearDown(); - mQosCallbackMockHelper = null; - } - mMockVpn.disconnect(); - waitForIdle(); - - FakeSettingsProvider.clearSettingsProvider(); - ConnectivityResources.setResourcesContextForTest(null); - - mCsHandlerThread.quitSafely(); - mAlarmManagerThread.quitSafely(); - } - - private void mockDefaultPackages() throws Exception { - final String myPackageName = mContext.getPackageName(); - final PackageInfo myPackageInfo = mContext.getPackageManager().getPackageInfo( - myPackageName, PackageManager.GET_PERMISSIONS); - when(mPackageManager.getPackagesForUid(Binder.getCallingUid())).thenReturn( - new String[] {myPackageName}); - when(mPackageManager.getPackageInfoAsUser(eq(myPackageName), anyInt(), - eq(UserHandle.getCallingUserId()))).thenReturn(myPackageInfo); - - when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( - Arrays.asList(new PackageInfo[] { - buildPackageInfo(/* SYSTEM */ false, APP1_UID), - buildPackageInfo(/* SYSTEM */ false, APP2_UID), - buildPackageInfo(/* SYSTEM */ false, VPN_UID) - })); - - // Create a fake always-on VPN package. - final int userId = UserHandle.getCallingUserId(); - final ApplicationInfo applicationInfo = new ApplicationInfo(); - applicationInfo.targetSdkVersion = Build.VERSION_CODES.R; // Always-on supported in N+. - when(mPackageManager.getApplicationInfoAsUser(eq(ALWAYS_ON_PACKAGE), anyInt(), - eq(userId))).thenReturn(applicationInfo); - - // Minimal mocking to keep Vpn#isAlwaysOnPackageSupported happy. - ResolveInfo rInfo = new ResolveInfo(); - rInfo.serviceInfo = new ServiceInfo(); - rInfo.serviceInfo.metaData = new Bundle(); - final List<ResolveInfo> services = Arrays.asList(new ResolveInfo[]{rInfo}); - when(mPackageManager.queryIntentServicesAsUser(any(), eq(PackageManager.GET_META_DATA), - eq(userId))).thenReturn(services); - when(mPackageManager.getPackageUidAsUser(TEST_PACKAGE_NAME, userId)) - .thenReturn(Process.myUid()); - when(mPackageManager.getPackageUidAsUser(ALWAYS_ON_PACKAGE, userId)) - .thenReturn(VPN_UID); - } - - private void verifyActiveNetwork(int transport) { - // Test getActiveNetworkInfo() - assertNotNull(mCm.getActiveNetworkInfo()); - assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType()); - // Test getActiveNetwork() - assertNotNull(mCm.getActiveNetwork()); - assertEquals(mCm.getActiveNetwork(), mCm.getActiveNetworkForUid(Process.myUid())); - if (!NetworkCapabilities.isValidTransport(transport)) { - throw new IllegalStateException("Unknown transport " + transport); - } - switch (transport) { - case TRANSPORT_WIFI: - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - break; - case TRANSPORT_CELLULAR: - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - break; - case TRANSPORT_ETHERNET: - assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - break; - default: - break; - } - // Test getNetworkInfo(Network) - assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork())); - assertEquals(transportToLegacyType(transport), - mCm.getNetworkInfo(mCm.getActiveNetwork()).getType()); - assertNotNull(mCm.getActiveNetworkInfoForUid(Process.myUid())); - // Test getNetworkCapabilities(Network) - assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork())); - assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport)); - } - - private void verifyNoNetwork() { - waitForIdle(); - // Test getActiveNetworkInfo() - assertNull(mCm.getActiveNetworkInfo()); - // Test getActiveNetwork() - assertNull(mCm.getActiveNetwork()); - assertNull(mCm.getActiveNetworkForUid(Process.myUid())); - // Test getAllNetworks() - assertEmpty(mCm.getAllNetworks()); - assertEmpty(mCm.getAllNetworkStateSnapshots()); - } - - /** - * Class to simplify expecting broadcasts using BroadcastInterceptingContext. - * Ensures that the receiver is unregistered after the expected broadcast is received. This - * cannot be done in the BroadcastReceiver itself because BroadcastInterceptingContext runs - * the receivers' receive method while iterating over the list of receivers, and unregistering - * the receiver during iteration throws ConcurrentModificationException. - */ - private class ExpectedBroadcast extends CompletableFuture<Intent> { - private final BroadcastReceiver mReceiver; - - ExpectedBroadcast(BroadcastReceiver receiver) { - mReceiver = receiver; - } - - public Intent expectBroadcast(int timeoutMs) throws Exception { - try { - return get(timeoutMs, TimeUnit.MILLISECONDS); - } catch (TimeoutException e) { - fail("Expected broadcast not received after " + timeoutMs + " ms"); - return null; - } finally { - mServiceContext.unregisterReceiver(mReceiver); - } - } - - public Intent expectBroadcast() throws Exception { - return expectBroadcast(BROADCAST_TIMEOUT_MS); - } - - public void expectNoBroadcast(int timeoutMs) throws Exception { - waitForIdle(); - try { - final Intent intent = get(timeoutMs, TimeUnit.MILLISECONDS); - fail("Unexpected broadcast: " + intent.getAction() + " " + intent.getExtras()); - } catch (TimeoutException expected) { - } finally { - mServiceContext.unregisterReceiver(mReceiver); - } - } - } - - /** Expects that {@code count} CONNECTIVITY_ACTION broadcasts are received. */ - private ExpectedBroadcast registerConnectivityBroadcast(final int count) { - return registerConnectivityBroadcastThat(count, intent -> true); - } - - private ExpectedBroadcast registerConnectivityBroadcastThat(final int count, - @NonNull final Predicate<Intent> filter) { - final IntentFilter intentFilter = new IntentFilter(CONNECTIVITY_ACTION); - // AtomicReference allows receiver to access expected even though it is constructed later. - final AtomicReference<ExpectedBroadcast> expectedRef = new AtomicReference<>(); - final BroadcastReceiver receiver = new BroadcastReceiver() { - private int mRemaining = count; - public void onReceive(Context context, Intent intent) { - final int type = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1); - final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO); - Log.d(TAG, "Received CONNECTIVITY_ACTION type=" + type + " ni=" + ni); - if (!filter.test(intent)) return; - if (--mRemaining == 0) { - expectedRef.get().complete(intent); - } - } - }; - final ExpectedBroadcast expected = new ExpectedBroadcast(receiver); - expectedRef.set(expected); - mServiceContext.registerReceiver(receiver, intentFilter); - return expected; - } - - private boolean extraInfoInBroadcastHasExpectedNullness(NetworkInfo ni) { - final DetailedState state = ni.getDetailedState(); - if (state == DetailedState.CONNECTED && ni.getExtraInfo() == null) return false; - // Expect a null extraInfo if the network is CONNECTING, because a CONNECTIVITY_ACTION - // broadcast with a state of CONNECTING only happens due to legacy VPN lockdown, which also - // nulls out extraInfo. - if (state == DetailedState.CONNECTING && ni.getExtraInfo() != null) return false; - // Can't make any assertions about DISCONNECTED broadcasts. When a network actually - // disconnects, disconnectAndDestroyNetwork sets its state to DISCONNECTED and its extraInfo - // to null. But if the DISCONNECTED broadcast is just simulated by LegacyTypeTracker due to - // a network switch, extraInfo will likely be populated. - // This is likely a bug in CS, but likely not one we can fix without impacting apps. - return true; - } - - private ExpectedBroadcast expectConnectivityAction(int type, NetworkInfo.DetailedState state) { - return registerConnectivityBroadcastThat(1, intent -> { - final int actualType = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1); - final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO); - return type == actualType - && state == ni.getDetailedState() - && extraInfoInBroadcastHasExpectedNullness(ni); - }); - } - - @Test - public void testNetworkTypes() { - // Ensure that our mocks for the networkAttributes config variable work as expected. If they - // don't, then tests that depend on CONNECTIVITY_ACTION broadcasts for these network types - // 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)); - assertTrue(mCm.isNetworkSupported(TYPE_MOBILE_FOTA)); - assertFalse(mCm.isNetworkSupported(TYPE_PROXY)); - - // 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)); - } - - @Test - public void testNetworkFeature() throws Exception { - // Connect the cell agent and wait for the connected broadcast. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.addCapability(NET_CAPABILITY_SUPL); - ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); - mCellNetworkAgent.connect(true); - b.expectBroadcast(); - - // Build legacy request for SUPL. - final NetworkCapabilities legacyCaps = new NetworkCapabilities(); - legacyCaps.addTransportType(TRANSPORT_CELLULAR); - legacyCaps.addCapability(NET_CAPABILITY_SUPL); - final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL, - ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST); - - // File request, withdraw it and make sure no broadcast is sent - b = registerConnectivityBroadcast(1); - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.requestNetwork(legacyRequest, callback); - callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); - mCm.unregisterNetworkCallback(callback); - b.expectNoBroadcast(800); // 800ms long enough to at least flake if this is sent - - // Disconnect the network and expect mobile disconnected broadcast. - b = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); - mCellNetworkAgent.disconnect(); - b.expectBroadcast(); - } - - @Test - public void testLingering() throws Exception { - verifyNoNetwork(); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - assertNull(mCm.getActiveNetworkInfo()); - assertNull(mCm.getActiveNetwork()); - // Test bringing up validated cellular. - ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); - mCellNetworkAgent.connect(true); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_CELLULAR); - assertLength(2, mCm.getAllNetworks()); - assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) || - mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); - assertTrue(mCm.getAllNetworks()[0].equals(mWiFiNetworkAgent.getNetwork()) || - mCm.getAllNetworks()[1].equals(mWiFiNetworkAgent.getNetwork())); - // Test bringing up validated WiFi. - b = registerConnectivityBroadcast(2); - mWiFiNetworkAgent.connect(true); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_WIFI); - assertLength(2, mCm.getAllNetworks()); - assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) || - mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); - assertTrue(mCm.getAllNetworks()[0].equals(mCellNetworkAgent.getNetwork()) || - mCm.getAllNetworks()[1].equals(mCellNetworkAgent.getNetwork())); - // Test cellular linger timeout. - mCellNetworkAgent.expectDisconnected(); - waitForIdle(); - assertLength(1, mCm.getAllNetworks()); - verifyActiveNetwork(TRANSPORT_WIFI); - assertLength(1, mCm.getAllNetworks()); - assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork()); - // Test WiFi disconnect. - b = registerConnectivityBroadcast(1); - mWiFiNetworkAgent.disconnect(); - b.expectBroadcast(); - verifyNoNetwork(); - } - - /** - * Verify a newly created network will be inactive instead of torn down even if no one is - * requesting. - */ - @Test - public void testNewNetworkInactive() throws Exception { - // Create a callback that monitoring the testing network. - final TestNetworkCallback listenCallback = new TestNetworkCallback(); - mCm.registerNetworkCallback(new NetworkRequest.Builder().build(), listenCallback); - - // 1. Create a network that is not requested by anyone, and does not satisfy any of the - // default requests. Verify that the network will be inactive instead of torn down. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connectWithoutInternet(); - listenCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - listenCallback.assertNoCallback(); - - // Verify that the network will be torn down after nascent expiry. A small period of time - // is added in case of flakiness. - final int nascentTimeoutMs = - mService.mNascentDelayMs + mService.mNascentDelayMs / 4; - listenCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent, nascentTimeoutMs); - - // 2. Create a network that is satisfied by a request comes later. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connectWithoutInternet(); - listenCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - final NetworkRequest wifiRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI).build(); - final TestNetworkCallback wifiCallback = new TestNetworkCallback(); - mCm.requestNetwork(wifiRequest, wifiCallback); - wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - - // Verify that the network will be kept since the request is still satisfied. And is able - // to get disconnected as usual if the request is released after the nascent timer expires. - listenCallback.assertNoCallback(nascentTimeoutMs); - mCm.unregisterNetworkCallback(wifiCallback); - listenCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - // 3. Create a network that is satisfied by a request comes later. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connectWithoutInternet(); - listenCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - mCm.requestNetwork(wifiRequest, wifiCallback); - wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - - // Verify that the network will still be torn down after the request gets removed. - mCm.unregisterNetworkCallback(wifiCallback); - listenCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - // There is no need to ensure that LOSING is never sent in the common case that the - // network immediately satisfies a request that was already present, because it is already - // verified anywhere whenever {@code TestNetworkCallback#expectAvailable*} is called. - - mCm.unregisterNetworkCallback(listenCallback); - } - - /** - * Verify a newly created network will be inactive and switch to background if only background - * request is satisfied. - */ - @Test - public void testNewNetworkInactive_bgNetwork() throws Exception { - // Create a callback that monitoring the wifi network. - final TestNetworkCallback wifiListenCallback = new TestNetworkCallback(); - mCm.registerNetworkCallback(new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI).build(), wifiListenCallback); - - // Create callbacks that can monitor background and foreground mobile networks. - // This is done by granting using background networks permission before registration. Thus, - // the service will not add {@code NET_CAPABILITY_FOREGROUND} by default. - grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); - final TestNetworkCallback bgMobileListenCallback = new TestNetworkCallback(); - final TestNetworkCallback fgMobileListenCallback = new TestNetworkCallback(); - mCm.registerNetworkCallback(new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR).build(), bgMobileListenCallback); - mCm.registerNetworkCallback(new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR) - .addCapability(NET_CAPABILITY_FOREGROUND).build(), fgMobileListenCallback); - - // Connect wifi, which satisfies default request. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - wifiListenCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); - - // Connect a cellular network, verify that satisfies only the background callback. - setAlwaysOnNetworks(true); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - bgMobileListenCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - fgMobileListenCallback.assertNoCallback(); - assertFalse(isForegroundNetwork(mCellNetworkAgent)); - - mCellNetworkAgent.disconnect(); - bgMobileListenCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - fgMobileListenCallback.assertNoCallback(); - - mCm.unregisterNetworkCallback(wifiListenCallback); - mCm.unregisterNetworkCallback(bgMobileListenCallback); - mCm.unregisterNetworkCallback(fgMobileListenCallback); - } - - @Test - public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception { - // Test bringing up unvalidated WiFi - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - ExpectedBroadcast b = registerConnectivityBroadcast(1); - mWiFiNetworkAgent.connect(false); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_WIFI); - // Test bringing up unvalidated cellular - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(false); - waitForIdle(); - verifyActiveNetwork(TRANSPORT_WIFI); - // Test cellular disconnect. - mCellNetworkAgent.disconnect(); - waitForIdle(); - verifyActiveNetwork(TRANSPORT_WIFI); - // Test bringing up validated cellular - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - b = registerConnectivityBroadcast(2); - mCellNetworkAgent.connect(true); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_CELLULAR); - // Test cellular disconnect. - b = registerConnectivityBroadcast(2); - mCellNetworkAgent.disconnect(); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_WIFI); - // Test WiFi disconnect. - b = registerConnectivityBroadcast(1); - mWiFiNetworkAgent.disconnect(); - b.expectBroadcast(); - verifyNoNetwork(); - } - - @Test - public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception { - // Test bringing up unvalidated cellular. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - ExpectedBroadcast b = registerConnectivityBroadcast(1); - mCellNetworkAgent.connect(false); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_CELLULAR); - // Test bringing up unvalidated WiFi. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - b = registerConnectivityBroadcast(2); - mWiFiNetworkAgent.connect(false); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_WIFI); - // Test WiFi disconnect. - b = registerConnectivityBroadcast(2); - mWiFiNetworkAgent.disconnect(); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_CELLULAR); - // Test cellular disconnect. - b = registerConnectivityBroadcast(1); - mCellNetworkAgent.disconnect(); - b.expectBroadcast(); - verifyNoNetwork(); - } - - @Test - public void testUnlingeringDoesNotValidate() throws Exception { - // Test bringing up unvalidated WiFi. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - ExpectedBroadcast b = registerConnectivityBroadcast(1); - mWiFiNetworkAgent.connect(false); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_WIFI); - assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( - NET_CAPABILITY_VALIDATED)); - // Test bringing up validated cellular. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - b = registerConnectivityBroadcast(2); - mCellNetworkAgent.connect(true); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_CELLULAR); - assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( - NET_CAPABILITY_VALIDATED)); - // Test cellular disconnect. - b = registerConnectivityBroadcast(2); - mCellNetworkAgent.disconnect(); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_WIFI); - // Unlingering a network should not cause it to be marked as validated. - assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( - NET_CAPABILITY_VALIDATED)); - } - - @Test - public void testCellularOutscoresWeakWifi() throws Exception { - // Test bringing up validated cellular. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - ExpectedBroadcast b = registerConnectivityBroadcast(1); - mCellNetworkAgent.connect(true); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_CELLULAR); - // Test bringing up validated WiFi. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - b = registerConnectivityBroadcast(2); - mWiFiNetworkAgent.connect(true); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_WIFI); - // Test WiFi getting really weak. - b = registerConnectivityBroadcast(2); - mWiFiNetworkAgent.adjustScore(-11); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_CELLULAR); - // Test WiFi restoring signal strength. - b = registerConnectivityBroadcast(2); - mWiFiNetworkAgent.adjustScore(11); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_WIFI); - } - - @Test - public void testReapingNetwork() throws Exception { - // Test bringing up WiFi without NET_CAPABILITY_INTERNET. - // Expect it to be torn down immediately because it satisfies no requests. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connectWithoutInternet(); - mWiFiNetworkAgent.expectDisconnected(); - // Test bringing up cellular without NET_CAPABILITY_INTERNET. - // Expect it to be torn down immediately because it satisfies no requests. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mCellNetworkAgent.connectWithoutInternet(); - mCellNetworkAgent.expectDisconnected(); - // Test bringing up validated WiFi. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - final ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); - mWiFiNetworkAgent.connect(true); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_WIFI); - // Test bringing up unvalidated cellular. - // Expect it to be torn down because it could never be the highest scoring network - // satisfying the default request even if it validated. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(false); - mCellNetworkAgent.expectDisconnected(); - verifyActiveNetwork(TRANSPORT_WIFI); - mWiFiNetworkAgent.disconnect(); - mWiFiNetworkAgent.expectDisconnected(); - } - - @Test - public void testCellularFallback() throws Exception { - // Test bringing up validated cellular. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - ExpectedBroadcast b = registerConnectivityBroadcast(1); - mCellNetworkAgent.connect(true); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_CELLULAR); - // Test bringing up validated WiFi. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - b = registerConnectivityBroadcast(2); - mWiFiNetworkAgent.connect(true); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_WIFI); - // Reevaluate WiFi (it'll instantly fail DNS). - b = registerConnectivityBroadcast(2); - assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( - NET_CAPABILITY_VALIDATED)); - mCm.reportBadNetwork(mWiFiNetworkAgent.getNetwork()); - // Should quickly fall back to Cellular. - b.expectBroadcast(); - assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( - NET_CAPABILITY_VALIDATED)); - verifyActiveNetwork(TRANSPORT_CELLULAR); - // Reevaluate cellular (it'll instantly fail DNS). - b = registerConnectivityBroadcast(2); - assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( - NET_CAPABILITY_VALIDATED)); - mCm.reportBadNetwork(mCellNetworkAgent.getNetwork()); - // Should quickly fall back to WiFi. - b.expectBroadcast(); - assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( - NET_CAPABILITY_VALIDATED)); - assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( - NET_CAPABILITY_VALIDATED)); - verifyActiveNetwork(TRANSPORT_WIFI); - } - - @Test - public void testWiFiFallback() throws Exception { - // Test bringing up unvalidated WiFi. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - ExpectedBroadcast b = registerConnectivityBroadcast(1); - mWiFiNetworkAgent.connect(false); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_WIFI); - // Test bringing up validated cellular. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - b = registerConnectivityBroadcast(2); - mCellNetworkAgent.connect(true); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_CELLULAR); - // Reevaluate cellular (it'll instantly fail DNS). - b = registerConnectivityBroadcast(2); - assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( - NET_CAPABILITY_VALIDATED)); - mCm.reportBadNetwork(mCellNetworkAgent.getNetwork()); - // Should quickly fall back to WiFi. - b.expectBroadcast(); - assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( - NET_CAPABILITY_VALIDATED)); - verifyActiveNetwork(TRANSPORT_WIFI); - } - - @Test - public void testRequiresValidation() { - assertTrue(NetworkMonitorUtils.isValidationRequired( - mCm.getDefaultRequest().networkCapabilities)); - } - - /** - * Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks - * this class receives, by calling expectCallback() exactly once each time a callback is - * received. assertNoCallback may be called at any time. - */ - private class TestNetworkCallback extends TestableNetworkCallback { - TestNetworkCallback() { - super(TEST_CALLBACK_TIMEOUT_MS); - } - - @Override - public void assertNoCallback() { - // TODO: better support this use case in TestableNetworkCallback - waitForIdle(); - assertNoCallback(0 /* timeout */); - } - - @Override - public <T extends CallbackEntry> T expectCallback(final KClass<T> type, final HasNetwork n, - final long timeoutMs) { - final T callback = super.expectCallback(type, n, timeoutMs); - if (callback instanceof CallbackEntry.Losing) { - // TODO : move this to the specific test(s) needing this rather than here. - final CallbackEntry.Losing losing = (CallbackEntry.Losing) callback; - final int maxMsToLive = losing.getMaxMsToLive(); - String msg = String.format( - "Invalid linger time value %d, must be between %d and %d", - maxMsToLive, 0, mService.mLingerDelayMs); - assertTrue(msg, 0 <= maxMsToLive && maxMsToLive <= mService.mLingerDelayMs); - } - return callback; - } - } - - // Can't be part of TestNetworkCallback because "cannot be declared static; static methods can - // only be declared in a static or top level type". - static void assertNoCallbacks(TestNetworkCallback ... callbacks) { - for (TestNetworkCallback c : callbacks) { - c.assertNoCallback(); - } - } - - static void expectOnLost(TestNetworkAgentWrapper network, TestNetworkCallback ... callbacks) { - for (TestNetworkCallback c : callbacks) { - c.expectCallback(CallbackEntry.LOST, network); - } - } - - static void expectAvailableCallbacksUnvalidatedWithSpecifier(TestNetworkAgentWrapper network, - NetworkSpecifier specifier, TestNetworkCallback ... callbacks) { - for (TestNetworkCallback c : callbacks) { - c.expectCallback(CallbackEntry.AVAILABLE, network); - c.expectCapabilitiesThat(network, (nc) -> - !nc.hasCapability(NET_CAPABILITY_VALIDATED) - && Objects.equals(specifier, nc.getNetworkSpecifier())); - c.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, network); - c.expectCallback(CallbackEntry.BLOCKED_STATUS, network); - } - } - - @Test - public void testStateChangeNetworkCallbacks() throws Exception { - final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); - final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); - final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); - final NetworkRequest genericRequest = new NetworkRequest.Builder() - .clearCapabilities().build(); - final NetworkRequest wifiRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI).build(); - final NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR).build(); - mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); - mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); - mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); - - // Test unvalidated networks - ExpectedBroadcast b = registerConnectivityBroadcast(1); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(false); - genericNetworkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - cellNetworkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - b.expectBroadcast(); - assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); - - // This should not trigger spurious onAvailable() callbacks, b/21762680. - mCellNetworkAgent.adjustScore(-1); - waitForIdle(); - assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - - b = registerConnectivityBroadcast(2); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - b.expectBroadcast(); - assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); - - b = registerConnectivityBroadcast(2); - mWiFiNetworkAgent.disconnect(); - genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - cellNetworkCallback.assertNoCallback(); - b.expectBroadcast(); - assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); - - b = registerConnectivityBroadcast(1); - mCellNetworkAgent.disconnect(); - genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - b.expectBroadcast(); - assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); - - // Test validated networks - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - genericNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); - - // This should not trigger spurious onAvailable() callbacks, b/21762680. - mCellNetworkAgent.adjustScore(-1); - waitForIdle(); - assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - genericNetworkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - genericNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - wifiNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); - cellNetworkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); - - mWiFiNetworkAgent.disconnect(); - genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); - - mCellNetworkAgent.disconnect(); - genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); - } - - private void doNetworkCallbacksSanitizationTest(boolean sanitized) throws Exception { - final TestNetworkCallback callback = new TestNetworkCallback(); - final TestNetworkCallback defaultCallback = new TestNetworkCallback(); - final NetworkRequest wifiRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI).build(); - mCm.registerNetworkCallback(wifiRequest, callback); - mCm.registerDefaultNetworkCallback(defaultCallback); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - - final LinkProperties newLp = new LinkProperties(); - final Uri capportUrl = Uri.parse("https://capport.example.com/api"); - final CaptivePortalData capportData = new CaptivePortalData.Builder() - .setCaptive(true).build(); - - final Uri expectedCapportUrl = sanitized ? null : capportUrl; - newLp.setCaptivePortalApiUrl(capportUrl); - mWiFiNetworkAgent.sendLinkProperties(newLp); - callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> - Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())); - defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> - Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())); - - final CaptivePortalData expectedCapportData = sanitized ? null : capportData; - mWiFiNetworkAgent.notifyCapportApiDataChanged(capportData); - callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> - Objects.equals(expectedCapportData, lp.getCaptivePortalData())); - defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> - Objects.equals(expectedCapportData, lp.getCaptivePortalData())); - - final LinkProperties lp = mCm.getLinkProperties(mWiFiNetworkAgent.getNetwork()); - assertEquals(expectedCapportUrl, lp.getCaptivePortalApiUrl()); - assertEquals(expectedCapportData, lp.getCaptivePortalData()); - } - - @Test - public void networkCallbacksSanitizationTest_Sanitize() throws Exception { - mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - PERMISSION_DENIED); - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); - doNetworkCallbacksSanitizationTest(true /* sanitized */); - } - - @Test - public void networkCallbacksSanitizationTest_NoSanitize_NetworkStack() throws Exception { - mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - PERMISSION_GRANTED); - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); - doNetworkCallbacksSanitizationTest(false /* sanitized */); - } - - @Test - public void networkCallbacksSanitizationTest_NoSanitize_Settings() throws Exception { - mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - PERMISSION_DENIED); - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); - doNetworkCallbacksSanitizationTest(false /* sanitized */); - } - - @Test - public void testOwnerUidCannotChange() throws Exception { - final NetworkCapabilities ncTemplate = new NetworkCapabilities(); - final int originalOwnerUid = Process.myUid(); - ncTemplate.setOwnerUid(originalOwnerUid); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), - ncTemplate); - mWiFiNetworkAgent.connect(false); - waitForIdle(); - - // Send ConnectivityService an update to the mWiFiNetworkAgent's capabilities that changes - // the owner UID and an unrelated capability. - NetworkCapabilities agentCapabilities = mWiFiNetworkAgent.getNetworkCapabilities(); - assertEquals(originalOwnerUid, agentCapabilities.getOwnerUid()); - agentCapabilities.setOwnerUid(42); - assertFalse(agentCapabilities.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); - agentCapabilities.addCapability(NET_CAPABILITY_NOT_CONGESTED); - mWiFiNetworkAgent.setNetworkCapabilities(agentCapabilities, true); - waitForIdle(); - - // Owner UIDs are not visible without location permission. - setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION); - - // Check that the capability change has been applied but the owner UID is not modified. - NetworkCapabilities nc = mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()); - assertEquals(originalOwnerUid, nc.getOwnerUid()); - assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); - } - - @Test - public void testMultipleLingering() throws Exception { - // This test would be flaky with the default 120ms timer: that is short enough that - // lingered networks are torn down before assertions can be run. We don't want to mock the - // lingering timer to keep the WakeupMessage logic realistic: this has already proven useful - // in detecting races. - mService.mLingerDelayMs = 300; - - NetworkRequest request = new NetworkRequest.Builder() - .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED) - .build(); - TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, callback); - - TestNetworkCallback defaultCallback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(defaultCallback); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); - - mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - - mCellNetworkAgent.connect(true); - callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - mWiFiNetworkAgent.connect(true); - // We get AVAILABLE on wifi when wifi connects and satisfies our unmetered request. - // We then get LOSING when wifi validates and cell is outscored. - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - // TODO: Investigate sending validated before losing. - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - mEthernetNetworkAgent.connect(true); - callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent); - // TODO: Investigate sending validated before losing. - callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent); - callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent); - defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent); - assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - mEthernetNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); - defaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); - defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - for (int i = 0; i < 4; i++) { - TestNetworkAgentWrapper oldNetwork, newNetwork; - if (i % 2 == 0) { - mWiFiNetworkAgent.adjustScore(-15); - oldNetwork = mWiFiNetworkAgent; - newNetwork = mCellNetworkAgent; - } else { - mWiFiNetworkAgent.adjustScore(15); - oldNetwork = mCellNetworkAgent; - newNetwork = mWiFiNetworkAgent; - - } - callback.expectCallback(CallbackEntry.LOSING, oldNetwork); - // TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no - // longer lingering? - defaultCallback.expectAvailableCallbacksValidated(newNetwork); - assertEquals(newNetwork.getNetwork(), mCm.getActiveNetwork()); - } - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - - // Verify that if a network no longer satisfies a request, we send LOST and not LOSING, even - // if the network is still up. - mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); - // We expect a notification about the capabilities change, and nothing else. - defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, mWiFiNetworkAgent); - defaultCallback.assertNoCallback(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - // Wifi no longer satisfies our listen, which is for an unmetered network. - // But because its score is 55, it's still up (and the default network). - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - - // Disconnect our test networks. - mWiFiNetworkAgent.disconnect(); - defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - mCellNetworkAgent.disconnect(); - defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - waitForIdle(); - assertEquals(null, mCm.getActiveNetwork()); - - mCm.unregisterNetworkCallback(callback); - waitForIdle(); - - // Check that a network is only lingered or torn down if it would not satisfy a request even - // if it validated. - request = new NetworkRequest.Builder().clearCapabilities().build(); - callback = new TestNetworkCallback(); - - mCm.registerNetworkCallback(request, callback); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(false); // Score: 10 - callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - // Bring up wifi with a score of 20. - // Cell stays up because it would satisfy the default request if it validated. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); // Score: 20 - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - // Bring up wifi, then validate it. Previous versions would immediately tear down cell, but - // it's arguably correct to linger it, since it was the default network before it validated. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - // TODO: Investigate sending validated before losing. - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - mCellNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - waitForIdle(); - assertEquals(null, mCm.getActiveNetwork()); - - // If a network is lingering, and we add and remove a request from it, resume lingering. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - // TODO: Investigate sending validated before losing. - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR).build(); - NetworkCallback noopCallback = new NetworkCallback(); - mCm.requestNetwork(cellRequest, noopCallback); - // TODO: should this cause an AVAILABLE callback, to indicate that the network is no longer - // lingering? - mCm.unregisterNetworkCallback(noopCallback); - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - - // Similar to the above: lingering can start even after the lingered request is removed. - // Disconnect wifi and switch to cell. - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - // Cell is now the default network. Pin it with a cell-specific request. - noopCallback = new NetworkCallback(); // Can't reuse NetworkCallbacks. http://b/20701525 - mCm.requestNetwork(cellRequest, noopCallback); - - // Now connect wifi, and expect it to become the default network. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - callback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); - defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - // The default request is lingering on cell, but nothing happens to cell, and we send no - // callbacks for it, because it's kept up by cellRequest. - callback.assertNoCallback(); - // Now unregister cellRequest and expect cell to start lingering. - mCm.unregisterNetworkCallback(noopCallback); - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - - // Let linger run its course. - callback.assertNoCallback(); - final int lingerTimeoutMs = mService.mLingerDelayMs + mService.mLingerDelayMs / 4; - callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, lingerTimeoutMs); - - // Register a TRACK_DEFAULT request and check that it does not affect lingering. - TestNetworkCallback trackDefaultCallback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(trackDefaultCallback); - trackDefaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); - mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); - mEthernetNetworkAgent.connect(true); - callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent); - callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent); - callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent); - trackDefaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent); - defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - // Let linger run its course. - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent, lingerTimeoutMs); - - // Clean up. - mEthernetNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); - defaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); - trackDefaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); - - mCm.unregisterNetworkCallback(callback); - mCm.unregisterNetworkCallback(defaultCallback); - mCm.unregisterNetworkCallback(trackDefaultCallback); - } - - private void grantUsingBackgroundNetworksPermissionForUid(final int uid) throws Exception { - grantUsingBackgroundNetworksPermissionForUid(uid, mContext.getPackageName()); - } - - private void grantUsingBackgroundNetworksPermissionForUid( - final int uid, final String packageName) throws Exception { - when(mPackageManager.getPackageInfo( - eq(packageName), eq(GET_PERMISSIONS | MATCH_ANY_USER))) - .thenReturn(buildPackageInfo(true /* hasSystemPermission */, uid)); - mService.mPermissionMonitor.onPackageAdded(packageName, uid); - } - - @Test - public void testNetworkGoesIntoBackgroundAfterLinger() throws Exception { - setAlwaysOnNetworks(true); - grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); - NetworkRequest request = new NetworkRequest.Builder() - .clearCapabilities() - .build(); - TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, callback); - - TestNetworkCallback defaultCallback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(defaultCallback); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - - mCellNetworkAgent.connect(true); - callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - - // Wifi comes up and cell lingers. - mWiFiNetworkAgent.connect(true); - defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - - // File a request for cellular, then release it. - NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR).build(); - NetworkCallback noopCallback = new NetworkCallback(); - mCm.requestNetwork(cellRequest, noopCallback); - mCm.unregisterNetworkCallback(noopCallback); - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - - // Let linger run its course. - callback.assertNoCallback(); - final int lingerTimeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; - callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent, - lingerTimeoutMs); - - // Clean up. - mCm.unregisterNetworkCallback(defaultCallback); - mCm.unregisterNetworkCallback(callback); - } - - private NativeNetworkConfig nativeNetworkConfigPhysical(int netId, int permission) { - return new NativeNetworkConfig(netId, NativeNetworkType.PHYSICAL, permission, - /*secure=*/ false, VpnManager.TYPE_VPN_NONE); - } - - private NativeNetworkConfig nativeNetworkConfigVpn(int netId, boolean secure, int vpnType) { - return new NativeNetworkConfig(netId, NativeNetworkType.VIRTUAL, INetd.PERMISSION_NONE, - secure, vpnType); - } - - @Test - public void testNetworkAgentCallbacks() throws Exception { - // Keeps track of the order of events that happen in this test. - final LinkedBlockingQueue<String> eventOrder = new LinkedBlockingQueue<>(); - - final NetworkRequest request = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI).build(); - final TestNetworkCallback callback = new TestNetworkCallback(); - final AtomicReference<Network> wifiNetwork = new AtomicReference<>(); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - - // Expectations for state when various callbacks fire. These expectations run on the handler - // thread and not on the test thread because they need to prevent the handler thread from - // advancing while they examine state. - - // 1. When onCreated fires, netd has been told to create the network. - mWiFiNetworkAgent.setCreatedCallback(() -> { - eventOrder.offer("onNetworkCreated"); - wifiNetwork.set(mWiFiNetworkAgent.getNetwork()); - assertNotNull(wifiNetwork.get()); - try { - verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( - wifiNetwork.get().getNetId(), INetd.PERMISSION_NONE)); - } catch (RemoteException impossible) { - fail(); - } - }); - - // 2. onNetworkUnwanted isn't precisely ordered with respect to any particular events. Just - // check that it is fired at some point after disconnect. - mWiFiNetworkAgent.setUnwantedCallback(() -> eventOrder.offer("onNetworkUnwanted")); - - // 3. While the teardown timer is running, connectivity APIs report the network is gone, but - // netd has not yet been told to destroy it. - final Runnable duringTeardown = () -> { - eventOrder.offer("timePasses"); - assertNull(mCm.getLinkProperties(wifiNetwork.get())); - try { - verify(mMockNetd, never()).networkDestroy(wifiNetwork.get().getNetId()); - } catch (RemoteException impossible) { - fail(); - } - }; - - // 4. After onNetworkDisconnected is called, connectivity APIs report the network is gone, - // and netd has been told to destroy it. - mWiFiNetworkAgent.setDisconnectedCallback(() -> { - eventOrder.offer("onNetworkDisconnected"); - assertNull(mCm.getLinkProperties(wifiNetwork.get())); - try { - verify(mMockNetd).networkDestroy(wifiNetwork.get().getNetId()); - } catch (RemoteException impossible) { - fail(); - } - }); - - // Connect a network, and file a request for it after it has come up, to ensure the nascent - // timer is cleared and the test does not have to wait for it. Filing the request after the - // network has come up is necessary because ConnectivityService does not appear to clear the - // nascent timer if the first request satisfied by the network was filed before the network - // connected. - // TODO: fix this bug, file the request before connecting, and remove the waitForIdle. - mWiFiNetworkAgent.connectWithoutInternet(); - waitForIdle(); - mCm.requestNetwork(request, callback); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - - // Set teardown delay and make sure CS has processed it. - mWiFiNetworkAgent.getNetworkAgent().setTeardownDelayMillis(300); - waitForIdle(); - - // Post the duringTeardown lambda to the handler so it fires while teardown is in progress. - // The delay must be long enough it will run after the unregisterNetworkCallback has torn - // down the network and started the teardown timer, and short enough that the lambda is - // scheduled to run before the teardown timer. - final Handler h = new Handler(mCsHandlerThread.getLooper()); - h.postDelayed(duringTeardown, 150); - - // Disconnect the network and check that events happened in the right order. - mCm.unregisterNetworkCallback(callback); - assertEquals("onNetworkCreated", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - assertEquals("onNetworkUnwanted", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - assertEquals("timePasses", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - assertEquals("onNetworkDisconnected", eventOrder.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - - mCm.unregisterNetworkCallback(callback); - } - - @Test - public void testExplicitlySelected() throws Exception { - NetworkRequest request = new NetworkRequest.Builder() - .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) - .build(); - TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, callback); - - // Bring up validated cell. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - - // Bring up unvalidated wifi with explicitlySelected=true. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.explicitlySelected(true, false); - mWiFiNetworkAgent.connect(false); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - - // Cell Remains the default. - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - - // Lower wifi's score to below than cell, and check that it doesn't disconnect because - // it's explicitly selected. - mWiFiNetworkAgent.adjustScore(-40); - mWiFiNetworkAgent.adjustScore(40); - callback.assertNoCallback(); - - // If the user chooses yes on the "No Internet access, stay connected?" dialog, we switch to - // wifi even though it's unvalidated. - mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), true, false); - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - - // Disconnect wifi, and then reconnect, again with explicitlySelected=true. - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.explicitlySelected(true, false); - mWiFiNetworkAgent.connect(false); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - - // If the user chooses no on the "No Internet access, stay connected?" dialog, we ask the - // network to disconnect. - mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), false, false); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - // Reconnect, again with explicitlySelected=true, but this time validate. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.explicitlySelected(true, false); - mWiFiNetworkAgent.connect(true); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - - mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); - mEthernetNetworkAgent.connect(true); - callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent); - callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent); - callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent); - assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - callback.assertNoCallback(); - - // Disconnect wifi, and then reconnect as if the user had selected "yes, don't ask again" - // (i.e., with explicitlySelected=true and acceptUnvalidated=true). Expect to switch to - // wifi immediately. - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.explicitlySelected(true, true); - mWiFiNetworkAgent.connect(false); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - callback.expectCallback(CallbackEntry.LOSING, mEthernetNetworkAgent); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - mEthernetNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); - - // Disconnect and reconnect with explicitlySelected=false and acceptUnvalidated=true. - // Check that the network is not scored specially and that the device prefers cell data. - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.explicitlySelected(false, true); - mWiFiNetworkAgent.connect(false); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - - // Clean up. - mWiFiNetworkAgent.disconnect(); - mCellNetworkAgent.disconnect(); - - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - } - - private void tryNetworkFactoryRequests(int capability) throws Exception { - // Verify NOT_RESTRICTED is set appropriately - final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability) - .build().networkCapabilities; - if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN - || capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA - || capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS - || capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP - || capability == NET_CAPABILITY_VSIM || capability == NET_CAPABILITY_BIP - || capability == NET_CAPABILITY_ENTERPRISE) { - assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - } else { - assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - } - - NetworkCapabilities filter = new NetworkCapabilities(); - filter.addTransportType(TRANSPORT_CELLULAR); - filter.addCapability(capability); - // Add NOT_VCN_MANAGED capability into filter unconditionally since some requests will add - // NOT_VCN_MANAGED automatically but not for NetworkCapabilities, - // see {@code NetworkCapabilities#deduceNotVcnManagedCapability} for more details. - filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); - final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); - handlerThread.start(); - final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), - mServiceContext, "testFactory", filter, mCsHandlerThread); - testFactory.setScoreFilter(45); - testFactory.register(); - - final NetworkCallback networkCallback; - if (capability != NET_CAPABILITY_INTERNET) { - // If the capability passed in argument is part of the default request, then the - // factory will see the default request. Otherwise the filter will prevent the - // factory from seeing it. In that case, add a request so it can be tested. - assertFalse(testFactory.getMyStartRequested()); - NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build(); - networkCallback = new NetworkCallback(); - mCm.requestNetwork(request, networkCallback); - } else { - networkCallback = null; - } - testFactory.expectRequestAdd(); - testFactory.assertRequestCountEquals(1); - assertTrue(testFactory.getMyStartRequested()); - - // Now bring in a higher scored network. - TestNetworkAgentWrapper testAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - // When testAgent connects, because of its score (50 legacy int / cell transport) - // it will beat or equal the testFactory's offer, so the request will be removed. - // Note the agent as validated only if the capability is INTERNET, as it's the only case - // where it makes sense. - testAgent.connect(NET_CAPABILITY_INTERNET == capability /* validated */); - testAgent.addCapability(capability); - testFactory.expectRequestRemove(); - testFactory.assertRequestCountEquals(0); - assertFalse(testFactory.getMyStartRequested()); - - // Add a request and make sure it's not sent to the factory, because the agent - // is satisfying it better. - final NetworkCallback cb = new ConnectivityManager.NetworkCallback(); - mCm.requestNetwork(new NetworkRequest.Builder().addCapability(capability).build(), cb); - expectNoRequestChanged(testFactory); - testFactory.assertRequestCountEquals(0); - assertFalse(testFactory.getMyStartRequested()); - - // If using legacy scores, make the test agent weak enough to have the exact same score as - // the factory (50 for cell - 5 adjustment). Make sure the factory doesn't see the request. - // If not using legacy score, this is a no-op and the "same score removes request" behavior - // has already been tested above. - testAgent.adjustScore(-5); - expectNoRequestChanged(testFactory); - assertFalse(testFactory.getMyStartRequested()); - - // Make the test agent weak enough that the factory will see the two requests (the one that - // was just sent, and either the default one or the one sent at the top of this test if - // the default won't be seen). - testAgent.setScore(new NetworkScore.Builder().setLegacyInt(2).setExiting(true).build()); - testFactory.expectRequestAdds(2); - testFactory.assertRequestCountEquals(2); - assertTrue(testFactory.getMyStartRequested()); - - // Now unregister and make sure the request is removed. - mCm.unregisterNetworkCallback(cb); - testFactory.expectRequestRemove(); - - // Bring in a bunch of requests. - assertEquals(1, testFactory.getMyRequestCount()); - ConnectivityManager.NetworkCallback[] networkCallbacks = - new ConnectivityManager.NetworkCallback[10]; - for (int i = 0; i< networkCallbacks.length; i++) { - networkCallbacks[i] = new ConnectivityManager.NetworkCallback(); - NetworkRequest.Builder builder = new NetworkRequest.Builder(); - builder.addCapability(capability); - mCm.requestNetwork(builder.build(), networkCallbacks[i]); - } - testFactory.expectRequestAdds(10); - testFactory.assertRequestCountEquals(11); // +1 for the default/test specific request - assertTrue(testFactory.getMyStartRequested()); - - // Remove the requests. - for (int i = 0; i < networkCallbacks.length; i++) { - mCm.unregisterNetworkCallback(networkCallbacks[i]); - } - testFactory.expectRequestRemoves(10); - testFactory.assertRequestCountEquals(1); - assertTrue(testFactory.getMyStartRequested()); - - // Adjust the agent score up again. Expect the request to be withdrawn. - testAgent.setScore(new NetworkScore.Builder().setLegacyInt(50).build()); - testFactory.expectRequestRemove(); - testFactory.assertRequestCountEquals(0); - assertFalse(testFactory.getMyStartRequested()); - - // Drop the higher scored network. - testAgent.disconnect(); - testFactory.expectRequestAdd(); - testFactory.assertRequestCountEquals(1); - assertEquals(1, testFactory.getMyRequestCount()); - assertTrue(testFactory.getMyStartRequested()); - - testFactory.terminate(); - if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback); - handlerThread.quit(); - } - - @Test - public void testNetworkFactoryRequests() throws Exception { - tryNetworkFactoryRequests(NET_CAPABILITY_MMS); - tryNetworkFactoryRequests(NET_CAPABILITY_SUPL); - tryNetworkFactoryRequests(NET_CAPABILITY_DUN); - tryNetworkFactoryRequests(NET_CAPABILITY_FOTA); - tryNetworkFactoryRequests(NET_CAPABILITY_IMS); - tryNetworkFactoryRequests(NET_CAPABILITY_CBS); - tryNetworkFactoryRequests(NET_CAPABILITY_WIFI_P2P); - tryNetworkFactoryRequests(NET_CAPABILITY_IA); - tryNetworkFactoryRequests(NET_CAPABILITY_RCS); - tryNetworkFactoryRequests(NET_CAPABILITY_XCAP); - tryNetworkFactoryRequests(NET_CAPABILITY_ENTERPRISE); - tryNetworkFactoryRequests(NET_CAPABILITY_EIMS); - tryNetworkFactoryRequests(NET_CAPABILITY_NOT_METERED); - tryNetworkFactoryRequests(NET_CAPABILITY_INTERNET); - tryNetworkFactoryRequests(NET_CAPABILITY_TRUSTED); - tryNetworkFactoryRequests(NET_CAPABILITY_NOT_VPN); - tryNetworkFactoryRequests(NET_CAPABILITY_VSIM); - tryNetworkFactoryRequests(NET_CAPABILITY_BIP); - // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed. - } - - @Test - public void testRegisterIgnoringScore() throws Exception { - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(90).build()); - mWiFiNetworkAgent.connect(true /* validated */); - - // Make sure the factory sees the default network - final NetworkCapabilities filter = new NetworkCapabilities(); - filter.addTransportType(TRANSPORT_CELLULAR); - filter.addCapability(NET_CAPABILITY_INTERNET); - filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); - final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); - handlerThread.start(); - final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), - mServiceContext, "testFactory", filter, mCsHandlerThread); - testFactory.register(); - - final MockNetworkFactory testFactoryAll = new MockNetworkFactory(handlerThread.getLooper(), - mServiceContext, "testFactoryAll", filter, mCsHandlerThread); - testFactoryAll.registerIgnoringScore(); - - // The regular test factory should not see the request, because WiFi is stronger than cell. - expectNoRequestChanged(testFactory); - // With ignoringScore though the request is seen. - testFactoryAll.expectRequestAdd(); - - // The legacy int will be ignored anyway, set the only other knob to true - mWiFiNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(110) - .setTransportPrimary(true).build()); - - expectNoRequestChanged(testFactory); // still not seeing the request - expectNoRequestChanged(testFactoryAll); // still seeing the request - - mWiFiNetworkAgent.disconnect(); - } - - @Test - public void testNetworkFactoryUnregister() throws Exception { - // Make sure the factory sees the default network - final NetworkCapabilities filter = new NetworkCapabilities(); - filter.addCapability(NET_CAPABILITY_INTERNET); - filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); - - final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); - handlerThread.start(); - - // Checks that calling setScoreFilter on a NetworkFactory immediately before closing it - // does not crash. - for (int i = 0; i < 100; i++) { - final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), - mServiceContext, "testFactory", filter, mCsHandlerThread); - // Register the factory and don't be surprised when the default request arrives. - testFactory.register(); - testFactory.expectRequestAdd(); - - testFactory.setScoreFilter(42); - testFactory.terminate(); - - if (i % 2 == 0) { - try { - testFactory.register(); - fail("Re-registering terminated NetworkFactory should throw"); - } catch (IllegalStateException expected) { - } - } - } - handlerThread.quit(); - } - - @Test - public void testNoMutableNetworkRequests() throws Exception { - final PendingIntent pendingIntent = PendingIntent.getBroadcast( - mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); - NetworkRequest request1 = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_VALIDATED) - .build(); - NetworkRequest request2 = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL) - .build(); - - Class<IllegalArgumentException> expected = IllegalArgumentException.class; - assertThrows(expected, () -> mCm.requestNetwork(request1, new NetworkCallback())); - assertThrows(expected, () -> mCm.requestNetwork(request1, pendingIntent)); - assertThrows(expected, () -> mCm.requestNetwork(request2, new NetworkCallback())); - assertThrows(expected, () -> mCm.requestNetwork(request2, pendingIntent)); - } - - @Test - public void testMMSonWiFi() throws Exception { - // Test bringing up cellular without MMS NetworkRequest gets reaped - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS); - mCellNetworkAgent.connectWithoutInternet(); - mCellNetworkAgent.expectDisconnected(); - waitForIdle(); - assertEmpty(mCm.getAllNetworks()); - verifyNoNetwork(); - - // Test bringing up validated WiFi. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - final ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); - mWiFiNetworkAgent.connect(true); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_WIFI); - - // Register MMS NetworkRequest - NetworkRequest.Builder builder = new NetworkRequest.Builder(); - builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); - final TestNetworkCallback networkCallback = new TestNetworkCallback(); - mCm.requestNetwork(builder.build(), networkCallback); - - // Test bringing up unvalidated cellular with MMS - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS); - mCellNetworkAgent.connectWithoutInternet(); - networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - verifyActiveNetwork(TRANSPORT_WIFI); - - // Test releasing NetworkRequest disconnects cellular with MMS - mCm.unregisterNetworkCallback(networkCallback); - mCellNetworkAgent.expectDisconnected(); - verifyActiveNetwork(TRANSPORT_WIFI); - } - - @Test - public void testMMSonCell() throws Exception { - // Test bringing up cellular without MMS - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - ExpectedBroadcast b = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); - mCellNetworkAgent.connect(false); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_CELLULAR); - - // Register MMS NetworkRequest - NetworkRequest.Builder builder = new NetworkRequest.Builder(); - builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); - final TestNetworkCallback networkCallback = new TestNetworkCallback(); - mCm.requestNetwork(builder.build(), networkCallback); - - // Test bringing up MMS cellular network - TestNetworkAgentWrapper - mmsNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS); - mmsNetworkAgent.connectWithoutInternet(); - networkCallback.expectAvailableCallbacksUnvalidated(mmsNetworkAgent); - verifyActiveNetwork(TRANSPORT_CELLULAR); - - // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent - mCm.unregisterNetworkCallback(networkCallback); - mmsNetworkAgent.expectDisconnected(); - verifyActiveNetwork(TRANSPORT_CELLULAR); - } - - @Test - public void testPartialConnectivity() throws Exception { - // Register network callback. - NetworkRequest request = new NetworkRequest.Builder() - .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) - .build(); - TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, callback); - - // Bring up validated mobile data. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - - // Bring up wifi with partial connectivity. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connectWithPartialConnectivity(); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent); - - // Mobile data should be the default network. - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - callback.assertNoCallback(); - - // With HTTPS probe disabled, NetworkMonitor should pass the network validation with http - // probe. - mWiFiNetworkAgent.setNetworkPartialValid(false /* isStrictMode */); - // If the user chooses yes to use this partial connectivity wifi, switch the default - // network to wifi and check if wifi becomes valid or not. - mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */, - false /* always */); - // If user accepts partial connectivity network, - // NetworkMonitor#setAcceptPartialConnectivity() should be called too. - waitForIdle(); - verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); - - // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is - // validated. - mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - NetworkCapabilities nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, - mWiFiNetworkAgent); - assertTrue(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - - // Disconnect and reconnect wifi with partial connectivity again. - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connectWithPartialConnectivity(); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent); - - // Mobile data should be the default network. - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - - // If the user chooses no, disconnect wifi immediately. - mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), false/* accept */, - false /* always */); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - // If user accepted partial connectivity before, and device reconnects to that network - // again, but now the network has full connectivity. The network shouldn't contain - // NET_CAPABILITY_PARTIAL_CONNECTIVITY. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - // acceptUnvalidated is also used as setting for accepting partial networks. - mWiFiNetworkAgent.explicitlySelected(true /* explicitlySelected */, - true /* acceptUnvalidated */); - mWiFiNetworkAgent.connect(true); - - // If user accepted partial connectivity network before, - // NetworkMonitor#setAcceptPartialConnectivity() will be called in - // ConnectivityService#updateNetworkInfo(). - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - assertFalse(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)); - - // Wifi should be the default network. - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - // The user accepted partial connectivity and selected "don't ask again". Now the user - // reconnects to the partial connectivity network. Switch to wifi as soon as partial - // connectivity is detected. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.explicitlySelected(true /* explicitlySelected */, - true /* acceptUnvalidated */); - mWiFiNetworkAgent.connectWithPartialConnectivity(); - // If user accepted partial connectivity network before, - // NetworkMonitor#setAcceptPartialConnectivity() will be called in - // ConnectivityService#updateNetworkInfo(). - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent); - mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */); - - // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is - // validated. - mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); - callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - // If the user accepted partial connectivity, and the device auto-reconnects to the partial - // connectivity network, it should contain both PARTIAL_CONNECTIVITY and VALIDATED. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.explicitlySelected(false /* explicitlySelected */, - true /* acceptUnvalidated */); - - // NetworkMonitor will immediately (once the HTTPS probe fails...) report the network as - // valid, because ConnectivityService calls setAcceptPartialConnectivity before it calls - // notifyNetworkConnected. - mWiFiNetworkAgent.connectWithPartialValidConnectivity(false /* isStrictMode */); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity(); - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - callback.expectCapabilitiesWith( - NET_CAPABILITY_PARTIAL_CONNECTIVITY | NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - } - - @Test - public void testCaptivePortalOnPartialConnectivity() throws Exception { - final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); - final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); - mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); - - final TestNetworkCallback validatedCallback = new TestNetworkCallback(); - final NetworkRequest validatedRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_VALIDATED).build(); - mCm.registerNetworkCallback(validatedRequest, validatedCallback); - - // Bring up a network with a captive portal. - // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - String redirectUrl = "http://android.com/path"; - mWiFiNetworkAgent.connectWithCaptivePortal(redirectUrl, false /* isStrictMode */); - captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), redirectUrl); - - // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. - mCm.startCaptivePortalApp(mWiFiNetworkAgent.getNetwork()); - verify(mWiFiNetworkAgent.mNetworkMonitor, timeout(TIMEOUT_MS).times(1)) - .launchCaptivePortalApp(); - - // Report that the captive portal is dismissed with partial connectivity, and check that - // callbacks are fired. - mWiFiNetworkAgent.setNetworkPartial(); - mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); - waitForIdle(); - captivePortalCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, - mWiFiNetworkAgent); - - // Report partial connectivity is accepted. - mWiFiNetworkAgent.setNetworkPartialValid(false /* isStrictMode */); - mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */, - false /* always */); - waitForIdle(); - mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); - captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); - NetworkCapabilities nc = - validatedCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, - mWiFiNetworkAgent); - - mCm.unregisterNetworkCallback(captivePortalCallback); - mCm.unregisterNetworkCallback(validatedCallback); - } - - @Test - public void testCaptivePortal() throws Exception { - final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); - final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); - mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); - - final TestNetworkCallback validatedCallback = new TestNetworkCallback(); - final NetworkRequest validatedRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_VALIDATED).build(); - mCm.registerNetworkCallback(validatedRequest, validatedCallback); - - // Bring up a network with a captive portal. - // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - String firstRedirectUrl = "http://example.com/firstPath"; - mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl, false /* isStrictMode */); - captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl); - - // Take down network. - // Expect onLost callback. - mWiFiNetworkAgent.disconnect(); - captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - // Bring up a network with a captive portal. - // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - String secondRedirectUrl = "http://example.com/secondPath"; - mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl, false /* isStrictMode */); - captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), secondRedirectUrl); - - // Make captive portal disappear then revalidate. - // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL. - mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */); - mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); - captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - // Expect NET_CAPABILITY_VALIDATED onAvailable callback. - validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - - // Break network connectivity. - // Expect NET_CAPABILITY_VALIDATED onLost callback. - mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */); - mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false); - validatedCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - } - - @Test - public void testCaptivePortalApp() throws Exception { - final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); - final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); - mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); - - final TestNetworkCallback validatedCallback = new TestNetworkCallback(); - final NetworkRequest validatedRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_VALIDATED).build(); - mCm.registerNetworkCallback(validatedRequest, validatedCallback); - - // Bring up wifi. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - Network wifiNetwork = mWiFiNetworkAgent.getNetwork(); - - // Check that calling startCaptivePortalApp does nothing. - final int fastTimeoutMs = 100; - mCm.startCaptivePortalApp(wifiNetwork); - waitForIdle(); - verify(mWiFiNetworkAgent.mNetworkMonitor, never()).launchCaptivePortalApp(); - mServiceContext.expectNoStartActivityIntent(fastTimeoutMs); - - // Turn into a captive portal. - mWiFiNetworkAgent.setNetworkPortal("http://example.com", false /* isStrictMode */); - mCm.reportNetworkConnectivity(wifiNetwork, false); - captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - validatedCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - // Check that startCaptivePortalApp sends the expected command to NetworkMonitor. - mCm.startCaptivePortalApp(wifiNetwork); - waitForIdle(); - verify(mWiFiNetworkAgent.mNetworkMonitor).launchCaptivePortalApp(); - - // NetworkMonitor uses startCaptivePortal(Network, Bundle) (startCaptivePortalAppInternal) - final Bundle testBundle = new Bundle(); - final String testKey = "testkey"; - final String testValue = "testvalue"; - testBundle.putString(testKey, testValue); - mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - PERMISSION_GRANTED); - mCm.startCaptivePortalApp(wifiNetwork, testBundle); - final Intent signInIntent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS); - assertEquals(ACTION_CAPTIVE_PORTAL_SIGN_IN, signInIntent.getAction()); - assertEquals(testValue, signInIntent.getStringExtra(testKey)); - - // Report that the captive portal is dismissed, and check that callbacks are fired - mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */); - mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); - validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); - captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - mCm.unregisterNetworkCallback(validatedCallback); - mCm.unregisterNetworkCallback(captivePortalCallback); - } - - @Test - public void testAvoidOrIgnoreCaptivePortals() throws Exception { - final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); - final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); - mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); - - final TestNetworkCallback validatedCallback = new TestNetworkCallback(); - final NetworkRequest validatedRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_VALIDATED).build(); - mCm.registerNetworkCallback(validatedRequest, validatedCallback); - - setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID); - // Bring up a network with a captive portal. - // Expect it to fail to connect and not result in any callbacks. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - String firstRedirectUrl = "http://example.com/firstPath"; - - mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl, false /* isStrictMode */); - mWiFiNetworkAgent.expectDisconnected(); - mWiFiNetworkAgent.expectPreventReconnectReceived(); - - assertNoCallbacks(captivePortalCallback, validatedCallback); - } - - @Test - public void testCaptivePortalApi() throws Exception { - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); - - final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); - final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); - mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - final String redirectUrl = "http://example.com/firstPath"; - - mWiFiNetworkAgent.connectWithCaptivePortal(redirectUrl, false /* isStrictMode */); - captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - - final CaptivePortalData testData = new CaptivePortalData.Builder() - .setUserPortalUrl(Uri.parse(redirectUrl)) - .setBytesRemaining(12345L) - .build(); - - mWiFiNetworkAgent.notifyCapportApiDataChanged(testData); - - captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, - lp -> testData.equals(lp.getCaptivePortalData())); - - final LinkProperties newLps = new LinkProperties(); - newLps.setMtu(1234); - mWiFiNetworkAgent.sendLinkProperties(newLps); - // CaptivePortalData is not lost and unchanged when LPs are received from the NetworkAgent - captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, - lp -> testData.equals(lp.getCaptivePortalData()) && lp.getMtu() == 1234); - } - - private TestNetworkCallback setupNetworkCallbackAndConnectToWifi() throws Exception { - // Grant NETWORK_SETTINGS permission to be able to receive LinkProperties change callbacks - // with sensitive (captive portal) data - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); - - final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); - final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); - mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - - mWiFiNetworkAgent.connectWithCaptivePortal(TEST_REDIRECT_URL, false /* isStrictMode */); - captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - return captivePortalCallback; - } - - private class CaptivePortalTestData { - CaptivePortalTestData(CaptivePortalData naPasspointData, CaptivePortalData capportData, - CaptivePortalData naOtherData, CaptivePortalData expectedMergedPasspointData, - CaptivePortalData expectedMergedOtherData) { - mNaPasspointData = naPasspointData; - mCapportData = capportData; - mNaOtherData = naOtherData; - mExpectedMergedPasspointData = expectedMergedPasspointData; - mExpectedMergedOtherData = expectedMergedOtherData; - } - - public final CaptivePortalData mNaPasspointData; - public final CaptivePortalData mCapportData; - public final CaptivePortalData mNaOtherData; - public final CaptivePortalData mExpectedMergedPasspointData; - public final CaptivePortalData mExpectedMergedOtherData; - - } - - private CaptivePortalTestData setupCaptivePortalData() { - final CaptivePortalData capportData = new CaptivePortalData.Builder() - .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) - .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_CAPPORT)) - .setUserPortalUrl(Uri.parse(TEST_USER_PORTAL_API_URL_CAPPORT)) - .setExpiryTime(1000000L) - .setBytesRemaining(12345L) - .build(); - - final CaptivePortalData naPasspointData = new CaptivePortalData.Builder() - .setBytesRemaining(80802L) - .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_PASSPOINT), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) - .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) - .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); - - final CaptivePortalData naOtherData = new CaptivePortalData.Builder() - .setBytesRemaining(80802L) - .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_OTHER), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) - .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_OTHER), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) - .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); - - final CaptivePortalData expectedMergedPasspointData = new CaptivePortalData.Builder() - .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) - .setBytesRemaining(12345L) - .setExpiryTime(1000000L) - .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA_PASSPOINT), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) - .setUserPortalUrl(Uri.parse(TEST_TERMS_AND_CONDITIONS_URL_NA_PASSPOINT), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) - .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); - - final CaptivePortalData expectedMergedOtherData = new CaptivePortalData.Builder() - .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL)) - .setBytesRemaining(12345L) - .setExpiryTime(1000000L) - .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_CAPPORT)) - .setUserPortalUrl(Uri.parse(TEST_USER_PORTAL_API_URL_CAPPORT)) - .setVenueFriendlyName(TEST_FRIENDLY_NAME).build(); - return new CaptivePortalTestData(naPasspointData, capportData, naOtherData, - expectedMergedPasspointData, expectedMergedOtherData); - } - - @Test - public void testMergeCaptivePortalApiWithFriendlyNameAndVenueUrl() throws Exception { - final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); - final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); - - // Baseline capport data - mWiFiNetworkAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); - - captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, - lp -> captivePortalTestData.mCapportData.equals(lp.getCaptivePortalData())); - - // Venue URL, T&C URL and friendly name from Network agent with Passpoint source, confirm - // that API data gets precedence on the bytes remaining. - final LinkProperties linkProperties = new LinkProperties(); - linkProperties.setCaptivePortalData(captivePortalTestData.mNaPasspointData); - mWiFiNetworkAgent.sendLinkProperties(linkProperties); - - // Make sure that the capport data is merged - captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, - lp -> captivePortalTestData.mExpectedMergedPasspointData - .equals(lp.getCaptivePortalData())); - - // Now send this information from non-Passpoint source, confirm that Capport data takes - // precedence - linkProperties.setCaptivePortalData(captivePortalTestData.mNaOtherData); - mWiFiNetworkAgent.sendLinkProperties(linkProperties); - - // Make sure that the capport data is merged - captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, - lp -> captivePortalTestData.mExpectedMergedOtherData - .equals(lp.getCaptivePortalData())); - - // Create a new LP with no Network agent capport data - final LinkProperties newLps = new LinkProperties(); - newLps.setMtu(1234); - mWiFiNetworkAgent.sendLinkProperties(newLps); - // CaptivePortalData is not lost and has the original values when LPs are received from the - // NetworkAgent - captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, - lp -> captivePortalTestData.mCapportData.equals(lp.getCaptivePortalData()) - && lp.getMtu() == 1234); - - // Now send capport data only from the Network agent - mWiFiNetworkAgent.notifyCapportApiDataChanged(null); - captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, - lp -> lp.getCaptivePortalData() == null); - - newLps.setCaptivePortalData(captivePortalTestData.mNaPasspointData); - mWiFiNetworkAgent.sendLinkProperties(newLps); - - // Make sure that only the network agent capport data is available - captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, - lp -> captivePortalTestData.mNaPasspointData.equals(lp.getCaptivePortalData())); - } - - @Test - public void testMergeCaptivePortalDataFromNetworkAgentFirstThenCapport() throws Exception { - final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); - final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); - - // Venue URL and friendly name from Network agent, confirm that API data gets precedence - // on the bytes remaining. - final LinkProperties linkProperties = new LinkProperties(); - linkProperties.setCaptivePortalData(captivePortalTestData.mNaPasspointData); - mWiFiNetworkAgent.sendLinkProperties(linkProperties); - - // Make sure that the data is saved correctly - captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, - lp -> captivePortalTestData.mNaPasspointData.equals(lp.getCaptivePortalData())); - - // Expected merged data: Network agent data is preferred, and values that are not used by - // it are merged from capport data - mWiFiNetworkAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); - - // Make sure that the Capport data is merged correctly - captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, - lp -> captivePortalTestData.mExpectedMergedPasspointData.equals( - lp.getCaptivePortalData())); - - // Now set the naData to null - linkProperties.setCaptivePortalData(null); - mWiFiNetworkAgent.sendLinkProperties(linkProperties); - - // Make sure that the Capport data is retained correctly - captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, - lp -> captivePortalTestData.mCapportData.equals(lp.getCaptivePortalData())); - } - - @Test - public void testMergeCaptivePortalDataFromNetworkAgentOtherSourceFirstThenCapport() - throws Exception { - final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi(); - final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData(); - - // Venue URL and friendly name from Network agent, confirm that API data gets precedence - // on the bytes remaining. - final LinkProperties linkProperties = new LinkProperties(); - linkProperties.setCaptivePortalData(captivePortalTestData.mNaOtherData); - mWiFiNetworkAgent.sendLinkProperties(linkProperties); - - // Make sure that the data is saved correctly - captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, - lp -> captivePortalTestData.mNaOtherData.equals(lp.getCaptivePortalData())); - - // Expected merged data: Network agent data is preferred, and values that are not used by - // it are merged from capport data - mWiFiNetworkAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData); - - // Make sure that the Capport data is merged correctly - captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, - lp -> captivePortalTestData.mExpectedMergedOtherData.equals( - lp.getCaptivePortalData())); - } - - private NetworkRequest.Builder newWifiRequestBuilder() { - return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI); - } - - /** - * Verify request matching behavior with network specifiers. - * - * This test does not check updating the specifier on a live network because the specifier is - * immutable and this triggers a WTF in - * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)}. - */ - @Test - public void testNetworkSpecifier() throws Exception { - // A NetworkSpecifier subclass that matches all networks but must not be visible to apps. - class ConfidentialMatchAllNetworkSpecifier extends NetworkSpecifier implements - Parcelable { - @Override - public boolean canBeSatisfiedBy(NetworkSpecifier other) { - return true; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) {} - - @Override - public NetworkSpecifier redact() { - return null; - } - } - - // A network specifier that matches either another LocalNetworkSpecifier with the same - // string or a ConfidentialMatchAllNetworkSpecifier, and can be passed to apps as is. - class LocalStringNetworkSpecifier extends NetworkSpecifier implements Parcelable { - private String mString; - - LocalStringNetworkSpecifier(String string) { - mString = string; - } - - @Override - public boolean canBeSatisfiedBy(NetworkSpecifier other) { - if (other instanceof LocalStringNetworkSpecifier) { - return TextUtils.equals(mString, - ((LocalStringNetworkSpecifier) other).mString); - } - if (other instanceof ConfidentialMatchAllNetworkSpecifier) return true; - return false; - } - - @Override - public int describeContents() { - return 0; - } - @Override - public void writeToParcel(Parcel dest, int flags) {} - } - - - NetworkRequest rEmpty1 = newWifiRequestBuilder().build(); - NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build(); - NetworkRequest rEmpty3 = newWifiRequestBuilder().setNetworkSpecifier("").build(); - NetworkRequest rEmpty4 = newWifiRequestBuilder().setNetworkSpecifier( - (NetworkSpecifier) null).build(); - NetworkRequest rFoo = newWifiRequestBuilder().setNetworkSpecifier( - new LocalStringNetworkSpecifier("foo")).build(); - NetworkRequest rBar = newWifiRequestBuilder().setNetworkSpecifier( - new LocalStringNetworkSpecifier("bar")).build(); - - TestNetworkCallback cEmpty1 = new TestNetworkCallback(); - TestNetworkCallback cEmpty2 = new TestNetworkCallback(); - TestNetworkCallback cEmpty3 = new TestNetworkCallback(); - TestNetworkCallback cEmpty4 = new TestNetworkCallback(); - TestNetworkCallback cFoo = new TestNetworkCallback(); - TestNetworkCallback cBar = new TestNetworkCallback(); - TestNetworkCallback[] emptyCallbacks = new TestNetworkCallback[] { - cEmpty1, cEmpty2, cEmpty3, cEmpty4 }; - - mCm.registerNetworkCallback(rEmpty1, cEmpty1); - mCm.registerNetworkCallback(rEmpty2, cEmpty2); - mCm.registerNetworkCallback(rEmpty3, cEmpty3); - mCm.registerNetworkCallback(rEmpty4, cEmpty4); - mCm.registerNetworkCallback(rFoo, cFoo); - mCm.registerNetworkCallback(rBar, cBar); - - LocalStringNetworkSpecifier nsFoo = new LocalStringNetworkSpecifier("foo"); - LocalStringNetworkSpecifier nsBar = new LocalStringNetworkSpecifier("bar"); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, null /* specifier */, - cEmpty1, cEmpty2, cEmpty3, cEmpty4); - assertNoCallbacks(cFoo, cBar); - - mWiFiNetworkAgent.disconnect(); - expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.setNetworkSpecifier(nsFoo); - mWiFiNetworkAgent.connect(false); - expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, nsFoo, - cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); - cBar.assertNoCallback(); - assertEquals(nsFoo, - mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); - assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); - - mWiFiNetworkAgent.disconnect(); - expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.setNetworkSpecifier(nsBar); - mWiFiNetworkAgent.connect(false); - expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, nsBar, - cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); - cFoo.assertNoCallback(); - assertEquals(nsBar, - mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); - - mWiFiNetworkAgent.disconnect(); - expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar); - cFoo.assertNoCallback(); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.setNetworkSpecifier(new ConfidentialMatchAllNetworkSpecifier()); - mWiFiNetworkAgent.connect(false); - expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, null /* specifier */, - cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); - assertNull( - mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); - - mWiFiNetworkAgent.disconnect(); - expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); - } - - /** - * @return the context's attribution tag - */ - private String getAttributionTag() { - return mContext.getAttributionTag(); - } - - @Test - public void testInvalidNetworkSpecifier() { - assertThrows(IllegalArgumentException.class, () -> { - NetworkRequest.Builder builder = new NetworkRequest.Builder(); - builder.setNetworkSpecifier(new MatchAllNetworkSpecifier()); - }); - - assertThrows(IllegalArgumentException.class, () -> { - NetworkCapabilities networkCapabilities = new NetworkCapabilities(); - networkCapabilities.addTransportType(TRANSPORT_WIFI) - .setNetworkSpecifier(new MatchAllNetworkSpecifier()); - mService.requestNetwork(Process.INVALID_UID, networkCapabilities, - NetworkRequest.Type.REQUEST.ordinal(), null, 0, null, - ConnectivityManager.TYPE_WIFI, NetworkCallback.FLAG_NONE, - mContext.getPackageName(), getAttributionTag()); - }); - - class NonParcelableSpecifier extends NetworkSpecifier { - @Override - public boolean canBeSatisfiedBy(NetworkSpecifier other) { - return false; - } - }; - class ParcelableSpecifier extends NonParcelableSpecifier implements Parcelable { - @Override public int describeContents() { return 0; } - @Override public void writeToParcel(Parcel p, int flags) {} - } - - final NetworkRequest.Builder builder = - new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET); - assertThrows(ClassCastException.class, () -> { - builder.setNetworkSpecifier(new NonParcelableSpecifier()); - Parcel parcelW = Parcel.obtain(); - builder.build().writeToParcel(parcelW, 0); - }); - - final NetworkRequest nr = - new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET) - .setNetworkSpecifier(new ParcelableSpecifier()) - .build(); - assertNotNull(nr); - - assertThrows(BadParcelableException.class, () -> { - Parcel parcelW = Parcel.obtain(); - nr.writeToParcel(parcelW, 0); - byte[] bytes = parcelW.marshall(); - parcelW.recycle(); - - Parcel parcelR = Parcel.obtain(); - parcelR.unmarshall(bytes, 0, bytes.length); - parcelR.setDataPosition(0); - NetworkRequest rereadNr = NetworkRequest.CREATOR.createFromParcel(parcelR); - }); - } - - @Test - public void testNetworkRequestUidSpoofSecurityException() throws Exception { - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - NetworkRequest networkRequest = newWifiRequestBuilder().build(); - TestNetworkCallback networkCallback = new TestNetworkCallback(); - doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString()); - assertThrows(SecurityException.class, () -> { - mCm.requestNetwork(networkRequest, networkCallback); - }); - } - - @Test - public void testInvalidSignalStrength() { - NetworkRequest r = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_INTERNET) - .addTransportType(TRANSPORT_WIFI) - .setSignalStrength(-75) - .build(); - // Registering a NetworkCallback with signal strength but w/o NETWORK_SIGNAL_STRENGTH_WAKEUP - // permission should get SecurityException. - assertThrows(SecurityException.class, () -> - mCm.registerNetworkCallback(r, new NetworkCallback())); - - assertThrows(SecurityException.class, () -> - mCm.registerNetworkCallback(r, PendingIntent.getService( - mServiceContext, 0 /* requestCode */, new Intent(), FLAG_IMMUTABLE))); - - // Requesting a Network with signal strength should get IllegalArgumentException. - assertThrows(IllegalArgumentException.class, () -> - mCm.requestNetwork(r, new NetworkCallback())); - - assertThrows(IllegalArgumentException.class, () -> - mCm.requestNetwork(r, PendingIntent.getService( - mServiceContext, 0 /* requestCode */, new Intent(), FLAG_IMMUTABLE))); - } - - @Test - public void testRegisterDefaultNetworkCallback() throws Exception { - // NETWORK_SETTINGS is necessary to call registerSystemDefaultNetworkCallback. - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); - - final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(defaultNetworkCallback); - defaultNetworkCallback.assertNoCallback(); - - final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); - final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); - mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, handler); - systemDefaultCallback.assertNoCallback(); - - // Create a TRANSPORT_CELLULAR request to keep the mobile interface up - // whenever Wi-Fi is up. Without this, the mobile network agent is - // reaped before any other activity can take place. - final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); - final NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR).build(); - mCm.requestNetwork(cellRequest, cellNetworkCallback); - cellNetworkCallback.assertNoCallback(); - - // Bring up cell and expect CALLBACK_AVAILABLE. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - systemDefaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - // Bring up wifi and expect CALLBACK_AVAILABLE. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - cellNetworkCallback.assertNoCallback(); - defaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - systemDefaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - // Bring down cell. Expect no default network callback, since it wasn't the default. - mCellNetworkAgent.disconnect(); - cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - defaultNetworkCallback.assertNoCallback(); - systemDefaultCallback.assertNoCallback(); - assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - // Bring up cell. Expect no default network callback, since it won't be the default. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - defaultNetworkCallback.assertNoCallback(); - systemDefaultCallback.assertNoCallback(); - assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - assertEquals(systemDefaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - // Bring down wifi. Expect the default network callback to notified of LOST wifi - // followed by AVAILABLE cell. - mWiFiNetworkAgent.disconnect(); - cellNetworkCallback.assertNoCallback(); - defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - defaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - systemDefaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - mCellNetworkAgent.disconnect(); - cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - systemDefaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - waitForIdle(); - assertEquals(null, mCm.getActiveNetwork()); - - mMockVpn.establishForMyUid(); - assertUidRangesUpdatedForMyUid(true); - defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); - systemDefaultCallback.assertNoCallback(); - assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - assertEquals(null, systemDefaultCallback.getLastAvailableNetwork()); - - mMockVpn.disconnect(); - defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); - systemDefaultCallback.assertNoCallback(); - waitForIdle(); - assertEquals(null, mCm.getActiveNetwork()); - } - - @Test - public void testAdditionalStateCallbacks() throws Exception { - // File a network request for mobile. - final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); - final NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR).build(); - mCm.requestNetwork(cellRequest, cellNetworkCallback); - - // Bring up the mobile network. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - - // We should get onAvailable(), onCapabilitiesChanged(), and - // onLinkPropertiesChanged() in rapid succession. Additionally, we - // should get onCapabilitiesChanged() when the mobile network validates. - cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - cellNetworkCallback.assertNoCallback(); - - // Update LinkProperties. - final LinkProperties lp = new LinkProperties(); - lp.setInterfaceName("foonet_data0"); - mCellNetworkAgent.sendLinkProperties(lp); - // We should get onLinkPropertiesChanged(). - cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, - mCellNetworkAgent); - cellNetworkCallback.assertNoCallback(); - - // Suspend the network. - mCellNetworkAgent.suspend(); - cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_SUSPENDED, - mCellNetworkAgent); - cellNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mCellNetworkAgent); - cellNetworkCallback.assertNoCallback(); - assertEquals(NetworkInfo.State.SUSPENDED, mCm.getActiveNetworkInfo().getState()); - - // Register a garden variety default network request. - TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(dfltNetworkCallback); - // We should get onAvailable(), onCapabilitiesChanged(), onLinkPropertiesChanged(), - // as well as onNetworkSuspended() in rapid succession. - dfltNetworkCallback.expectAvailableAndSuspendedCallbacks(mCellNetworkAgent, true); - dfltNetworkCallback.assertNoCallback(); - mCm.unregisterNetworkCallback(dfltNetworkCallback); - - mCellNetworkAgent.resume(); - cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_SUSPENDED, - mCellNetworkAgent); - cellNetworkCallback.expectCallback(CallbackEntry.RESUMED, mCellNetworkAgent); - cellNetworkCallback.assertNoCallback(); - assertEquals(NetworkInfo.State.CONNECTED, mCm.getActiveNetworkInfo().getState()); - - dfltNetworkCallback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(dfltNetworkCallback); - // This time onNetworkSuspended should not be called. - dfltNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - dfltNetworkCallback.assertNoCallback(); - - mCm.unregisterNetworkCallback(dfltNetworkCallback); - mCm.unregisterNetworkCallback(cellNetworkCallback); - } - - @Test - public void testRegisterPrivilegedDefaultCallbacksRequireNetworkSettings() throws Exception { - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(false /* validated */); - - final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); - final TestNetworkCallback callback = new TestNetworkCallback(); - assertThrows(SecurityException.class, - () -> mCm.registerSystemDefaultNetworkCallback(callback, handler)); - callback.assertNoCallback(); - assertThrows(SecurityException.class, - () -> mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler)); - callback.assertNoCallback(); - - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); - mCm.registerSystemDefaultNetworkCallback(callback, handler); - callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - mCm.unregisterNetworkCallback(callback); - - mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler); - callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - mCm.unregisterNetworkCallback(callback); - } - - private void setCaptivePortalMode(int mode) { - ContentResolver cr = mServiceContext.getContentResolver(); - Settings.Global.putInt(cr, ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE, mode); - } - - private void setAlwaysOnNetworks(boolean enable) { - ContentResolver cr = mServiceContext.getContentResolver(); - Settings.Global.putInt(cr, ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, - enable ? 1 : 0); - mService.updateAlwaysOnNetworks(); - waitForIdle(); - } - - private void setPrivateDnsSettings(int mode, String specifier) { - ConnectivitySettingsManager.setPrivateDnsMode(mServiceContext, mode); - ConnectivitySettingsManager.setPrivateDnsHostname(mServiceContext, specifier); - mService.updatePrivateDnsSettings(); - waitForIdle(); - } - - private boolean isForegroundNetwork(TestNetworkAgentWrapper network) { - NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); - assertNotNull(nc); - return nc.hasCapability(NET_CAPABILITY_FOREGROUND); - } - - @Test - public void testBackgroundNetworks() throws Exception { - // Create a cellular background request. - grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); - final TestNetworkCallback cellBgCallback = new TestNetworkCallback(); - mCm.requestBackgroundNetwork(new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR).build(), - cellBgCallback, mCsHandlerThread.getThreadHandler()); - - // Make callbacks for monitoring. - final NetworkRequest request = new NetworkRequest.Builder().build(); - final NetworkRequest fgRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_FOREGROUND).build(); - final TestNetworkCallback callback = new TestNetworkCallback(); - final TestNetworkCallback fgCallback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, callback); - mCm.registerNetworkCallback(fgRequest, fgCallback); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - fgCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - assertTrue(isForegroundNetwork(mCellNetworkAgent)); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - - // When wifi connects, cell lingers. - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - fgCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - fgCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - fgCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - assertTrue(isForegroundNetwork(mCellNetworkAgent)); - assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); - - // When lingering is complete, cell is still there but is now in the background. - waitForIdle(); - int timeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; - fgCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, timeoutMs); - // Expect a network capabilities update sans FOREGROUND. - callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); - assertFalse(isForegroundNetwork(mCellNetworkAgent)); - assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); - - // File a cell request and check that cell comes into the foreground. - final NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR).build(); - final TestNetworkCallback cellCallback = new TestNetworkCallback(); - mCm.requestNetwork(cellRequest, cellCallback); - cellCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - fgCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - // Expect a network capabilities update with FOREGROUND, because the most recent - // request causes its state to change. - cellCallback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); - callback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); - assertTrue(isForegroundNetwork(mCellNetworkAgent)); - assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); - - // Release the request. The network immediately goes into the background, since it was not - // lingering. - mCm.unregisterNetworkCallback(cellCallback); - fgCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - // Expect a network capabilities update sans FOREGROUND. - callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent); - assertFalse(isForegroundNetwork(mCellNetworkAgent)); - assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); - - // Disconnect wifi and check that cell is foreground again. - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - fgCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - fgCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - assertTrue(isForegroundNetwork(mCellNetworkAgent)); - - mCm.unregisterNetworkCallback(callback); - mCm.unregisterNetworkCallback(fgCallback); - mCm.unregisterNetworkCallback(cellBgCallback); - } - - @Ignore // This test has instrinsic chances of spurious failures: ignore for continuous testing. - public void benchmarkRequestRegistrationAndCallbackDispatch() throws Exception { - // TODO: turn this unit test into a real benchmarking test. - // Benchmarks connecting and switching performance in the presence of a large number of - // NetworkRequests. - // 1. File NUM_REQUESTS requests. - // 2. Have a network connect. Wait for NUM_REQUESTS onAvailable callbacks to fire. - // 3. Have a new network connect and outscore the previous. Wait for NUM_REQUESTS onLosing - // and NUM_REQUESTS onAvailable callbacks to fire. - // See how long it took. - final int NUM_REQUESTS = 90; - final int REGISTER_TIME_LIMIT_MS = 200; - final int CONNECT_TIME_LIMIT_MS = 60; - final int SWITCH_TIME_LIMIT_MS = 60; - final int UNREGISTER_TIME_LIMIT_MS = 20; - - final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); - final NetworkCallback[] callbacks = new NetworkCallback[NUM_REQUESTS]; - final CountDownLatch availableLatch = new CountDownLatch(NUM_REQUESTS); - final CountDownLatch losingLatch = new CountDownLatch(NUM_REQUESTS); - - for (int i = 0; i < NUM_REQUESTS; i++) { - callbacks[i] = new NetworkCallback() { - @Override public void onAvailable(Network n) { availableLatch.countDown(); } - @Override public void onLosing(Network n, int t) { losingLatch.countDown(); } - }; - } - - assertRunsInAtMost("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> { - for (NetworkCallback cb : callbacks) { - mCm.registerNetworkCallback(request, cb); - } - }); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - // Don't request that the network validate, because otherwise connect() will block until - // the network gets NET_CAPABILITY_VALIDATED, after all the callbacks below have fired, - // and we won't actually measure anything. - mCellNetworkAgent.connect(false); - - long onAvailableDispatchingDuration = durationOf(() -> { - await(availableLatch, 10 * CONNECT_TIME_LIMIT_MS); - }); - Log.d(TAG, String.format("Dispatched %d of %d onAvailable callbacks in %dms", - NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS, - onAvailableDispatchingDuration)); - assertTrue(String.format("Dispatching %d onAvailable callbacks in %dms, expected %dms", - NUM_REQUESTS, onAvailableDispatchingDuration, CONNECT_TIME_LIMIT_MS), - onAvailableDispatchingDuration <= CONNECT_TIME_LIMIT_MS); - - // Give wifi a high enough score that we'll linger cell when wifi comes up. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.adjustScore(40); - mWiFiNetworkAgent.connect(false); - - long onLostDispatchingDuration = durationOf(() -> { - await(losingLatch, 10 * SWITCH_TIME_LIMIT_MS); - }); - Log.d(TAG, String.format("Dispatched %d of %d onLosing callbacks in %dms", - NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, onLostDispatchingDuration)); - assertTrue(String.format("Dispatching %d onLosing callbacks in %dms, expected %dms", - NUM_REQUESTS, onLostDispatchingDuration, SWITCH_TIME_LIMIT_MS), - onLostDispatchingDuration <= SWITCH_TIME_LIMIT_MS); - - assertRunsInAtMost("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> { - for (NetworkCallback cb : callbacks) { - mCm.unregisterNetworkCallback(cb); - } - }); - } - - @Test - public void testMobileDataAlwaysOn() throws Exception { - grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid()); - final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); - final NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR).build(); - mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); - - final HandlerThread handlerThread = new HandlerThread("MobileDataAlwaysOnFactory"); - handlerThread.start(); - NetworkCapabilities filter = new NetworkCapabilities() - .addTransportType(TRANSPORT_CELLULAR) - .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) - .addCapability(NET_CAPABILITY_INTERNET); - final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), - mServiceContext, "testFactory", filter, mCsHandlerThread); - testFactory.setScoreFilter(40); - - // Register the factory and expect it to start looking for a network. - testFactory.register(); - - try { - // Expect the factory to receive the default network request. - testFactory.expectRequestAdd(); - testFactory.assertRequestCountEquals(1); - assertTrue(testFactory.getMyStartRequested()); - - // Bring up wifi. The factory stops looking for a network. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - // Score 60 - 40 penalty for not validated yet, then 60 when it validates - mWiFiNetworkAgent.connect(true); - // The network connects with a low score, so the offer can still beat it and - // nothing happens. Then the network validates, and the offer with its filter score - // of 40 can no longer beat it and the request is removed. - testFactory.expectRequestRemove(); - testFactory.assertRequestCountEquals(0); - - assertFalse(testFactory.getMyStartRequested()); - - // Turn on mobile data always on. This request will not match the wifi request, so - // it will be sent to the test factory whose filters allow to see it. - setAlwaysOnNetworks(true); - testFactory.expectRequestAdd(); - testFactory.assertRequestCountEquals(1); - - assertTrue(testFactory.getMyStartRequested()); - - // Bring up cell data and check that the factory stops looking. - assertLength(1, mCm.getAllNetworks()); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(false); - cellNetworkCallback.expectAvailableCallbacks(mCellNetworkAgent, false, false, false, - TEST_CALLBACK_TIMEOUT_MS); - // When cell connects, it will satisfy the "mobile always on request" right away - // by virtue of being the only network that can satisfy the request. However, its - // score is low (50 - 40 = 10) so the test factory can still hope to beat it. - expectNoRequestChanged(testFactory); - - // Next, cell validates. This gives it a score of 50 and the test factory can't - // hope to beat that according to its filters. It will see the message that its - // offer is now unnecessary. - mCellNetworkAgent.setNetworkValid(true); - // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is - // validated – see testPartialConnectivity. - mCm.reportNetworkConnectivity(mCellNetworkAgent.getNetwork(), true); - cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mCellNetworkAgent); - testFactory.expectRequestRemove(); - testFactory.assertRequestCountEquals(0); - // Accordingly, the factory shouldn't be started. - assertFalse(testFactory.getMyStartRequested()); - - // Check that cell data stays up. - waitForIdle(); - verifyActiveNetwork(TRANSPORT_WIFI); - assertLength(2, mCm.getAllNetworks()); - - // Cell disconnects. There is still the "mobile data always on" request outstanding, - // and the test factory should see it now that it isn't hopelessly outscored. - mCellNetworkAgent.disconnect(); - cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - assertLength(1, mCm.getAllNetworks()); - testFactory.expectRequestAdd(); - testFactory.assertRequestCountEquals(1); - - // Reconnect cell validated, see the request disappear again. Then withdraw the - // mobile always on request. This will tear down cell, and there shouldn't be a - // blip where the test factory briefly sees the request or anything. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - assertLength(2, mCm.getAllNetworks()); - testFactory.expectRequestRemove(); - testFactory.assertRequestCountEquals(0); - setAlwaysOnNetworks(false); - expectNoRequestChanged(testFactory); - testFactory.assertRequestCountEquals(0); - assertFalse(testFactory.getMyStartRequested()); - // ... and cell data to be torn down immediately since it is no longer nascent. - cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - waitForIdle(); - assertLength(1, mCm.getAllNetworks()); - } finally { - testFactory.terminate(); - mCm.unregisterNetworkCallback(cellNetworkCallback); - handlerThread.quit(); - } - } - - @Test - public void testAvoidBadWifiSetting() throws Exception { - final ContentResolver cr = mServiceContext.getContentResolver(); - final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI; - - mPolicyTracker.mConfigRestrictsAvoidBadWifi = false; - String[] values = new String[] {null, "0", "1"}; - for (int i = 0; i < values.length; i++) { - Settings.Global.putInt(cr, settingName, 1); - mPolicyTracker.reevaluate(); - waitForIdle(); - String msg = String.format("config=false, setting=%s", values[i]); - assertTrue(mService.avoidBadWifi()); - assertFalse(msg, mPolicyTracker.shouldNotifyWifiUnvalidated()); - } - - mPolicyTracker.mConfigRestrictsAvoidBadWifi = true; - - Settings.Global.putInt(cr, settingName, 0); - mPolicyTracker.reevaluate(); - waitForIdle(); - assertFalse(mService.avoidBadWifi()); - assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); - - Settings.Global.putInt(cr, settingName, 1); - mPolicyTracker.reevaluate(); - waitForIdle(); - assertTrue(mService.avoidBadWifi()); - assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated()); - - Settings.Global.putString(cr, settingName, null); - mPolicyTracker.reevaluate(); - waitForIdle(); - assertFalse(mService.avoidBadWifi()); - assertTrue(mPolicyTracker.shouldNotifyWifiUnvalidated()); - } - - @Ignore("Refactoring in progress b/178071397") - @Test - public void testAvoidBadWifi() throws Exception { - final ContentResolver cr = mServiceContext.getContentResolver(); - - // Pretend we're on a carrier that restricts switching away from bad wifi. - mPolicyTracker.mConfigRestrictsAvoidBadWifi = true; - - // File a request for cell to ensure it doesn't go down. - final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); - final NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR).build(); - mCm.requestNetwork(cellRequest, cellNetworkCallback); - - TestNetworkCallback defaultCallback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(defaultCallback); - - NetworkRequest validatedWifiRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI) - .addCapability(NET_CAPABILITY_VALIDATED) - .build(); - TestNetworkCallback validatedWifiCallback = new TestNetworkCallback(); - mCm.registerNetworkCallback(validatedWifiRequest, validatedWifiCallback); - - Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 0); - mPolicyTracker.reevaluate(); - - // Bring up validated cell. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - Network cellNetwork = mCellNetworkAgent.getNetwork(); - - // Bring up validated wifi. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - Network wifiNetwork = mWiFiNetworkAgent.getNetwork(); - - // Fail validation on wifi. - mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */); - mCm.reportNetworkConnectivity(wifiNetwork, false); - defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - validatedWifiCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - // Because avoid bad wifi is off, we don't switch to cellular. - defaultCallback.assertNoCallback(); - assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( - NET_CAPABILITY_VALIDATED)); - assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( - NET_CAPABILITY_VALIDATED)); - assertEquals(mCm.getActiveNetwork(), wifiNetwork); - - // Simulate switching to a carrier that does not restrict avoiding bad wifi, and expect - // that we switch back to cell. - mPolicyTracker.mConfigRestrictsAvoidBadWifi = false; - mPolicyTracker.reevaluate(); - defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - assertEquals(mCm.getActiveNetwork(), cellNetwork); - - // Switch back to a restrictive carrier. - mPolicyTracker.mConfigRestrictsAvoidBadWifi = true; - mPolicyTracker.reevaluate(); - defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - assertEquals(mCm.getActiveNetwork(), wifiNetwork); - - // Simulate the user selecting "switch" on the dialog, and check that we switch to cell. - mCm.setAvoidUnvalidated(wifiNetwork); - defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( - NET_CAPABILITY_VALIDATED)); - assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( - NET_CAPABILITY_VALIDATED)); - assertEquals(mCm.getActiveNetwork(), cellNetwork); - - // Disconnect and reconnect wifi to clear the one-time switch above. - mWiFiNetworkAgent.disconnect(); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - validatedWifiCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - wifiNetwork = mWiFiNetworkAgent.getNetwork(); - - // Fail validation on wifi and expect the dialog to appear. - mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */); - mCm.reportNetworkConnectivity(wifiNetwork, false); - defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - validatedWifiCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - // Simulate the user selecting "switch" and checking the don't ask again checkbox. - Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1); - mPolicyTracker.reevaluate(); - - // We now switch to cell. - defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability( - NET_CAPABILITY_VALIDATED)); - assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability( - NET_CAPABILITY_VALIDATED)); - assertEquals(mCm.getActiveNetwork(), cellNetwork); - - // Simulate the user turning the cellular fallback setting off and then on. - // We switch to wifi and then to cell. - Settings.Global.putString(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null); - mPolicyTracker.reevaluate(); - defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - assertEquals(mCm.getActiveNetwork(), wifiNetwork); - Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1); - mPolicyTracker.reevaluate(); - defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - assertEquals(mCm.getActiveNetwork(), cellNetwork); - - // If cell goes down, we switch to wifi. - mCellNetworkAgent.disconnect(); - defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - validatedWifiCallback.assertNoCallback(); - - mCm.unregisterNetworkCallback(cellNetworkCallback); - mCm.unregisterNetworkCallback(validatedWifiCallback); - mCm.unregisterNetworkCallback(defaultCallback); - } - - @Test - public void testMeteredMultipathPreferenceSetting() throws Exception { - final ContentResolver cr = mServiceContext.getContentResolver(); - final String settingName = ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE; - - for (int config : Arrays.asList(0, 3, 2)) { - for (String setting: Arrays.asList(null, "0", "2", "1")) { - mPolicyTracker.mConfigMeteredMultipathPreference = config; - Settings.Global.putString(cr, settingName, setting); - mPolicyTracker.reevaluate(); - waitForIdle(); - - final int expected = (setting != null) ? Integer.parseInt(setting) : config; - String msg = String.format("config=%d, setting=%s", config, setting); - assertEquals(msg, expected, mCm.getMultipathPreference(null)); - } - } - } - - /** - * Validate that a satisfied network request does not trigger onUnavailable() once the - * time-out period expires. - */ - @Test - public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { - NetworkRequest nr = new NetworkRequest.Builder().addTransportType( - NetworkCapabilities.TRANSPORT_WIFI).build(); - final TestNetworkCallback networkCallback = new TestNetworkCallback(); - mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false, - TEST_CALLBACK_TIMEOUT_MS); - - // pass timeout and validate that UNAVAILABLE is not called - networkCallback.assertNoCallback(); - } - - /** - * Validate that a satisfied network request followed by a disconnected (lost) network does - * not trigger onUnavailable() once the time-out period expires. - */ - @Test - public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() throws Exception { - NetworkRequest nr = new NetworkRequest.Builder().addTransportType( - NetworkCapabilities.TRANSPORT_WIFI).build(); - final TestNetworkCallback networkCallback = new TestNetworkCallback(); - mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false, - TEST_CALLBACK_TIMEOUT_MS); - mWiFiNetworkAgent.disconnect(); - networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - // Validate that UNAVAILABLE is not called - networkCallback.assertNoCallback(); - } - - /** - * Validate that when a time-out is specified for a network request the onUnavailable() - * callback is called when time-out expires. Then validate that if network request is - * (somehow) satisfied - the callback isn't called later. - */ - @Test - public void testTimedoutNetworkRequest() throws Exception { - NetworkRequest nr = new NetworkRequest.Builder().addTransportType( - NetworkCapabilities.TRANSPORT_WIFI).build(); - final TestNetworkCallback networkCallback = new TestNetworkCallback(); - final int timeoutMs = 10; - mCm.requestNetwork(nr, networkCallback, timeoutMs); - - // pass timeout and validate that UNAVAILABLE is called - networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null); - - // create a network satisfying request - validate that request not triggered - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - networkCallback.assertNoCallback(); - } - - /** - * Validate that when a network request is unregistered (cancelled), no posterior event can - * trigger the callback. - */ - @Test - public void testNoCallbackAfterUnregisteredNetworkRequest() throws Exception { - NetworkRequest nr = new NetworkRequest.Builder().addTransportType( - NetworkCapabilities.TRANSPORT_WIFI).build(); - final TestNetworkCallback networkCallback = new TestNetworkCallback(); - final int timeoutMs = 10; - - mCm.requestNetwork(nr, networkCallback, timeoutMs); - mCm.unregisterNetworkCallback(networkCallback); - // Regardless of the timeout, unregistering the callback in ConnectivityManager ensures - // that this callback will not be called. - networkCallback.assertNoCallback(); - - // create a network satisfying request - validate that request not triggered - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - networkCallback.assertNoCallback(); - } - - @Test - public void testUnfulfillableNetworkRequest() throws Exception { - runUnfulfillableNetworkRequest(false); - } - - @Test - public void testUnfulfillableNetworkRequestAfterUnregister() throws Exception { - runUnfulfillableNetworkRequest(true); - } - - /** - * Validate the callback flow for a factory releasing a request as unfulfillable. - */ - private void runUnfulfillableNetworkRequest(boolean preUnregister) throws Exception { - NetworkRequest nr = new NetworkRequest.Builder().addTransportType( - NetworkCapabilities.TRANSPORT_WIFI).build(); - final TestNetworkCallback networkCallback = new TestNetworkCallback(); - - final HandlerThread handlerThread = new HandlerThread("testUnfulfillableNetworkRequest"); - handlerThread.start(); - NetworkCapabilities filter = new NetworkCapabilities() - .addTransportType(TRANSPORT_WIFI) - .addCapability(NET_CAPABILITY_INTERNET) - .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); - final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), - mServiceContext, "testFactory", filter, mCsHandlerThread); - testFactory.setScoreFilter(40); - - // Register the factory and expect it to receive the default request. - testFactory.register(); - testFactory.expectRequestAdd(); - - try { - // Now file the test request and expect it. - mCm.requestNetwork(nr, networkCallback); - final NetworkRequest newRequest = testFactory.expectRequestAdd().request; - - if (preUnregister) { - mCm.unregisterNetworkCallback(networkCallback); - - // The request has been released : the factory should see it removed - // immediately. - testFactory.expectRequestRemove(); - - // Simulate the factory releasing the request as unfulfillable: no-op since - // the callback has already been unregistered (but a test that no exceptions are - // thrown). - testFactory.triggerUnfulfillable(newRequest); - } else { - // Simulate the factory releasing the request as unfulfillable and expect - // onUnavailable! - testFactory.triggerUnfulfillable(newRequest); - - networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null); - - // Declaring a request unfulfillable releases it automatically. - testFactory.expectRequestRemove(); - - // unregister network callback - a no-op (since already freed by the - // on-unavailable), but should not fail or throw exceptions. - mCm.unregisterNetworkCallback(networkCallback); - - // The factory should not see any further removal, as this request has - // already been removed. - } - } finally { - testFactory.terminate(); - handlerThread.quit(); - } - } - - private static class TestKeepaliveCallback extends PacketKeepaliveCallback { - - public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR } - - private class CallbackValue { - public CallbackType callbackType; - public int error; - - public CallbackValue(CallbackType type) { - this.callbackType = type; - this.error = PacketKeepalive.SUCCESS; - assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); - } - - public CallbackValue(CallbackType type, int error) { - this.callbackType = type; - this.error = error; - assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); - } - - @Override - public boolean equals(Object o) { - return o instanceof CallbackValue && - this.callbackType == ((CallbackValue) o).callbackType && - this.error == ((CallbackValue) o).error; - } - - @Override - public String toString() { - return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error); - } - } - - private final LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); - - @Override - public void onStarted() { - mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); - } - - @Override - public void onStopped() { - mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); - } - - @Override - public void onError(int error) { - mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); - } - - private void expectCallback(CallbackValue callbackValue) throws InterruptedException { - assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - } - - public void expectStarted() throws Exception { - expectCallback(new CallbackValue(CallbackType.ON_STARTED)); - } - - public void expectStopped() throws Exception { - expectCallback(new CallbackValue(CallbackType.ON_STOPPED)); - } - - public void expectError(int error) throws Exception { - expectCallback(new CallbackValue(CallbackType.ON_ERROR, error)); - } - } - - private static class TestSocketKeepaliveCallback extends SocketKeepalive.Callback { - - public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR }; - - private class CallbackValue { - public CallbackType callbackType; - public int error; - - CallbackValue(CallbackType type) { - this.callbackType = type; - this.error = SocketKeepalive.SUCCESS; - assertTrue("onError callback must have error", type != CallbackType.ON_ERROR); - } - - CallbackValue(CallbackType type, int error) { - this.callbackType = type; - this.error = error; - assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR); - } - - @Override - public boolean equals(Object o) { - return o instanceof CallbackValue - && this.callbackType == ((CallbackValue) o).callbackType - && this.error == ((CallbackValue) o).error; - } - - @Override - public String toString() { - return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, - error); - } - } - - private LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>(); - private final Executor mExecutor; - - TestSocketKeepaliveCallback(@NonNull Executor executor) { - mExecutor = executor; - } - - @Override - public void onStarted() { - mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED)); - } - - @Override - public void onStopped() { - mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED)); - } - - @Override - public void onError(int error) { - mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error)); - } - - private void expectCallback(CallbackValue callbackValue) throws InterruptedException { - assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - - } - - public void expectStarted() throws InterruptedException { - expectCallback(new CallbackValue(CallbackType.ON_STARTED)); - } - - public void expectStopped() throws InterruptedException { - expectCallback(new CallbackValue(CallbackType.ON_STOPPED)); - } - - public void expectError(int error) throws InterruptedException { - expectCallback(new CallbackValue(CallbackType.ON_ERROR, error)); - } - - public void assertNoCallback() { - waitForIdleSerialExecutor(mExecutor, TIMEOUT_MS); - CallbackValue cv = mCallbacks.peek(); - assertNull("Unexpected callback: " + cv, cv); - } - } - - private Network connectKeepaliveNetwork(LinkProperties lp) throws Exception { - // Ensure the network is disconnected before anything else occurs - if (mWiFiNetworkAgent != null) { - assertNull(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork())); - } - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); - mWiFiNetworkAgent.connect(true); - b.expectBroadcast(); - verifyActiveNetwork(TRANSPORT_WIFI); - mWiFiNetworkAgent.sendLinkProperties(lp); - waitForIdle(); - return mWiFiNetworkAgent.getNetwork(); - } - - @Test - public void testPacketKeepalives() throws Exception { - InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); - InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); - InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); - InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); - InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); - - final int validKaInterval = 15; - final int invalidKaInterval = 9; - - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName("wlan12"); - lp.addLinkAddress(new LinkAddress(myIPv6, 64)); - lp.addLinkAddress(new LinkAddress(myIPv4, 25)); - lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); - lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); - - Network notMyNet = new Network(61234); - Network myNet = connectKeepaliveNetwork(lp); - - TestKeepaliveCallback callback = new TestKeepaliveCallback(); - PacketKeepalive ka; - - // Attempt to start keepalives with invalid parameters and check for errors. - ka = mCm.startNattKeepalive(notMyNet, validKaInterval, callback, myIPv4, 1234, dstIPv4); - callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); - - ka = mCm.startNattKeepalive(myNet, invalidKaInterval, callback, myIPv4, 1234, dstIPv4); - callback.expectError(PacketKeepalive.ERROR_INVALID_INTERVAL); - - ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 1234, dstIPv6); - callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); - - ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv6, 1234, dstIPv4); - callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); - - // NAT-T is only supported for IPv4. - ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv6, 1234, dstIPv6); - callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); - - ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); - callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); - - ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 123456, dstIPv4); - callback.expectError(PacketKeepalive.ERROR_INVALID_PORT); - - ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); - callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); - - ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); - callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED); - - // Check that a started keepalive can be stopped. - mWiFiNetworkAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); - ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); - callback.expectStarted(); - mWiFiNetworkAgent.setStopKeepaliveEvent(PacketKeepalive.SUCCESS); - ka.stop(); - callback.expectStopped(); - - // Check that deleting the IP address stops the keepalive. - LinkProperties bogusLp = new LinkProperties(lp); - ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); - callback.expectStarted(); - bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); - bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); - mWiFiNetworkAgent.sendLinkProperties(bogusLp); - callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); - mWiFiNetworkAgent.sendLinkProperties(lp); - - // Check that a started keepalive is stopped correctly when the network disconnects. - ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); - callback.expectStarted(); - mWiFiNetworkAgent.disconnect(); - mWiFiNetworkAgent.expectDisconnected(); - callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); - - // ... and that stopping it after that has no adverse effects. - waitForIdle(); - final Network myNetAlias = myNet; - assertNull(mCm.getNetworkCapabilities(myNetAlias)); - ka.stop(); - - // Reconnect. - myNet = connectKeepaliveNetwork(lp); - mWiFiNetworkAgent.setStartKeepaliveEvent(PacketKeepalive.SUCCESS); - - // Check that keepalive slots start from 1 and increment. The first one gets slot 1. - mWiFiNetworkAgent.setExpectedKeepaliveSlot(1); - ka = mCm.startNattKeepalive(myNet, validKaInterval, callback, myIPv4, 12345, dstIPv4); - callback.expectStarted(); - - // The second one gets slot 2. - mWiFiNetworkAgent.setExpectedKeepaliveSlot(2); - TestKeepaliveCallback callback2 = new TestKeepaliveCallback(); - PacketKeepalive ka2 = mCm.startNattKeepalive( - myNet, validKaInterval, callback2, myIPv4, 6789, dstIPv4); - callback2.expectStarted(); - - // Now stop the first one and create a third. This also gets slot 1. - ka.stop(); - callback.expectStopped(); - - mWiFiNetworkAgent.setExpectedKeepaliveSlot(1); - TestKeepaliveCallback callback3 = new TestKeepaliveCallback(); - PacketKeepalive ka3 = mCm.startNattKeepalive( - myNet, validKaInterval, callback3, myIPv4, 9876, dstIPv4); - callback3.expectStarted(); - - ka2.stop(); - callback2.expectStopped(); - - ka3.stop(); - callback3.expectStopped(); - } - - // Helper method to prepare the executor and run test - private void runTestWithSerialExecutors(ExceptionUtils.ThrowingConsumer<Executor> functor) - throws Exception { - final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor(); - final Executor executorInline = (Runnable r) -> r.run(); - functor.accept(executorSingleThread); - executorSingleThread.shutdown(); - functor.accept(executorInline); - } - - @Test - public void testNattSocketKeepalives() throws Exception { - runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesWithExecutor(executor)); - runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesFdWithExecutor(executor)); - } - - private void doTestNattSocketKeepalivesWithExecutor(Executor executor) throws Exception { - // TODO: 1. Move this outside of ConnectivityServiceTest. - // 2. Make test to verify that Nat-T keepalive socket is created by IpSecService. - // 3. Mock ipsec service. - final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); - final InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); - final InetAddress myIPv6 = InetAddress.getByName("2001:db8::1"); - final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); - final InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888"); - - final int validKaInterval = 15; - final int invalidKaInterval = 9; - - final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); - final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); - final int srcPort = testSocket.getPort(); - - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName("wlan12"); - lp.addLinkAddress(new LinkAddress(myIPv6, 64)); - lp.addLinkAddress(new LinkAddress(myIPv4, 25)); - lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); - lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); - - Network notMyNet = new Network(61234); - Network myNet = connectKeepaliveNetwork(lp); - - TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); - - // Attempt to start keepalives with invalid parameters and check for errors. - // Invalid network. - try (SocketKeepalive ka = mCm.createSocketKeepalive( - notMyNet, testSocket, myIPv4, dstIPv4, executor, callback)) { - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); - } - - // Invalid interval. - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { - ka.start(invalidKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_INTERVAL); - } - - // Invalid destination. - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocket, myIPv4, dstIPv6, executor, callback)) { - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); - } - - // Invalid source; - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocket, myIPv6, dstIPv4, executor, callback)) { - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); - } - - // NAT-T is only supported for IPv4. - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocket, myIPv6, dstIPv6, executor, callback)) { - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); - } - - // Basic check before testing started keepalive. - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_UNSUPPORTED); - } - - // Check that a started keepalive can be stopped. - mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { - ka.start(validKaInterval); - callback.expectStarted(); - mWiFiNetworkAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); - ka.stop(); - callback.expectStopped(); - - // Check that keepalive could be restarted. - ka.start(validKaInterval); - callback.expectStarted(); - ka.stop(); - callback.expectStopped(); - - // Check that keepalive can be restarted without waiting for callback. - ka.start(validKaInterval); - callback.expectStarted(); - ka.stop(); - ka.start(validKaInterval); - callback.expectStopped(); - callback.expectStarted(); - ka.stop(); - callback.expectStopped(); - } - - // Check that deleting the IP address stops the keepalive. - LinkProperties bogusLp = new LinkProperties(lp); - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { - ka.start(validKaInterval); - callback.expectStarted(); - bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25)); - bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25)); - mWiFiNetworkAgent.sendLinkProperties(bogusLp); - callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS); - mWiFiNetworkAgent.sendLinkProperties(lp); - } - - // Check that a started keepalive is stopped correctly when the network disconnects. - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { - ka.start(validKaInterval); - callback.expectStarted(); - mWiFiNetworkAgent.disconnect(); - mWiFiNetworkAgent.expectDisconnected(); - callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); - - // ... and that stopping it after that has no adverse effects. - waitForIdle(); - final Network myNetAlias = myNet; - assertNull(mCm.getNetworkCapabilities(myNetAlias)); - ka.stop(); - callback.assertNoCallback(); - } - - // Reconnect. - myNet = connectKeepaliveNetwork(lp); - mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); - - // Check that a stop followed by network disconnects does not result in crash. - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { - ka.start(validKaInterval); - callback.expectStarted(); - // Delay the response of keepalive events in networkAgent long enough to make sure - // the follow-up network disconnection will be processed first. - mWiFiNetworkAgent.setKeepaliveResponseDelay(3 * TIMEOUT_MS); - ka.stop(); - - // Make sure the stop has been processed. Wait for executor idle is needed to prevent - // flaky since the actual stop call to the service is delegated to executor thread. - waitForIdleSerialExecutor(executor, TIMEOUT_MS); - waitForIdle(); - - mWiFiNetworkAgent.disconnect(); - mWiFiNetworkAgent.expectDisconnected(); - callback.expectStopped(); - callback.assertNoCallback(); - } - - // Reconnect. - waitForIdle(); - myNet = connectKeepaliveNetwork(lp); - mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); - - // Check that keepalive slots start from 1 and increment. The first one gets slot 1. - mWiFiNetworkAgent.setExpectedKeepaliveSlot(1); - int srcPort2 = 0; - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocket, myIPv4, dstIPv4, executor, callback)) { - ka.start(validKaInterval); - callback.expectStarted(); - - // The second one gets slot 2. - mWiFiNetworkAgent.setExpectedKeepaliveSlot(2); - final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket(); - srcPort2 = testSocket2.getPort(); - TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor); - try (SocketKeepalive ka2 = mCm.createSocketKeepalive( - myNet, testSocket2, myIPv4, dstIPv4, executor, callback2)) { - ka2.start(validKaInterval); - callback2.expectStarted(); - - ka.stop(); - callback.expectStopped(); - - ka2.stop(); - callback2.expectStopped(); - - testSocket.close(); - testSocket2.close(); - } - } - - // Check that there is no port leaked after all keepalives and sockets are closed. - // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. - // assertFalse(isUdpPortInUse(srcPort)); - // assertFalse(isUdpPortInUse(srcPort2)); - - mWiFiNetworkAgent.disconnect(); - mWiFiNetworkAgent.expectDisconnected(); - mWiFiNetworkAgent = null; - } - - @Test - public void testTcpSocketKeepalives() throws Exception { - runTestWithSerialExecutors(executor -> doTestTcpSocketKeepalivesWithExecutor(executor)); - } - - private void doTestTcpSocketKeepalivesWithExecutor(Executor executor) throws Exception { - final int srcPortV4 = 12345; - final int srcPortV6 = 23456; - final InetAddress myIPv4 = InetAddress.getByName("127.0.0.1"); - final InetAddress myIPv6 = InetAddress.getByName("::1"); - - final int validKaInterval = 15; - - final LinkProperties lp = new LinkProperties(); - lp.setInterfaceName("wlan12"); - lp.addLinkAddress(new LinkAddress(myIPv6, 64)); - lp.addLinkAddress(new LinkAddress(myIPv4, 25)); - lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); - lp.addRoute(new RouteInfo(InetAddress.getByName("127.0.0.254"))); - - final Network notMyNet = new Network(61234); - final Network myNet = connectKeepaliveNetwork(lp); - - final Socket testSocketV4 = new Socket(); - final Socket testSocketV6 = new Socket(); - - TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); - - // Attempt to start Tcp keepalives with invalid parameters and check for errors. - // Invalid network. - try (SocketKeepalive ka = mCm.createSocketKeepalive( - notMyNet, testSocketV4, executor, callback)) { - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_NETWORK); - } - - // Invalid Socket (socket is not bound with IPv4 address). - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocketV4, executor, callback)) { - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); - } - - // Invalid Socket (socket is not bound with IPv6 address). - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocketV6, executor, callback)) { - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); - } - - // Bind the socket address - testSocketV4.bind(new InetSocketAddress(myIPv4, srcPortV4)); - testSocketV6.bind(new InetSocketAddress(myIPv6, srcPortV6)); - - // Invalid Socket (socket is bound with IPv4 address). - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocketV4, executor, callback)) { - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); - } - - // Invalid Socket (socket is bound with IPv6 address). - try (SocketKeepalive ka = mCm.createSocketKeepalive( - myNet, testSocketV6, executor, callback)) { - ka.start(validKaInterval); - callback.expectError(SocketKeepalive.ERROR_INVALID_SOCKET); - } - - testSocketV4.close(); - testSocketV6.close(); - - mWiFiNetworkAgent.disconnect(); - mWiFiNetworkAgent.expectDisconnected(); - mWiFiNetworkAgent = null; - } - - private void doTestNattSocketKeepalivesFdWithExecutor(Executor executor) throws Exception { - final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); - final InetAddress anyIPv4 = InetAddress.getByName("0.0.0.0"); - final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8"); - final int validKaInterval = 15; - - // Prepare the target network. - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName("wlan12"); - lp.addLinkAddress(new LinkAddress(myIPv4, 25)); - lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); - Network myNet = connectKeepaliveNetwork(lp); - mWiFiNetworkAgent.setStartKeepaliveEvent(SocketKeepalive.SUCCESS); - mWiFiNetworkAgent.setStopKeepaliveEvent(SocketKeepalive.SUCCESS); - - TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(executor); - - // Prepare the target file descriptor, keep only one instance. - final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); - final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(); - final int srcPort = testSocket.getPort(); - final ParcelFileDescriptor testPfd = - ParcelFileDescriptor.dup(testSocket.getFileDescriptor()); - testSocket.close(); - assertTrue(isUdpPortInUse(srcPort)); - - // Start keepalive and explicit make the variable goes out of scope with try-with-resources - // block. - try (SocketKeepalive ka = mCm.createNattKeepalive( - myNet, testPfd, myIPv4, dstIPv4, executor, callback)) { - ka.start(validKaInterval); - callback.expectStarted(); - ka.stop(); - callback.expectStopped(); - } - - // Check that the ParcelFileDescriptor is still valid after keepalive stopped, - // ErrnoException with EBADF will be thrown if the socket is closed when checking local - // address. - assertTrue(isUdpPortInUse(srcPort)); - final InetSocketAddress sa = - (InetSocketAddress) Os.getsockname(testPfd.getFileDescriptor()); - assertEquals(anyIPv4, sa.getAddress()); - - testPfd.close(); - // TODO: enable this check after ensuring a valid free port. See b/129512753#comment7. - // assertFalse(isUdpPortInUse(srcPort)); - - mWiFiNetworkAgent.disconnect(); - mWiFiNetworkAgent.expectDisconnected(); - mWiFiNetworkAgent = null; - } - - private static boolean isUdpPortInUse(int port) { - try (DatagramSocket ignored = new DatagramSocket(port)) { - return false; - } catch (IOException alreadyInUse) { - return true; - } - } - - @Test - public void testGetCaptivePortalServerUrl() throws Exception { - String url = mCm.getCaptivePortalServerUrl(); - assertEquals("http://connectivitycheck.gstatic.com/generate_204", url); - } - - private static class TestNetworkPinner extends NetworkPinner { - public static boolean awaitPin(int timeoutMs) throws InterruptedException { - synchronized(sLock) { - if (sNetwork == null) { - sLock.wait(timeoutMs); - } - return sNetwork != null; - } - } - - public static boolean awaitUnpin(int timeoutMs) throws InterruptedException { - synchronized(sLock) { - if (sNetwork != null) { - sLock.wait(timeoutMs); - } - return sNetwork == null; - } - } - } - - private void assertPinnedToWifiWithCellDefault() { - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess()); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - } - - private void assertPinnedToWifiWithWifiDefault() { - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getBoundNetworkForProcess()); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - } - - private void assertNotPinnedToWifi() { - assertNull(mCm.getBoundNetworkForProcess()); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - } - - @Test - public void testNetworkPinner() throws Exception { - NetworkRequest wifiRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI) - .build(); - assertNull(mCm.getBoundNetworkForProcess()); - - TestNetworkPinner.pin(mServiceContext, wifiRequest); - assertNull(mCm.getBoundNetworkForProcess()); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - - // When wi-fi connects, expect to be pinned. - assertTrue(TestNetworkPinner.awaitPin(100)); - assertPinnedToWifiWithCellDefault(); - - // Disconnect and expect the pin to drop. - mWiFiNetworkAgent.disconnect(); - assertTrue(TestNetworkPinner.awaitUnpin(100)); - assertNotPinnedToWifi(); - - // Reconnecting does not cause the pin to come back. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - assertFalse(TestNetworkPinner.awaitPin(100)); - assertNotPinnedToWifi(); - - // Pinning while connected causes the pin to take effect immediately. - TestNetworkPinner.pin(mServiceContext, wifiRequest); - assertTrue(TestNetworkPinner.awaitPin(100)); - assertPinnedToWifiWithCellDefault(); - - // Explicitly unpin and expect to use the default network again. - TestNetworkPinner.unpin(); - assertNotPinnedToWifi(); - - // Disconnect cell and wifi. - ExpectedBroadcast b = registerConnectivityBroadcast(3); // cell down, wifi up, wifi down. - mCellNetworkAgent.disconnect(); - mWiFiNetworkAgent.disconnect(); - b.expectBroadcast(); - - // Pinning takes effect even if the pinned network is the default when the pin is set... - TestNetworkPinner.pin(mServiceContext, wifiRequest); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - assertTrue(TestNetworkPinner.awaitPin(100)); - assertPinnedToWifiWithWifiDefault(); - - // ... and is maintained even when that network is no longer the default. - b = registerConnectivityBroadcast(1); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mCellNetworkAgent.connect(true); - b.expectBroadcast(); - assertPinnedToWifiWithCellDefault(); - } - - @Test - public void testNetworkCallbackMaximum() throws Exception { - final int MAX_REQUESTS = 100; - final int CALLBACKS = 89; - final int INTENTS = 11; - final int SYSTEM_ONLY_MAX_REQUESTS = 250; - assertEquals(MAX_REQUESTS, CALLBACKS + INTENTS); - - NetworkRequest networkRequest = new NetworkRequest.Builder().build(); - ArrayList<Object> registered = new ArrayList<>(); - - int j = 0; - while (j++ < CALLBACKS / 2) { - NetworkCallback cb = new NetworkCallback(); - mCm.requestNetwork(networkRequest, cb); - registered.add(cb); - } - while (j++ < CALLBACKS) { - NetworkCallback cb = new NetworkCallback(); - mCm.registerNetworkCallback(networkRequest, cb); - registered.add(cb); - } - j = 0; - while (j++ < INTENTS / 2) { - final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, - new Intent("a" + j), FLAG_IMMUTABLE); - mCm.requestNetwork(networkRequest, pi); - registered.add(pi); - } - while (j++ < INTENTS) { - final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0 /* requestCode */, - new Intent("b" + j), FLAG_IMMUTABLE); - mCm.registerNetworkCallback(networkRequest, pi); - registered.add(pi); - } - - // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added. - assertThrows(TooManyRequestsException.class, () -> - mCm.requestNetwork(networkRequest, new NetworkCallback()) - ); - assertThrows(TooManyRequestsException.class, () -> - mCm.registerNetworkCallback(networkRequest, new NetworkCallback()) - ); - assertThrows(TooManyRequestsException.class, () -> - mCm.requestNetwork(networkRequest, - PendingIntent.getBroadcast(mContext, 0 /* requestCode */, - new Intent("c"), FLAG_IMMUTABLE)) - ); - assertThrows(TooManyRequestsException.class, () -> - mCm.registerNetworkCallback(networkRequest, - PendingIntent.getBroadcast(mContext, 0 /* requestCode */, - new Intent("d"), FLAG_IMMUTABLE)) - ); - - // The system gets another SYSTEM_ONLY_MAX_REQUESTS slots. - final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); - withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { - ArrayList<NetworkCallback> systemRegistered = new ArrayList<>(); - for (int i = 0; i < SYSTEM_ONLY_MAX_REQUESTS - 1; i++) { - NetworkCallback cb = new NetworkCallback(); - if (i % 2 == 0) { - mCm.registerDefaultNetworkCallbackForUid(1000000 + i, cb, handler); - } else { - mCm.registerNetworkCallback(networkRequest, cb); - } - systemRegistered.add(cb); - } - waitForIdle(); - - assertThrows(TooManyRequestsException.class, () -> - mCm.registerDefaultNetworkCallbackForUid(1001042, new NetworkCallback(), - handler)); - assertThrows(TooManyRequestsException.class, () -> - mCm.registerNetworkCallback(networkRequest, new NetworkCallback())); - - for (NetworkCallback callback : systemRegistered) { - mCm.unregisterNetworkCallback(callback); - } - waitForIdle(); // Wait for requests to be unregistered before giving up the permission. - }); - - for (Object o : registered) { - if (o instanceof NetworkCallback) { - mCm.unregisterNetworkCallback((NetworkCallback)o); - } - if (o instanceof PendingIntent) { - mCm.unregisterNetworkCallback((PendingIntent)o); - } - } - waitForIdle(); - - // Test that the limit is not hit when MAX_REQUESTS requests are added and removed. - for (int i = 0; i < MAX_REQUESTS; i++) { - NetworkCallback networkCallback = new NetworkCallback(); - mCm.requestNetwork(networkRequest, networkCallback); - mCm.unregisterNetworkCallback(networkCallback); - } - waitForIdle(); - - for (int i = 0; i < MAX_REQUESTS; i++) { - NetworkCallback networkCallback = new NetworkCallback(); - mCm.registerNetworkCallback(networkRequest, networkCallback); - mCm.unregisterNetworkCallback(networkCallback); - } - waitForIdle(); - - for (int i = 0; i < MAX_REQUESTS; i++) { - NetworkCallback networkCallback = new NetworkCallback(); - mCm.registerDefaultNetworkCallback(networkCallback); - mCm.unregisterNetworkCallback(networkCallback); - } - waitForIdle(); - - for (int i = 0; i < MAX_REQUESTS; i++) { - NetworkCallback networkCallback = new NetworkCallback(); - mCm.registerDefaultNetworkCallback(networkCallback); - mCm.unregisterNetworkCallback(networkCallback); - } - waitForIdle(); - - withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { - for (int i = 0; i < MAX_REQUESTS; i++) { - NetworkCallback networkCallback = new NetworkCallback(); - mCm.registerDefaultNetworkCallbackForUid(1000000 + i, networkCallback, - new Handler(ConnectivityThread.getInstanceLooper())); - mCm.unregisterNetworkCallback(networkCallback); - } - }); - waitForIdle(); - - for (int i = 0; i < MAX_REQUESTS; i++) { - final PendingIntent pendingIntent = PendingIntent.getBroadcast( - mContext, 0 /* requestCode */, new Intent("e" + i), FLAG_IMMUTABLE); - mCm.requestNetwork(networkRequest, pendingIntent); - mCm.unregisterNetworkCallback(pendingIntent); - } - waitForIdle(); - - for (int i = 0; i < MAX_REQUESTS; i++) { - final PendingIntent pendingIntent = PendingIntent.getBroadcast( - mContext, 0 /* requestCode */, new Intent("f" + i), FLAG_IMMUTABLE); - mCm.registerNetworkCallback(networkRequest, pendingIntent); - mCm.unregisterNetworkCallback(pendingIntent); - } - } - - @Test - public void testNetworkInfoOfTypeNone() throws Exception { - ExpectedBroadcast b = registerConnectivityBroadcast(1); - - verifyNoNetwork(); - TestNetworkAgentWrapper wifiAware = new TestNetworkAgentWrapper(TRANSPORT_WIFI_AWARE); - assertNull(mCm.getActiveNetworkInfo()); - - Network[] allNetworks = mCm.getAllNetworks(); - assertLength(1, allNetworks); - Network network = allNetworks[0]; - NetworkCapabilities capabilities = mCm.getNetworkCapabilities(network); - assertTrue(capabilities.hasTransport(TRANSPORT_WIFI_AWARE)); - - final NetworkRequest request = - new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI_AWARE).build(); - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, callback); - - // Bring up wifi aware network. - wifiAware.connect(false, false, false /* isStrictMode */); - callback.expectAvailableCallbacksUnvalidated(wifiAware); - - assertNull(mCm.getActiveNetworkInfo()); - assertNull(mCm.getActiveNetwork()); - // TODO: getAllNetworkInfo is dirty and returns a non-empty array right from the start - // of this test. Fix it and uncomment the assert below. - //assertEmpty(mCm.getAllNetworkInfo()); - - // Disconnect wifi aware network. - wifiAware.disconnect(); - callback.expectCallbackThat(TIMEOUT_MS, (info) -> info instanceof CallbackEntry.Lost); - mCm.unregisterNetworkCallback(callback); - - verifyNoNetwork(); - b.expectNoBroadcast(10); - } - - @Test - public void testDeprecatedAndUnsupportedOperations() throws Exception { - final int TYPE_NONE = ConnectivityManager.TYPE_NONE; - assertNull(mCm.getNetworkInfo(TYPE_NONE)); - assertNull(mCm.getNetworkForType(TYPE_NONE)); - assertNull(mCm.getLinkProperties(TYPE_NONE)); - assertFalse(mCm.isNetworkSupported(TYPE_NONE)); - - assertThrows(IllegalArgumentException.class, - () -> mCm.networkCapabilitiesForType(TYPE_NONE)); - - Class<UnsupportedOperationException> unsupported = UnsupportedOperationException.class; - assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_WIFI, "")); - assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_WIFI, "")); - // TODO: let test context have configuration application target sdk version - // and test that pre-M requesting for TYPE_NONE sends back APN_REQUEST_FAILED - assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_NONE, "")); - assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_NONE, "")); - assertThrows(unsupported, () -> mCm.requestRouteToHostAddress(TYPE_NONE, null)); - } - - @Test - public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() throws Exception { - final NetworkRequest networkRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI).build(); - final TestNetworkCallback networkCallback = new TestNetworkCallback(); - mCm.registerNetworkCallback(networkRequest, networkCallback); - - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName(WIFI_IFNAME); - LinkAddress myIpv4Address = new LinkAddress("192.168.12.3/24"); - RouteInfo myIpv4DefaultRoute = new RouteInfo((IpPrefix) null, - InetAddresses.parseNumericAddress("192.168.12.1"), lp.getInterfaceName()); - lp.addLinkAddress(myIpv4Address); - lp.addRoute(myIpv4DefaultRoute); - - // Verify direct routes are added when network agent is first registered in - // ConnectivityService. - TestNetworkAgentWrapper networkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); - networkAgent.connect(true); - networkCallback.expectCallback(CallbackEntry.AVAILABLE, networkAgent); - networkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, networkAgent); - CallbackEntry.LinkPropertiesChanged cbi = - networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, - networkAgent); - networkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, networkAgent); - networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, networkAgent); - networkCallback.assertNoCallback(); - checkDirectlyConnectedRoutes(cbi.getLp(), Arrays.asList(myIpv4Address), - Arrays.asList(myIpv4DefaultRoute)); - checkDirectlyConnectedRoutes(mCm.getLinkProperties(networkAgent.getNetwork()), - Arrays.asList(myIpv4Address), Arrays.asList(myIpv4DefaultRoute)); - - // Verify direct routes are added during subsequent link properties updates. - LinkProperties newLp = new LinkProperties(lp); - LinkAddress myIpv6Address1 = new LinkAddress("fe80::cafe/64"); - LinkAddress myIpv6Address2 = new LinkAddress("2001:db8::2/64"); - newLp.addLinkAddress(myIpv6Address1); - newLp.addLinkAddress(myIpv6Address2); - networkAgent.sendLinkProperties(newLp); - cbi = networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, networkAgent); - networkCallback.assertNoCallback(); - checkDirectlyConnectedRoutes(cbi.getLp(), - Arrays.asList(myIpv4Address, myIpv6Address1, myIpv6Address2), - Arrays.asList(myIpv4DefaultRoute)); - mCm.unregisterNetworkCallback(networkCallback); - } - - private <T> void assertSameElementsNoDuplicates(T[] expected, T[] actual) { - // Easier to implement than a proper "assertSameElements" method that also correctly deals - // with duplicates. - final String msg = Arrays.toString(expected) + " != " + Arrays.toString(actual); - assertEquals(msg, expected.length, actual.length); - Set expectedSet = new ArraySet<>(Arrays.asList(expected)); - assertEquals("expected contains duplicates", expectedSet.size(), expected.length); - // actual cannot have duplicates because it's the same length and has the same elements. - Set actualSet = new ArraySet<>(Arrays.asList(actual)); - assertEquals(expectedSet, actualSet); - } - - private void expectNetworkStatus(Network[] networks, String defaultIface, - Integer vpnUid, String vpnIfname, String[] underlyingIfaces) throws Exception { - ArgumentCaptor<List<Network>> networksCaptor = ArgumentCaptor.forClass(List.class); - ArgumentCaptor<List<UnderlyingNetworkInfo>> vpnInfosCaptor = - ArgumentCaptor.forClass(List.class); - - verify(mStatsManager, atLeastOnce()).notifyNetworkStatus(networksCaptor.capture(), - any(List.class), eq(defaultIface), vpnInfosCaptor.capture()); - - assertSameElementsNoDuplicates(networksCaptor.getValue().toArray(), networks); - - UnderlyingNetworkInfo[] infos = - vpnInfosCaptor.getValue().toArray(new UnderlyingNetworkInfo[0]); - if (vpnUid != null) { - assertEquals("Should have exactly one VPN:", 1, infos.length); - UnderlyingNetworkInfo info = infos[0]; - assertEquals("Unexpected VPN owner:", (int) vpnUid, info.getOwnerUid()); - assertEquals("Unexpected VPN interface:", vpnIfname, info.getInterface()); - assertSameElementsNoDuplicates(underlyingIfaces, - info.getUnderlyingInterfaces().toArray(new String[0])); - } else { - assertEquals(0, infos.length); - return; - } - } - - private void expectNetworkStatus( - Network[] networks, String defaultIface) throws Exception { - expectNetworkStatus(networks, defaultIface, null, null, new String[0]); - } - - @Test - public void testStatsIfacesChanged() throws Exception { - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - - final Network[] onlyCell = new Network[] {mCellNetworkAgent.getNetwork()}; - final Network[] onlyWifi = new Network[] {mWiFiNetworkAgent.getNetwork()}; - - LinkProperties cellLp = new LinkProperties(); - cellLp.setInterfaceName(MOBILE_IFNAME); - LinkProperties wifiLp = new LinkProperties(); - wifiLp.setInterfaceName(WIFI_IFNAME); - - // Simple connection should have updated ifaces - mCellNetworkAgent.connect(false); - mCellNetworkAgent.sendLinkProperties(cellLp); - waitForIdle(); - expectNetworkStatus(onlyCell, MOBILE_IFNAME); - reset(mStatsManager); - - // Default network switch should update ifaces. - mWiFiNetworkAgent.connect(false); - mWiFiNetworkAgent.sendLinkProperties(wifiLp); - waitForIdle(); - assertEquals(wifiLp, mService.getActiveLinkProperties()); - expectNetworkStatus(onlyWifi, WIFI_IFNAME); - reset(mStatsManager); - - // Disconnect should update ifaces. - mWiFiNetworkAgent.disconnect(); - waitForIdle(); - expectNetworkStatus(onlyCell, MOBILE_IFNAME); - reset(mStatsManager); - - // Metered change should update ifaces - mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); - waitForIdle(); - expectNetworkStatus(onlyCell, MOBILE_IFNAME); - reset(mStatsManager); - - mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); - waitForIdle(); - expectNetworkStatus(onlyCell, MOBILE_IFNAME); - reset(mStatsManager); - - // Temp metered change shouldn't update ifaces - mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); - waitForIdle(); - verify(mStatsManager, never()).notifyNetworkStatus(eq(Arrays.asList(onlyCell)), - any(List.class), eq(MOBILE_IFNAME), any(List.class)); - reset(mStatsManager); - - // Roaming change should update ifaces - mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); - waitForIdle(); - expectNetworkStatus(onlyCell, MOBILE_IFNAME); - reset(mStatsManager); - - // Test VPNs. - final LinkProperties lp = new LinkProperties(); - lp.setInterfaceName(VPN_IFNAME); - - mMockVpn.establishForMyUid(lp); - assertUidRangesUpdatedForMyUid(true); - - final Network[] cellAndVpn = new Network[] { - mCellNetworkAgent.getNetwork(), mMockVpn.getNetwork()}; - - // A VPN with default (null) underlying networks sets the underlying network's interfaces... - expectNetworkStatus(cellAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, - new String[]{MOBILE_IFNAME}); - - // ...and updates them as the default network switches. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - mWiFiNetworkAgent.sendLinkProperties(wifiLp); - final Network[] onlyNull = new Network[]{null}; - final Network[] wifiAndVpn = new Network[] { - mWiFiNetworkAgent.getNetwork(), mMockVpn.getNetwork()}; - final Network[] cellAndWifi = new Network[] { - mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork()}; - final Network[] cellNullAndWifi = new Network[] { - mCellNetworkAgent.getNetwork(), null, mWiFiNetworkAgent.getNetwork()}; - - waitForIdle(); - assertEquals(wifiLp, mService.getActiveLinkProperties()); - expectNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME, - new String[]{WIFI_IFNAME}); - reset(mStatsManager); - - // A VPN that sets its underlying networks passes the underlying interfaces, and influences - // the default interface sent to NetworkStatsService by virtue of applying to the system - // server UID (or, in this test, to the test's UID). This is the reason for sending - // MOBILE_IFNAME even though the default network is wifi. - // TODO: fix this to pass in the actual default network interface. Whether or not the VPN - // applies to the system server UID should not have any bearing on network stats. - mMockVpn.setUnderlyingNetworks(onlyCell); - waitForIdle(); - expectNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, - new String[]{MOBILE_IFNAME}); - reset(mStatsManager); - - mMockVpn.setUnderlyingNetworks(cellAndWifi); - waitForIdle(); - expectNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, - new String[]{MOBILE_IFNAME, WIFI_IFNAME}); - reset(mStatsManager); - - // Null underlying networks are ignored. - mMockVpn.setUnderlyingNetworks(cellNullAndWifi); - waitForIdle(); - expectNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, - new String[]{MOBILE_IFNAME, WIFI_IFNAME}); - reset(mStatsManager); - - // If an underlying network disconnects, that interface should no longer be underlying. - // This doesn't actually work because disconnectAndDestroyNetwork only notifies - // NetworkStatsService before the underlying network is actually removed. So the underlying - // network will only be removed if notifyIfacesChangedForNetworkStats is called again. This - // could result in incorrect data usage measurements if the interface used by the - // disconnected network is reused by a system component that does not register an agent for - // it (e.g., tethering). - mCellNetworkAgent.disconnect(); - waitForIdle(); - assertNull(mService.getLinkProperties(mCellNetworkAgent.getNetwork())); - expectNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, - new String[]{MOBILE_IFNAME, WIFI_IFNAME}); - - // Confirm that we never tell NetworkStatsService that cell is no longer the underlying - // network for the VPN... - verify(mStatsManager, never()).notifyNetworkStatus(any(List.class), - any(List.class), any() /* anyString() doesn't match null */, - argThat(infos -> infos.get(0).getUnderlyingInterfaces().size() == 1 - && WIFI_IFNAME.equals(infos.get(0).getUnderlyingInterfaces().get(0)))); - verifyNoMoreInteractions(mStatsManager); - reset(mStatsManager); - - // ... but if something else happens that causes notifyIfacesChangedForNetworkStats to be - // called again, it does. For example, connect Ethernet, but with a low score, such that it - // does not become the default network. - mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); - mEthernetNetworkAgent.setScore( - new NetworkScore.Builder().setLegacyInt(30).setExiting(true).build()); - mEthernetNetworkAgent.connect(false); - waitForIdle(); - verify(mStatsManager).notifyNetworkStatus(any(List.class), - any(List.class), any() /* anyString() doesn't match null */, - argThat(vpnInfos -> vpnInfos.get(0).getUnderlyingInterfaces().size() == 1 - && WIFI_IFNAME.equals(vpnInfos.get(0).getUnderlyingInterfaces().get(0)))); - mEthernetNetworkAgent.disconnect(); - waitForIdle(); - reset(mStatsManager); - - // When a VPN declares no underlying networks (i.e., no connectivity), getAllVpnInfo - // does not return the VPN, so CS does not pass it to NetworkStatsService. This causes - // NetworkStatsFactory#adjustForTunAnd464Xlat not to attempt any VPN data migration, which - // is probably a performance improvement (though it's very unlikely that a VPN would declare - // no underlying networks). - // Also, for the same reason as above, the active interface passed in is null. - mMockVpn.setUnderlyingNetworks(new Network[0]); - waitForIdle(); - expectNetworkStatus(wifiAndVpn, null); - reset(mStatsManager); - - // Specifying only a null underlying network is the same as no networks. - mMockVpn.setUnderlyingNetworks(onlyNull); - waitForIdle(); - expectNetworkStatus(wifiAndVpn, null); - reset(mStatsManager); - - // Specifying networks that are all disconnected is the same as specifying no networks. - mMockVpn.setUnderlyingNetworks(onlyCell); - waitForIdle(); - expectNetworkStatus(wifiAndVpn, null); - reset(mStatsManager); - - // Passing in null again means follow the default network again. - mMockVpn.setUnderlyingNetworks(null); - waitForIdle(); - expectNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME, - new String[]{WIFI_IFNAME}); - reset(mStatsManager); - } - - @Test - public void testBasicDnsConfigurationPushed() throws Exception { - setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); - - // Clear any interactions that occur as a result of CS starting up. - reset(mMockDnsResolver); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - waitForIdle(); - verify(mMockDnsResolver, never()).setResolverConfiguration(any()); - verifyNoMoreInteractions(mMockDnsResolver); - - final LinkProperties cellLp = new LinkProperties(); - cellLp.setInterfaceName(MOBILE_IFNAME); - // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does - // "is-reachable" testing in order to not program netd with unreachable - // nameservers that it might try repeated to validate. - cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); - cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), - MOBILE_IFNAME)); - cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); - cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), - MOBILE_IFNAME)); - mCellNetworkAgent.sendLinkProperties(cellLp); - mCellNetworkAgent.connect(false); - waitForIdle(); - - verify(mMockDnsResolver, times(1)).createNetworkCache( - eq(mCellNetworkAgent.getNetwork().netId)); - // CS tells dnsresolver about the empty DNS config for this network. - verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); - reset(mMockDnsResolver); - - cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); - mCellNetworkAgent.sendLinkProperties(cellLp); - waitForIdle(); - verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( - mResolverParamsParcelCaptor.capture()); - ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); - assertEquals(1, resolvrParams.servers.length); - assertTrue(ArrayUtils.contains(resolvrParams.servers, "2001:db8::1")); - // Opportunistic mode. - assertTrue(ArrayUtils.contains(resolvrParams.tlsServers, "2001:db8::1")); - reset(mMockDnsResolver); - - cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); - mCellNetworkAgent.sendLinkProperties(cellLp); - waitForIdle(); - verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( - mResolverParamsParcelCaptor.capture()); - resolvrParams = mResolverParamsParcelCaptor.getValue(); - assertEquals(2, resolvrParams.servers.length); - assertTrue(ArrayUtils.containsAll(resolvrParams.servers, - new String[]{"2001:db8::1", "192.0.2.1"})); - // Opportunistic mode. - assertEquals(2, resolvrParams.tlsServers.length); - assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers, - new String[]{"2001:db8::1", "192.0.2.1"})); - reset(mMockDnsResolver); - - final String TLS_SPECIFIER = "tls.example.com"; - final String TLS_SERVER6 = "2001:db8:53::53"; - final InetAddress[] TLS_IPS = new InetAddress[]{ InetAddress.getByName(TLS_SERVER6) }; - final String[] TLS_SERVERS = new String[]{ TLS_SERVER6 }; - mCellNetworkAgent.mNmCallbacks.notifyPrivateDnsConfigResolved( - new PrivateDnsConfig(TLS_SPECIFIER, TLS_IPS).toParcel()); - - waitForIdle(); - verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( - mResolverParamsParcelCaptor.capture()); - resolvrParams = mResolverParamsParcelCaptor.getValue(); - assertEquals(2, resolvrParams.servers.length); - assertTrue(ArrayUtils.containsAll(resolvrParams.servers, - new String[]{"2001:db8::1", "192.0.2.1"})); - reset(mMockDnsResolver); - } - - @Test - public void testDnsConfigurationTransTypesPushed() throws Exception { - // Clear any interactions that occur as a result of CS starting up. - reset(mMockDnsResolver); - - final NetworkRequest request = new NetworkRequest.Builder() - .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) - .build(); - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, callback); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - verify(mMockDnsResolver, times(1)).createNetworkCache( - eq(mWiFiNetworkAgent.getNetwork().netId)); - verify(mMockDnsResolver, times(2)).setResolverConfiguration( - mResolverParamsParcelCaptor.capture()); - final ResolverParamsParcel resolverParams = mResolverParamsParcelCaptor.getValue(); - assertContainsExactly(resolverParams.transportTypes, TRANSPORT_WIFI); - reset(mMockDnsResolver); - } - - @Test - public void testPrivateDnsNotification() throws Exception { - NetworkRequest request = new NetworkRequest.Builder() - .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) - .build(); - TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, callback); - // Bring up wifi. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - // Private DNS resolution failed, checking if the notification will be shown or not. - mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */); - mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); - waitForIdle(); - // If network validation failed, NetworkMonitor will re-evaluate the network. - // ConnectivityService should filter the redundant notification. This part is trying to - // simulate that situation and check if ConnectivityService could filter that case. - mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); - waitForIdle(); - verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).notify(anyString(), - eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); - // If private DNS resolution successful, the PRIVATE_DNS_BROKEN notification shouldn't be - // shown. - mWiFiNetworkAgent.setNetworkValid(true /* isStrictMode */); - mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); - waitForIdle(); - verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).cancel(anyString(), - eq(NotificationType.PRIVATE_DNS_BROKEN.eventId)); - // If private DNS resolution failed again, the PRIVATE_DNS_BROKEN notification should be - // shown again. - mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */); - mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); - waitForIdle(); - verify(mNotificationManager, timeout(TIMEOUT_MS).times(2)).notify(anyString(), - eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); - } - - @Test - public void testPrivateDnsSettingsChange() throws Exception { - // Clear any interactions that occur as a result of CS starting up. - reset(mMockDnsResolver); - - // The default on Android is opportunistic mode ("Automatic"). - setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); - - final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); - final NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR).build(); - mCm.requestNetwork(cellRequest, cellNetworkCallback); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - waitForIdle(); - // CS tells netd about the empty DNS config for this network. - verify(mMockDnsResolver, never()).setResolverConfiguration(any()); - verifyNoMoreInteractions(mMockDnsResolver); - - final LinkProperties cellLp = new LinkProperties(); - cellLp.setInterfaceName(MOBILE_IFNAME); - // Add IPv4 and IPv6 default routes, because DNS-over-TLS code does - // "is-reachable" testing in order to not program netd with unreachable - // nameservers that it might try repeated to validate. - cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24")); - cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), - MOBILE_IFNAME)); - cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); - cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), - MOBILE_IFNAME)); - cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); - cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); - - mCellNetworkAgent.sendLinkProperties(cellLp); - mCellNetworkAgent.connect(false); - waitForIdle(); - verify(mMockDnsResolver, times(1)).createNetworkCache( - eq(mCellNetworkAgent.getNetwork().netId)); - verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( - mResolverParamsParcelCaptor.capture()); - ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); - assertEquals(2, resolvrParams.tlsServers.length); - assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers, - new String[] { "2001:db8::1", "192.0.2.1" })); - // Opportunistic mode. - assertEquals(2, resolvrParams.tlsServers.length); - assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers, - new String[] { "2001:db8::1", "192.0.2.1" })); - reset(mMockDnsResolver); - cellNetworkCallback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); - cellNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, - mCellNetworkAgent); - CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback( - CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); - cellNetworkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent); - cellNetworkCallback.assertNoCallback(); - assertFalse(cbi.getLp().isPrivateDnsActive()); - assertNull(cbi.getLp().getPrivateDnsServerName()); - - setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); - verify(mMockDnsResolver, times(1)).setResolverConfiguration( - mResolverParamsParcelCaptor.capture()); - resolvrParams = mResolverParamsParcelCaptor.getValue(); - assertEquals(2, resolvrParams.servers.length); - assertTrue(ArrayUtils.containsAll(resolvrParams.servers, - new String[] { "2001:db8::1", "192.0.2.1" })); - reset(mMockDnsResolver); - cellNetworkCallback.assertNoCallback(); - - setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); - verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( - mResolverParamsParcelCaptor.capture()); - resolvrParams = mResolverParamsParcelCaptor.getValue(); - assertEquals(2, resolvrParams.servers.length); - assertTrue(ArrayUtils.containsAll(resolvrParams.servers, - new String[] { "2001:db8::1", "192.0.2.1" })); - assertEquals(2, resolvrParams.tlsServers.length); - assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers, - new String[] { "2001:db8::1", "192.0.2.1" })); - reset(mMockDnsResolver); - cellNetworkCallback.assertNoCallback(); - - setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com"); - // Can't test dns configuration for strict mode without properly mocking - // out the DNS lookups, but can test that LinkProperties is updated. - cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, - mCellNetworkAgent); - cellNetworkCallback.assertNoCallback(); - assertTrue(cbi.getLp().isPrivateDnsActive()); - assertEquals("strict.example.com", cbi.getLp().getPrivateDnsServerName()); - } - - private PrivateDnsValidationEventParcel makePrivateDnsValidationEvent( - final int netId, final String ipAddress, final String hostname, final int validation) { - final PrivateDnsValidationEventParcel event = new PrivateDnsValidationEventParcel(); - event.netId = netId; - event.ipAddress = ipAddress; - event.hostname = hostname; - event.validation = validation; - return event; - } - - @Test - public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception { - // The default on Android is opportunistic mode ("Automatic"). - setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); - - final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); - final NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR).build(); - mCm.requestNetwork(cellRequest, cellNetworkCallback); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - waitForIdle(); - LinkProperties lp = new LinkProperties(); - mCellNetworkAgent.sendLinkProperties(lp); - mCellNetworkAgent.connect(false); - waitForIdle(); - cellNetworkCallback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); - cellNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, - mCellNetworkAgent); - CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback( - CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); - cellNetworkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent); - cellNetworkCallback.assertNoCallback(); - assertFalse(cbi.getLp().isPrivateDnsActive()); - assertNull(cbi.getLp().getPrivateDnsServerName()); - Set<InetAddress> dnsServers = new HashSet<>(); - checkDnsServers(cbi.getLp(), dnsServers); - - // Send a validation event for a server that is not part of the current - // resolver config. The validation event should be ignored. - mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( - makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "", - "145.100.185.18", VALIDATION_RESULT_SUCCESS)); - cellNetworkCallback.assertNoCallback(); - - // Add a dns server to the LinkProperties. - LinkProperties lp2 = new LinkProperties(lp); - lp2.addDnsServer(InetAddress.getByName("145.100.185.16")); - mCellNetworkAgent.sendLinkProperties(lp2); - cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, - mCellNetworkAgent); - cellNetworkCallback.assertNoCallback(); - assertFalse(cbi.getLp().isPrivateDnsActive()); - assertNull(cbi.getLp().getPrivateDnsServerName()); - dnsServers.add(InetAddress.getByName("145.100.185.16")); - checkDnsServers(cbi.getLp(), dnsServers); - - // Send a validation event containing a hostname that is not part of - // the current resolver config. The validation event should be ignored. - mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( - makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, - "145.100.185.16", "hostname", VALIDATION_RESULT_SUCCESS)); - cellNetworkCallback.assertNoCallback(); - - // Send a validation event where validation failed. - mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( - makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, - "145.100.185.16", "", VALIDATION_RESULT_FAILURE)); - cellNetworkCallback.assertNoCallback(); - - // Send a validation event where validation succeeded for a server in - // the current resolver config. A LinkProperties callback with updated - // private dns fields should be sent. - mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent( - makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, - "145.100.185.16", "", VALIDATION_RESULT_SUCCESS)); - cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, - mCellNetworkAgent); - cellNetworkCallback.assertNoCallback(); - assertTrue(cbi.getLp().isPrivateDnsActive()); - assertNull(cbi.getLp().getPrivateDnsServerName()); - checkDnsServers(cbi.getLp(), dnsServers); - - // The private dns fields in LinkProperties should be preserved when - // the network agent sends unrelated changes. - LinkProperties lp3 = new LinkProperties(lp2); - lp3.setMtu(1300); - mCellNetworkAgent.sendLinkProperties(lp3); - cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, - mCellNetworkAgent); - cellNetworkCallback.assertNoCallback(); - assertTrue(cbi.getLp().isPrivateDnsActive()); - assertNull(cbi.getLp().getPrivateDnsServerName()); - checkDnsServers(cbi.getLp(), dnsServers); - assertEquals(1300, cbi.getLp().getMtu()); - - // Removing the only validated server should affect the private dns - // fields in LinkProperties. - LinkProperties lp4 = new LinkProperties(lp3); - lp4.removeDnsServer(InetAddress.getByName("145.100.185.16")); - mCellNetworkAgent.sendLinkProperties(lp4); - cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, - mCellNetworkAgent); - cellNetworkCallback.assertNoCallback(); - assertFalse(cbi.getLp().isPrivateDnsActive()); - assertNull(cbi.getLp().getPrivateDnsServerName()); - dnsServers.remove(InetAddress.getByName("145.100.185.16")); - checkDnsServers(cbi.getLp(), dnsServers); - assertEquals(1300, cbi.getLp().getMtu()); - } - - private void checkDirectlyConnectedRoutes(Object callbackObj, - Collection<LinkAddress> linkAddresses, Collection<RouteInfo> otherRoutes) { - assertTrue(callbackObj instanceof LinkProperties); - LinkProperties lp = (LinkProperties) callbackObj; - - Set<RouteInfo> expectedRoutes = new ArraySet<>(); - expectedRoutes.addAll(otherRoutes); - for (LinkAddress address : linkAddresses) { - RouteInfo localRoute = new RouteInfo(address, null, lp.getInterfaceName()); - // Duplicates in linkAddresses are considered failures - assertTrue(expectedRoutes.add(localRoute)); - } - List<RouteInfo> observedRoutes = lp.getRoutes(); - assertEquals(expectedRoutes.size(), observedRoutes.size()); - assertTrue(observedRoutes.containsAll(expectedRoutes)); - } - - private static void checkDnsServers(Object callbackObj, Set<InetAddress> dnsServers) { - assertTrue(callbackObj instanceof LinkProperties); - LinkProperties lp = (LinkProperties) callbackObj; - assertEquals(dnsServers.size(), lp.getDnsServers().size()); - assertTrue(lp.getDnsServers().containsAll(dnsServers)); - } - - @Test - public void testApplyUnderlyingCapabilities() throws Exception { - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mCellNetworkAgent.connect(false /* validated */); - mWiFiNetworkAgent.connect(false /* validated */); - - final NetworkCapabilities cellNc = new NetworkCapabilities() - .addTransportType(TRANSPORT_CELLULAR) - .addCapability(NET_CAPABILITY_INTERNET) - .addCapability(NET_CAPABILITY_NOT_CONGESTED) - .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) - .setLinkDownstreamBandwidthKbps(10); - final NetworkCapabilities wifiNc = new NetworkCapabilities() - .addTransportType(TRANSPORT_WIFI) - .addCapability(NET_CAPABILITY_INTERNET) - .addCapability(NET_CAPABILITY_NOT_METERED) - .addCapability(NET_CAPABILITY_NOT_ROAMING) - .addCapability(NET_CAPABILITY_NOT_CONGESTED) - .addCapability(NET_CAPABILITY_NOT_SUSPENDED) - .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) - .setLinkUpstreamBandwidthKbps(20); - mCellNetworkAgent.setNetworkCapabilities(cellNc, true /* sendToConnectivityService */); - mWiFiNetworkAgent.setNetworkCapabilities(wifiNc, true /* sendToConnectivityService */); - waitForIdle(); - - final Network mobile = mCellNetworkAgent.getNetwork(); - final Network wifi = mWiFiNetworkAgent.getNetwork(); - - final NetworkCapabilities initialCaps = new NetworkCapabilities(); - initialCaps.addTransportType(TRANSPORT_VPN); - initialCaps.addCapability(NET_CAPABILITY_INTERNET); - initialCaps.removeCapability(NET_CAPABILITY_NOT_VPN); - - final NetworkCapabilities withNoUnderlying = new NetworkCapabilities(); - withNoUnderlying.addCapability(NET_CAPABILITY_INTERNET); - withNoUnderlying.addCapability(NET_CAPABILITY_NOT_CONGESTED); - withNoUnderlying.addCapability(NET_CAPABILITY_NOT_ROAMING); - withNoUnderlying.addCapability(NET_CAPABILITY_NOT_SUSPENDED); - withNoUnderlying.addTransportType(TRANSPORT_VPN); - withNoUnderlying.removeCapability(NET_CAPABILITY_NOT_VPN); - - final NetworkCapabilities withMobileUnderlying = new NetworkCapabilities(withNoUnderlying); - withMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); - withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); - withMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); - withMobileUnderlying.setLinkDownstreamBandwidthKbps(10); - - final NetworkCapabilities withWifiUnderlying = new NetworkCapabilities(withNoUnderlying); - withWifiUnderlying.addTransportType(TRANSPORT_WIFI); - withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); - withWifiUnderlying.setLinkUpstreamBandwidthKbps(20); - - final NetworkCapabilities withWifiAndMobileUnderlying = - new NetworkCapabilities(withNoUnderlying); - withWifiAndMobileUnderlying.addTransportType(TRANSPORT_CELLULAR); - withWifiAndMobileUnderlying.addTransportType(TRANSPORT_WIFI); - withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); - withWifiAndMobileUnderlying.removeCapability(NET_CAPABILITY_NOT_ROAMING); - withWifiAndMobileUnderlying.setLinkDownstreamBandwidthKbps(10); - withWifiAndMobileUnderlying.setLinkUpstreamBandwidthKbps(20); - - final NetworkCapabilities initialCapsNotMetered = new NetworkCapabilities(initialCaps); - initialCapsNotMetered.addCapability(NET_CAPABILITY_NOT_METERED); - - NetworkCapabilities caps = new NetworkCapabilities(initialCaps); - mService.applyUnderlyingCapabilities(new Network[]{}, initialCapsNotMetered, caps); - assertEquals(withNoUnderlying, caps); - - caps = new NetworkCapabilities(initialCaps); - mService.applyUnderlyingCapabilities(new Network[]{null}, initialCapsNotMetered, caps); - assertEquals(withNoUnderlying, caps); - - caps = new NetworkCapabilities(initialCaps); - mService.applyUnderlyingCapabilities(new Network[]{mobile}, initialCapsNotMetered, caps); - assertEquals(withMobileUnderlying, caps); - - mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCapsNotMetered, caps); - assertEquals(withWifiUnderlying, caps); - - withWifiUnderlying.removeCapability(NET_CAPABILITY_NOT_METERED); - caps = new NetworkCapabilities(initialCaps); - mService.applyUnderlyingCapabilities(new Network[]{wifi}, initialCaps, caps); - assertEquals(withWifiUnderlying, caps); - - caps = new NetworkCapabilities(initialCaps); - mService.applyUnderlyingCapabilities(new Network[]{mobile, wifi}, initialCaps, caps); - assertEquals(withWifiAndMobileUnderlying, caps); - - withWifiUnderlying.addCapability(NET_CAPABILITY_NOT_METERED); - caps = new NetworkCapabilities(initialCaps); - mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, - initialCapsNotMetered, caps); - assertEquals(withWifiAndMobileUnderlying, caps); - - caps = new NetworkCapabilities(initialCaps); - mService.applyUnderlyingCapabilities(new Network[]{null, mobile, null, wifi}, - initialCapsNotMetered, caps); - assertEquals(withWifiAndMobileUnderlying, caps); - - mService.applyUnderlyingCapabilities(null, initialCapsNotMetered, caps); - assertEquals(withWifiUnderlying, caps); - } - - @Test - public void testVpnConnectDisconnectUnderlyingNetwork() throws Exception { - final TestNetworkCallback callback = new TestNetworkCallback(); - final NetworkRequest request = new NetworkRequest.Builder() - .removeCapability(NET_CAPABILITY_NOT_VPN).build(); - - mCm.registerNetworkCallback(request, callback); - - // Bring up a VPN that specifies an underlying network that does not exist yet. - // Note: it's sort of meaningless for a VPN app to declare a network that doesn't exist yet, - // (and doing so is difficult without using reflection) but it's good to test that the code - // behaves approximately correctly. - mMockVpn.establishForMyUid(false, true, false); - assertUidRangesUpdatedForMyUid(true); - final Network wifiNetwork = new Network(mNetIdManager.peekNextNetId()); - mMockVpn.setUnderlyingNetworks(new Network[]{wifiNetwork}); - callback.expectAvailableCallbacksUnvalidated(mMockVpn); - assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) - .hasTransport(TRANSPORT_VPN)); - assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) - .hasTransport(TRANSPORT_WIFI)); - - // Make that underlying network connect, and expect to see its capabilities immediately - // reflected in the VPN's capabilities. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - assertEquals(wifiNetwork, mWiFiNetworkAgent.getNetwork()); - mWiFiNetworkAgent.connect(false); - // TODO: the callback for the VPN happens before any callbacks are called for the wifi - // network that has just connected. There appear to be two issues here: - // 1. The VPN code will accept an underlying network as soon as getNetworkCapabilities() for - // it returns non-null (which happens very early, during handleRegisterNetworkAgent). - // This is not correct because that that point the network is not connected and cannot - // pass any traffic. - // 2. When a network connects, updateNetworkInfo propagates underlying network capabilities - // before rematching networks. - // Given that this scenario can't really happen, this is probably fine for now. - callback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) - .hasTransport(TRANSPORT_VPN)); - assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) - .hasTransport(TRANSPORT_WIFI)); - - // Disconnect the network, and expect to see the VPN capabilities change accordingly. - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - callback.expectCapabilitiesThat(mMockVpn, (nc) -> - nc.getTransportTypes().length == 1 && nc.hasTransport(TRANSPORT_VPN)); - - mMockVpn.disconnect(); - mCm.unregisterNetworkCallback(callback); - } - - private void assertGetNetworkInfoOfGetActiveNetworkIsConnected(boolean expectedConnectivity) { - // What Chromium used to do before https://chromium-review.googlesource.com/2605304 - assertEquals("Unexpected result for getActiveNetworkInfo(getActiveNetwork())", - expectedConnectivity, mCm.getNetworkInfo(mCm.getActiveNetwork()).isConnected()); - } - - @Test - public void testVpnUnderlyingNetworkSuspended() throws Exception { - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(callback); - - // Connect a VPN. - mMockVpn.establishForMyUid(false /* validated */, true /* hasInternet */, - false /* isStrictMode */); - callback.expectAvailableCallbacksUnvalidated(mMockVpn); - - // Connect cellular data. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(false /* validated */); - callback.expectCapabilitiesThat(mMockVpn, - nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) - && nc.hasTransport(TRANSPORT_CELLULAR)); - callback.assertNoCallback(); - - assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) - .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); - - // Suspend the cellular network and expect the VPN to be suspended. - mCellNetworkAgent.suspend(); - callback.expectCapabilitiesThat(mMockVpn, - nc -> !nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) - && nc.hasTransport(TRANSPORT_CELLULAR)); - callback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn); - callback.assertNoCallback(); - - assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) - .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - assertNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); - assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_VPN, DetailedState.SUSPENDED); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); - // VPN's main underlying network is suspended, so no connectivity. - assertGetNetworkInfoOfGetActiveNetworkIsConnected(false); - - // Switch to another network. The VPN should no longer be suspended. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false /* validated */); - callback.expectCapabilitiesThat(mMockVpn, - nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) - && nc.hasTransport(TRANSPORT_WIFI)); - callback.expectCallback(CallbackEntry.RESUMED, mMockVpn); - callback.assertNoCallback(); - - assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) - .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); - - // Unsuspend cellular and then switch back to it. The VPN remains not suspended. - mCellNetworkAgent.resume(); - callback.assertNoCallback(); - mWiFiNetworkAgent.disconnect(); - callback.expectCapabilitiesThat(mMockVpn, - nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) - && nc.hasTransport(TRANSPORT_CELLULAR)); - // Spurious double callback? - callback.expectCapabilitiesThat(mMockVpn, - nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) - && nc.hasTransport(TRANSPORT_CELLULAR)); - callback.assertNoCallback(); - - assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) - .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); - - // Suspend cellular and expect no connectivity. - mCellNetworkAgent.suspend(); - callback.expectCapabilitiesThat(mMockVpn, - nc -> !nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) - && nc.hasTransport(TRANSPORT_CELLULAR)); - callback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn); - callback.assertNoCallback(); - - assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) - .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - assertNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); - assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_VPN, DetailedState.SUSPENDED); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.SUSPENDED); - assertGetNetworkInfoOfGetActiveNetworkIsConnected(false); - - // Resume cellular and expect that connectivity comes back. - mCellNetworkAgent.resume(); - callback.expectCapabilitiesThat(mMockVpn, - nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED) - && nc.hasTransport(TRANSPORT_CELLULAR)); - callback.expectCallback(CallbackEntry.RESUMED, mMockVpn); - callback.assertNoCallback(); - - assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork()) - .hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertGetNetworkInfoOfGetActiveNetworkIsConnected(true); - } - - @Test - public void testVpnNetworkActive() throws Exception { - // NETWORK_SETTINGS is necessary to call registerSystemDefaultNetworkCallback. - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); - - final int uid = Process.myUid(); - - final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); - final TestNetworkCallback genericNotVpnNetworkCallback = new TestNetworkCallback(); - final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); - final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); - final TestNetworkCallback defaultCallback = new TestNetworkCallback(); - final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); - final NetworkRequest genericNotVpnRequest = new NetworkRequest.Builder().build(); - final NetworkRequest genericRequest = new NetworkRequest.Builder() - .removeCapability(NET_CAPABILITY_NOT_VPN).build(); - final NetworkRequest wifiRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI).build(); - final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() - .removeCapability(NET_CAPABILITY_NOT_VPN) - .addTransportType(TRANSPORT_VPN).build(); - mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); - mCm.registerNetworkCallback(genericNotVpnRequest, genericNotVpnNetworkCallback); - mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); - mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); - mCm.registerDefaultNetworkCallback(defaultCallback); - mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, - new Handler(ConnectivityThread.getInstanceLooper())); - defaultCallback.assertNoCallback(); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false); - - genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - genericNotVpnNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - vpnNetworkCallback.assertNoCallback(); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - final Set<UidRange> ranges = uidRangesForUids(uid); - mMockVpn.registerAgent(ranges); - mMockVpn.setUnderlyingNetworks(new Network[0]); - - // VPN networks do not satisfy the default request and are automatically validated - // by NetworkMonitor - assertFalse(NetworkMonitorUtils.isValidationRequired( - mMockVpn.getAgent().getNetworkCapabilities())); - mMockVpn.getAgent().setNetworkValid(false /* isStrictMode */); - - mMockVpn.connect(false); - - genericNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); - genericNotVpnNetworkCallback.assertNoCallback(); - wifiNetworkCallback.assertNoCallback(); - vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); - defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); - systemDefaultCallback.assertNoCallback(); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - assertEquals(mWiFiNetworkAgent.getNetwork(), - systemDefaultCallback.getLastAvailableNetwork()); - - ranges.clear(); - mMockVpn.setUids(ranges); - - genericNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); - genericNotVpnNetworkCallback.assertNoCallback(); - wifiNetworkCallback.assertNoCallback(); - vpnNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); - - // TODO : The default network callback should actually get a LOST call here (also see the - // comment below for AVAILABLE). This is because ConnectivityService does not look at UID - // ranges at all when determining whether a network should be rematched. In practice, VPNs - // can't currently update their UIDs without disconnecting, so this does not matter too - // much, but that is the reason the test here has to check for an update to the - // capabilities instead of the expected LOST then AVAILABLE. - defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn); - systemDefaultCallback.assertNoCallback(); - - ranges.add(new UidRange(uid, uid)); - mMockVpn.setUids(ranges); - - genericNetworkCallback.expectAvailableCallbacksValidated(mMockVpn); - genericNotVpnNetworkCallback.assertNoCallback(); - wifiNetworkCallback.assertNoCallback(); - vpnNetworkCallback.expectAvailableCallbacksValidated(mMockVpn); - // TODO : Here like above, AVAILABLE would be correct, but because this can't actually - // happen outside of the test, ConnectivityService does not rematch callbacks. - defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn); - systemDefaultCallback.assertNoCallback(); - - mWiFiNetworkAgent.disconnect(); - - genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - genericNotVpnNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - vpnNetworkCallback.assertNoCallback(); - defaultCallback.assertNoCallback(); - systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - - mMockVpn.disconnect(); - - genericNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); - genericNotVpnNetworkCallback.assertNoCallback(); - wifiNetworkCallback.assertNoCallback(); - vpnNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn); - defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn); - systemDefaultCallback.assertNoCallback(); - assertEquals(null, mCm.getActiveNetwork()); - - mCm.unregisterNetworkCallback(genericNetworkCallback); - mCm.unregisterNetworkCallback(wifiNetworkCallback); - mCm.unregisterNetworkCallback(vpnNetworkCallback); - mCm.unregisterNetworkCallback(defaultCallback); - mCm.unregisterNetworkCallback(systemDefaultCallback); - } - - @Test - public void testVpnWithoutInternet() throws Exception { - final int uid = Process.myUid(); - - final TestNetworkCallback defaultCallback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(defaultCallback); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - - defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, - false /* isStrictMode */); - assertUidRangesUpdatedForMyUid(true); - - defaultCallback.assertNoCallback(); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - mMockVpn.disconnect(); - defaultCallback.assertNoCallback(); - - mCm.unregisterNetworkCallback(defaultCallback); - } - - @Test - public void testVpnWithInternet() throws Exception { - final int uid = Process.myUid(); - - final TestNetworkCallback defaultCallback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(defaultCallback); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - - defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - mMockVpn.establishForMyUid(true /* validated */, true /* hasInternet */, - false /* isStrictMode */); - assertUidRangesUpdatedForMyUid(true); - - defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - mMockVpn.disconnect(); - defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn); - defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); - - mCm.unregisterNetworkCallback(defaultCallback); - } - - @Test - public void testVpnUnvalidated() throws Exception { - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(callback); - - // Bring up Ethernet. - mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); - mEthernetNetworkAgent.connect(true); - callback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); - callback.assertNoCallback(); - - // Bring up a VPN that has the INTERNET capability, initially unvalidated. - mMockVpn.establishForMyUid(false /* validated */, true /* hasInternet */, - false /* isStrictMode */); - assertUidRangesUpdatedForMyUid(true); - - // Even though the VPN is unvalidated, it becomes the default network for our app. - callback.expectAvailableCallbacksUnvalidated(mMockVpn); - callback.assertNoCallback(); - - assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); - - NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); - assertFalse(nc.hasCapability(NET_CAPABILITY_VALIDATED)); - assertTrue(nc.hasCapability(NET_CAPABILITY_INTERNET)); - - assertFalse(NetworkMonitorUtils.isValidationRequired( - mMockVpn.getAgent().getNetworkCapabilities())); - assertTrue(NetworkMonitorUtils.isPrivateDnsValidationRequired( - mMockVpn.getAgent().getNetworkCapabilities())); - - // Pretend that the VPN network validates. - mMockVpn.getAgent().setNetworkValid(false /* isStrictMode */); - mMockVpn.getAgent().mNetworkMonitor.forceReevaluation(Process.myUid()); - // Expect to see the validated capability, but no other changes, because the VPN is already - // the default network for the app. - callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mMockVpn); - callback.assertNoCallback(); - - mMockVpn.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mMockVpn); - callback.expectAvailableCallbacksValidated(mEthernetNetworkAgent); - } - - @Test - public void testVpnStartsWithUnderlyingCaps() throws Exception { - final int uid = Process.myUid(); - - final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); - final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() - .removeCapability(NET_CAPABILITY_NOT_VPN) - .addTransportType(TRANSPORT_VPN) - .build(); - mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); - vpnNetworkCallback.assertNoCallback(); - - // Connect cell. It will become the default network, and in the absence of setting - // underlying networks explicitly it will become the sole underlying network for the vpn. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); - mCellNetworkAgent.connect(true); - - mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, - false /* isStrictMode */); - assertUidRangesUpdatedForMyUid(true); - - vpnNetworkCallback.expectAvailableCallbacks(mMockVpn.getNetwork(), - false /* suspended */, false /* validated */, false /* blocked */, TIMEOUT_MS); - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn.getNetwork(), TIMEOUT_MS, - nc -> nc.hasCapability(NET_CAPABILITY_VALIDATED)); - - final NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); - assertTrue(nc.hasTransport(TRANSPORT_VPN)); - assertTrue(nc.hasTransport(TRANSPORT_CELLULAR)); - assertFalse(nc.hasTransport(TRANSPORT_WIFI)); - assertTrue(nc.hasCapability(NET_CAPABILITY_VALIDATED)); - assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); - assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - - assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); - } - - private void assertDefaultNetworkCapabilities(int userId, NetworkAgentWrapper... networks) { - final NetworkCapabilities[] defaultCaps = mService.getDefaultNetworkCapabilitiesForUser( - userId, "com.android.calling.package", "com.test"); - final String defaultCapsString = Arrays.toString(defaultCaps); - assertEquals(defaultCapsString, defaultCaps.length, networks.length); - final Set<NetworkCapabilities> defaultCapsSet = new ArraySet<>(defaultCaps); - for (NetworkAgentWrapper network : networks) { - final NetworkCapabilities nc = mCm.getNetworkCapabilities(network.getNetwork()); - final String msg = "Did not find " + nc + " in " + Arrays.toString(defaultCaps); - assertTrue(msg, defaultCapsSet.contains(nc)); - } - } - - @Test - public void testVpnSetUnderlyingNetworks() throws Exception { - final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); - final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() - .removeCapability(NET_CAPABILITY_NOT_VPN) - .addTransportType(TRANSPORT_VPN) - .build(); - NetworkCapabilities nc; - mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); - vpnNetworkCallback.assertNoCallback(); - - mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, - false /* isStrictMode */); - assertUidRangesUpdatedForMyUid(true); - - vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); - nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); - assertTrue(nc.hasTransport(TRANSPORT_VPN)); - assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); - assertFalse(nc.hasTransport(TRANSPORT_WIFI)); - // For safety reasons a VPN without underlying networks is considered metered. - assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); - // A VPN without underlying networks is not suspended. - assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); - - final int userId = UserHandle.getUserId(Process.myUid()); - assertDefaultNetworkCapabilities(userId /* no networks */); - - // Connect cell and use it as an underlying network. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); - mCellNetworkAgent.connect(true); - - mMockVpn.setUnderlyingNetworks( - new Network[] { mCellNetworkAgent.getNetwork() }); - - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) - && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - assertDefaultNetworkCapabilities(userId, mCellNetworkAgent); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); - mWiFiNetworkAgent.connect(true); - - mMockVpn.setUnderlyingNetworks( - new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); - - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) - && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); - - // Don't disconnect, but note the VPN is not using wifi any more. - mMockVpn.setUnderlyingNetworks( - new Network[] { mCellNetworkAgent.getNetwork() }); - - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) - && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - // The return value of getDefaultNetworkCapabilitiesForUser always includes the default - // network (wifi) as well as the underlying networks (cell). - assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); - - // Remove NOT_SUSPENDED from the only network and observe VPN is now suspended. - mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) - && !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn); - - // Add NOT_SUSPENDED again and observe VPN is no longer suspended. - mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) - && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, mMockVpn); - - // Use Wifi but not cell. Note the VPN is now unmetered and not suspended. - mMockVpn.setUnderlyingNetworks( - new Network[] { mWiFiNetworkAgent.getNetwork() }); - - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) - && caps.hasCapability(NET_CAPABILITY_NOT_METERED) - && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - assertDefaultNetworkCapabilities(userId, mWiFiNetworkAgent); - - // Use both again. - mMockVpn.setUnderlyingNetworks( - new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); - - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) - && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); - - // Cell is suspended again. As WiFi is not, this should not cause a callback. - mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); - vpnNetworkCallback.assertNoCallback(); - - // Stop using WiFi. The VPN is suspended again. - mMockVpn.setUnderlyingNetworks( - new Network[] { mCellNetworkAgent.getNetwork() }); - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && caps.hasTransport(TRANSPORT_CELLULAR) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) - && !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn); - assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); - - // Use both again. - mMockVpn.setUnderlyingNetworks( - new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); - - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) - && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); - vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, mMockVpn); - assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent); - - // Disconnect cell. Receive update without even removing the dead network from the - // underlying networks – it's dead anyway. Not metered any more. - mCellNetworkAgent.disconnect(); - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) - && caps.hasCapability(NET_CAPABILITY_NOT_METERED)); - assertDefaultNetworkCapabilities(userId, mWiFiNetworkAgent); - - // Disconnect wifi too. No underlying networks means this is now metered. - mWiFiNetworkAgent.disconnect(); - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); - // When a network disconnects, the callbacks are fired before all state is updated, so for a - // short time, synchronous calls will behave as if the network is still connected. Wait for - // things to settle. - waitForIdle(); - assertDefaultNetworkCapabilities(userId /* no networks */); - - mMockVpn.disconnect(); - } - - @Test - public void testNullUnderlyingNetworks() throws Exception { - final int uid = Process.myUid(); - - final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); - final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() - .removeCapability(NET_CAPABILITY_NOT_VPN) - .addTransportType(TRANSPORT_VPN) - .build(); - NetworkCapabilities nc; - mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); - vpnNetworkCallback.assertNoCallback(); - - mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */, - false /* isStrictMode */); - assertUidRangesUpdatedForMyUid(true); - - vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); - nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); - assertTrue(nc.hasTransport(TRANSPORT_VPN)); - assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); - assertFalse(nc.hasTransport(TRANSPORT_WIFI)); - // By default, VPN is set to track default network (i.e. its underlying networks is null). - // In case of no default network, VPN is considered metered. - assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); - assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); - - // Connect to Cell; Cell is the default network. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); - - // Connect to WiFi; WiFi is the new default. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - mWiFiNetworkAgent.connect(true); - - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) - && caps.hasCapability(NET_CAPABILITY_NOT_METERED)); - - // Disconnect Cell. The default network did not change, so there shouldn't be any changes in - // the capabilities. - mCellNetworkAgent.disconnect(); - - // Disconnect wifi too. Now we have no default network. - mWiFiNetworkAgent.disconnect(); - - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, - (caps) -> caps.hasTransport(TRANSPORT_VPN) - && !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); - - mMockVpn.disconnect(); - } - - @Test - public void testRestrictedProfileAffectsVpnUidRanges() throws Exception { - // NETWORK_SETTINGS is necessary to see the UID ranges in NetworkCapabilities. - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); - - final NetworkRequest request = new NetworkRequest.Builder() - .removeCapability(NET_CAPABILITY_NOT_VPN) - .build(); - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, callback); - - // Bring up a VPN - mMockVpn.establishForMyUid(); - assertUidRangesUpdatedForMyUid(true); - callback.expectAvailableThenValidatedCallbacks(mMockVpn); - callback.assertNoCallback(); - - final int uid = Process.myUid(); - NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); - assertNotNull("nc=" + nc, nc.getUids()); - assertEquals(nc.getUids(), UidRange.toIntRanges(uidRangesForUids(uid))); - assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); - - // Set an underlying network and expect to see the VPN transports change. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - callback.expectCapabilitiesThat(mMockVpn, (caps) - -> caps.hasTransport(TRANSPORT_VPN) - && caps.hasTransport(TRANSPORT_WIFI)); - callback.expectCapabilitiesThat(mWiFiNetworkAgent, (caps) - -> caps.hasCapability(NET_CAPABILITY_VALIDATED)); - - when(mPackageManager.getPackageUidAsUser(ALWAYS_ON_PACKAGE, RESTRICTED_USER)) - .thenReturn(UserHandle.getUid(RESTRICTED_USER, VPN_UID)); - - final Intent addedIntent = new Intent(ACTION_USER_ADDED); - addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); - addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); - - // Send a USER_ADDED broadcast for it. - processBroadcast(addedIntent); - - // Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added - // restricted user. - final UidRange rRange = UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); - final Range<Integer> restrictUidRange = new Range<Integer>(rRange.start, rRange.stop); - final Range<Integer> singleUidRange = new Range<Integer>(uid, uid); - callback.expectCapabilitiesThat(mMockVpn, (caps) - -> caps.getUids().size() == 2 - && caps.getUids().contains(singleUidRange) - && caps.getUids().contains(restrictUidRange) - && caps.hasTransport(TRANSPORT_VPN) - && caps.hasTransport(TRANSPORT_WIFI)); - - // Change the VPN's capabilities somehow (specifically, disconnect wifi). - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - callback.expectCapabilitiesThat(mMockVpn, (caps) - -> caps.getUids().size() == 2 - && caps.getUids().contains(singleUidRange) - && caps.getUids().contains(restrictUidRange) - && caps.hasTransport(TRANSPORT_VPN) - && !caps.hasTransport(TRANSPORT_WIFI)); - - // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user. - final Intent removedIntent = new Intent(ACTION_USER_REMOVED); - removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); - removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); - processBroadcast(removedIntent); - - // Expect that the VPN gains the UID range for the restricted user, and that the capability - // change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved. - callback.expectCapabilitiesThat(mMockVpn, (caps) - -> caps.getUids().size() == 1 - && caps.getUids().contains(singleUidRange) - && caps.hasTransport(TRANSPORT_VPN) - && !caps.hasTransport(TRANSPORT_WIFI)); - } - - @Test - public void testLockdownVpnWithRestrictedProfiles() throws Exception { - // For ConnectivityService#setAlwaysOnVpnPackage. - mServiceContext.setPermission( - Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED); - // For call Vpn#setAlwaysOnPackage. - mServiceContext.setPermission( - Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); - // Necessary to see the UID ranges in NetworkCapabilities. - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); - - final NetworkRequest request = new NetworkRequest.Builder() - .removeCapability(NET_CAPABILITY_NOT_VPN) - .build(); - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, callback); - - final int uid = Process.myUid(); - - // Connect wifi and check that UIDs in the main and restricted profiles have network access. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true /* validated */); - final int restrictedUid = UserHandle.getUid(RESTRICTED_USER, 42 /* appId */); - assertNotNull(mCm.getActiveNetworkForUid(uid)); - assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); - - // Enable always-on VPN lockdown. The main user loses network access because no VPN is up. - final ArrayList<String> allowList = new ArrayList<>(); - mVpnManagerService.setAlwaysOnVpnPackage(PRIMARY_USER, ALWAYS_ON_PACKAGE, - true /* lockdown */, allowList); - waitForIdle(); - assertNull(mCm.getActiveNetworkForUid(uid)); - // This is arguably overspecified: a UID that is not running doesn't have an active network. - // But it's useful to check that non-default users do not lose network access, and to prove - // that the loss of connectivity below is indeed due to the restricted profile coming up. - assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); - - // Start the restricted profile, and check that the UID within it loses network access. - when(mPackageManager.getPackageUidAsUser(ALWAYS_ON_PACKAGE, RESTRICTED_USER)) - .thenReturn(UserHandle.getUid(RESTRICTED_USER, VPN_UID)); - when(mUserManager.getAliveUsers()).thenReturn(Arrays.asList(PRIMARY_USER_INFO, - RESTRICTED_USER_INFO)); - // TODO: check that VPN app within restricted profile still has access, etc. - final Intent addedIntent = new Intent(ACTION_USER_ADDED); - addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); - addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); - processBroadcast(addedIntent); - assertNull(mCm.getActiveNetworkForUid(uid)); - assertNull(mCm.getActiveNetworkForUid(restrictedUid)); - - // Stop the restricted profile, and check that the UID within it has network access again. - when(mUserManager.getAliveUsers()).thenReturn(Arrays.asList(PRIMARY_USER_INFO)); - - // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user. - final Intent removedIntent = new Intent(ACTION_USER_REMOVED); - removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER)); - removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER); - processBroadcast(removedIntent); - assertNull(mCm.getActiveNetworkForUid(uid)); - assertNotNull(mCm.getActiveNetworkForUid(restrictedUid)); - - mVpnManagerService.setAlwaysOnVpnPackage(PRIMARY_USER, null, false /* lockdown */, - allowList); - waitForIdle(); - } - - @Test - public void testIsActiveNetworkMeteredOverWifi() throws Exception { - // Returns true by default when no network is available. - assertTrue(mCm.isActiveNetworkMetered()); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - mWiFiNetworkAgent.connect(true); - waitForIdle(); - - assertFalse(mCm.isActiveNetworkMetered()); - } - - @Test - public void testIsActiveNetworkMeteredOverCell() throws Exception { - // Returns true by default when no network is available. - assertTrue(mCm.isActiveNetworkMetered()); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); - mCellNetworkAgent.connect(true); - waitForIdle(); - - assertTrue(mCm.isActiveNetworkMetered()); - } - - @Test - public void testIsActiveNetworkMeteredOverVpnTrackingPlatformDefault() throws Exception { - // Returns true by default when no network is available. - assertTrue(mCm.isActiveNetworkMetered()); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); - mCellNetworkAgent.connect(true); - waitForIdle(); - assertTrue(mCm.isActiveNetworkMetered()); - - // Connect VPN network. By default it is using current default network (Cell). - mMockVpn.establishForMyUid(); - assertUidRangesUpdatedForMyUid(true); - - // Ensure VPN is now the active network. - assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); - - // Expect VPN to be metered. - assertTrue(mCm.isActiveNetworkMetered()); - - // Connect WiFi. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - mWiFiNetworkAgent.connect(true); - waitForIdle(); - // VPN should still be the active network. - assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); - - // Expect VPN to be unmetered as it should now be using WiFi (new default). - assertFalse(mCm.isActiveNetworkMetered()); - - // Disconnecting Cell should not affect VPN's meteredness. - mCellNetworkAgent.disconnect(); - waitForIdle(); - - assertFalse(mCm.isActiveNetworkMetered()); - - // Disconnect WiFi; Now there is no platform default network. - mWiFiNetworkAgent.disconnect(); - waitForIdle(); - - // VPN without any underlying networks is treated as metered. - assertTrue(mCm.isActiveNetworkMetered()); - - mMockVpn.disconnect(); - } - - @Test - public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() throws Exception { - // Returns true by default when no network is available. - assertTrue(mCm.isActiveNetworkMetered()); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); - mCellNetworkAgent.connect(true); - waitForIdle(); - assertTrue(mCm.isActiveNetworkMetered()); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - mWiFiNetworkAgent.connect(true); - waitForIdle(); - assertFalse(mCm.isActiveNetworkMetered()); - - // Connect VPN network. - mMockVpn.establishForMyUid(); - assertUidRangesUpdatedForMyUid(true); - - // Ensure VPN is now the active network. - assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); - // VPN is using Cell - mMockVpn.setUnderlyingNetworks( - new Network[] { mCellNetworkAgent.getNetwork() }); - waitForIdle(); - - // Expect VPN to be metered. - assertTrue(mCm.isActiveNetworkMetered()); - - // VPN is now using WiFi - mMockVpn.setUnderlyingNetworks( - new Network[] { mWiFiNetworkAgent.getNetwork() }); - waitForIdle(); - - // Expect VPN to be unmetered - assertFalse(mCm.isActiveNetworkMetered()); - - // VPN is using Cell | WiFi. - mMockVpn.setUnderlyingNetworks( - new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); - waitForIdle(); - - // Expect VPN to be metered. - assertTrue(mCm.isActiveNetworkMetered()); - - // VPN is using WiFi | Cell. - mMockVpn.setUnderlyingNetworks( - new Network[] { mWiFiNetworkAgent.getNetwork(), mCellNetworkAgent.getNetwork() }); - waitForIdle(); - - // Order should not matter and VPN should still be metered. - assertTrue(mCm.isActiveNetworkMetered()); - - // VPN is not using any underlying networks. - mMockVpn.setUnderlyingNetworks(new Network[0]); - waitForIdle(); - - // VPN without underlying networks is treated as metered. - assertTrue(mCm.isActiveNetworkMetered()); - - mMockVpn.disconnect(); - } - - @Test - public void testIsActiveNetworkMeteredOverAlwaysMeteredVpn() throws Exception { - // Returns true by default when no network is available. - assertTrue(mCm.isActiveNetworkMetered()); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - mWiFiNetworkAgent.connect(true); - waitForIdle(); - assertFalse(mCm.isActiveNetworkMetered()); - - // Connect VPN network. - mMockVpn.registerAgent(true /* isAlwaysMetered */, uidRangesForUids(Process.myUid()), - new LinkProperties()); - mMockVpn.connect(true); - waitForIdle(); - assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); - - // VPN is tracking current platform default (WiFi). - mMockVpn.setUnderlyingNetworks(null); - waitForIdle(); - - // Despite VPN using WiFi (which is unmetered), VPN itself is marked as always metered. - assertTrue(mCm.isActiveNetworkMetered()); - - - // VPN explicitly declares WiFi as its underlying network. - mMockVpn.setUnderlyingNetworks( - new Network[] { mWiFiNetworkAgent.getNetwork() }); - waitForIdle(); - - // Doesn't really matter whether VPN declares its underlying networks explicitly. - assertTrue(mCm.isActiveNetworkMetered()); - - // With WiFi lost, VPN is basically without any underlying networks. And in that case it is - // anyways suppose to be metered. - mWiFiNetworkAgent.disconnect(); - waitForIdle(); - - assertTrue(mCm.isActiveNetworkMetered()); - - mMockVpn.disconnect(); - } - - private class DetailedBlockedStatusCallback extends TestNetworkCallback { - public void expectAvailableThenValidatedCallbacks(HasNetwork n, int blockedStatus) { - super.expectAvailableThenValidatedCallbacks(n.getNetwork(), blockedStatus, TIMEOUT_MS); - } - public void expectBlockedStatusCallback(HasNetwork n, int blockedStatus) { - // This doesn't work: - // super.expectBlockedStatusCallback(blockedStatus, n.getNetwork()); - super.expectBlockedStatusCallback(blockedStatus, n.getNetwork(), TIMEOUT_MS); - } - public void onBlockedStatusChanged(Network network, int blockedReasons) { - getHistory().add(new CallbackEntry.BlockedStatusInt(network, blockedReasons)); - } - } - - @Test - public void testNetworkBlockedStatus() throws Exception { - final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); - final NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR) - .build(); - mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); - final DetailedBlockedStatusCallback detailedCallback = new DetailedBlockedStatusCallback(); - mCm.registerNetworkCallback(cellRequest, detailedCallback); - - mockUidNetworkingBlocked(); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - detailedCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent, - BLOCKED_REASON_NONE); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertExtraInfoFromCmPresent(mCellNetworkAgent); - - setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER); - cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); - detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, - BLOCKED_REASON_BATTERY_SAVER); - assertNull(mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertExtraInfoFromCmBlocked(mCellNetworkAgent); - - // If blocked state does not change but blocked reason does, the boolean callback is called. - // TODO: investigate de-duplicating. - setBlockedReasonChanged(BLOCKED_METERED_REASON_USER_RESTRICTED); - cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); - detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, - BLOCKED_METERED_REASON_USER_RESTRICTED); - - setBlockedReasonChanged(BLOCKED_REASON_NONE); - cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); - detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertExtraInfoFromCmPresent(mCellNetworkAgent); - - setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); - cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); - detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, - BLOCKED_METERED_REASON_DATA_SAVER); - assertNull(mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertExtraInfoFromCmBlocked(mCellNetworkAgent); - - // Restrict the network based on UID rule and NOT_METERED capability change. - mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); - cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); - detailedCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); - detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertExtraInfoFromCmPresent(mCellNetworkAgent); - - mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); - cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, - mCellNetworkAgent); - cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); - detailedCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, - mCellNetworkAgent); - detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, - BLOCKED_METERED_REASON_DATA_SAVER); - assertNull(mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertExtraInfoFromCmBlocked(mCellNetworkAgent); - - setBlockedReasonChanged(BLOCKED_REASON_NONE); - cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); - detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertExtraInfoFromCmPresent(mCellNetworkAgent); - - setBlockedReasonChanged(BLOCKED_REASON_NONE); - cellNetworkCallback.assertNoCallback(); - detailedCallback.assertNoCallback(); - - // Restrict background data. Networking is not blocked because the network is unmetered. - setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); - cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); - detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, - BLOCKED_METERED_REASON_DATA_SAVER); - assertNull(mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertExtraInfoFromCmBlocked(mCellNetworkAgent); - setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); - cellNetworkCallback.assertNoCallback(); - - setBlockedReasonChanged(BLOCKED_REASON_NONE); - cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); - detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertExtraInfoFromCmPresent(mCellNetworkAgent); - - setBlockedReasonChanged(BLOCKED_REASON_NONE); - cellNetworkCallback.assertNoCallback(); - detailedCallback.assertNoCallback(); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertExtraInfoFromCmPresent(mCellNetworkAgent); - - mCm.unregisterNetworkCallback(cellNetworkCallback); - } - - @Test - public void testNetworkBlockedStatusBeforeAndAfterConnect() throws Exception { - final TestNetworkCallback defaultCallback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(defaultCallback); - mockUidNetworkingBlocked(); - - // No Networkcallbacks invoked before any network is active. - setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER); - setBlockedReasonChanged(BLOCKED_REASON_NONE); - setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); - defaultCallback.assertNoCallback(); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); - defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mCellNetworkAgent); - - // Allow to use the network after switching to NOT_METERED network. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - mWiFiNetworkAgent.connect(true); - defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - - // Switch to METERED network. Restrict the use of the network. - mWiFiNetworkAgent.disconnect(); - defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - defaultCallback.expectAvailableCallbacksValidatedAndBlocked(mCellNetworkAgent); - - // Network becomes NOT_METERED. - mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); - defaultCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); - - // Verify there's no Networkcallbacks invoked after data saver on/off. - setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER); - setBlockedReasonChanged(BLOCKED_REASON_NONE); - defaultCallback.assertNoCallback(); - - mCellNetworkAgent.disconnect(); - defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - defaultCallback.assertNoCallback(); - - mCm.unregisterNetworkCallback(defaultCallback); - } - - private void expectNetworkRejectNonSecureVpn(InOrder inOrder, boolean add, - UidRangeParcel... expected) throws Exception { - inOrder.verify(mMockNetd).networkRejectNonSecureVpn(eq(add), aryEq(expected)); - } - - private void checkNetworkInfo(NetworkInfo ni, int type, DetailedState state) { - assertNotNull(ni); - assertEquals(type, ni.getType()); - assertEquals(ConnectivityManager.getNetworkTypeName(type), state, ni.getDetailedState()); - if (state == DetailedState.CONNECTED || state == DetailedState.SUSPENDED) { - assertNotNull(ni.getExtraInfo()); - } else { - // Technically speaking, a network that's in CONNECTING state will generally have a - // non-null extraInfo. This doesn't actually happen in this test because it never calls - // a legacy API while a network is connecting. When a network is in CONNECTING state - // because of legacy lockdown VPN, its extraInfo is always null. - assertNull(ni.getExtraInfo()); - } - } - - private void assertActiveNetworkInfo(int type, DetailedState state) { - checkNetworkInfo(mCm.getActiveNetworkInfo(), type, state); - } - private void assertNetworkInfo(int type, DetailedState state) { - checkNetworkInfo(mCm.getNetworkInfo(type), type, state); - } - - private void assertExtraInfoFromCm(TestNetworkAgentWrapper network, boolean present) { - final NetworkInfo niForNetwork = mCm.getNetworkInfo(network.getNetwork()); - final NetworkInfo niForType = mCm.getNetworkInfo(network.getLegacyType()); - if (present) { - assertEquals(network.getExtraInfo(), niForNetwork.getExtraInfo()); - assertEquals(network.getExtraInfo(), niForType.getExtraInfo()); - } else { - assertNull(niForNetwork.getExtraInfo()); - assertNull(niForType.getExtraInfo()); - } - } - - private void assertExtraInfoFromCmBlocked(TestNetworkAgentWrapper network) { - assertExtraInfoFromCm(network, false); - } - - private void assertExtraInfoFromCmPresent(TestNetworkAgentWrapper network) { - assertExtraInfoFromCm(network, true); - } - - // Checks that each of the |agents| receive a blocked status change callback with the specified - // |blocked| value, in any order. This is needed because when an event affects multiple - // networks, ConnectivityService does not guarantee the order in which callbacks are fired. - private void assertBlockedCallbackInAnyOrder(TestNetworkCallback callback, boolean blocked, - TestNetworkAgentWrapper... agents) { - final List<Network> expectedNetworks = Arrays.asList(agents).stream() - .map((agent) -> agent.getNetwork()) - .collect(Collectors.toList()); - - // Expect exactly one blocked callback for each agent. - for (int i = 0; i < agents.length; i++) { - CallbackEntry e = callback.expectCallbackThat(TIMEOUT_MS, (c) -> - c instanceof CallbackEntry.BlockedStatus - && ((CallbackEntry.BlockedStatus) c).getBlocked() == blocked); - Network network = e.getNetwork(); - assertTrue("Received unexpected blocked callback for network " + network, - expectedNetworks.remove(network)); - } - } - - @Test - public void testNetworkBlockedStatusAlwaysOnVpn() throws Exception { - mServiceContext.setPermission( - Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED); - mServiceContext.setPermission( - Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); - - final TestNetworkCallback callback = new TestNetworkCallback(); - final NetworkRequest request = new NetworkRequest.Builder() - .removeCapability(NET_CAPABILITY_NOT_VPN) - .build(); - mCm.registerNetworkCallback(request, callback); - - final TestNetworkCallback defaultCallback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(defaultCallback); - - final TestNetworkCallback vpnUidCallback = new TestNetworkCallback(); - final NetworkRequest vpnUidRequest = new NetworkRequest.Builder().build(); - registerNetworkCallbackAsUid(vpnUidRequest, vpnUidCallback, VPN_UID); - - final TestNetworkCallback vpnUidDefaultCallback = new TestNetworkCallback(); - registerDefaultNetworkCallbackAsUid(vpnUidDefaultCallback, VPN_UID); - - final TestNetworkCallback vpnDefaultCallbackAsUid = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallbackForUid(VPN_UID, vpnDefaultCallbackAsUid, - new Handler(ConnectivityThread.getInstanceLooper())); - - final int uid = Process.myUid(); - final int userId = UserHandle.getUserId(uid); - final ArrayList<String> allowList = new ArrayList<>(); - mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, - allowList); - waitForIdle(); - - UidRangeParcel firstHalf = new UidRangeParcel(1, VPN_UID - 1); - UidRangeParcel secondHalf = new UidRangeParcel(VPN_UID + 1, 99999); - InOrder inOrder = inOrder(mMockNetd); - expectNetworkRejectNonSecureVpn(inOrder, true, firstHalf, secondHalf); - - // Connect a network when lockdown is active, expect to see it blocked. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(false /* validated */); - callback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent); - defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent); - vpnUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - vpnUidDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - vpnDefaultCallbackAsUid.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); - assertNull(mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); - // Mobile is BLOCKED even though it's not actually connected. - assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); - - // Disable lockdown, expect to see the network unblocked. - mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList); - callback.expectBlockedStatusCallback(false, mWiFiNetworkAgent); - defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent); - vpnUidCallback.assertNoCallback(); - vpnUidDefaultCallback.assertNoCallback(); - vpnDefaultCallbackAsUid.assertNoCallback(); - expectNetworkRejectNonSecureVpn(inOrder, false, firstHalf, secondHalf); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - - // Add our UID to the allowlist and re-enable lockdown, expect network is not blocked. - allowList.add(TEST_PACKAGE_NAME); - mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, - allowList); - callback.assertNoCallback(); - defaultCallback.assertNoCallback(); - vpnUidCallback.assertNoCallback(); - vpnUidDefaultCallback.assertNoCallback(); - vpnDefaultCallbackAsUid.assertNoCallback(); - - // The following requires that the UID of this test package is greater than VPN_UID. This - // is always true in practice because a plain AOSP build with no apps installed has almost - // 200 packages installed. - final UidRangeParcel piece1 = new UidRangeParcel(1, VPN_UID - 1); - final UidRangeParcel piece2 = new UidRangeParcel(VPN_UID + 1, uid - 1); - final UidRangeParcel piece3 = new UidRangeParcel(uid + 1, 99999); - expectNetworkRejectNonSecureVpn(inOrder, true, piece1, piece2, piece3); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - - // Connect a new network, expect it to be unblocked. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(false /* validated */); - callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - defaultCallback.assertNoCallback(); - vpnUidCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - vpnUidDefaultCallback.assertNoCallback(); - vpnDefaultCallbackAsUid.assertNoCallback(); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - // Cellular is DISCONNECTED because it's not the default and there are no requests for it. - assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - - // Disable lockdown, remove our UID from the allowlist, and re-enable lockdown. - // Everything should now be blocked. - mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList); - waitForIdle(); - expectNetworkRejectNonSecureVpn(inOrder, false, piece1, piece2, piece3); - allowList.clear(); - mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, - allowList); - waitForIdle(); - expectNetworkRejectNonSecureVpn(inOrder, true, firstHalf, secondHalf); - defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent); - assertBlockedCallbackInAnyOrder(callback, true, mWiFiNetworkAgent, mCellNetworkAgent); - vpnUidCallback.assertNoCallback(); - vpnUidDefaultCallback.assertNoCallback(); - vpnDefaultCallbackAsUid.assertNoCallback(); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); - assertNull(mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); - - // Disable lockdown. Everything is unblocked. - mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList); - defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent); - assertBlockedCallbackInAnyOrder(callback, false, mWiFiNetworkAgent, mCellNetworkAgent); - vpnUidCallback.assertNoCallback(); - vpnUidDefaultCallback.assertNoCallback(); - vpnDefaultCallbackAsUid.assertNoCallback(); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - - // Enable and disable an always-on VPN package without lockdown. Expect no changes. - reset(mMockNetd); - mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, false /* lockdown */, - allowList); - inOrder.verify(mMockNetd, never()).networkRejectNonSecureVpn(anyBoolean(), any()); - callback.assertNoCallback(); - defaultCallback.assertNoCallback(); - vpnUidCallback.assertNoCallback(); - vpnUidDefaultCallback.assertNoCallback(); - vpnDefaultCallbackAsUid.assertNoCallback(); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - - mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList); - inOrder.verify(mMockNetd, never()).networkRejectNonSecureVpn(anyBoolean(), any()); - callback.assertNoCallback(); - defaultCallback.assertNoCallback(); - vpnUidCallback.assertNoCallback(); - vpnUidDefaultCallback.assertNoCallback(); - vpnDefaultCallbackAsUid.assertNoCallback(); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - - // Enable lockdown and connect a VPN. The VPN is not blocked. - mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, - allowList); - defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent); - assertBlockedCallbackInAnyOrder(callback, true, mWiFiNetworkAgent, mCellNetworkAgent); - vpnUidCallback.assertNoCallback(); - vpnUidDefaultCallback.assertNoCallback(); - vpnDefaultCallbackAsUid.assertNoCallback(); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); - assertNull(mCm.getActiveNetwork()); - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); - - mMockVpn.establishForMyUid(); - assertUidRangesUpdatedForMyUid(true); - defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); - vpnUidCallback.assertNoCallback(); // vpnUidCallback has NOT_VPN capability. - vpnUidDefaultCallback.assertNoCallback(); // VPN does not apply to VPN_UID - vpnDefaultCallbackAsUid.assertNoCallback(); - assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork()); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID)); - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - - mMockVpn.disconnect(); - defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn); - defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent); - vpnUidCallback.assertNoCallback(); - vpnUidDefaultCallback.assertNoCallback(); - vpnDefaultCallbackAsUid.assertNoCallback(); - assertNull(mCm.getActiveNetwork()); - - mCm.unregisterNetworkCallback(callback); - mCm.unregisterNetworkCallback(defaultCallback); - mCm.unregisterNetworkCallback(vpnUidCallback); - mCm.unregisterNetworkCallback(vpnUidDefaultCallback); - mCm.unregisterNetworkCallback(vpnDefaultCallbackAsUid); - } - - private void setupLegacyLockdownVpn() { - final String profileName = "testVpnProfile"; - final byte[] profileTag = profileName.getBytes(StandardCharsets.UTF_8); - when(mVpnProfileStore.get(Credentials.LOCKDOWN_VPN)).thenReturn(profileTag); - - final VpnProfile profile = new VpnProfile(profileName); - profile.name = "My VPN"; - profile.server = "192.0.2.1"; - profile.dnsServers = "8.8.8.8"; - profile.type = VpnProfile.TYPE_IPSEC_XAUTH_PSK; - final byte[] encodedProfile = profile.encode(); - when(mVpnProfileStore.get(Credentials.VPN + profileName)).thenReturn(encodedProfile); - } - - private void establishLegacyLockdownVpn(Network underlying) throws Exception { - // The legacy lockdown VPN only supports userId 0, and must have an underlying network. - assertNotNull(underlying); - mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY); - // The legacy lockdown VPN only supports userId 0. - final Set<UidRange> ranges = Collections.singleton(PRIMARY_UIDRANGE); - mMockVpn.registerAgent(ranges); - mMockVpn.setUnderlyingNetworks(new Network[]{underlying}); - mMockVpn.connect(true); - } - - @Test - public void testLegacyLockdownVpn() throws Exception { - mServiceContext.setPermission( - Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED); - // For LockdownVpnTracker to call registerSystemDefaultNetworkCallback. - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); - - final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, callback); - - final TestNetworkCallback defaultCallback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(defaultCallback); - - final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback(); - mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback, - new Handler(ConnectivityThread.getInstanceLooper())); - - // Pretend lockdown VPN was configured. - setupLegacyLockdownVpn(); - - // LockdownVpnTracker disables the Vpn teardown code and enables lockdown. - // Check the VPN's state before it does so. - assertTrue(mMockVpn.getEnableTeardown()); - assertFalse(mMockVpn.getLockdown()); - - // Send a USER_UNLOCKED broadcast so CS starts LockdownVpnTracker. - final int userId = UserHandle.getUserId(Process.myUid()); - final Intent addedIntent = new Intent(ACTION_USER_UNLOCKED); - addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId)); - addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); - processBroadcast(addedIntent); - - // Lockdown VPN disables teardown and enables lockdown. - assertFalse(mMockVpn.getEnableTeardown()); - assertTrue(mMockVpn.getLockdown()); - - // Bring up a network. - // Expect nothing to happen because the network does not have an IPv4 default route: legacy - // VPN only supports IPv4. - final LinkProperties cellLp = new LinkProperties(); - cellLp.setInterfaceName("rmnet0"); - cellLp.addLinkAddress(new LinkAddress("2001:db8::1/64")); - cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, "rmnet0")); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); - mCellNetworkAgent.connect(false /* validated */); - callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); - defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); - systemDefaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); - waitForIdle(); - assertNull(mMockVpn.getAgent()); - - // Add an IPv4 address. Ideally the VPN should start, but it doesn't because nothing calls - // LockdownVpnTracker#handleStateChangedLocked. This is a bug. - // TODO: consider fixing this. - cellLp.addLinkAddress(new LinkAddress("192.0.2.2/25")); - cellLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "rmnet0")); - mCellNetworkAgent.sendLinkProperties(cellLp); - callback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); - defaultCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); - systemDefaultCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, - mCellNetworkAgent); - waitForIdle(); - assertNull(mMockVpn.getAgent()); - - // Disconnect, then try again with a network that supports IPv4 at connection time. - // Expect lockdown VPN to come up. - ExpectedBroadcast b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); - mCellNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - systemDefaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - b1.expectBroadcast(); - - // When lockdown VPN is active, the NetworkInfo state in CONNECTIVITY_ACTION is overwritten - // with the state of the VPN network. So expect a CONNECTING broadcast. - b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTING); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); - mCellNetworkAgent.connect(false /* validated */); - callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); - defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); - systemDefaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent); - b1.expectBroadcast(); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED); - assertExtraInfoFromCmBlocked(mCellNetworkAgent); - - // TODO: it would be nice if we could simply rely on the production code here, and have - // LockdownVpnTracker start the VPN, have the VPN code register its NetworkAgent with - // ConnectivityService, etc. That would require duplicating a fair bit of code from the - // Vpn tests around how to mock out LegacyVpnRunner. But even if we did that, this does not - // work for at least two reasons: - // 1. In this test, calling registerNetworkAgent does not actually result in an agent being - // registered. This is because nothing calls onNetworkMonitorCreated, which is what - // actually ends up causing handleRegisterNetworkAgent to be called. Code in this test - // that wants to register an agent must use TestNetworkAgentWrapper. - // 2. Even if we exposed Vpn#agentConnect to the test, and made MockVpn#agentConnect call - // the TestNetworkAgentWrapper code, this would deadlock because the - // TestNetworkAgentWrapper code cannot be called on the handler thread since it calls - // waitForIdle(). - mMockVpn.expectStartLegacyVpnRunner(); - b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED); - ExpectedBroadcast b2 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED); - establishLegacyLockdownVpn(mCellNetworkAgent.getNetwork()); - callback.expectAvailableThenValidatedCallbacks(mMockVpn); - defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); - systemDefaultCallback.assertNoCallback(); - NetworkCapabilities vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); - b1.expectBroadcast(); - b2.expectBroadcast(); - assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); - assertExtraInfoFromCmPresent(mCellNetworkAgent); - assertTrue(vpnNc.hasTransport(TRANSPORT_VPN)); - assertTrue(vpnNc.hasTransport(TRANSPORT_CELLULAR)); - assertFalse(vpnNc.hasTransport(TRANSPORT_WIFI)); - assertFalse(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED)); - assertVpnTransportInfo(vpnNc, VpnManager.TYPE_VPN_LEGACY); - - // Switch default network from cell to wifi. Expect VPN to disconnect and reconnect. - final LinkProperties wifiLp = new LinkProperties(); - wifiLp.setInterfaceName("wlan0"); - wifiLp.addLinkAddress(new LinkAddress("192.0.2.163/25")); - wifiLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "wlan0")); - final NetworkCapabilities wifiNc = new NetworkCapabilities(); - wifiNc.addTransportType(TRANSPORT_WIFI); - wifiNc.addCapability(NET_CAPABILITY_NOT_METERED); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc); - - b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED); - // Wifi is CONNECTING because the VPN isn't up yet. - b2 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTING); - ExpectedBroadcast b3 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED); - mWiFiNetworkAgent.connect(false /* validated */); - b1.expectBroadcast(); - b2.expectBroadcast(); - b3.expectBroadcast(); - mMockVpn.expectStopVpnRunnerPrivileged(); - mMockVpn.expectStartLegacyVpnRunner(); - - // TODO: why is wifi not blocked? Is it because when this callback is sent, the VPN is still - // connected, so the network is not considered blocked by the lockdown UID ranges? But the - // fact that a VPN is connected should only result in the VPN itself being unblocked, not - // any other network. Bug in isUidBlockedByVpn? - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - callback.expectCallback(CallbackEntry.LOST, mMockVpn); - defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn); - defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent); - systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - - // While the VPN is reconnecting on the new network, everything is blocked. - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED); - assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED); - assertExtraInfoFromCmBlocked(mWiFiNetworkAgent); - - // The VPN comes up again on wifi. - b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED); - b2 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED); - establishLegacyLockdownVpn(mWiFiNetworkAgent.getNetwork()); - callback.expectAvailableThenValidatedCallbacks(mMockVpn); - defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); - systemDefaultCallback.assertNoCallback(); - b1.expectBroadcast(); - b2.expectBroadcast(); - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); - assertExtraInfoFromCmPresent(mWiFiNetworkAgent); - vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); - assertTrue(vpnNc.hasTransport(TRANSPORT_VPN)); - assertTrue(vpnNc.hasTransport(TRANSPORT_WIFI)); - assertFalse(vpnNc.hasTransport(TRANSPORT_CELLULAR)); - assertTrue(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED)); - - // Disconnect cell. Nothing much happens since it's not the default network. - mCellNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - defaultCallback.assertNoCallback(); - systemDefaultCallback.assertNoCallback(); - - assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED); - assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED); - assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED); - assertExtraInfoFromCmPresent(mWiFiNetworkAgent); - - b1 = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); - b2 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED); - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - b1.expectBroadcast(); - callback.expectCapabilitiesThat(mMockVpn, nc -> !nc.hasTransport(TRANSPORT_WIFI)); - mMockVpn.expectStopVpnRunnerPrivileged(); - callback.expectCallback(CallbackEntry.LOST, mMockVpn); - b2.expectBroadcast(); - } - - /** - * Test mutable and requestable network capabilities such as - * {@link NetworkCapabilities#NET_CAPABILITY_TRUSTED} and - * {@link NetworkCapabilities#NET_CAPABILITY_NOT_VCN_MANAGED}. Verify that the - * {@code ConnectivityService} re-assign the networks accordingly. - */ - @Test - public final void testLoseMutableAndRequestableCaps() throws Exception { - final int[] testCaps = new int [] { - NET_CAPABILITY_TRUSTED, - NET_CAPABILITY_NOT_VCN_MANAGED - }; - for (final int testCap : testCaps) { - // Create requests with and without the testing capability. - final TestNetworkCallback callbackWithCap = new TestNetworkCallback(); - final TestNetworkCallback callbackWithoutCap = new TestNetworkCallback(); - mCm.requestNetwork(new NetworkRequest.Builder().addCapability(testCap).build(), - callbackWithCap); - mCm.requestNetwork(new NetworkRequest.Builder().removeCapability(testCap).build(), - callbackWithoutCap); - - // Setup networks with testing capability and verify the default network changes. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.addCapability(testCap); - mCellNetworkAgent.connect(true); - callbackWithCap.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - callbackWithoutCap.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId)); - reset(mMockNetd); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.addCapability(testCap); - mWiFiNetworkAgent.connect(true); - callbackWithCap.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - callbackWithoutCap.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - verify(mMockNetd).networkSetDefault(eq(mWiFiNetworkAgent.getNetwork().netId)); - reset(mMockNetd); - - // Remove the testing capability on wifi, verify the callback and default network - // changes back to cellular. - mWiFiNetworkAgent.removeCapability(testCap); - callbackWithCap.expectAvailableCallbacksValidated(mCellNetworkAgent); - callbackWithoutCap.expectCapabilitiesWithout(testCap, mWiFiNetworkAgent); - verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId)); - reset(mMockNetd); - - mCellNetworkAgent.removeCapability(testCap); - callbackWithCap.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - callbackWithoutCap.assertNoCallback(); - verify(mMockNetd).networkClearDefault(); - - mCm.unregisterNetworkCallback(callbackWithCap); - mCm.unregisterNetworkCallback(callbackWithoutCap); - } - } - - @Test - public final void testBatteryStatsNetworkType() throws Exception { - final LinkProperties cellLp = new LinkProperties(); - cellLp.setInterfaceName("cell0"); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); - mCellNetworkAgent.connect(true); - waitForIdle(); - verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext, - cellLp.getInterfaceName(), - new int[] { TRANSPORT_CELLULAR }); - - final LinkProperties wifiLp = new LinkProperties(); - wifiLp.setInterfaceName("wifi0"); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp); - mWiFiNetworkAgent.connect(true); - waitForIdle(); - verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext, - wifiLp.getInterfaceName(), - new int[] { TRANSPORT_WIFI }); - - mCellNetworkAgent.disconnect(); - mWiFiNetworkAgent.disconnect(); - - cellLp.setInterfaceName("wifi0"); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); - mCellNetworkAgent.connect(true); - waitForIdle(); - verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext, - cellLp.getInterfaceName(), - new int[] { TRANSPORT_CELLULAR }); - mCellNetworkAgent.disconnect(); - } - - /** - * Make simulated InterfaceConfigParcel for Nat464Xlat to query clat lower layer info. - */ - private InterfaceConfigurationParcel getClatInterfaceConfigParcel(LinkAddress la) { - final InterfaceConfigurationParcel cfg = new InterfaceConfigurationParcel(); - cfg.hwAddr = "11:22:33:44:55:66"; - cfg.ipv4Addr = la.getAddress().getHostAddress(); - cfg.prefixLength = la.getPrefixLength(); - return cfg; - } - - /** - * Make expected stack link properties, copied from Nat464Xlat. - */ - private LinkProperties makeClatLinkProperties(LinkAddress la) { - LinkAddress clatAddress = la; - LinkProperties stacked = new LinkProperties(); - stacked.setInterfaceName(CLAT_PREFIX + MOBILE_IFNAME); - RouteInfo ipv4Default = new RouteInfo( - new LinkAddress(Inet4Address.ANY, 0), - clatAddress.getAddress(), CLAT_PREFIX + MOBILE_IFNAME); - stacked.addRoute(ipv4Default); - stacked.addLinkAddress(clatAddress); - return stacked; - } - - private Nat64PrefixEventParcel makeNat64PrefixEvent(final int netId, final int prefixOperation, - final String prefixAddress, final int prefixLength) { - final Nat64PrefixEventParcel event = new Nat64PrefixEventParcel(); - event.netId = netId; - event.prefixOperation = prefixOperation; - event.prefixAddress = prefixAddress; - event.prefixLength = prefixLength; - return event; - } - - @Test - public void testStackedLinkProperties() throws Exception { - final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24"); - final LinkAddress myIpv6 = new LinkAddress("2001:db8:1::1/64"); - final String kNat64PrefixString = "2001:db8:64:64:64:64::"; - final IpPrefix kNat64Prefix = new IpPrefix(InetAddress.getByName(kNat64PrefixString), 96); - final String kOtherNat64PrefixString = "64:ff9b::"; - final IpPrefix kOtherNat64Prefix = new IpPrefix( - InetAddress.getByName(kOtherNat64PrefixString), 96); - final RouteInfo defaultRoute = new RouteInfo((IpPrefix) null, myIpv6.getAddress(), - MOBILE_IFNAME); - final RouteInfo ipv6Subnet = new RouteInfo(myIpv6, null, MOBILE_IFNAME); - final RouteInfo ipv4Subnet = new RouteInfo(myIpv4, null, MOBILE_IFNAME); - final RouteInfo stackedDefault = new RouteInfo((IpPrefix) null, myIpv4.getAddress(), - CLAT_PREFIX + MOBILE_IFNAME); - - final NetworkRequest networkRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR) - .addCapability(NET_CAPABILITY_INTERNET) - .build(); - final TestNetworkCallback networkCallback = new TestNetworkCallback(); - mCm.registerNetworkCallback(networkRequest, networkCallback); - - // Prepare ipv6 only link properties. - final LinkProperties cellLp = new LinkProperties(); - cellLp.setInterfaceName(MOBILE_IFNAME); - cellLp.addLinkAddress(myIpv6); - cellLp.addRoute(defaultRoute); - cellLp.addRoute(ipv6Subnet); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp); - reset(mMockDnsResolver); - reset(mMockNetd); - - // Connect with ipv6 link properties. Expect prefix discovery to be started. - mCellNetworkAgent.connect(true); - final int cellNetId = mCellNetworkAgent.getNetwork().netId; - waitForIdle(); - - verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical(cellNetId, - INetd.PERMISSION_NONE)); - assertRoutesAdded(cellNetId, ipv6Subnet, defaultRoute); - verify(mMockDnsResolver, times(1)).createNetworkCache(eq(cellNetId)); - verify(mMockNetd, times(1)).networkAddInterface(cellNetId, MOBILE_IFNAME); - verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext, - cellLp.getInterfaceName(), - new int[] { TRANSPORT_CELLULAR }); - - networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); - - // Switching default network updates TCP buffer sizes. - verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); - // Add an IPv4 address. Expect prefix discovery to be stopped. Netd doesn't tell us that - // the NAT64 prefix was removed because one was never discovered. - cellLp.addLinkAddress(myIpv4); - mCellNetworkAgent.sendLinkProperties(cellLp); - networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); - assertRoutesAdded(cellNetId, ipv4Subnet); - verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); - verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any()); - - // Make sure BatteryStats was not told about any v4- interfaces, as none should have - // come online yet. - waitForIdle(); - verify(mDeps, never()) - .reportNetworkInterfaceForTransports(eq(mServiceContext), startsWith("v4-"), any()); - - verifyNoMoreInteractions(mMockNetd); - verifyNoMoreInteractions(mMockDnsResolver); - reset(mMockNetd); - reset(mMockDnsResolver); - when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME)) - .thenReturn(getClatInterfaceConfigParcel(myIpv4)); - - // Remove IPv4 address. Expect prefix discovery to be started again. - cellLp.removeLinkAddress(myIpv4); - mCellNetworkAgent.sendLinkProperties(cellLp); - networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); - verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); - assertRoutesRemoved(cellNetId, ipv4Subnet); - - // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started. - Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent); - assertNull(mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getNat64Prefix()); - mService.mResolverUnsolEventCallback.onNat64PrefixEvent( - makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); - LinkProperties lpBeforeClat = networkCallback.expectCallback( - CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent).getLp(); - assertEquals(0, lpBeforeClat.getStackedLinks().size()); - assertEquals(kNat64Prefix, lpBeforeClat.getNat64Prefix()); - verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString()); - - // Clat iface comes up. Expect stacked link to be added. - clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true); - networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); - List<LinkProperties> stackedLps = mCm.getLinkProperties(mCellNetworkAgent.getNetwork()) - .getStackedLinks(); - assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0)); - assertRoutesAdded(cellNetId, stackedDefault); - verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); - // Change trivial linkproperties and see if stacked link is preserved. - cellLp.addDnsServer(InetAddress.getByName("8.8.8.8")); - mCellNetworkAgent.sendLinkProperties(cellLp); - networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); - - List<LinkProperties> stackedLpsAfterChange = - mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getStackedLinks(); - assertNotEquals(stackedLpsAfterChange, Collections.EMPTY_LIST); - assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0)); - - verify(mMockDnsResolver, times(1)).setResolverConfiguration( - mResolverParamsParcelCaptor.capture()); - ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue(); - assertEquals(1, resolvrParams.servers.length); - assertTrue(ArrayUtils.contains(resolvrParams.servers, "8.8.8.8")); - - for (final LinkProperties stackedLp : stackedLpsAfterChange) { - verify(mDeps).reportNetworkInterfaceForTransports( - mServiceContext, stackedLp.getInterfaceName(), - new int[] { TRANSPORT_CELLULAR }); - } - reset(mMockNetd); - when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME)) - .thenReturn(getClatInterfaceConfigParcel(myIpv4)); - // Change the NAT64 prefix without first removing it. - // Expect clatd to be stopped and started with the new prefix. - mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( - cellNetId, PREFIX_OPERATION_ADDED, kOtherNat64PrefixString, 96)); - networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, - (lp) -> lp.getStackedLinks().size() == 0); - verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); - assertRoutesRemoved(cellNetId, stackedDefault); - verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); - - verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kOtherNat64Prefix.toString()); - networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, - (lp) -> lp.getNat64Prefix().equals(kOtherNat64Prefix)); - clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true); - networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, - (lp) -> lp.getStackedLinks().size() == 1); - assertRoutesAdded(cellNetId, stackedDefault); - verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); - reset(mMockNetd); - - // Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked - // linkproperties are cleaned up. - cellLp.addLinkAddress(myIpv4); - cellLp.addRoute(ipv4Subnet); - mCellNetworkAgent.sendLinkProperties(cellLp); - networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); - assertRoutesAdded(cellNetId, ipv4Subnet); - verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); - verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); - - // As soon as stop is called, the linkproperties lose the stacked interface. - networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); - LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellNetworkAgent.getNetwork()); - LinkProperties expected = new LinkProperties(cellLp); - expected.setNat64Prefix(kOtherNat64Prefix); - assertEquals(expected, actualLpAfterIpv4); - assertEquals(0, actualLpAfterIpv4.getStackedLinks().size()); - assertRoutesRemoved(cellNetId, stackedDefault); - - // The interface removed callback happens but has no effect after stop is called. - clat.interfaceRemoved(CLAT_PREFIX + MOBILE_IFNAME); - networkCallback.assertNoCallback(); - verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); - verifyNoMoreInteractions(mMockNetd); - verifyNoMoreInteractions(mMockDnsResolver); - reset(mMockNetd); - reset(mMockDnsResolver); - when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME)) - .thenReturn(getClatInterfaceConfigParcel(myIpv4)); - - // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone. - mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( - cellNetId, PREFIX_OPERATION_REMOVED, kOtherNat64PrefixString, 96)); - networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, - (lp) -> lp.getNat64Prefix() == null); - - // Remove IPv4 address and expect prefix discovery and clatd to be started again. - cellLp.removeLinkAddress(myIpv4); - cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME)); - cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8")); - mCellNetworkAgent.sendLinkProperties(cellLp); - networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); - assertRoutesRemoved(cellNetId, ipv4Subnet); // Directly-connected routes auto-added. - verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); - mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( - cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96)); - networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); - verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString()); - - // Clat iface comes up. Expect stacked link to be added. - clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true); - networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, - (lp) -> lp.getStackedLinks().size() == 1 && lp.getNat64Prefix() != null); - assertRoutesAdded(cellNetId, stackedDefault); - verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); - - // NAT64 prefix is removed. Expect that clat is stopped. - mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent( - cellNetId, PREFIX_OPERATION_REMOVED, kNat64PrefixString, 96)); - networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, - (lp) -> lp.getStackedLinks().size() == 0 && lp.getNat64Prefix() == null); - assertRoutesRemoved(cellNetId, ipv4Subnet, stackedDefault); - - // Stop has no effect because clat is already stopped. - verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); - networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, - (lp) -> lp.getStackedLinks().size() == 0); - verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); - verify(mMockNetd, times(1)).interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME); - verifyNoMoreInteractions(mMockNetd); - // Clean up. - mCellNetworkAgent.disconnect(); - networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - networkCallback.assertNoCallback(); - mCm.unregisterNetworkCallback(networkCallback); - } - - private void expectNat64PrefixChange(TestableNetworkCallback callback, - TestNetworkAgentWrapper agent, IpPrefix prefix) { - callback.expectLinkPropertiesThat(agent, x -> Objects.equals(x.getNat64Prefix(), prefix)); - } - - @Test - public void testNat64PrefixMultipleSources() throws Exception { - final String iface = "wlan0"; - final String pref64FromRaStr = "64:ff9b::"; - final String pref64FromDnsStr = "2001:db8:64::"; - final IpPrefix pref64FromRa = new IpPrefix(InetAddress.getByName(pref64FromRaStr), 96); - final IpPrefix pref64FromDns = new IpPrefix(InetAddress.getByName(pref64FromDnsStr), 96); - final IpPrefix newPref64FromRa = new IpPrefix("2001:db8:64:64:64:64::/96"); - - final NetworkRequest request = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_INTERNET) - .build(); - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, callback); - - final LinkProperties baseLp = new LinkProperties(); - baseLp.setInterfaceName(iface); - baseLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); - baseLp.addDnsServer(InetAddress.getByName("2001:4860:4860::6464")); - - reset(mMockNetd, mMockDnsResolver); - InOrder inOrder = inOrder(mMockNetd, mMockDnsResolver); - - // If a network already has a NAT64 prefix on connect, clatd is started immediately and - // prefix discovery is never started. - LinkProperties lp = new LinkProperties(baseLp); - lp.setNat64Prefix(pref64FromRa); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp); - mWiFiNetworkAgent.connect(false); - final Network network = mWiFiNetworkAgent.getNetwork(); - int netId = network.getNetId(); - callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString()); - inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); - inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); - callback.assertNoCallback(); - assertEquals(pref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); - - // If the RA prefix is withdrawn, clatd is stopped and prefix discovery is started. - lp.setNat64Prefix(null); - mWiFiNetworkAgent.sendLinkProperties(lp); - expectNat64PrefixChange(callback, mWiFiNetworkAgent, null); - inOrder.verify(mMockNetd).clatdStop(iface); - inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); - inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); - - // If the RA prefix appears while DNS discovery is in progress, discovery is stopped and - // clatd is started with the prefix from the RA. - lp.setNat64Prefix(pref64FromRa); - mWiFiNetworkAgent.sendLinkProperties(lp); - expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromRa); - inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString()); - inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); - inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); - - // Withdraw the RA prefix so we can test the case where an RA prefix appears after DNS - // discovery has succeeded. - lp.setNat64Prefix(null); - mWiFiNetworkAgent.sendLinkProperties(lp); - expectNat64PrefixChange(callback, mWiFiNetworkAgent, null); - inOrder.verify(mMockNetd).clatdStop(iface); - inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); - inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); - - mService.mResolverUnsolEventCallback.onNat64PrefixEvent( - makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); - expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns); - inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString()); - - // If an RA advertises the same prefix that was discovered by DNS, nothing happens: prefix - // discovery is not stopped, and there are no callbacks. - lp.setNat64Prefix(pref64FromDns); - mWiFiNetworkAgent.sendLinkProperties(lp); - callback.assertNoCallback(); - inOrder.verify(mMockNetd, never()).clatdStop(iface); - inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString()); - inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); - inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); - inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); - - // If the RA is later withdrawn, nothing happens again. - lp.setNat64Prefix(null); - mWiFiNetworkAgent.sendLinkProperties(lp); - callback.assertNoCallback(); - inOrder.verify(mMockNetd, never()).clatdStop(iface); - inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString()); - inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); - inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); - inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); - - // If the RA prefix changes, clatd is restarted and prefix discovery is stopped. - lp.setNat64Prefix(pref64FromRa); - mWiFiNetworkAgent.sendLinkProperties(lp); - expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromRa); - inOrder.verify(mMockNetd).clatdStop(iface); - inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); - - // Stopping prefix discovery results in a prefix removed notification. - mService.mResolverUnsolEventCallback.onNat64PrefixEvent( - makeNat64PrefixEvent(netId, PREFIX_OPERATION_REMOVED, pref64FromDnsStr, 96)); - - inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString()); - inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString()); - inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); - - // If the RA prefix changes, clatd is restarted and prefix discovery is not started. - lp.setNat64Prefix(newPref64FromRa); - mWiFiNetworkAgent.sendLinkProperties(lp); - expectNat64PrefixChange(callback, mWiFiNetworkAgent, newPref64FromRa); - inOrder.verify(mMockNetd).clatdStop(iface); - inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); - inOrder.verify(mMockNetd).clatdStart(iface, newPref64FromRa.toString()); - inOrder.verify(mMockDnsResolver).setPrefix64(netId, newPref64FromRa.toString()); - inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); - inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); - - // If the RA prefix changes to the same value, nothing happens. - lp.setNat64Prefix(newPref64FromRa); - mWiFiNetworkAgent.sendLinkProperties(lp); - callback.assertNoCallback(); - assertEquals(newPref64FromRa, mCm.getLinkProperties(network).getNat64Prefix()); - inOrder.verify(mMockNetd, never()).clatdStop(iface); - inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString()); - inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); - inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); - inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); - - // The transition between no prefix and DNS prefix is tested in testStackedLinkProperties. - - // If the same prefix is learned first by DNS and then by RA, and clat is later stopped, - // (e.g., because the network disconnects) setPrefix64(netid, "") is never called. - lp.setNat64Prefix(null); - mWiFiNetworkAgent.sendLinkProperties(lp); - expectNat64PrefixChange(callback, mWiFiNetworkAgent, null); - inOrder.verify(mMockNetd).clatdStop(iface); - inOrder.verify(mMockDnsResolver).setPrefix64(netId, ""); - inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId); - mService.mResolverUnsolEventCallback.onNat64PrefixEvent( - makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96)); - expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns); - inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString()); - inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), any()); - - lp.setNat64Prefix(pref64FromDns); - mWiFiNetworkAgent.sendLinkProperties(lp); - callback.assertNoCallback(); - inOrder.verify(mMockNetd, never()).clatdStop(iface); - inOrder.verify(mMockNetd, never()).clatdStart(eq(iface), anyString()); - inOrder.verify(mMockDnsResolver, never()).stopPrefix64Discovery(netId); - inOrder.verify(mMockDnsResolver, never()).startPrefix64Discovery(netId); - inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); - - // When tearing down a network, clat state is only updated after CALLBACK_LOST is fired, but - // before CONNECTIVITY_ACTION is sent. Wait for CONNECTIVITY_ACTION before verifying that - // clat has been stopped, or the test will be flaky. - ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); - mWiFiNetworkAgent.disconnect(); - callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - b.expectBroadcast(); - - inOrder.verify(mMockNetd).clatdStop(iface); - inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId); - inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), anyString()); - - mCm.unregisterNetworkCallback(callback); - } - - @Test - public void testWith464XlatDisable() throws Exception { - doReturn(false).when(mDeps).getCellular464XlatEnabled(); - - final TestNetworkCallback callback = new TestNetworkCallback(); - final TestNetworkCallback defaultCallback = new TestNetworkCallback(); - final NetworkRequest networkRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_INTERNET) - .build(); - mCm.registerNetworkCallback(networkRequest, callback); - mCm.registerDefaultNetworkCallback(defaultCallback); - - // Bring up validated cell. - final LinkProperties cellLp = new LinkProperties(); - cellLp.setInterfaceName(MOBILE_IFNAME); - cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); - cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, MOBILE_IFNAME)); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - - mCellNetworkAgent.sendLinkProperties(cellLp); - mCellNetworkAgent.connect(true); - callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - final int cellNetId = mCellNetworkAgent.getNetwork().netId; - waitForIdle(); - - verify(mMockDnsResolver, never()).startPrefix64Discovery(cellNetId); - Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent); - assertTrue("Nat464Xlat was not IDLE", !clat.isStarted()); - - // This cannot happen because prefix discovery cannot succeed if it is never started. - mService.mResolverUnsolEventCallback.onNat64PrefixEvent( - makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, "64:ff9b::", 96)); - - // ... but still, check that even if it did, clatd would not be started. - verify(mMockNetd, never()).clatdStart(anyString(), anyString()); - assertTrue("Nat464Xlat was not IDLE", !clat.isStarted()); - } - - @Test - public void testDataActivityTracking() throws Exception { - final TestNetworkCallback networkCallback = new TestNetworkCallback(); - final NetworkRequest networkRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_INTERNET) - .build(); - mCm.registerNetworkCallback(networkRequest, networkCallback); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - final LinkProperties cellLp = new LinkProperties(); - cellLp.setInterfaceName(MOBILE_IFNAME); - mCellNetworkAgent.sendLinkProperties(cellLp); - mCellNetworkAgent.connect(true); - networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), - eq(Integer.toString(TRANSPORT_CELLULAR))); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - final LinkProperties wifiLp = new LinkProperties(); - wifiLp.setInterfaceName(WIFI_IFNAME); - mWiFiNetworkAgent.sendLinkProperties(wifiLp); - - // Network switch - mWiFiNetworkAgent.connect(true); - networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(), - eq(Integer.toString(TRANSPORT_WIFI))); - verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), - eq(Integer.toString(TRANSPORT_CELLULAR))); - - // Disconnect wifi and switch back to cell - reset(mMockNetd); - mWiFiNetworkAgent.disconnect(); - networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - assertNoCallbacks(networkCallback); - verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(), - eq(Integer.toString(TRANSPORT_WIFI))); - verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(), - eq(Integer.toString(TRANSPORT_CELLULAR))); - - // reconnect wifi - reset(mMockNetd); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - wifiLp.setInterfaceName(WIFI_IFNAME); - mWiFiNetworkAgent.sendLinkProperties(wifiLp); - mWiFiNetworkAgent.connect(true); - networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(), - eq(Integer.toString(TRANSPORT_WIFI))); - verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), - eq(Integer.toString(TRANSPORT_CELLULAR))); - - // Disconnect cell - reset(mMockNetd); - mCellNetworkAgent.disconnect(); - networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - // LOST callback is triggered earlier than removing idle timer. Broadcast should also be - // sent as network being switched. Ensure rule removal for cell will not be triggered - // unexpectedly before network being removed. - waitForIdle(); - verify(mMockNetd, times(0)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(), - eq(Integer.toString(TRANSPORT_CELLULAR))); - verify(mMockNetd, times(1)).networkDestroy(eq(mCellNetworkAgent.getNetwork().netId)); - verify(mMockDnsResolver, times(1)) - .destroyNetworkCache(eq(mCellNetworkAgent.getNetwork().netId)); - - // Disconnect wifi - ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED); - mWiFiNetworkAgent.disconnect(); - b.expectBroadcast(); - verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(), - eq(Integer.toString(TRANSPORT_WIFI))); - - // Clean up - mCm.unregisterNetworkCallback(networkCallback); - } - - private void verifyTcpBufferSizeChange(String tcpBufferSizes) throws Exception { - String[] values = tcpBufferSizes.split(","); - String rmemValues = String.join(" ", values[0], values[1], values[2]); - String wmemValues = String.join(" ", values[3], values[4], values[5]); - verify(mMockNetd, atLeastOnce()).setTcpRWmemorySize(rmemValues, wmemValues); - reset(mMockNetd); - } - - @Test - public void testTcpBufferReset() throws Exception { - final String testTcpBufferSizes = "1,2,3,4,5,6"; - final NetworkRequest networkRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR) - .addCapability(NET_CAPABILITY_INTERNET) - .build(); - final TestNetworkCallback networkCallback = new TestNetworkCallback(); - mCm.registerNetworkCallback(networkRequest, networkCallback); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - reset(mMockNetd); - // Switching default network updates TCP buffer sizes. - mCellNetworkAgent.connect(false); - networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); - // Change link Properties should have updated tcp buffer size. - LinkProperties lp = new LinkProperties(); - lp.setTcpBufferSizes(testTcpBufferSizes); - mCellNetworkAgent.sendLinkProperties(lp); - networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); - verifyTcpBufferSizeChange(testTcpBufferSizes); - // Clean up. - mCellNetworkAgent.disconnect(); - networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - networkCallback.assertNoCallback(); - mCm.unregisterNetworkCallback(networkCallback); - } - - @Test - public void testGetGlobalProxyForNetwork() throws Exception { - final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - final Network wifiNetwork = mWiFiNetworkAgent.getNetwork(); - when(mService.mProxyTracker.getGlobalProxy()).thenReturn(testProxyInfo); - assertEquals(testProxyInfo, mService.getProxyForNetwork(wifiNetwork)); - } - - @Test - public void testGetProxyForActiveNetwork() throws Exception { - final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - waitForIdle(); - assertNull(mService.getProxyForNetwork(null)); - - final LinkProperties testLinkProperties = new LinkProperties(); - testLinkProperties.setHttpProxy(testProxyInfo); - - mWiFiNetworkAgent.sendLinkProperties(testLinkProperties); - waitForIdle(); - - assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); - } - - @Test - public void testGetProxyForVPN() throws Exception { - final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); - - // Set up a WiFi network with no proxy - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - waitForIdle(); - assertNull(mService.getProxyForNetwork(null)); - - // Connect a VPN network with a proxy. - LinkProperties testLinkProperties = new LinkProperties(); - testLinkProperties.setHttpProxy(testProxyInfo); - mMockVpn.establishForMyUid(testLinkProperties); - assertUidRangesUpdatedForMyUid(true); - - // Test that the VPN network returns a proxy, and the WiFi does not. - assertEquals(testProxyInfo, mService.getProxyForNetwork(mMockVpn.getNetwork())); - assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); - assertNull(mService.getProxyForNetwork(mWiFiNetworkAgent.getNetwork())); - - // Test that the VPN network returns no proxy when it is set to null. - testLinkProperties.setHttpProxy(null); - mMockVpn.sendLinkProperties(testLinkProperties); - waitForIdle(); - assertNull(mService.getProxyForNetwork(mMockVpn.getNetwork())); - assertNull(mService.getProxyForNetwork(null)); - - // Set WiFi proxy and check that the vpn proxy is still null. - testLinkProperties.setHttpProxy(testProxyInfo); - mWiFiNetworkAgent.sendLinkProperties(testLinkProperties); - waitForIdle(); - assertNull(mService.getProxyForNetwork(null)); - - // Disconnect from VPN and check that the active network, which is now the WiFi, has the - // correct proxy setting. - mMockVpn.disconnect(); - waitForIdle(); - assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertEquals(testProxyInfo, mService.getProxyForNetwork(mWiFiNetworkAgent.getNetwork())); - assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); - } - - @Test - public void testFullyRoutedVpnResultsInInterfaceFilteringRules() throws Exception { - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName("tun0"); - lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); - lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); - // The uid range needs to cover the test app so the network is visible to it. - final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); - mMockVpn.establish(lp, VPN_UID, vpnRange); - assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); - - // A connected VPN should have interface rules set up. There are two expected invocations, - // one during the VPN initial connection, one during the VPN LinkProperties update. - ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); - verify(mMockNetd, times(2)).firewallAddUidInterfaceRules(eq("tun0"), uidCaptor.capture()); - assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); - assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); - assertTrue(mService.mPermissionMonitor.getVpnUidRanges("tun0").equals(vpnRange)); - - mMockVpn.disconnect(); - waitForIdle(); - - // Disconnected VPN should have interface rules removed - verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture()); - assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); - assertNull(mService.mPermissionMonitor.getVpnUidRanges("tun0")); - } - - @Test - public void testLegacyVpnDoesNotResultInInterfaceFilteringRule() throws Exception { - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName("tun0"); - lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); - lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); - // The uid range needs to cover the test app so the network is visible to it. - final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); - mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange); - assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID); - - // Legacy VPN should not have interface rules set up - verify(mMockNetd, never()).firewallAddUidInterfaceRules(any(), any()); - } - - @Test - public void testLocalIpv4OnlyVpnDoesNotResultInInterfaceFilteringRule() - throws Exception { - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName("tun0"); - lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun0")); - lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); - // The uid range needs to cover the test app so the network is visible to it. - final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); - mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange); - assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID); - - // IPv6 unreachable route should not be misinterpreted as a default route - verify(mMockNetd, never()).firewallAddUidInterfaceRules(any(), any()); - } - - @Test - public void testVpnHandoverChangesInterfaceFilteringRule() throws Exception { - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName("tun0"); - lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); - lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); - // The uid range needs to cover the test app so the network is visible to it. - final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); - mMockVpn.establish(lp, VPN_UID, vpnRange); - assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); - - // Connected VPN should have interface rules set up. There are two expected invocations, - // one during VPN uid update, one during VPN LinkProperties update - ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); - verify(mMockNetd, times(2)).firewallAddUidInterfaceRules(eq("tun0"), uidCaptor.capture()); - assertContainsExactly(uidCaptor.getAllValues().get(0), APP1_UID, APP2_UID); - assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); - - reset(mMockNetd); - InOrder inOrder = inOrder(mMockNetd); - lp.setInterfaceName("tun1"); - mMockVpn.sendLinkProperties(lp); - waitForIdle(); - // VPN handover (switch to a new interface) should result in rules being updated (old rules - // removed first, then new rules added) - inOrder.verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture()); - assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); - inOrder.verify(mMockNetd).firewallAddUidInterfaceRules(eq("tun1"), uidCaptor.capture()); - assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); - - reset(mMockNetd); - lp = new LinkProperties(); - lp.setInterfaceName("tun1"); - lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun1")); - mMockVpn.sendLinkProperties(lp); - waitForIdle(); - // VPN not routing everything should no longer have interface filtering rules - verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture()); - assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); - - reset(mMockNetd); - lp = new LinkProperties(); - lp.setInterfaceName("tun1"); - lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); - lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); - mMockVpn.sendLinkProperties(lp); - waitForIdle(); - // Back to routing all IPv6 traffic should have filtering rules - verify(mMockNetd).firewallAddUidInterfaceRules(eq("tun1"), uidCaptor.capture()); - assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); - } - - @Test - public void testUidUpdateChangesInterfaceFilteringRule() throws Exception { - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName("tun0"); - lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); - lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); - // The uid range needs to cover the test app so the network is visible to it. - final UidRange vpnRange = PRIMARY_UIDRANGE; - final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); - mMockVpn.establish(lp, VPN_UID, vpnRanges); - assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); - - reset(mMockNetd); - InOrder inOrder = inOrder(mMockNetd); - - // Update to new range which is old range minus APP1, i.e. only APP2 - final Set<UidRange> newRanges = new HashSet<>(Arrays.asList( - new UidRange(vpnRange.start, APP1_UID - 1), - new UidRange(APP1_UID + 1, vpnRange.stop))); - mMockVpn.setUids(newRanges); - waitForIdle(); - - ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); - // Verify old rules are removed before new rules are added - inOrder.verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture()); - assertContainsExactly(uidCaptor.getValue(), APP1_UID, APP2_UID); - inOrder.verify(mMockNetd).firewallAddUidInterfaceRules(eq("tun0"), uidCaptor.capture()); - assertContainsExactly(uidCaptor.getValue(), APP2_UID); - } - - @Test - public void testLinkPropertiesWithWakeOnLanForActiveNetwork() throws Exception { - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - - LinkProperties wifiLp = new LinkProperties(); - wifiLp.setInterfaceName(WIFI_WOL_IFNAME); - wifiLp.setWakeOnLanSupported(false); - - // Default network switch should update ifaces. - mWiFiNetworkAgent.connect(false); - mWiFiNetworkAgent.sendLinkProperties(wifiLp); - waitForIdle(); - - // ConnectivityService should have changed the WakeOnLanSupported to true - wifiLp.setWakeOnLanSupported(true); - assertEquals(wifiLp, mService.getActiveLinkProperties()); - } - - @Test - public void testLegacyExtraInfoSentToNetworkMonitor() throws Exception { - class TestNetworkAgent extends NetworkAgent { - TestNetworkAgent(Context context, Looper looper, NetworkAgentConfig config) { - super(context, looper, "MockAgent", new NetworkCapabilities(), - new LinkProperties(), 40 , config, null /* provider */); - } - } - final NetworkAgent naNoExtraInfo = new TestNetworkAgent( - mServiceContext, mCsHandlerThread.getLooper(), new NetworkAgentConfig()); - naNoExtraInfo.register(); - verify(mNetworkStack).makeNetworkMonitor(any(), isNull(String.class), any()); - naNoExtraInfo.unregister(); - - reset(mNetworkStack); - final NetworkAgentConfig config = - new NetworkAgentConfig.Builder().setLegacyExtraInfo("legacyinfo").build(); - final NetworkAgent naExtraInfo = new TestNetworkAgent( - mServiceContext, mCsHandlerThread.getLooper(), config); - naExtraInfo.register(); - verify(mNetworkStack).makeNetworkMonitor(any(), eq("legacyinfo"), any()); - naExtraInfo.unregister(); - } - - // To avoid granting location permission bypass. - private void denyAllLocationPrivilegedPermissions() { - mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - PERMISSION_DENIED); - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); - mServiceContext.setPermission(Manifest.permission.NETWORK_STACK, - PERMISSION_DENIED); - mServiceContext.setPermission(Manifest.permission.NETWORK_SETUP_WIZARD, - PERMISSION_DENIED); - } - - private void setupLocationPermissions( - int targetSdk, boolean locationToggle, String op, String perm) throws Exception { - denyAllLocationPrivilegedPermissions(); - - final ApplicationInfo applicationInfo = new ApplicationInfo(); - applicationInfo.targetSdkVersion = targetSdk; - when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any())) - .thenReturn(applicationInfo); - when(mPackageManager.getTargetSdkVersion(any())).thenReturn(targetSdk); - - when(mLocationManager.isLocationEnabledForUser(any())).thenReturn(locationToggle); - - if (op != null) { - when(mAppOpsManager.noteOp(eq(op), eq(Process.myUid()), - eq(mContext.getPackageName()), eq(getAttributionTag()), anyString())) - .thenReturn(AppOpsManager.MODE_ALLOWED); - } - - if (perm != null) { - mServiceContext.setPermission(perm, PERMISSION_GRANTED); - } - } - - private int getOwnerUidNetCapsPermission(int ownerUid, int callerUid, - boolean includeLocationSensitiveInfo) { - final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid); - - return mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( - netCap, includeLocationSensitiveInfo, Process.myUid(), callerUid, - mContext.getPackageName(), getAttributionTag()) - .getOwnerUid(); - } - - private void verifyTransportInfoCopyNetCapsPermission( - int callerUid, boolean includeLocationSensitiveInfo, - boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) { - final TransportInfo transportInfo = mock(TransportInfo.class); - when(transportInfo.getApplicableRedactions()).thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION); - final NetworkCapabilities netCap = - new NetworkCapabilities().setTransportInfo(transportInfo); - - mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( - netCap, includeLocationSensitiveInfo, Process.myPid(), callerUid, - mContext.getPackageName(), getAttributionTag()); - if (shouldMakeCopyWithLocationSensitiveFieldsParcelable) { - verify(transportInfo).makeCopy(REDACT_NONE); - } else { - verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); - } - } - - private void verifyOwnerUidAndTransportInfoNetCapsPermission( - boolean shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag, - boolean shouldInclLocationSensitiveOwnerUidWithIncludeFlag, - boolean shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag, - boolean shouldInclLocationSensitiveTransportInfoWithIncludeFlag) { - final int myUid = Process.myUid(); - - final int expectedOwnerUidWithoutIncludeFlag = - shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag - ? myUid : INVALID_UID; - assertEquals(expectedOwnerUidWithoutIncludeFlag, getOwnerUidNetCapsPermission( - myUid, myUid, false /* includeLocationSensitiveInfo */)); - - final int expectedOwnerUidWithIncludeFlag = - shouldInclLocationSensitiveOwnerUidWithIncludeFlag ? myUid : INVALID_UID; - assertEquals(expectedOwnerUidWithIncludeFlag, getOwnerUidNetCapsPermission( - myUid, myUid, true /* includeLocationSensitiveInfo */)); - - verifyTransportInfoCopyNetCapsPermission(myUid, - false, /* includeLocationSensitiveInfo */ - shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag); - - verifyTransportInfoCopyNetCapsPermission(myUid, - true, /* includeLocationSensitiveInfo */ - shouldInclLocationSensitiveTransportInfoWithIncludeFlag); - - } - - private void verifyOwnerUidAndTransportInfoNetCapsPermissionPreS() { - verifyOwnerUidAndTransportInfoNetCapsPermission( - // Ensure that owner uid is included even if the request asks to remove it (which is - // the default) since the app has necessary permissions and targetSdk < S. - true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ - true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - // Ensure that location info is removed if the request asks to remove it even if the - // app has necessary permissions. - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ - ); - } - - @Test - public void testCreateWithLocationInfoSanitizedWithFineLocationAfterQPreS() - throws Exception { - setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION); - - verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); - } - - @Test - public void testCreateWithLocationInfoSanitizedWithFineLocationPreSWithAndWithoutCallbackFlag() - throws Exception { - setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION); - - verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); - } - - @Test - public void - testCreateWithLocationInfoSanitizedWithFineLocationAfterSWithAndWithoutCallbackFlag() - throws Exception { - setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION); - - verifyOwnerUidAndTransportInfoNetCapsPermission( - // Ensure that the owner UID is removed if the request asks us to remove it even - // if the app has necessary permissions since targetSdk >= S. - false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ - true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - // Ensure that location info is removed if the request asks to remove it even if the - // app has necessary permissions. - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ - ); - } - - @Test - public void testCreateWithLocationInfoSanitizedWithCoarseLocationPreQ() - throws Exception { - setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION, - Manifest.permission.ACCESS_COARSE_LOCATION); - - verifyOwnerUidAndTransportInfoNetCapsPermissionPreS(); - } - - private void verifyOwnerUidAndTransportInfoNetCapsNotIncluded() { - verifyOwnerUidAndTransportInfoNetCapsPermission( - false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */ - false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */ - false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */ - false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */ - ); - } - - @Test - public void testCreateWithLocationInfoSanitizedLocationOff() throws Exception { - // Test that even with fine location permission, and UIDs matching, the UID is sanitized. - setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION); - - verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); - } - - @Test - public void testCreateWithLocationInfoSanitizedWrongUid() throws Exception { - // Test that even with fine location permission, not being the owner leads to sanitization. - setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION); - - final int myUid = Process.myUid(); - assertEquals(Process.INVALID_UID, - getOwnerUidNetCapsPermission(myUid + 1, myUid, - true /* includeLocationSensitiveInfo */)); - } - - @Test - public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterQ() - throws Exception { - // Test that not having fine location permission leads to sanitization. - setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION, - Manifest.permission.ACCESS_COARSE_LOCATION); - - verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); - } - - @Test - public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterS() - throws Exception { - // Test that not having fine location permission leads to sanitization. - setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_COARSE_LOCATION, - Manifest.permission.ACCESS_COARSE_LOCATION); - - verifyOwnerUidAndTransportInfoNetCapsNotIncluded(); - } - - @Test - public void testCreateForCallerWithLocalMacAddressSanitizedWithLocalMacAddressPermission() - throws Exception { - mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_GRANTED); - - final TransportInfo transportInfo = mock(TransportInfo.class); - when(transportInfo.getApplicableRedactions()) - .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS); - final NetworkCapabilities netCap = - new NetworkCapabilities().setTransportInfo(transportInfo); - - mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( - netCap, false /* includeLocationSensitiveInfoInTransportInfo */, - Process.myPid(), Process.myUid(), - mContext.getPackageName(), getAttributionTag()); - // don't redact MAC_ADDRESS fields, only location sensitive fields. - verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); - } - - @Test - public void testCreateForCallerWithLocalMacAddressSanitizedWithoutLocalMacAddressPermission() - throws Exception { - mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED); - - final TransportInfo transportInfo = mock(TransportInfo.class); - when(transportInfo.getApplicableRedactions()) - .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS); - final NetworkCapabilities netCap = - new NetworkCapabilities().setTransportInfo(transportInfo); - - mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( - netCap, false /* includeLocationSensitiveInfoInTransportInfo */, - Process.myPid(), Process.myUid(), - mContext.getPackageName(), getAttributionTag()); - // redact both MAC_ADDRESS & location sensitive fields. - verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION - | REDACT_FOR_LOCAL_MAC_ADDRESS); - } - - @Test - public void testCreateForCallerWithLocalMacAddressSanitizedWithSettingsPermission() - throws Exception { - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); - - final TransportInfo transportInfo = mock(TransportInfo.class); - when(transportInfo.getApplicableRedactions()) - .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS); - final NetworkCapabilities netCap = - new NetworkCapabilities().setTransportInfo(transportInfo); - - mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( - netCap, false /* includeLocationSensitiveInfoInTransportInfo */, - Process.myPid(), Process.myUid(), - mContext.getPackageName(), getAttributionTag()); - // don't redact NETWORK_SETTINGS fields, only location sensitive fields. - verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION); - } - - @Test - public void testCreateForCallerWithLocalMacAddressSanitizedWithoutSettingsPermission() - throws Exception { - mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED); - - final TransportInfo transportInfo = mock(TransportInfo.class); - when(transportInfo.getApplicableRedactions()) - .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS); - final NetworkCapabilities netCap = - new NetworkCapabilities().setTransportInfo(transportInfo); - - mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled( - netCap, false /* includeLocationSensitiveInfoInTransportInfo */, - Process.myPid(), Process.myUid(), - mContext.getPackageName(), getAttributionTag()); - // redact both NETWORK_SETTINGS & location sensitive fields. - verify(transportInfo).makeCopy( - REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS); - } - - /** - * Test TransportInfo to verify redaction mechanism. - */ - private static class TestTransportInfo implements TransportInfo { - public final boolean locationRedacted; - public final boolean localMacAddressRedacted; - public final boolean settingsRedacted; - - TestTransportInfo() { - locationRedacted = false; - localMacAddressRedacted = false; - settingsRedacted = false; - } - - TestTransportInfo(boolean locationRedacted, boolean localMacAddressRedacted, - boolean settingsRedacted) { - this.locationRedacted = locationRedacted; - this.localMacAddressRedacted = - localMacAddressRedacted; - this.settingsRedacted = settingsRedacted; - } - - @Override - public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) { - return new TestTransportInfo( - locationRedacted | (redactions & REDACT_FOR_ACCESS_FINE_LOCATION) != 0, - localMacAddressRedacted | (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0, - settingsRedacted | (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0 - ); - } - - @Override - public @NetworkCapabilities.RedactionType long getApplicableRedactions() { - return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS - | REDACT_FOR_NETWORK_SETTINGS; - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof TestTransportInfo)) return false; - TestTransportInfo that = (TestTransportInfo) other; - return that.locationRedacted == this.locationRedacted - && that.localMacAddressRedacted == this.localMacAddressRedacted - && that.settingsRedacted == this.settingsRedacted; - } - - @Override - public int hashCode() { - return Objects.hash(locationRedacted, localMacAddressRedacted, settingsRedacted); - } - - @Override - public String toString() { - return String.format( - "TestTransportInfo{locationRedacted=%s macRedacted=%s settingsRedacted=%s}", - locationRedacted, localMacAddressRedacted, settingsRedacted); - } - } - - private TestTransportInfo getTestTransportInfo(NetworkCapabilities nc) { - return (TestTransportInfo) nc.getTransportInfo(); - } - - private TestTransportInfo getTestTransportInfo(TestNetworkAgentWrapper n) { - final NetworkCapabilities nc = mCm.getNetworkCapabilities(n.getNetwork()); - assertNotNull(nc); - return getTestTransportInfo(nc); - } - - - private void verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps( - @NonNull TestNetworkCallback wifiNetworkCallback, int actualOwnerUid, - @NonNull TransportInfo actualTransportInfo, int expectedOwnerUid, - @NonNull TransportInfo expectedTransportInfo) throws Exception { - when(mPackageManager.getTargetSdkVersion(anyString())).thenReturn(Build.VERSION_CODES.S); - final NetworkCapabilities ncTemplate = - new NetworkCapabilities() - .addTransportType(TRANSPORT_WIFI) - .setOwnerUid(actualOwnerUid); - - final NetworkRequest wifiRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI).build(); - mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), - ncTemplate); - mWiFiNetworkAgent.connect(false); - - wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - - // Send network capabilities update with TransportInfo to trigger capabilities changed - // callback. - mWiFiNetworkAgent.setNetworkCapabilities( - ncTemplate.setTransportInfo(actualTransportInfo), true); - - wifiNetworkCallback.expectCapabilitiesThat(mWiFiNetworkAgent, - nc -> Objects.equals(expectedOwnerUid, nc.getOwnerUid()) - && Objects.equals(expectedTransportInfo, nc.getTransportInfo())); - } - - @Test - public void testVerifyLocationDataIsNotIncludedWhenInclFlagNotSet() throws Exception { - final TestNetworkCallback wifiNetworkCallack = new TestNetworkCallback(); - final int ownerUid = Process.myUid(); - final TransportInfo transportInfo = new TestTransportInfo(); - // Even though the test uid holds privileged permissions, mask location fields since - // the callback did not explicitly opt-in to get location data. - final TransportInfo sanitizedTransportInfo = new TestTransportInfo( - true, /* locationRedacted */ - true, /* localMacAddressRedacted */ - true /* settingsRedacted */ - ); - // Should not expect location data since the callback does not set the flag for including - // location data. - verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps( - wifiNetworkCallack, ownerUid, transportInfo, INVALID_UID, sanitizedTransportInfo); - } - - @Test - public void testTransportInfoRedactionInSynchronousCalls() throws Exception { - final NetworkCapabilities ncTemplate = new NetworkCapabilities() - .addTransportType(TRANSPORT_WIFI) - .setTransportInfo(new TestTransportInfo()); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), - ncTemplate); - mWiFiNetworkAgent.connect(true /* validated; waits for callback */); - - // NETWORK_SETTINGS redaction is controlled by the NETWORK_SETTINGS permission - assertTrue(getTestTransportInfo(mWiFiNetworkAgent).settingsRedacted); - withPermission(NETWORK_SETTINGS, () -> { - assertFalse(getTestTransportInfo(mWiFiNetworkAgent).settingsRedacted); - }); - assertTrue(getTestTransportInfo(mWiFiNetworkAgent).settingsRedacted); - - // LOCAL_MAC_ADDRESS redaction is controlled by the LOCAL_MAC_ADDRESS permission - assertTrue(getTestTransportInfo(mWiFiNetworkAgent).localMacAddressRedacted); - withPermission(LOCAL_MAC_ADDRESS, () -> { - assertFalse(getTestTransportInfo(mWiFiNetworkAgent).localMacAddressRedacted); - }); - assertTrue(getTestTransportInfo(mWiFiNetworkAgent).localMacAddressRedacted); - - // Synchronous getNetworkCapabilities calls never return unredacted location-sensitive - // information. - assertTrue(getTestTransportInfo(mWiFiNetworkAgent).locationRedacted); - setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION); - assertTrue(getTestTransportInfo(mWiFiNetworkAgent).locationRedacted); - denyAllLocationPrivilegedPermissions(); - assertTrue(getTestTransportInfo(mWiFiNetworkAgent).locationRedacted); - } - - private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType) - throws Exception { - final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); - mMockVpn.setVpnType(vpnType); - mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange); - assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid); - - final UnderlyingNetworkInfo underlyingNetworkInfo = - new UnderlyingNetworkInfo(vpnOwnerUid, VPN_IFNAME, new ArrayList<String>()); - mMockVpn.setUnderlyingNetworkInfo(underlyingNetworkInfo); - when(mDeps.getConnectionOwnerUid(anyInt(), any(), any())).thenReturn(42); - } - - private void setupConnectionOwnerUidAsVpnApp(int vpnOwnerUid, @VpnManager.VpnType int vpnType) - throws Exception { - setupConnectionOwnerUid(vpnOwnerUid, vpnType); - - // Test as VPN app - mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); - mServiceContext.setPermission( - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_DENIED); - } - - private ConnectionInfo getTestConnectionInfo() throws Exception { - return new ConnectionInfo( - IPPROTO_TCP, - new InetSocketAddress(InetAddresses.parseNumericAddress("1.2.3.4"), 1234), - new InetSocketAddress(InetAddresses.parseNumericAddress("2.3.4.5"), 2345)); - } - - @Test - public void testGetConnectionOwnerUidPlatformVpn() throws Exception { - final int myUid = Process.myUid(); - setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_PLATFORM); - - assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo())); - } - - @Test - public void testGetConnectionOwnerUidVpnServiceWrongUser() throws Exception { - final int myUid = Process.myUid(); - setupConnectionOwnerUidAsVpnApp(myUid + 1, VpnManager.TYPE_VPN_SERVICE); - - assertEquals(INVALID_UID, mService.getConnectionOwnerUid(getTestConnectionInfo())); - } - - @Test - public void testGetConnectionOwnerUidVpnServiceDoesNotThrow() throws Exception { - final int myUid = Process.myUid(); - setupConnectionOwnerUidAsVpnApp(myUid, VpnManager.TYPE_VPN_SERVICE); - - assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); - } - - @Test - public void testGetConnectionOwnerUidVpnServiceNetworkStackDoesNotThrow() throws Exception { - final int myUid = Process.myUid(); - setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); - mServiceContext.setPermission( - android.Manifest.permission.NETWORK_STACK, PERMISSION_GRANTED); - - assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); - } - - @Test - public void testGetConnectionOwnerUidVpnServiceMainlineNetworkStackDoesNotThrow() - throws Exception { - final int myUid = Process.myUid(); - setupConnectionOwnerUid(myUid, VpnManager.TYPE_VPN_SERVICE); - mServiceContext.setPermission( - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_GRANTED); - - assertEquals(42, mService.getConnectionOwnerUid(getTestConnectionInfo())); - } - - private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid) { - final PackageInfo packageInfo = new PackageInfo(); - if (hasSystemPermission) { - packageInfo.requestedPermissions = new String[] { - CHANGE_NETWORK_STATE, CONNECTIVITY_USE_RESTRICTED_NETWORKS }; - packageInfo.requestedPermissionsFlags = new int[] { - REQUESTED_PERMISSION_GRANTED, REQUESTED_PERMISSION_GRANTED }; - } else { - packageInfo.requestedPermissions = new String[0]; - } - packageInfo.applicationInfo = new ApplicationInfo(); - packageInfo.applicationInfo.privateFlags = 0; - packageInfo.applicationInfo.uid = UserHandle.getUid(UserHandle.USER_SYSTEM, - UserHandle.getAppId(uid)); - return packageInfo; - } - - @Test - public void testRegisterConnectivityDiagnosticsCallbackInvalidRequest() throws Exception { - final NetworkRequest request = - new NetworkRequest( - new NetworkCapabilities(), TYPE_ETHERNET, 0, NetworkRequest.Type.NONE); - try { - mService.registerConnectivityDiagnosticsCallback( - mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); - fail("registerConnectivityDiagnosticsCallback should throw on invalid NetworkRequest"); - } catch (IllegalArgumentException expected) { - } - } - - private void assertRouteInfoParcelMatches(RouteInfo route, RouteInfoParcel parcel) { - assertEquals(route.getDestination().toString(), parcel.destination); - assertEquals(route.getInterface(), parcel.ifName); - assertEquals(route.getMtu(), parcel.mtu); - - switch (route.getType()) { - case RouteInfo.RTN_UNICAST: - if (route.hasGateway()) { - assertEquals(route.getGateway().getHostAddress(), parcel.nextHop); - } else { - assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); - } - break; - case RouteInfo.RTN_UNREACHABLE: - assertEquals(INetd.NEXTHOP_UNREACHABLE, parcel.nextHop); - break; - case RouteInfo.RTN_THROW: - assertEquals(INetd.NEXTHOP_THROW, parcel.nextHop); - break; - default: - assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); - break; - } - } - - private void assertRoutesAdded(int netId, RouteInfo... routes) throws Exception { - ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); - verify(mMockNetd, times(routes.length)).networkAddRouteParcel(eq(netId), captor.capture()); - for (int i = 0; i < routes.length; i++) { - assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); - } - } - - private void assertRoutesRemoved(int netId, RouteInfo... routes) throws Exception { - ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); - verify(mMockNetd, times(routes.length)).networkRemoveRouteParcel(eq(netId), - captor.capture()); - for (int i = 0; i < routes.length; i++) { - assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); - } - } - - @Test - public void testRegisterUnregisterConnectivityDiagnosticsCallback() throws Exception { - final NetworkRequest wifiRequest = - new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); - when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder); - - mService.registerConnectivityDiagnosticsCallback( - mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); - - // Block until all other events are done processing. - HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); - - verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); - verify(mConnectivityDiagnosticsCallback).asBinder(); - assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); - - mService.unregisterConnectivityDiagnosticsCallback(mConnectivityDiagnosticsCallback); - verify(mIBinder, timeout(TIMEOUT_MS)) - .unlinkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); - assertFalse(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); - verify(mConnectivityDiagnosticsCallback, atLeastOnce()).asBinder(); - } - - @Test - public void testRegisterDuplicateConnectivityDiagnosticsCallback() throws Exception { - final NetworkRequest wifiRequest = - new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(); - when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder); - - mService.registerConnectivityDiagnosticsCallback( - mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); - - // Block until all other events are done processing. - HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); - - verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt()); - verify(mConnectivityDiagnosticsCallback).asBinder(); - assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); - - // Register the same callback again - mService.registerConnectivityDiagnosticsCallback( - mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName()); - - // Block until all other events are done processing. - HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); - - assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder)); - } - - public NetworkAgentInfo fakeMobileNai(NetworkCapabilities nc) { - final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, - ConnectivityManager.getNetworkTypeName(TYPE_MOBILE), - TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE)); - return new NetworkAgentInfo(null, new Network(NET_ID), info, new LinkProperties(), - nc, new NetworkScore.Builder().setLegacyInt(0).build(), - mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0, - INVALID_UID, TEST_LINGER_DELAY_MS, mQosCallbackTracker, - new ConnectivityService.Dependencies()); - } - - @Test - public void testCheckConnectivityDiagnosticsPermissionsNetworkStack() throws Exception { - final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); - - mServiceContext.setPermission( - android.Manifest.permission.NETWORK_STACK, PERMISSION_GRANTED); - assertTrue( - "NetworkStack permission not applied", - mService.checkConnectivityDiagnosticsPermissions( - Process.myPid(), Process.myUid(), naiWithoutUid, - mContext.getOpPackageName())); - } - - @Test - public void testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName() throws Exception { - final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); - - mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); - - assertFalse( - "Mismatched uid/package name should not pass the location permission check", - mService.checkConnectivityDiagnosticsPermissions( - Process.myPid() + 1, Process.myUid() + 1, naiWithoutUid, - mContext.getOpPackageName())); - } - - @Test - public void testCheckConnectivityDiagnosticsPermissionsNoLocationPermission() throws Exception { - final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); - - mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); - - assertFalse( - "ACCESS_FINE_LOCATION permission necessary for Connectivity Diagnostics", - mService.checkConnectivityDiagnosticsPermissions( - Process.myPid(), Process.myUid(), naiWithoutUid, - mContext.getOpPackageName())); - } - - @Test - public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception { - final NetworkAgentInfo naiWithoutUid = fakeMobileNai(new NetworkCapabilities()); - - mMockVpn.establishForMyUid(); - assertUidRangesUpdatedForMyUid(true); - - // Wait for networks to connect and broadcasts to be sent before removing permissions. - waitForIdle(); - setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION); - - assertTrue(mMockVpn.setUnderlyingNetworks(new Network[] {naiWithoutUid.network})); - waitForIdle(); - assertTrue( - "Active VPN permission not applied", - mService.checkConnectivityDiagnosticsPermissions( - Process.myPid(), Process.myUid(), naiWithoutUid, - mContext.getOpPackageName())); - - assertTrue(mMockVpn.setUnderlyingNetworks(null)); - waitForIdle(); - assertFalse( - "VPN shouldn't receive callback on non-underlying network", - mService.checkConnectivityDiagnosticsPermissions( - Process.myPid(), Process.myUid(), naiWithoutUid, - mContext.getOpPackageName())); - } - - @Test - public void testCheckConnectivityDiagnosticsPermissionsNetworkAdministrator() throws Exception { - final NetworkCapabilities nc = new NetworkCapabilities(); - nc.setAdministratorUids(new int[] {Process.myUid()}); - final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); - - setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION); - mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); - - assertTrue( - "NetworkCapabilities administrator uid permission not applied", - mService.checkConnectivityDiagnosticsPermissions( - Process.myPid(), Process.myUid(), naiWithUid, mContext.getOpPackageName())); - } - - @Test - public void testCheckConnectivityDiagnosticsPermissionsFails() throws Exception { - final NetworkCapabilities nc = new NetworkCapabilities(); - nc.setOwnerUid(Process.myUid()); - nc.setAdministratorUids(new int[] {Process.myUid()}); - final NetworkAgentInfo naiWithUid = fakeMobileNai(nc); - - setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION); - mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); - - // Use wrong pid and uid - assertFalse( - "Permissions allowed when they shouldn't be granted", - mService.checkConnectivityDiagnosticsPermissions( - Process.myPid() + 1, Process.myUid() + 1, naiWithUid, - mContext.getOpPackageName())); - } - - @Test - public void testRegisterConnectivityDiagnosticsCallbackCallsOnConnectivityReport() - throws Exception { - // Set up the Network, which leads to a ConnectivityReport being cached for the network. - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(callback); - final LinkProperties linkProperties = new LinkProperties(); - linkProperties.setInterfaceName(INTERFACE_NAME); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, linkProperties); - mCellNetworkAgent.connect(true); - callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - callback.assertNoCallback(); - - final NetworkRequest request = new NetworkRequest.Builder().build(); - when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder); - - mServiceContext.setPermission( - android.Manifest.permission.NETWORK_STACK, PERMISSION_GRANTED); - - mService.registerConnectivityDiagnosticsCallback( - mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); - - // Block until all other events are done processing. - HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); - - verify(mConnectivityDiagnosticsCallback) - .onConnectivityReportAvailable(argThat(report -> { - return INTERFACE_NAME.equals(report.getLinkProperties().getInterfaceName()) - && report.getNetworkCapabilities().hasTransport(TRANSPORT_CELLULAR); - })); - } - - private void setUpConnectivityDiagnosticsCallback() throws Exception { - final NetworkRequest request = new NetworkRequest.Builder().build(); - when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder); - - mServiceContext.setPermission( - android.Manifest.permission.NETWORK_STACK, PERMISSION_GRANTED); - - mService.registerConnectivityDiagnosticsCallback( - mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); - - // Block until all other events are done processing. - HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); - - // Connect the cell agent verify that it notifies TestNetworkCallback that it is available - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(callback); - - final NetworkCapabilities ncTemplate = new NetworkCapabilities() - .addTransportType(TRANSPORT_CELLULAR) - .setTransportInfo(new TestTransportInfo()); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), - ncTemplate); - mCellNetworkAgent.connect(true); - callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - callback.assertNoCallback(); - } - - private boolean areConnDiagCapsRedacted(NetworkCapabilities nc) { - TestTransportInfo ti = (TestTransportInfo) nc.getTransportInfo(); - return nc.getUids() == null - && nc.getAdministratorUids().length == 0 - && nc.getOwnerUid() == Process.INVALID_UID - && getTestTransportInfo(nc).locationRedacted - && getTestTransportInfo(nc).localMacAddressRedacted - && getTestTransportInfo(nc).settingsRedacted; - } - - @Test - public void testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable() - throws Exception { - setUpConnectivityDiagnosticsCallback(); - - // Block until all other events are done processing. - HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); - - // Verify onConnectivityReport fired - verify(mConnectivityDiagnosticsCallback).onConnectivityReportAvailable( - argThat(report -> areConnDiagCapsRedacted(report.getNetworkCapabilities()))); - } - - @Test - public void testConnectivityDiagnosticsCallbackOnDataStallSuspected() throws Exception { - setUpConnectivityDiagnosticsCallback(); - - // Trigger notifyDataStallSuspected() on the INetworkMonitorCallbacks instance in the - // cellular network agent - mCellNetworkAgent.notifyDataStallSuspected(); - - // Block until all other events are done processing. - HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); - - // Verify onDataStallSuspected fired - verify(mConnectivityDiagnosticsCallback).onDataStallSuspected( - argThat(report -> areConnDiagCapsRedacted(report.getNetworkCapabilities()))); - } - - @Test - public void testConnectivityDiagnosticsCallbackOnConnectivityReported() throws Exception { - setUpConnectivityDiagnosticsCallback(); - - final Network n = mCellNetworkAgent.getNetwork(); - final boolean hasConnectivity = true; - mService.reportNetworkConnectivity(n, hasConnectivity); - - // Block until all other events are done processing. - HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); - - // Verify onNetworkConnectivityReported fired - verify(mConnectivityDiagnosticsCallback) - .onNetworkConnectivityReported(eq(n), eq(hasConnectivity)); - - final boolean noConnectivity = false; - mService.reportNetworkConnectivity(n, noConnectivity); - - // Block until all other events are done processing. - HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS); - - // Wait for onNetworkConnectivityReported to fire - verify(mConnectivityDiagnosticsCallback) - .onNetworkConnectivityReported(eq(n), eq(noConnectivity)); - } - - @Test - public void testRouteAddDeleteUpdate() throws Exception { - final NetworkRequest request = new NetworkRequest.Builder().build(); - final TestNetworkCallback networkCallback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, networkCallback); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - reset(mMockNetd); - mCellNetworkAgent.connect(false); - networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - final int netId = mCellNetworkAgent.getNetwork().netId; - - final String iface = "rmnet_data0"; - final InetAddress gateway = InetAddress.getByName("fe80::5678"); - RouteInfo direct = RouteInfo.makeHostRoute(gateway, iface); - RouteInfo rio1 = new RouteInfo(new IpPrefix("2001:db8:1::/48"), gateway, iface); - RouteInfo rio2 = new RouteInfo(new IpPrefix("2001:db8:2::/48"), gateway, iface); - RouteInfo defaultRoute = new RouteInfo((IpPrefix) null, gateway, iface); - RouteInfo defaultWithMtu = new RouteInfo(null, gateway, iface, RouteInfo.RTN_UNICAST, - 1280 /* mtu */); - - // Send LinkProperties and check that we ask netd to add routes. - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName(iface); - lp.addRoute(direct); - lp.addRoute(rio1); - lp.addRoute(defaultRoute); - mCellNetworkAgent.sendLinkProperties(lp); - networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, x -> x.getRoutes().size() == 3); - - assertRoutesAdded(netId, direct, rio1, defaultRoute); - reset(mMockNetd); - - // Send updated LinkProperties and check that we ask netd to add, remove, update routes. - assertTrue(lp.getRoutes().contains(defaultRoute)); - lp.removeRoute(rio1); - lp.addRoute(rio2); - lp.addRoute(defaultWithMtu); - // Ensure adding the same route with a different MTU replaces the previous route. - assertFalse(lp.getRoutes().contains(defaultRoute)); - assertTrue(lp.getRoutes().contains(defaultWithMtu)); - - mCellNetworkAgent.sendLinkProperties(lp); - networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, - x -> x.getRoutes().contains(rio2)); - - assertRoutesRemoved(netId, rio1); - assertRoutesAdded(netId, rio2); - - ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); - verify(mMockNetd).networkUpdateRouteParcel(eq(netId), captor.capture()); - assertRouteInfoParcelMatches(defaultWithMtu, captor.getValue()); - - - mCm.unregisterNetworkCallback(networkCallback); - } - - @Test - public void testDumpDoesNotCrash() { - mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); - // Filing a couple requests prior to testing the dump. - final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); - final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); - final NetworkRequest genericRequest = new NetworkRequest.Builder() - .clearCapabilities().build(); - final NetworkRequest wifiRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI).build(); - mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); - mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); - final StringWriter stringWriter = new StringWriter(); - - mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); - - assertFalse(stringWriter.toString().isEmpty()); - } - - @Test - public void testRequestsSortedByIdSortsCorrectly() { - final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); - final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); - final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); - final NetworkRequest genericRequest = new NetworkRequest.Builder() - .clearCapabilities().build(); - final NetworkRequest wifiRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI).build(); - final NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR).build(); - mCm.registerNetworkCallback(genericRequest, genericNetworkCallback); - mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback); - mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); - waitForIdle(); - - final ConnectivityService.NetworkRequestInfo[] nriOutput = mService.requestsSortedById(); - - assertTrue(nriOutput.length > 1); - for (int i = 0; i < nriOutput.length - 1; i++) { - final boolean isRequestIdInOrder = - nriOutput[i].mRequests.get(0).requestId - < nriOutput[i + 1].mRequests.get(0).requestId; - assertTrue(isRequestIdInOrder); - } - } - - private void assertUidRangesUpdatedForMyUid(boolean add) throws Exception { - final int uid = Process.myUid(); - assertVpnUidRangesUpdated(add, uidRangesForUids(uid), uid); - } - - private void assertVpnUidRangesUpdated(boolean add, Set<UidRange> vpnRanges, int exemptUid) - throws Exception { - InOrder inOrder = inOrder(mMockNetd); - ArgumentCaptor<int[]> exemptUidCaptor = ArgumentCaptor.forClass(int[].class); - - inOrder.verify(mMockNetd, times(1)).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)), - exemptUidCaptor.capture()); - assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid); - - if (add) { - inOrder.verify(mMockNetd, times(1)) - .networkAddUidRanges(eq(mMockVpn.getNetwork().getNetId()), - eq(toUidRangeStableParcels(vpnRanges))); - } else { - inOrder.verify(mMockNetd, times(1)) - .networkRemoveUidRanges(eq(mMockVpn.getNetwork().getNetId()), - eq(toUidRangeStableParcels(vpnRanges))); - } - - inOrder.verify(mMockNetd, times(1)).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)), - exemptUidCaptor.capture()); - assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid); - } - - @Test - public void testVpnUidRangesUpdate() throws Exception { - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName("tun0"); - lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); - lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); - final UidRange vpnRange = PRIMARY_UIDRANGE; - Set<UidRange> vpnRanges = Collections.singleton(vpnRange); - mMockVpn.establish(lp, VPN_UID, vpnRanges); - assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); - - reset(mMockNetd); - // Update to new range which is old range minus APP1, i.e. only APP2 - final Set<UidRange> newRanges = new HashSet<>(Arrays.asList( - new UidRange(vpnRange.start, APP1_UID - 1), - new UidRange(APP1_UID + 1, vpnRange.stop))); - mMockVpn.setUids(newRanges); - waitForIdle(); - - assertVpnUidRangesUpdated(true, newRanges, VPN_UID); - assertVpnUidRangesUpdated(false, vpnRanges, VPN_UID); - } - - @Test - public void testInvalidRequestTypes() { - final int[] invalidReqTypeInts = new int[]{-1, NetworkRequest.Type.NONE.ordinal(), - NetworkRequest.Type.LISTEN.ordinal(), NetworkRequest.Type.values().length}; - final NetworkCapabilities nc = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI); - - for (int reqTypeInt : invalidReqTypeInts) { - assertThrows("Expect throws for invalid request type " + reqTypeInt, - IllegalArgumentException.class, - () -> mService.requestNetwork(Process.INVALID_UID, nc, reqTypeInt, null, 0, - null, ConnectivityManager.TYPE_NONE, NetworkCallback.FLAG_NONE, - mContext.getPackageName(), getAttributionTag()) - ); - } - } - - @Test - public void testKeepConnected() throws Exception { - setAlwaysOnNetworks(false); - registerDefaultNetworkCallbacks(); - final TestNetworkCallback allNetworksCb = new TestNetworkCallback(); - final NetworkRequest allNetworksRequest = new NetworkRequest.Builder().clearCapabilities() - .build(); - mCm.registerNetworkCallback(allNetworksRequest, allNetworksCb); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true /* validated */); - - mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - allNetworksCb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true /* validated */); - - mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - // While the default callback doesn't see the network before it's validated, the listen - // sees the network come up and validate later - allNetworksCb.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); - allNetworksCb.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); - allNetworksCb.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); - allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, - TEST_LINGER_DELAY_MS * 2); - - // The cell network has disconnected (see LOST above) because it was outscored and - // had no requests (see setAlwaysOnNetworks(false) above) - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - final NetworkScore score = new NetworkScore.Builder().setLegacyInt(30).build(); - mCellNetworkAgent.setScore(score); - mCellNetworkAgent.connect(false /* validated */); - - // The cell network gets torn down right away. - allNetworksCb.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, - TEST_NASCENT_DELAY_MS * 2); - allNetworksCb.assertNoCallback(); - - // Now create a cell network with KEEP_CONNECTED_FOR_HANDOVER and make sure it's - // not disconnected immediately when outscored. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - final NetworkScore scoreKeepup = new NetworkScore.Builder().setLegacyInt(30) - .setKeepConnectedReason(KEEP_CONNECTED_FOR_HANDOVER).build(); - mCellNetworkAgent.setScore(scoreKeepup); - mCellNetworkAgent.connect(true /* validated */); - - allNetworksCb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - mDefaultNetworkCallback.assertNoCallback(); - - mWiFiNetworkAgent.disconnect(); - - allNetworksCb.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - - // Reconnect a WiFi network and make sure the cell network is still not torn down. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true /* validated */); - - allNetworksCb.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); - mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - - // Now remove the reason to keep connected and make sure the network lingers and is - // torn down. - mCellNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).build()); - allNetworksCb.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent, - TEST_NASCENT_DELAY_MS * 2); - allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, - TEST_LINGER_DELAY_MS * 2); - mDefaultNetworkCallback.assertNoCallback(); - - mCm.unregisterNetworkCallback(allNetworksCb); - // mDefaultNetworkCallback will be unregistered by tearDown() - } - - private class QosCallbackMockHelper { - @NonNull public final QosFilter mFilter; - @NonNull public final IQosCallback mCallback; - @NonNull public final TestNetworkAgentWrapper mAgentWrapper; - @NonNull private final List<IQosCallback> mCallbacks = new ArrayList(); - - QosCallbackMockHelper() throws Exception { - Log.d(TAG, "QosCallbackMockHelper: "); - mFilter = mock(QosFilter.class); - - // Ensure the network is disconnected before anything else occurs - assertNull(mCellNetworkAgent); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - - verifyActiveNetwork(TRANSPORT_CELLULAR); - waitForIdle(); - final Network network = mCellNetworkAgent.getNetwork(); - - final Pair<IQosCallback, IBinder> pair = createQosCallback(); - mCallback = pair.first; - - when(mFilter.getNetwork()).thenReturn(network); - when(mFilter.validate()).thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE); - mAgentWrapper = mCellNetworkAgent; - } - - void registerQosCallback(@NonNull final QosFilter filter, - @NonNull final IQosCallback callback) { - mCallbacks.add(callback); - final NetworkAgentInfo nai = - mService.getNetworkAgentInfoForNetwork(filter.getNetwork()); - mService.registerQosCallbackInternal(filter, callback, nai); - } - - void tearDown() { - for (int i = 0; i < mCallbacks.size(); i++) { - mService.unregisterQosCallback(mCallbacks.get(i)); - } - } - } - - private Pair<IQosCallback, IBinder> createQosCallback() { - final IQosCallback callback = mock(IQosCallback.class); - final IBinder binder = mock(Binder.class); - when(callback.asBinder()).thenReturn(binder); - when(binder.isBinderAlive()).thenReturn(true); - return new Pair<>(callback, binder); - } - - - @Test - public void testQosCallbackRegistration() throws Exception { - mQosCallbackMockHelper = new QosCallbackMockHelper(); - final NetworkAgentWrapper wrapper = mQosCallbackMockHelper.mAgentWrapper; - - when(mQosCallbackMockHelper.mFilter.validate()) - .thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE); - mQosCallbackMockHelper.registerQosCallback( - mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); - - final NetworkAgentWrapper.CallbackType.OnQosCallbackRegister cbRegister1 = - (NetworkAgentWrapper.CallbackType.OnQosCallbackRegister) - wrapper.getCallbackHistory().poll(1000, x -> true); - assertNotNull(cbRegister1); - - final int registerCallbackId = cbRegister1.mQosCallbackId; - mService.unregisterQosCallback(mQosCallbackMockHelper.mCallback); - final NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister cbUnregister; - cbUnregister = (NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister) - wrapper.getCallbackHistory().poll(1000, x -> true); - assertNotNull(cbUnregister); - assertEquals(registerCallbackId, cbUnregister.mQosCallbackId); - assertNull(wrapper.getCallbackHistory().poll(200, x -> true)); - } - - @Test - public void testQosCallbackNoRegistrationOnValidationError() throws Exception { - mQosCallbackMockHelper = new QosCallbackMockHelper(); - - when(mQosCallbackMockHelper.mFilter.validate()) - .thenReturn(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED); - mQosCallbackMockHelper.registerQosCallback( - mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); - waitForIdle(); - verify(mQosCallbackMockHelper.mCallback) - .onError(eq(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED)); - } - - @Test - public void testQosCallbackAvailableAndLost() throws Exception { - mQosCallbackMockHelper = new QosCallbackMockHelper(); - final int sessionId = 10; - final int qosCallbackId = 1; - - when(mQosCallbackMockHelper.mFilter.validate()) - .thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE); - mQosCallbackMockHelper.registerQosCallback( - mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); - waitForIdle(); - - final EpsBearerQosSessionAttributes attributes = new EpsBearerQosSessionAttributes( - 1, 2, 3, 4, 5, new ArrayList<>()); - mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() - .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); - waitForIdle(); - - verify(mQosCallbackMockHelper.mCallback).onQosEpsBearerSessionAvailable(argThat(session -> - session.getSessionId() == sessionId - && session.getSessionType() == QosSession.TYPE_EPS_BEARER), eq(attributes)); - - mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() - .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_EPS_BEARER); - waitForIdle(); - verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session -> - session.getSessionId() == sessionId - && session.getSessionType() == QosSession.TYPE_EPS_BEARER)); - } - - @Test - public void testNrQosCallbackAvailableAndLost() throws Exception { - mQosCallbackMockHelper = new QosCallbackMockHelper(); - final int sessionId = 10; - final int qosCallbackId = 1; - - when(mQosCallbackMockHelper.mFilter.validate()) - .thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE); - mQosCallbackMockHelper.registerQosCallback( - mQosCallbackMockHelper.mFilter, mQosCallbackMockHelper.mCallback); - waitForIdle(); - - final NrQosSessionAttributes attributes = new NrQosSessionAttributes( - 1, 2, 3, 4, 5, 6, 7, new ArrayList<>()); - mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() - .sendQosSessionAvailable(qosCallbackId, sessionId, attributes); - waitForIdle(); - - verify(mQosCallbackMockHelper.mCallback).onNrQosSessionAvailable(argThat(session -> - session.getSessionId() == sessionId - && session.getSessionType() == QosSession.TYPE_NR_BEARER), eq(attributes)); - - mQosCallbackMockHelper.mAgentWrapper.getNetworkAgent() - .sendQosSessionLost(qosCallbackId, sessionId, QosSession.TYPE_NR_BEARER); - waitForIdle(); - verify(mQosCallbackMockHelper.mCallback).onQosSessionLost(argThat(session -> - session.getSessionId() == sessionId - && session.getSessionType() == QosSession.TYPE_NR_BEARER)); - } - - @Test - public void testQosCallbackTooManyRequests() throws Exception { - mQosCallbackMockHelper = new QosCallbackMockHelper(); - - when(mQosCallbackMockHelper.mFilter.validate()) - .thenReturn(QosCallbackException.EX_TYPE_FILTER_NONE); - for (int i = 0; i < 100; i++) { - final Pair<IQosCallback, IBinder> pair = createQosCallback(); - - try { - mQosCallbackMockHelper.registerQosCallback( - mQosCallbackMockHelper.mFilter, pair.first); - } catch (ServiceSpecificException e) { - assertEquals(e.errorCode, ConnectivityManager.Errors.TOO_MANY_REQUESTS); - if (i < 50) { - fail("TOO_MANY_REQUESTS thrown too early, the count is " + i); - } - - // As long as there is at least 50 requests, it is safe to assume it works. - // Note: The count isn't being tested precisely against 100 because the counter - // is shared with request network. - return; - } - } - fail("TOO_MANY_REQUESTS never thrown"); - } - - private UidRange createUidRange(int userId) { - return UidRange.createForUser(UserHandle.of(userId)); - } - - private void mockGetApplicationInfo(@NonNull final String packageName, @NonNull final int uid) { - final ApplicationInfo applicationInfo = new ApplicationInfo(); - applicationInfo.uid = uid; - try { - when(mPackageManager.getApplicationInfo(eq(packageName), anyInt())) - .thenReturn(applicationInfo); - } catch (Exception e) { - fail(e.getMessage()); - } - } - - private void mockGetApplicationInfoThrowsNameNotFound(@NonNull final String packageName) - throws Exception { - when(mPackageManager.getApplicationInfo(eq(packageName), anyInt())) - .thenThrow(new PackageManager.NameNotFoundException(packageName)); - } - - private void mockHasSystemFeature(@NonNull final String featureName, - @NonNull final boolean hasFeature) { - when(mPackageManager.hasSystemFeature(eq(featureName))) - .thenReturn(hasFeature); - } - - private Range<Integer> getNriFirstUidRange( - @NonNull final ConnectivityService.NetworkRequestInfo nri) { - return nri.mRequests.get(0).networkCapabilities.getUids().iterator().next(); - } - - private OemNetworkPreferences createDefaultOemNetworkPreferences( - @OemNetworkPreferences.OemNetworkPreference final int preference) { - // Arrange PackageManager mocks - mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); - - // Build OemNetworkPreferences object - return new OemNetworkPreferences.Builder() - .addNetworkPreference(TEST_PACKAGE_NAME, preference) - .build(); - } - - @Test - public void testOemNetworkRequestFactoryPreferenceUninitializedThrowsError() - throws PackageManager.NameNotFoundException { - @OemNetworkPreferences.OemNetworkPreference final int prefToTest = - OEM_NETWORK_PREFERENCE_UNINITIALIZED; - - // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() - assertThrows(IllegalArgumentException.class, - () -> mService.new OemNetworkRequestFactory() - .createNrisFromOemNetworkPreferences( - createDefaultOemNetworkPreferences(prefToTest))); - } - - @Test - public void testOemNetworkRequestFactoryPreferenceOemPaid() - throws Exception { - // Expectations - final int expectedNumOfNris = 1; - final int expectedNumOfRequests = 3; - - @OemNetworkPreferences.OemNetworkPreference final int prefToTest = - OEM_NETWORK_PREFERENCE_OEM_PAID; - - // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() - final ArraySet<ConnectivityService.NetworkRequestInfo> nris = - mService.new OemNetworkRequestFactory() - .createNrisFromOemNetworkPreferences( - createDefaultOemNetworkPreferences(prefToTest)); - - final List<NetworkRequest> mRequests = nris.iterator().next().mRequests; - assertEquals(expectedNumOfNris, nris.size()); - assertEquals(expectedNumOfRequests, mRequests.size()); - assertTrue(mRequests.get(0).isListen()); - assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_NOT_METERED)); - assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_VALIDATED)); - assertTrue(mRequests.get(1).isRequest()); - assertTrue(mRequests.get(1).hasCapability(NET_CAPABILITY_OEM_PAID)); - assertEquals(NetworkRequest.Type.TRACK_DEFAULT, mRequests.get(2).type); - assertTrue(mService.getDefaultRequest().networkCapabilities.equalsNetCapabilities( - mRequests.get(2).networkCapabilities)); - } - - @Test - public void testOemNetworkRequestFactoryPreferenceOemPaidNoFallback() - throws Exception { - // Expectations - final int expectedNumOfNris = 1; - final int expectedNumOfRequests = 2; - - @OemNetworkPreferences.OemNetworkPreference final int prefToTest = - OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; - - // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() - final ArraySet<ConnectivityService.NetworkRequestInfo> nris = - mService.new OemNetworkRequestFactory() - .createNrisFromOemNetworkPreferences( - createDefaultOemNetworkPreferences(prefToTest)); - - final List<NetworkRequest> mRequests = nris.iterator().next().mRequests; - assertEquals(expectedNumOfNris, nris.size()); - assertEquals(expectedNumOfRequests, mRequests.size()); - assertTrue(mRequests.get(0).isListen()); - assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_NOT_METERED)); - assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_VALIDATED)); - assertTrue(mRequests.get(1).isRequest()); - assertTrue(mRequests.get(1).hasCapability(NET_CAPABILITY_OEM_PAID)); - } - - @Test - public void testOemNetworkRequestFactoryPreferenceOemPaidOnly() - throws Exception { - // Expectations - final int expectedNumOfNris = 1; - final int expectedNumOfRequests = 1; - - @OemNetworkPreferences.OemNetworkPreference final int prefToTest = - OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; - - // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() - final ArraySet<ConnectivityService.NetworkRequestInfo> nris = - mService.new OemNetworkRequestFactory() - .createNrisFromOemNetworkPreferences( - createDefaultOemNetworkPreferences(prefToTest)); - - final List<NetworkRequest> mRequests = nris.iterator().next().mRequests; - assertEquals(expectedNumOfNris, nris.size()); - assertEquals(expectedNumOfRequests, mRequests.size()); - assertTrue(mRequests.get(0).isRequest()); - assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PAID)); - } - - @Test - public void testOemNetworkRequestFactoryPreferenceOemPrivateOnly() - throws Exception { - // Expectations - final int expectedNumOfNris = 1; - final int expectedNumOfRequests = 1; - - @OemNetworkPreferences.OemNetworkPreference final int prefToTest = - OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; - - // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() - final ArraySet<ConnectivityService.NetworkRequestInfo> nris = - mService.new OemNetworkRequestFactory() - .createNrisFromOemNetworkPreferences( - createDefaultOemNetworkPreferences(prefToTest)); - - final List<NetworkRequest> mRequests = nris.iterator().next().mRequests; - assertEquals(expectedNumOfNris, nris.size()); - assertEquals(expectedNumOfRequests, mRequests.size()); - assertTrue(mRequests.get(0).isRequest()); - assertTrue(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PRIVATE)); - assertFalse(mRequests.get(0).hasCapability(NET_CAPABILITY_OEM_PAID)); - } - - @Test - public void testOemNetworkRequestFactoryCreatesCorrectNumOfNris() - throws Exception { - // Expectations - final int expectedNumOfNris = 2; - - // Arrange PackageManager mocks - final String testPackageName2 = "com.google.apps.dialer"; - mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); - mockGetApplicationInfo(testPackageName2, TEST_PACKAGE_UID); - - // Build OemNetworkPreferences object - final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; - final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; - final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() - .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) - .addNetworkPreference(testPackageName2, testOemPref2) - .build(); - - // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() - final ArraySet<ConnectivityService.NetworkRequestInfo> nris = - mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(pref); - - assertNotNull(nris); - assertEquals(expectedNumOfNris, nris.size()); - } - - @Test - public void testOemNetworkRequestFactoryMultiplePrefsCorrectlySetsUids() - throws Exception { - // Arrange PackageManager mocks - final String testPackageName2 = "com.google.apps.dialer"; - final int testPackageNameUid2 = 456; - mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); - mockGetApplicationInfo(testPackageName2, testPackageNameUid2); - - // Build OemNetworkPreferences object - final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; - final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; - final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() - .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) - .addNetworkPreference(testPackageName2, testOemPref2) - .build(); - - // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() - final List<ConnectivityService.NetworkRequestInfo> nris = - new ArrayList<>( - mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences( - pref)); - - // Sort by uid to access nris by index - nris.sort(Comparator.comparingInt(nri -> getNriFirstUidRange(nri).getLower())); - assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getLower()); - assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getUpper()); - assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getLower()); - assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getUpper()); - } - - @Test - public void testOemNetworkRequestFactoryMultipleUsersCorrectlySetsUids() - throws Exception { - // Arrange users - final int secondUser = 10; - final UserHandle secondUserHandle = new UserHandle(secondUser); - when(mUserManager.getUserHandles(anyBoolean())).thenReturn( - Arrays.asList(PRIMARY_USER_HANDLE, secondUserHandle)); - - // Arrange PackageManager mocks - mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); - - // Build OemNetworkPreferences object - final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; - final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() - .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) - .build(); - - // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() - final List<ConnectivityService.NetworkRequestInfo> nris = - new ArrayList<>( - mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences( - pref)); - - // UIDs for all users and all managed packages should be present. - // Two users each with two packages. - final int expectedUidSize = 2; - final List<Range<Integer>> uids = - new ArrayList<>(nris.get(0).mRequests.get(0).networkCapabilities.getUids()); - assertEquals(expectedUidSize, uids.size()); - - // Sort by uid to access nris by index - uids.sort(Comparator.comparingInt(uid -> uid.getLower())); - final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); - assertEquals(TEST_PACKAGE_UID, (int) uids.get(0).getLower()); - assertEquals(TEST_PACKAGE_UID, (int) uids.get(0).getUpper()); - assertEquals(secondUserTestPackageUid, (int) uids.get(1).getLower()); - assertEquals(secondUserTestPackageUid, (int) uids.get(1).getUpper()); - } - - @Test - public void testOemNetworkRequestFactoryAddsPackagesToCorrectPreference() - throws Exception { - // Expectations - final int expectedNumOfNris = 1; - final int expectedNumOfAppUids = 2; - - // Arrange PackageManager mocks - final String testPackageName2 = "com.google.apps.dialer"; - final int testPackageNameUid2 = 456; - mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); - mockGetApplicationInfo(testPackageName2, testPackageNameUid2); - - // Build OemNetworkPreferences object - final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; - final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() - .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) - .addNetworkPreference(testPackageName2, testOemPref) - .build(); - - // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() - final ArraySet<ConnectivityService.NetworkRequestInfo> nris = - mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(pref); - - assertEquals(expectedNumOfNris, nris.size()); - assertEquals(expectedNumOfAppUids, - nris.iterator().next().mRequests.get(0).networkCapabilities.getUids().size()); - } - - @Test - public void testSetOemNetworkPreferenceNullListenerAndPrefParamThrowsNpe() { - mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); - - // Act on ConnectivityService.setOemNetworkPreference() - assertThrows(NullPointerException.class, - () -> mService.setOemNetworkPreference( - null, - null)); - } - - @Test - public void testSetOemNetworkPreferenceFailsForNonAutomotive() - throws Exception { - mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; - - // Act on ConnectivityService.setOemNetworkPreference() - assertThrows(UnsupportedOperationException.class, - () -> mService.setOemNetworkPreference( - createDefaultOemNetworkPreferences(networkPref), - new TestOemListenerCallback())); - } - - private void setOemNetworkPreferenceAgentConnected(final int transportType, - final boolean connectAgent) throws Exception { - switch(transportType) { - // Corresponds to a metered cellular network. Will be used for the default network. - case TRANSPORT_CELLULAR: - if (!connectAgent) { - mCellNetworkAgent.disconnect(); - break; - } - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); - mCellNetworkAgent.connect(true); - break; - // Corresponds to a restricted ethernet network with OEM_PAID/OEM_PRIVATE. - case TRANSPORT_ETHERNET: - if (!connectAgent) { - stopOemManagedNetwork(); - break; - } - startOemManagedNetwork(true); - break; - // Corresponds to unmetered Wi-Fi. - case TRANSPORT_WIFI: - if (!connectAgent) { - mWiFiNetworkAgent.disconnect(); - break; - } - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - mWiFiNetworkAgent.connect(true); - break; - default: - throw new AssertionError("Unsupported transport type passed in."); - - } - waitForIdle(); - } - - private void startOemManagedNetwork(final boolean isOemPaid) throws Exception { - mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); - mEthernetNetworkAgent.addCapability( - isOemPaid ? NET_CAPABILITY_OEM_PAID : NET_CAPABILITY_OEM_PRIVATE); - mEthernetNetworkAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); - mEthernetNetworkAgent.connect(true); - } - - private void stopOemManagedNetwork() { - mEthernetNetworkAgent.disconnect(); - waitForIdle(); - } - - private void verifyMultipleDefaultNetworksTracksCorrectly( - final int expectedOemRequestsSize, - @NonNull final Network expectedDefaultNetwork, - @NonNull final Network expectedPerAppNetwork) { - // The current test setup assumes two tracked default network requests; one for the default - // network and the other for the OEM network preference being tested. This will be validated - // each time to confirm it doesn't change under test. - final int expectedDefaultNetworkRequestsSize = 2; - assertEquals(expectedDefaultNetworkRequestsSize, mService.mDefaultNetworkRequests.size()); - for (final ConnectivityService.NetworkRequestInfo defaultRequest - : mService.mDefaultNetworkRequests) { - final Network defaultNetwork = defaultRequest.getSatisfier() == null - ? null : defaultRequest.getSatisfier().network(); - // If this is the default request. - if (defaultRequest == mService.mDefaultRequest) { - assertEquals( - expectedDefaultNetwork, - defaultNetwork); - // Make sure this value doesn't change. - assertEquals(1, defaultRequest.mRequests.size()); - continue; - } - assertEquals(expectedPerAppNetwork, defaultNetwork); - assertEquals(expectedOemRequestsSize, defaultRequest.mRequests.size()); - } - verifyMultipleDefaultCallbacks(expectedDefaultNetwork, expectedPerAppNetwork); - } - - /** - * Verify default callbacks for 'available' fire as expected. This will only run if - * registerDefaultNetworkCallbacks() was executed prior and will only be different if the - * setOemNetworkPreference() per-app API was used for the current process. - * @param expectedSystemDefault the expected network for the system default. - * @param expectedPerAppDefault the expected network for the current process's default. - */ - private void verifyMultipleDefaultCallbacks( - @NonNull final Network expectedSystemDefault, - @NonNull final Network expectedPerAppDefault) { - if (null != mSystemDefaultNetworkCallback && null != expectedSystemDefault - && mService.mNoServiceNetwork.network() != expectedSystemDefault) { - // getLastAvailableNetwork() is used as this method can be called successively with - // the same network to validate therefore expectAvailableThenValidatedCallbacks - // can't be used. - assertEquals(mSystemDefaultNetworkCallback.getLastAvailableNetwork(), - expectedSystemDefault); - } - if (null != mDefaultNetworkCallback && null != expectedPerAppDefault - && mService.mNoServiceNetwork.network() != expectedPerAppDefault) { - assertEquals(mDefaultNetworkCallback.getLastAvailableNetwork(), - expectedPerAppDefault); - } - } - - private void registerDefaultNetworkCallbacks() { - // Using Manifest.permission.NETWORK_SETTINGS for registerSystemDefaultNetworkCallback() - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); - mSystemDefaultNetworkCallback = new TestNetworkCallback(); - mDefaultNetworkCallback = new TestNetworkCallback(); - mProfileDefaultNetworkCallback = new TestNetworkCallback(); - mCm.registerSystemDefaultNetworkCallback(mSystemDefaultNetworkCallback, - new Handler(ConnectivityThread.getInstanceLooper())); - mCm.registerDefaultNetworkCallback(mDefaultNetworkCallback); - registerDefaultNetworkCallbackAsUid(mProfileDefaultNetworkCallback, - TEST_WORK_PROFILE_APP_UID); - // TODO: test using ConnectivityManager#registerDefaultNetworkCallbackAsUid as well. - mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_DENIED); - } - - private void unregisterDefaultNetworkCallbacks() { - if (null != mDefaultNetworkCallback) { - mCm.unregisterNetworkCallback(mDefaultNetworkCallback); - } - if (null != mSystemDefaultNetworkCallback) { - mCm.unregisterNetworkCallback(mSystemDefaultNetworkCallback); - } - if (null != mProfileDefaultNetworkCallback) { - mCm.unregisterNetworkCallback(mProfileDefaultNetworkCallback); - } - } - - private void setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest( - @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup) - throws Exception { - final int testPackageNameUid = TEST_PACKAGE_UID; - final String testPackageName = "per.app.defaults.package"; - setupMultipleDefaultNetworksForOemNetworkPreferenceTest( - networkPrefToSetup, testPackageNameUid, testPackageName); - } - - private void setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest( - @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup) - throws Exception { - final int testPackageNameUid = Process.myUid(); - final String testPackageName = "per.app.defaults.package"; - setupMultipleDefaultNetworksForOemNetworkPreferenceTest( - networkPrefToSetup, testPackageNameUid, testPackageName); - } - - private void setupMultipleDefaultNetworksForOemNetworkPreferenceTest( - @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, - final int testPackageUid, @NonNull final String testPackageName) throws Exception { - // Only the default request should be included at start. - assertEquals(1, mService.mDefaultNetworkRequests.size()); - - final UidRangeParcel[] uidRanges = - toUidRangeStableParcels(uidRangesForUids(testPackageUid)); - setupSetOemNetworkPreferenceForPreferenceTest( - networkPrefToSetup, uidRanges, testPackageName); - } - - private void setupSetOemNetworkPreferenceForPreferenceTest( - @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup, - @NonNull final UidRangeParcel[] uidRanges, - @NonNull final String testPackageName) - throws Exception { - // These tests work off a single UID therefore using 'start' is valid. - mockGetApplicationInfo(testPackageName, uidRanges[0].start); - - setOemNetworkPreference(networkPrefToSetup, testPackageName); - } - - private void setOemNetworkPreference(final int networkPrefToSetup, - @NonNull final String... testPackageNames) - throws Exception { - mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); - - // Build OemNetworkPreferences object - final OemNetworkPreferences.Builder builder = new OemNetworkPreferences.Builder(); - for (final String packageName : testPackageNames) { - builder.addNetworkPreference(packageName, networkPrefToSetup); - } - final OemNetworkPreferences pref = builder.build(); - - // Act on ConnectivityService.setOemNetworkPreference() - final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback(); - mService.setOemNetworkPreference(pref, oemPrefListener); - - // Verify call returned successfully - oemPrefListener.expectOnComplete(); - } - - private static class TestOemListenerCallback implements IOnCompleteListener { - final CompletableFuture<Object> mDone = new CompletableFuture<>(); - - @Override - public void onComplete() { - mDone.complete(new Object()); - } - - void expectOnComplete() { - try { - mDone.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); - } catch (TimeoutException e) { - fail("Expected onComplete() not received after " + TIMEOUT_MS + " ms"); - } catch (Exception e) { - fail(e.getMessage()); - } - } - - @Override - public IBinder asBinder() { - return null; - } - } - - @Test - public void testMultiDefaultGetActiveNetworkIsCorrect() throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; - final int expectedOemPrefRequestSize = 1; - registerDefaultNetworkCallbacks(); - - // Setup the test process to use networkPref for their default network. - setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); - - // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. - // The active network for the default should be null at this point as this is a retricted - // network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mEthernetNetworkAgent.getNetwork()); - - // Verify that the active network is correct - verifyActiveNetwork(TRANSPORT_ETHERNET); - // default NCs will be unregistered in tearDown - } - - @Test - public void testMultiDefaultIsActiveNetworkMeteredIsCorrect() throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; - final int expectedOemPrefRequestSize = 1; - registerDefaultNetworkCallbacks(); - - // Setup the test process to use networkPref for their default network. - setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); - - // Returns true by default when no network is available. - assertTrue(mCm.isActiveNetworkMetered()); - - // Connect to an unmetered restricted network that will only be available to the OEM pref. - mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET); - mEthernetNetworkAgent.addCapability(NET_CAPABILITY_OEM_PAID); - mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - mEthernetNetworkAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); - mEthernetNetworkAgent.connect(true); - waitForIdle(); - - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mEthernetNetworkAgent.getNetwork()); - - assertFalse(mCm.isActiveNetworkMetered()); - // default NCs will be unregistered in tearDown - } - - @Test - public void testPerAppDefaultRegisterDefaultNetworkCallback() throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; - final int expectedOemPrefRequestSize = 1; - final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); - - // Register the default network callback before the pref is already set. This means that - // the policy will be applied to the callback on setOemNetworkPreference(). - mCm.registerDefaultNetworkCallback(defaultNetworkCallback); - defaultNetworkCallback.assertNoCallback(); - - final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); - withPermission(NETWORK_SETTINGS, () -> - mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, - new Handler(ConnectivityThread.getInstanceLooper()))); - - // Setup the test process to use networkPref for their default network. - setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); - - // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. - // The active nai for the default is null at this point as this is a restricted network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mEthernetNetworkAgent.getNetwork()); - - // At this point with a restricted network used, the available callback should trigger. - defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); - assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), - mEthernetNetworkAgent.getNetwork()); - otherUidDefaultCallback.assertNoCallback(); - - // Now bring down the default network which should trigger a LOST callback. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); - - // At this point, with no network is available, the lost callback should trigger - defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); - otherUidDefaultCallback.assertNoCallback(); - - // Confirm we can unregister without issues. - mCm.unregisterNetworkCallback(defaultNetworkCallback); - mCm.unregisterNetworkCallback(otherUidDefaultCallback); - } - - @Test - public void testPerAppDefaultRegisterDefaultNetworkCallbackAfterPrefSet() throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; - final int expectedOemPrefRequestSize = 1; - final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); - - // Setup the test process to use networkPref for their default network. - setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); - - // Register the default network callback after the pref is already set. This means that - // the policy will be applied to the callback on requestNetwork(). - mCm.registerDefaultNetworkCallback(defaultNetworkCallback); - defaultNetworkCallback.assertNoCallback(); - - final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); - withPermission(NETWORK_SETTINGS, () -> - mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, - new Handler(ConnectivityThread.getInstanceLooper()))); - - // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. - // The active nai for the default is null at this point as this is a restricted network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mEthernetNetworkAgent.getNetwork()); - - // At this point with a restricted network used, the available callback should trigger - defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); - assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), - mEthernetNetworkAgent.getNetwork()); - otherUidDefaultCallback.assertNoCallback(); - - // Now bring down the default network which should trigger a LOST callback. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); - otherUidDefaultCallback.assertNoCallback(); - - // At this point, with no network is available, the lost callback should trigger - defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); - otherUidDefaultCallback.assertNoCallback(); - - // Confirm we can unregister without issues. - mCm.unregisterNetworkCallback(defaultNetworkCallback); - mCm.unregisterNetworkCallback(otherUidDefaultCallback); - } - - @Test - public void testPerAppDefaultRegisterDefaultNetworkCallbackDoesNotFire() throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; - final int expectedOemPrefRequestSize = 1; - final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); - final int userId = UserHandle.getUserId(Process.myUid()); - - mCm.registerDefaultNetworkCallback(defaultNetworkCallback); - defaultNetworkCallback.assertNoCallback(); - - final TestNetworkCallback otherUidDefaultCallback = new TestNetworkCallback(); - withPermission(NETWORK_SETTINGS, () -> - mCm.registerDefaultNetworkCallbackForUid(TEST_PACKAGE_UID, otherUidDefaultCallback, - new Handler(ConnectivityThread.getInstanceLooper()))); - - // Setup a process different than the test process to use the default network. This means - // that the defaultNetworkCallback won't be tracked by the per-app policy. - setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref); - - // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. - // The active nai for the default is null at this point as this is a restricted network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mEthernetNetworkAgent.getNetwork()); - - // As this callback does not have access to the OEM_PAID network, it will not fire. - defaultNetworkCallback.assertNoCallback(); - assertDefaultNetworkCapabilities(userId /* no networks */); - - // The other UID does have access, and gets a callback. - otherUidDefaultCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent); - - // Bring up unrestricted cellular. This should now satisfy the default network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // At this point with an unrestricted network used, the available callback should trigger - // The other UID is unaffected and remains on the paid network. - defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), - mCellNetworkAgent.getNetwork()); - assertDefaultNetworkCapabilities(userId, mCellNetworkAgent); - otherUidDefaultCallback.assertNoCallback(); - - // Now bring down the per-app network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); - - // Since the callback didn't use the per-app network, only the other UID gets a callback. - // Because the preference specifies no fallback, it does not switch to cellular. - defaultNetworkCallback.assertNoCallback(); - otherUidDefaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent); - - // Now bring down the default network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); - - // As this callback was tracking the default, this should now trigger. - defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - otherUidDefaultCallback.assertNoCallback(); - - // Confirm we can unregister without issues. - mCm.unregisterNetworkCallback(defaultNetworkCallback); - mCm.unregisterNetworkCallback(otherUidDefaultCallback); - } - - /** - * This method assumes that the same uidRanges input will be used to verify that dependencies - * are called as expected. - */ - private void verifySetOemNetworkPreferenceForPreference( - @NonNull final UidRangeParcel[] uidRanges, - final int addUidRangesNetId, - final int addUidRangesTimes, - final int removeUidRangesNetId, - final int removeUidRangesTimes, - final boolean shouldDestroyNetwork) throws RemoteException { - verifySetOemNetworkPreferenceForPreference(uidRanges, uidRanges, - addUidRangesNetId, addUidRangesTimes, removeUidRangesNetId, removeUidRangesTimes, - shouldDestroyNetwork); - } - - private void verifySetOemNetworkPreferenceForPreference( - @NonNull final UidRangeParcel[] addedUidRanges, - @NonNull final UidRangeParcel[] removedUidRanges, - final int addUidRangesNetId, - final int addUidRangesTimes, - final int removeUidRangesNetId, - final int removeUidRangesTimes, - final boolean shouldDestroyNetwork) throws RemoteException { - final boolean useAnyIdForAdd = OEM_PREF_ANY_NET_ID == addUidRangesNetId; - final boolean useAnyIdForRemove = OEM_PREF_ANY_NET_ID == removeUidRangesNetId; - - // Validate netd. - verify(mMockNetd, times(addUidRangesTimes)) - .networkAddUidRanges( - (useAnyIdForAdd ? anyInt() : eq(addUidRangesNetId)), eq(addedUidRanges)); - verify(mMockNetd, times(removeUidRangesTimes)) - .networkRemoveUidRanges( - (useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId)), - eq(removedUidRanges)); - if (shouldDestroyNetwork) { - verify(mMockNetd, times(1)) - .networkDestroy((useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId))); - } - reset(mMockNetd); - } - - /** - * Test the tracked default requests clear previous OEM requests on setOemNetworkPreference(). - */ - @Test - public void testSetOemNetworkPreferenceClearPreviousOemValues() throws Exception { - @OemNetworkPreferences.OemNetworkPreference int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PAID; - final int testPackageUid = 123; - final String testPackageName = "com.google.apps.contacts"; - final UidRangeParcel[] uidRanges = - toUidRangeStableParcels(uidRangesForUids(testPackageUid)); - - // Validate the starting requests only includes the fallback request. - assertEquals(1, mService.mDefaultNetworkRequests.size()); - - // Add an OEM default network request to track. - setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); - - // Two requests should exist, one for the fallback and one for the pref. - assertEquals(2, mService.mDefaultNetworkRequests.size()); - - networkPref = OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; - setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); - - // Two requests should still exist validating the previous per-app request was replaced. - assertEquals(2, mService.mDefaultNetworkRequests.size()); - } - - /** - * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: - * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback - */ - @Test - public void testMultilayerForPreferenceOemPaidEvaluatesCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PAID; - - // Arrange PackageManager mocks - final UidRangeParcel[] uidRanges = - toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); - setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); - - // Verify the starting state. No networks should be connected. - verifySetOemNetworkPreferenceForPreference(uidRanges, - OEM_PREF_ANY_NET_ID, 0 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Test lowest to highest priority requests. - // Bring up metered cellular. This will satisfy the fallback network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifySetOemNetworkPreferenceForPreference(uidRanges, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); - verifySetOemNetworkPreferenceForPreference(uidRanges, - mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - false /* shouldDestroyNetwork */); - - // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); - verifySetOemNetworkPreferenceForPreference(uidRanges, - mWiFiNetworkAgent.getNetwork().netId, 1 /* times */, - mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, - false /* shouldDestroyNetwork */); - - // Disconnecting OEM_PAID should have no effect as it is lower in priority then unmetered. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); - // netd should not be called as default networks haven't changed. - verifySetOemNetworkPreferenceForPreference(uidRanges, - OEM_PREF_ANY_NET_ID, 0 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Disconnecting unmetered should put PANS on lowest priority fallback request. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); - verifySetOemNetworkPreferenceForPreference(uidRanges, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - mWiFiNetworkAgent.getNetwork().netId, 0 /* times */, - true /* shouldDestroyNetwork */); - - // Disconnecting the fallback network should result in no connectivity. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); - verifySetOemNetworkPreferenceForPreference(uidRanges, - OEM_PREF_ANY_NET_ID, 0 /* times */, - mCellNetworkAgent.getNetwork().netId, 0 /* times */, - true /* shouldDestroyNetwork */); - } - - /** - * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: - * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID - */ - @Test - public void testMultilayerForPreferenceOemPaidNoFallbackEvaluatesCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; - - // Arrange PackageManager mocks - final UidRangeParcel[] uidRanges = - toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); - setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); - - // Verify the starting state. This preference doesn't support using the fallback network - // therefore should be on the disconnected network as it has no networks to connect to. - verifySetOemNetworkPreferenceForPreference(uidRanges, - mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Test lowest to highest priority requests. - // Bring up metered cellular. This will satisfy the fallback network. - // This preference should not use this network as it doesn't support fallback usage. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifySetOemNetworkPreferenceForPreference(uidRanges, - OEM_PREF_ANY_NET_ID, 0 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); - verifySetOemNetworkPreferenceForPreference(uidRanges, - mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, - mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, - false /* shouldDestroyNetwork */); - - // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); - verifySetOemNetworkPreferenceForPreference(uidRanges, - mWiFiNetworkAgent.getNetwork().netId, 1 /* times */, - mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, - false /* shouldDestroyNetwork */); - - // Disconnecting unmetered should put PANS on OEM_PAID. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); - verifySetOemNetworkPreferenceForPreference(uidRanges, - mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, - mWiFiNetworkAgent.getNetwork().netId, 0 /* times */, - true /* shouldDestroyNetwork */); - - // Disconnecting OEM_PAID should result in no connectivity. - // OEM_PAID_NO_FALLBACK not supporting a fallback now uses the disconnected network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); - verifySetOemNetworkPreferenceForPreference(uidRanges, - mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, - mEthernetNetworkAgent.getNetwork().netId, 0 /* times */, - true /* shouldDestroyNetwork */); - } - - /** - * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: - * NET_CAPABILITY_OEM_PAID - * This preference should only apply to OEM_PAID networks. - */ - @Test - public void testMultilayerForPreferenceOemPaidOnlyEvaluatesCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; - - // Arrange PackageManager mocks - final UidRangeParcel[] uidRanges = - toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); - setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); - - // Verify the starting state. This preference doesn't support using the fallback network - // therefore should be on the disconnected network as it has no networks to connect to. - verifySetOemNetworkPreferenceForPreference(uidRanges, - mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Bring up metered cellular. This should not apply to this preference. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifySetOemNetworkPreferenceForPreference(uidRanges, - OEM_PREF_ANY_NET_ID, 0 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Bring up unmetered Wi-Fi. This should not apply to this preference. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); - verifySetOemNetworkPreferenceForPreference(uidRanges, - OEM_PREF_ANY_NET_ID, 0 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); - verifySetOemNetworkPreferenceForPreference(uidRanges, - mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, - mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, - false /* shouldDestroyNetwork */); - - // Disconnecting OEM_PAID should result in no connectivity. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); - verifySetOemNetworkPreferenceForPreference(uidRanges, - mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, - mEthernetNetworkAgent.getNetwork().netId, 0 /* times */, - true /* shouldDestroyNetwork */); - } - - /** - * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: - * NET_CAPABILITY_OEM_PRIVATE - * This preference should only apply to OEM_PRIVATE networks. - */ - @Test - public void testMultilayerForPreferenceOemPrivateOnlyEvaluatesCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; - - // Arrange PackageManager mocks - final UidRangeParcel[] uidRanges = - toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); - setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); - - // Verify the starting state. This preference doesn't support using the fallback network - // therefore should be on the disconnected network as it has no networks to connect to. - verifySetOemNetworkPreferenceForPreference(uidRanges, - mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Bring up metered cellular. This should not apply to this preference. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifySetOemNetworkPreferenceForPreference(uidRanges, - OEM_PREF_ANY_NET_ID, 0 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Bring up unmetered Wi-Fi. This should not apply to this preference. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); - verifySetOemNetworkPreferenceForPreference(uidRanges, - OEM_PREF_ANY_NET_ID, 0 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. - startOemManagedNetwork(false); - verifySetOemNetworkPreferenceForPreference(uidRanges, - mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, - mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, - false /* shouldDestroyNetwork */); - - // Disconnecting OEM_PRIVATE should result in no connectivity. - stopOemManagedNetwork(); - verifySetOemNetworkPreferenceForPreference(uidRanges, - mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, - mEthernetNetworkAgent.getNetwork().netId, 0 /* times */, - true /* shouldDestroyNetwork */); - } - - @Test - public void testMultilayerForMultipleUsersEvaluatesCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PAID; - - // Arrange users - final int secondUser = 10; - final UserHandle secondUserHandle = new UserHandle(secondUser); - when(mUserManager.getUserHandles(anyBoolean())).thenReturn( - Arrays.asList(PRIMARY_USER_HANDLE, secondUserHandle)); - - // Arrange PackageManager mocks - final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); - final UidRangeParcel[] uidRanges = - toUidRangeStableParcels( - uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid)); - setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); - - // Verify the starting state. No networks should be connected. - verifySetOemNetworkPreferenceForPreference(uidRanges, - OEM_PREF_ANY_NET_ID, 0 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Test that we correctly add the expected values for multiple users. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifySetOemNetworkPreferenceForPreference(uidRanges, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Test that we correctly remove the expected values for multiple users. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); - verifySetOemNetworkPreferenceForPreference(uidRanges, - OEM_PREF_ANY_NET_ID, 0 /* times */, - mCellNetworkAgent.getNetwork().netId, 0 /* times */, - true /* shouldDestroyNetwork */); - } - - @Test - public void testMultilayerForBroadcastedUsersEvaluatesCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PAID; - - // Arrange users - final int secondUser = 10; - final UserHandle secondUserHandle = new UserHandle(secondUser); - when(mUserManager.getUserHandles(anyBoolean())).thenReturn( - Arrays.asList(PRIMARY_USER_HANDLE)); - - // Arrange PackageManager mocks - final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); - final UidRangeParcel[] uidRangesSingleUser = - toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); - final UidRangeParcel[] uidRangesBothUsers = - toUidRangeStableParcels( - uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid)); - setupSetOemNetworkPreferenceForPreferenceTest( - networkPref, uidRangesSingleUser, TEST_PACKAGE_NAME); - - // Verify the starting state. No networks should be connected. - verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, - OEM_PREF_ANY_NET_ID, 0 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Test that we correctly add the expected values for multiple users. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Send a broadcast indicating a user was added. - when(mUserManager.getUserHandles(anyBoolean())).thenReturn( - Arrays.asList(PRIMARY_USER_HANDLE, secondUserHandle)); - final Intent addedIntent = new Intent(ACTION_USER_ADDED); - addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser)); - processBroadcast(addedIntent); - - // Test that we correctly add values for all users and remove for the single user. - verifySetOemNetworkPreferenceForPreference(uidRangesBothUsers, uidRangesSingleUser, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - false /* shouldDestroyNetwork */); - - // Send a broadcast indicating a user was removed. - when(mUserManager.getUserHandles(anyBoolean())).thenReturn( - Arrays.asList(PRIMARY_USER_HANDLE)); - final Intent removedIntent = new Intent(ACTION_USER_REMOVED); - removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(secondUser)); - processBroadcast(removedIntent); - - // Test that we correctly add values for the single user and remove for the all users. - verifySetOemNetworkPreferenceForPreference(uidRangesSingleUser, uidRangesBothUsers, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - false /* shouldDestroyNetwork */); - } - - @Test - public void testMultilayerForPackageChangesEvaluatesCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PAID; - final String packageScheme = "package:"; - - // Arrange PackageManager mocks - final String packageToInstall = "package.to.install"; - final int packageToInstallUid = 81387; - final UidRangeParcel[] uidRangesSinglePackage = - toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); - mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID); - mockGetApplicationInfoThrowsNameNotFound(packageToInstall); - setOemNetworkPreference(networkPref, TEST_PACKAGE_NAME, packageToInstall); - grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid(), packageToInstall); - - // Verify the starting state. No networks should be connected. - verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, - OEM_PREF_ANY_NET_ID, 0 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Test that we correctly add the expected values for installed packages. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - OEM_PREF_ANY_NET_ID, 0 /* times */, - false /* shouldDestroyNetwork */); - - // Set the system to recognize the package to be installed - mockGetApplicationInfo(packageToInstall, packageToInstallUid); - final UidRangeParcel[] uidRangesAllPackages = - toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID, packageToInstallUid)); - - // Send a broadcast indicating a package was installed. - final Intent addedIntent = new Intent(ACTION_PACKAGE_ADDED); - addedIntent.setData(Uri.parse(packageScheme + packageToInstall)); - processBroadcast(addedIntent); - - // Test the single package is removed and the combined packages are added. - verifySetOemNetworkPreferenceForPreference(uidRangesAllPackages, uidRangesSinglePackage, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - false /* shouldDestroyNetwork */); - - // Set the system to no longer recognize the package to be installed - mockGetApplicationInfoThrowsNameNotFound(packageToInstall); - - // Send a broadcast indicating a package was removed. - final Intent removedIntent = new Intent(ACTION_PACKAGE_REMOVED); - removedIntent.setData(Uri.parse(packageScheme + packageToInstall)); - processBroadcast(removedIntent); - - // Test the combined packages are removed and the single package is added. - verifySetOemNetworkPreferenceForPreference(uidRangesSinglePackage, uidRangesAllPackages, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - false /* shouldDestroyNetwork */); - - // Set the system to change the installed package's uid - final int replacedTestPackageUid = TEST_PACKAGE_UID + 1; - mockGetApplicationInfo(TEST_PACKAGE_NAME, replacedTestPackageUid); - final UidRangeParcel[] uidRangesReplacedPackage = - toUidRangeStableParcels(uidRangesForUids(replacedTestPackageUid)); - - // Send a broadcast indicating a package was replaced. - final Intent replacedIntent = new Intent(ACTION_PACKAGE_REPLACED); - replacedIntent.setData(Uri.parse(packageScheme + TEST_PACKAGE_NAME)); - processBroadcast(replacedIntent); - - // Test the original uid is removed and is replaced with the new uid. - verifySetOemNetworkPreferenceForPreference(uidRangesReplacedPackage, uidRangesSinglePackage, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - mCellNetworkAgent.getNetwork().netId, 1 /* times */, - false /* shouldDestroyNetwork */); - } - - /** - * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: - * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback - */ - @Test - public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; - setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); - final int expectedDefaultRequestSize = 2; - final int expectedOemPrefRequestSize = 3; - registerDefaultNetworkCallbacks(); - - // The fallback as well as the OEM preference should now be tracked. - assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); - - // Test lowest to highest priority requests. - // Bring up metered cellular. This will satisfy the fallback network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mCellNetworkAgent.getNetwork()); - - // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mWiFiNetworkAgent.getNetwork(), - mWiFiNetworkAgent.getNetwork()); - - // Disconnecting unmetered Wi-Fi will put the pref on OEM_PAID and fallback on cellular. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting OEM_PAID will put both on null as it is the last network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - null); - - // default callbacks will be unregistered in tearDown - } - - @Test - public void testNetworkFactoryRequestsWithMultilayerRequest() - throws Exception { - // First use OEM_PAID preference to create a multi-layer request : 1. listen for - // unmetered, 2. request network with cap OEM_PAID, 3, request the default network for - // fallback. - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; - setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); - - final HandlerThread handlerThread = new HandlerThread("MockFactory"); - handlerThread.start(); - NetworkCapabilities internetFilter = new NetworkCapabilities() - .addCapability(NET_CAPABILITY_INTERNET) - .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); - final MockNetworkFactory internetFactory = new MockNetworkFactory(handlerThread.getLooper(), - mServiceContext, "internetFactory", internetFilter, mCsHandlerThread); - internetFactory.setScoreFilter(40); - internetFactory.register(); - // Default internet request only. The unmetered request is never sent to factories (it's a - // LISTEN, not requestable). The 3rd (fallback) request in OEM_PAID NRI is TRACK_DEFAULT - // which is also not sent to factories. Finally, the OEM_PAID request doesn't match the - // internetFactory filter. - internetFactory.expectRequestAdds(1); - internetFactory.assertRequestCountEquals(1); - - NetworkCapabilities oemPaidFilter = new NetworkCapabilities() - .addCapability(NET_CAPABILITY_INTERNET) - .addCapability(NET_CAPABILITY_OEM_PAID) - .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) - .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); - final MockNetworkFactory oemPaidFactory = new MockNetworkFactory(handlerThread.getLooper(), - mServiceContext, "oemPaidFactory", oemPaidFilter, mCsHandlerThread); - oemPaidFactory.setScoreFilter(40); - oemPaidFactory.register(); - oemPaidFactory.expectRequestAdd(); // Because nobody satisfies the request - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - - // A network connected that satisfies the default internet request. For the OEM_PAID - // preference, this is not as good as an OEM_PAID network, so even if the score of - // the network is better than the factory announced, it still should try to bring up - // the network. - expectNoRequestChanged(oemPaidFactory); - oemPaidFactory.assertRequestCountEquals(1); - // The internet factory however is outscored, and should lose its requests. - internetFactory.expectRequestRemove(); - internetFactory.assertRequestCountEquals(0); - - final NetworkCapabilities oemPaidNc = new NetworkCapabilities(); - oemPaidNc.addCapability(NET_CAPABILITY_OEM_PAID); - oemPaidNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); - final TestNetworkAgentWrapper oemPaidAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, - new LinkProperties(), oemPaidNc); - oemPaidAgent.connect(true); - - // The oemPaidAgent has score 50/cell transport, so it beats what the oemPaidFactory can - // provide, therefore it loses the request. - oemPaidFactory.expectRequestRemove(); - oemPaidFactory.assertRequestCountEquals(0); - expectNoRequestChanged(internetFactory); - internetFactory.assertRequestCountEquals(0); - - oemPaidAgent.setScore(new NetworkScore.Builder().setLegacyInt(20).setExiting(true).build()); - // Now the that the agent is weak, the oemPaidFactory can beat the existing network for the - // OEM_PAID request. The internet factory however can't beat a network that has OEM_PAID - // for the preference request, so it doesn't see the request. - oemPaidFactory.expectRequestAdd(); - oemPaidFactory.assertRequestCountEquals(1); - expectNoRequestChanged(internetFactory); - internetFactory.assertRequestCountEquals(0); - - mCellNetworkAgent.disconnect(); - // The network satisfying the default internet request has disconnected, so the - // internetFactory sees the default request again. However there is a network with OEM_PAID - // connected, so the 2nd OEM_PAID req is already satisfied, so the oemPaidFactory doesn't - // care about networks that don't have OEM_PAID. - expectNoRequestChanged(oemPaidFactory); - oemPaidFactory.assertRequestCountEquals(1); - internetFactory.expectRequestAdd(); - internetFactory.assertRequestCountEquals(1); - - // Cell connects again, still with score 50. Back to the previous state. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - expectNoRequestChanged(oemPaidFactory); - oemPaidFactory.assertRequestCountEquals(1); - internetFactory.expectRequestRemove(); - internetFactory.assertRequestCountEquals(0); - - // Create a request that holds the upcoming wifi network. - final TestNetworkCallback wifiCallback = new TestNetworkCallback(); - mCm.requestNetwork(new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(), - wifiCallback); - - // Now WiFi connects and it's unmetered, but it's weaker than cell. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); - mWiFiNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).setExiting(true) - .build()); // Not the best Internet network, but unmetered - mWiFiNetworkAgent.connect(true); - - // The OEM_PAID preference prefers an unmetered network to an OEM_PAID network, so - // the oemPaidFactory can't beat wifi no matter how high its score. - oemPaidFactory.expectRequestRemove(); - expectNoRequestChanged(internetFactory); - - mCellNetworkAgent.disconnect(); - // Now that the best internet network (cell, with its 50 score compared to 30 for WiFi - // at this point), the default internet request is satisfied by a network worse than - // the internetFactory announced, so it gets the request. However, there is still an - // unmetered network, so the oemPaidNetworkFactory still can't beat this. - expectNoRequestChanged(oemPaidFactory); - internetFactory.expectRequestAdd(); - mCm.unregisterNetworkCallback(wifiCallback); - } - - /** - * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: - * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID - */ - @Test - public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidNoFallbackCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; - setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); - final int expectedDefaultRequestSize = 2; - final int expectedOemPrefRequestSize = 2; - registerDefaultNetworkCallbacks(); - - // The fallback as well as the OEM preference should now be tracked. - assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); - - // Test lowest to highest priority requests. - // Bring up metered cellular. This will satisfy the fallback network but not the pref. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mService.mNoServiceNetwork.network()); - - // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mWiFiNetworkAgent.getNetwork(), - mWiFiNetworkAgent.getNetwork()); - - // Disconnecting unmetered Wi-Fi will put the OEM pref on OEM_PAID and fallback on cellular. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting OEM_PAID puts the fallback on null and the pref on the disconnected net. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mService.mNoServiceNetwork.network()); - - // default callbacks will be unregistered in tearDown - } - - /** - * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: - * NET_CAPABILITY_OEM_PAID - * This preference should only apply to OEM_PAID networks. - */ - @Test - public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidOnlyCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; - setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); - final int expectedDefaultRequestSize = 2; - final int expectedOemPrefRequestSize = 1; - registerDefaultNetworkCallbacks(); - - // The fallback as well as the OEM preference should now be tracked. - assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); - - // Test lowest to highest priority requests. - // Bring up metered cellular. This will satisfy the fallback network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mService.mNoServiceNetwork.network()); - - // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mWiFiNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting OEM_PAID will keep the fallback on cellular and nothing for OEM_PAID. - // OEM_PAID_ONLY not supporting a fallback now uses the disconnected network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mService.mNoServiceNetwork.network()); - - // Disconnecting cellular will put the fallback on null and the pref on disconnected. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mService.mNoServiceNetwork.network()); - - // default callbacks will be unregistered in tearDown - } - - /** - * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: - * NET_CAPABILITY_OEM_PRIVATE - * This preference should only apply to OEM_PRIVATE networks. - */ - @Test - public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPrivateOnlyCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; - setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); - final int expectedDefaultRequestSize = 2; - final int expectedOemPrefRequestSize = 1; - registerDefaultNetworkCallbacks(); - - // The fallback as well as the OEM preference should now be tracked. - assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); - - // Test lowest to highest priority requests. - // Bring up metered cellular. This will satisfy the fallback network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mService.mNoServiceNetwork.network()); - - // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. - startOemManagedNetwork(false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mWiFiNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting OEM_PRIVATE will keep the fallback on cellular. - // OEM_PRIVATE_ONLY not supporting a fallback now uses to the disconnected network. - stopOemManagedNetwork(); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mService.mNoServiceNetwork.network()); - - // Disconnecting cellular will put the fallback on null and pref on disconnected. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mService.mNoServiceNetwork.network()); - - // default callbacks will be unregistered in tearDown - } - - @Test - public void testCapabilityWithOemNetworkPreference() throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; - setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref); - registerDefaultNetworkCallbacks(); - - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - - mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - - mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); - mSystemDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc -> - nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); - mDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc -> - nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); - - // default callbacks will be unregistered in tearDown - } - - @Test - public void testSetOemNetworkPreferenceLogsRequest() throws Exception { - mServiceContext.setPermission(DUMP, PERMISSION_GRANTED); - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PAID; - final StringWriter stringWriter = new StringWriter(); - final String logIdentifier = "UPDATE INITIATED: OemNetworkPreferences"; - final Pattern pattern = Pattern.compile(logIdentifier); - - final int expectedNumLogs = 2; - final UidRangeParcel[] uidRanges = - toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID)); - - // Call twice to generate two logs. - setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); - setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); - mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); - - final String dumpOutput = stringWriter.toString(); - final Matcher matcher = pattern.matcher(dumpOutput); - int count = 0; - while (matcher.find()) { - count++; - } - assertEquals(expectedNumLogs, count); - } - - @Test - public void testGetAllNetworkStateSnapshots() throws Exception { - verifyNoNetwork(); - - // Setup test cellular network with specified LinkProperties and NetworkCapabilities, - // verify the content of the snapshot matches. - final LinkProperties cellLp = new LinkProperties(); - final LinkAddress myIpv4Addr = new LinkAddress(InetAddress.getByName("192.0.2.129"), 25); - final LinkAddress myIpv6Addr = new LinkAddress(InetAddress.getByName("2001:db8::1"), 64); - cellLp.setInterfaceName("test01"); - cellLp.addLinkAddress(myIpv4Addr); - cellLp.addLinkAddress(myIpv6Addr); - cellLp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234"))); - cellLp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254"))); - cellLp.addRoute(new RouteInfo(myIpv4Addr, null)); - cellLp.addRoute(new RouteInfo(myIpv6Addr, null)); - final NetworkCapabilities cellNcTemplate = new NetworkCapabilities.Builder() - .addTransportType(TRANSPORT_CELLULAR).addCapability(NET_CAPABILITY_MMS).build(); - - final TestNetworkCallback cellCb = new TestNetworkCallback(); - mCm.requestNetwork(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), - cellCb); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp, cellNcTemplate); - mCellNetworkAgent.connect(true); - cellCb.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); - List<NetworkStateSnapshot> snapshots = mCm.getAllNetworkStateSnapshots(); - assertLength(1, snapshots); - - // Compose the expected cellular snapshot for verification. - final NetworkCapabilities cellNc = - mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()); - final NetworkStateSnapshot cellSnapshot = new NetworkStateSnapshot( - mCellNetworkAgent.getNetwork(), cellNc, cellLp, - null, ConnectivityManager.TYPE_MOBILE); - assertEquals(cellSnapshot, snapshots.get(0)); - - // Connect wifi and verify the snapshots. - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - waitForIdle(); - // Compose the expected wifi snapshot for verification. - final NetworkCapabilities wifiNc = - mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()); - final NetworkStateSnapshot wifiSnapshot = new NetworkStateSnapshot( - mWiFiNetworkAgent.getNetwork(), wifiNc, new LinkProperties(), null, - ConnectivityManager.TYPE_WIFI); - - snapshots = mCm.getAllNetworkStateSnapshots(); - assertLength(2, snapshots); - assertContainsAll(snapshots, cellSnapshot, wifiSnapshot); - - // Set cellular as suspended, verify the snapshots will not contain suspended networks. - // TODO: Consider include SUSPENDED networks, which should be considered as - // temporary shortage of connectivity of a connected network. - mCellNetworkAgent.suspend(); - waitForIdle(); - snapshots = mCm.getAllNetworkStateSnapshots(); - assertLength(1, snapshots); - assertEquals(wifiSnapshot, snapshots.get(0)); - - // Disconnect wifi, verify the snapshots contain nothing. - mWiFiNetworkAgent.disconnect(); - waitForIdle(); - snapshots = mCm.getAllNetworkStateSnapshots(); - assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - assertLength(0, snapshots); - - mCellNetworkAgent.resume(); - waitForIdle(); - snapshots = mCm.getAllNetworkStateSnapshots(); - assertLength(1, snapshots); - assertEquals(cellSnapshot, snapshots.get(0)); - - mCellNetworkAgent.disconnect(); - waitForIdle(); - verifyNoNetwork(); - mCm.unregisterNetworkCallback(cellCb); - } - - // Cannot be part of MockNetworkFactory since it requires method of the test. - private void expectNoRequestChanged(@NonNull MockNetworkFactory factory) { - waitForIdle(); - factory.assertNoRequestChanged(); - } - - @Test - public void testRegisterBestMatchingNetworkCallback_noIssueToFactory() throws Exception { - // Prepare mock mms factory. - final HandlerThread handlerThread = new HandlerThread("MockCellularFactory"); - handlerThread.start(); - NetworkCapabilities filter = new NetworkCapabilities() - .addTransportType(TRANSPORT_CELLULAR) - .addCapability(NET_CAPABILITY_MMS); - final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), - mServiceContext, "testFactory", filter, mCsHandlerThread); - testFactory.setScoreFilter(40); - - try { - // Register the factory. It doesn't see the default request because its filter does - // not include INTERNET. - testFactory.register(); - expectNoRequestChanged(testFactory); - testFactory.assertRequestCountEquals(0); - // The factory won't try to start the network since the default request doesn't - // match the filter (no INTERNET capability). - assertFalse(testFactory.getMyStartRequested()); - - // Register callback for listening best matching network. Verify that the request won't - // be sent to factory. - final TestNetworkCallback bestMatchingCb = new TestNetworkCallback(); - mCm.registerBestMatchingNetworkCallback( - new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build(), - bestMatchingCb, mCsHandlerThread.getThreadHandler()); - bestMatchingCb.assertNoCallback(); - expectNoRequestChanged(testFactory); - testFactory.assertRequestCountEquals(0); - assertFalse(testFactory.getMyStartRequested()); - - // Fire a normal mms request, verify the factory will only see the request. - final TestNetworkCallback mmsNetworkCallback = new TestNetworkCallback(); - final NetworkRequest mmsRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_MMS).build(); - mCm.requestNetwork(mmsRequest, mmsNetworkCallback); - testFactory.expectRequestAdd(); - testFactory.assertRequestCountEquals(1); - assertTrue(testFactory.getMyStartRequested()); - - // Unregister best matching callback, verify factory see no change. - mCm.unregisterNetworkCallback(bestMatchingCb); - expectNoRequestChanged(testFactory); - testFactory.assertRequestCountEquals(1); - assertTrue(testFactory.getMyStartRequested()); - } finally { - testFactory.terminate(); - } - } - - @Test - public void testRegisterBestMatchingNetworkCallback_trackBestNetwork() throws Exception { - final TestNetworkCallback bestMatchingCb = new TestNetworkCallback(); - mCm.registerBestMatchingNetworkCallback( - new NetworkRequest.Builder().addCapability(NET_CAPABILITY_TRUSTED).build(), - bestMatchingCb, mCsHandlerThread.getThreadHandler()); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - bestMatchingCb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - - mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - mWiFiNetworkAgent.connect(true); - bestMatchingCb.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - - // Change something on cellular to trigger capabilities changed, since the callback - // only cares about the best network, verify it received nothing from cellular. - mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); - bestMatchingCb.assertNoCallback(); - - // Make cellular the best network again, verify the callback now tracks cellular. - mWiFiNetworkAgent.adjustScore(-50); - bestMatchingCb.expectAvailableCallbacksValidated(mCellNetworkAgent); - - // Make cellular temporary non-trusted, which will not satisfying the request. - // Verify the callback switch from/to the other network accordingly. - mCellNetworkAgent.removeCapability(NET_CAPABILITY_TRUSTED); - bestMatchingCb.expectAvailableCallbacksValidated(mWiFiNetworkAgent); - mCellNetworkAgent.addCapability(NET_CAPABILITY_TRUSTED); - bestMatchingCb.expectAvailableDoubleValidatedCallbacks(mCellNetworkAgent); - - // Verify the callback doesn't care about wifi disconnect. - mWiFiNetworkAgent.disconnect(); - bestMatchingCb.assertNoCallback(); - mCellNetworkAgent.disconnect(); - bestMatchingCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - } - - private UidRangeParcel[] uidRangeFor(final UserHandle handle) { - UidRange range = UidRange.createForUser(handle); - return new UidRangeParcel[] { new UidRangeParcel(range.start, range.stop) }; - } - - private static class TestOnCompleteListener implements Runnable { - final class OnComplete {} - final ArrayTrackRecord<OnComplete>.ReadHead mHistory = - new ArrayTrackRecord<OnComplete>().newReadHead(); - - @Override - public void run() { - mHistory.add(new OnComplete()); - } - - public void expectOnComplete() { - assertNotNull(mHistory.poll(TIMEOUT_MS, it -> true)); - } - } - - private TestNetworkAgentWrapper makeEnterpriseNetworkAgent() throws Exception { - final NetworkCapabilities workNc = new NetworkCapabilities(); - workNc.addCapability(NET_CAPABILITY_ENTERPRISE); - workNc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); - return new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), workNc); - } - - private TestNetworkCallback mEnterpriseCallback; - private UserHandle setupEnterpriseNetwork() { - final UserHandle userHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); - mServiceContext.setWorkProfile(userHandle, true); - - // File a request to avoid the enterprise network being disconnected as soon as the default - // request goes away – it would make impossible to test that networkRemoveUidRanges - // is called, as the network would disconnect first for lack of a request. - mEnterpriseCallback = new TestNetworkCallback(); - final NetworkRequest keepUpRequest = new NetworkRequest.Builder() - .addCapability(NET_CAPABILITY_ENTERPRISE) - .build(); - mCm.requestNetwork(keepUpRequest, mEnterpriseCallback); - return userHandle; - } - - private void maybeTearDownEnterpriseNetwork() { - if (null != mEnterpriseCallback) { - mCm.unregisterNetworkCallback(mEnterpriseCallback); - } - } - - /** - * Make sure per-profile networking preference behaves as expected when the enterprise network - * goes up and down while the preference is active. Make sure they behave as expected whether - * there is a general default network or not. - */ - @Test - public void testPreferenceForUserNetworkUpDown() throws Exception { - final InOrder inOrder = inOrder(mMockNetd); - final UserHandle testHandle = setupEnterpriseNetwork(); - registerDefaultNetworkCallbacks(); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - - mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( - mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); - - - final TestOnCompleteListener listener = new TestOnCompleteListener(); - mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, - r -> r.run(), listener); - listener.expectOnComplete(); - - // Setting a network preference for this user will create a new set of routing rules for - // the UID range that corresponds to this user, so as to define the default network - // for these apps separately. This is true because the multi-layer request relevant to - // this UID range contains a TRACK_DEFAULT, so the range will be moved through UID-specific - // rules to the correct network – in this case the system default network. The case where - // the default network for the profile happens to be the same as the system default - // is not handled specially, the rules are always active as long as a preference is set. - inOrder.verify(mMockNetd).networkAddUidRanges(mCellNetworkAgent.getNetwork().netId, - uidRangeFor(testHandle)); - - // The enterprise network is not ready yet. - assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, - mProfileDefaultNetworkCallback); - - final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); - workAgent.connect(false); - - mProfileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent); - mSystemDefaultNetworkCallback.assertNoCallback(); - mDefaultNetworkCallback.assertNoCallback(); - inOrder.verify(mMockNetd).networkCreate( - nativeNetworkConfigPhysical(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); - inOrder.verify(mMockNetd).networkAddUidRanges(workAgent.getNetwork().netId, - uidRangeFor(testHandle)); - inOrder.verify(mMockNetd).networkRemoveUidRanges(mCellNetworkAgent.getNetwork().netId, - uidRangeFor(testHandle)); - - // Make sure changes to the work agent send callbacks to the app in the work profile, but - // not to the other apps. - workAgent.setNetworkValid(true /* isStrictMode */); - workAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); - mProfileDefaultNetworkCallback.expectCapabilitiesThat(workAgent, - nc -> nc.hasCapability(NET_CAPABILITY_VALIDATED) - && nc.hasCapability(NET_CAPABILITY_ENTERPRISE)); - assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); - - workAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); - mProfileDefaultNetworkCallback.expectCapabilitiesThat(workAgent, nc -> - nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); - assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); - - // Conversely, change a capability on the system-wide default network and make sure - // that only the apps outside of the work profile receive the callbacks. - mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); - mSystemDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc -> - nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); - mDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc -> - nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)); - mProfileDefaultNetworkCallback.assertNoCallback(); - - // Disconnect and reconnect the system-wide default network and make sure that the - // apps on this network see the appropriate callbacks, and the app on the work profile - // doesn't because it continues to use the enterprise network. - mCellNetworkAgent.disconnect(); - mSystemDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - mProfileDefaultNetworkCallback.assertNoCallback(); - inOrder.verify(mMockNetd).networkDestroy(mCellNetworkAgent.getNetwork().netId); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - mProfileDefaultNetworkCallback.assertNoCallback(); - inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( - mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); - - // When the agent disconnects, test that the app on the work profile falls back to the - // default network. - workAgent.disconnect(); - mProfileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, workAgent); - mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); - inOrder.verify(mMockNetd).networkAddUidRanges(mCellNetworkAgent.getNetwork().netId, - uidRangeFor(testHandle)); - inOrder.verify(mMockNetd).networkDestroy(workAgent.getNetwork().netId); - - mCellNetworkAgent.disconnect(); - mSystemDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - mProfileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); - - // Waiting for the handler to be idle before checking for networkDestroy is necessary - // here because ConnectivityService calls onLost before the network is fully torn down. - waitForIdle(); - inOrder.verify(mMockNetd).networkDestroy(mCellNetworkAgent.getNetwork().netId); - - // If the control comes here, callbacks seem to behave correctly in the presence of - // a default network when the enterprise network goes up and down. Now, make sure they - // also behave correctly in the absence of a system-wide default network. - final TestNetworkAgentWrapper workAgent2 = makeEnterpriseNetworkAgent(); - workAgent2.connect(false); - - mProfileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent2); - assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); - inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( - workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); - inOrder.verify(mMockNetd).networkAddUidRanges(workAgent2.getNetwork().netId, - uidRangeFor(testHandle)); - - workAgent2.setNetworkValid(true /* isStrictMode */); - workAgent2.mNetworkMonitor.forceReevaluation(Process.myUid()); - mProfileDefaultNetworkCallback.expectCapabilitiesThat(workAgent2, - nc -> nc.hasCapability(NET_CAPABILITY_ENTERPRISE) - && !nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); - inOrder.verify(mMockNetd, never()).networkAddUidRanges(anyInt(), any()); - - // When the agent disconnects, test that the app on the work profile falls back to the - // default network. - workAgent2.disconnect(); - mProfileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, workAgent2); - assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); - inOrder.verify(mMockNetd).networkDestroy(workAgent2.getNetwork().netId); - - assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, - mProfileDefaultNetworkCallback); - - // Callbacks will be unregistered by tearDown() - } - - /** - * Test that, in a given networking context, calling setPreferenceForUser to set per-profile - * defaults on then off works as expected. - */ - @Test - public void testSetPreferenceForUserOnOff() throws Exception { - final InOrder inOrder = inOrder(mMockNetd); - final UserHandle testHandle = setupEnterpriseNetwork(); - - // Connect both a regular cell agent and an enterprise network first. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - - final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); - workAgent.connect(true); - - final TestOnCompleteListener listener = new TestOnCompleteListener(); - mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, - r -> r.run(), listener); - listener.expectOnComplete(); - inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( - mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); - inOrder.verify(mMockNetd).networkAddUidRanges(workAgent.getNetwork().netId, - uidRangeFor(testHandle)); - - registerDefaultNetworkCallbacks(); - - mSystemDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); - - mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_DEFAULT, - r -> r.run(), listener); - listener.expectOnComplete(); - - mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); - inOrder.verify(mMockNetd).networkRemoveUidRanges(workAgent.getNetwork().netId, - uidRangeFor(testHandle)); - - workAgent.disconnect(); - mCellNetworkAgent.disconnect(); - - // Callbacks will be unregistered by tearDown() - } - - /** - * Test per-profile default networks for two different profiles concurrently. - */ - @Test - public void testSetPreferenceForTwoProfiles() throws Exception { - final InOrder inOrder = inOrder(mMockNetd); - final UserHandle testHandle2 = setupEnterpriseNetwork(); - final UserHandle testHandle4 = UserHandle.of(TEST_WORK_PROFILE_USER_ID + 2); - mServiceContext.setWorkProfile(testHandle4, true); - registerDefaultNetworkCallbacks(); - - final TestNetworkCallback app4Cb = new TestNetworkCallback(); - final int testWorkProfileAppUid4 = - UserHandle.getUid(testHandle4.getIdentifier(), TEST_APP_ID); - registerDefaultNetworkCallbackAsUid(app4Cb, testWorkProfileAppUid4); - - // Connect both a regular cell agent and an enterprise network first. - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - - final TestNetworkAgentWrapper workAgent = makeEnterpriseNetworkAgent(); - workAgent.connect(true); - - mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - app4Cb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( - mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); - inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( - workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); - - final TestOnCompleteListener listener = new TestOnCompleteListener(); - mCm.setProfileNetworkPreference(testHandle2, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, - r -> r.run(), listener); - listener.expectOnComplete(); - inOrder.verify(mMockNetd).networkAddUidRanges(workAgent.getNetwork().netId, - uidRangeFor(testHandle2)); - - mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(workAgent); - assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, - app4Cb); - - mCm.setProfileNetworkPreference(testHandle4, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, - r -> r.run(), listener); - listener.expectOnComplete(); - inOrder.verify(mMockNetd).networkAddUidRanges(workAgent.getNetwork().netId, - uidRangeFor(testHandle4)); - - app4Cb.expectAvailableCallbacksValidated(workAgent); - assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, - mProfileDefaultNetworkCallback); - - mCm.setProfileNetworkPreference(testHandle2, PROFILE_NETWORK_PREFERENCE_DEFAULT, - r -> r.run(), listener); - listener.expectOnComplete(); - inOrder.verify(mMockNetd).networkRemoveUidRanges(workAgent.getNetwork().netId, - uidRangeFor(testHandle2)); - - mProfileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent); - assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback, - app4Cb); - - workAgent.disconnect(); - mCellNetworkAgent.disconnect(); - - mCm.unregisterNetworkCallback(app4Cb); - // Other callbacks will be unregistered by tearDown() - } - - @Test - public void testProfilePreferenceRemovedUponUserRemoved() throws Exception { - final InOrder inOrder = inOrder(mMockNetd); - final UserHandle testHandle = setupEnterpriseNetwork(); - - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - mCellNetworkAgent.connect(true); - - final TestOnCompleteListener listener = new TestOnCompleteListener(); - mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, - r -> r.run(), listener); - listener.expectOnComplete(); - inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( - mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); - inOrder.verify(mMockNetd).networkAddUidRanges(mCellNetworkAgent.getNetwork().netId, - uidRangeFor(testHandle)); - - final Intent removedIntent = new Intent(ACTION_USER_REMOVED); - removedIntent.putExtra(Intent.EXTRA_USER, testHandle); - processBroadcast(removedIntent); - - inOrder.verify(mMockNetd).networkRemoveUidRanges(mCellNetworkAgent.getNetwork().netId, - uidRangeFor(testHandle)); - } - - /** - * Make sure that OEM preference and per-profile preference can't be used at the same - * time and throw ISE if tried - */ - @Test - public void testOemPreferenceAndProfilePreferenceExclusive() throws Exception { - final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); - mServiceContext.setWorkProfile(testHandle, true); - final TestOnCompleteListener listener = new TestOnCompleteListener(); - - setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest( - OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY); - assertThrows("Should not be able to set per-profile pref while OEM prefs present", - IllegalStateException.class, () -> - mCm.setProfileNetworkPreference(testHandle, - PROFILE_NETWORK_PREFERENCE_ENTERPRISE, - r -> r.run(), listener)); - - // Empty the OEM prefs - final TestOemListenerCallback oemPrefListener = new TestOemListenerCallback(); - final OemNetworkPreferences emptyOemPref = new OemNetworkPreferences.Builder().build(); - mService.setOemNetworkPreference(emptyOemPref, oemPrefListener); - oemPrefListener.expectOnComplete(); - - mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, - r -> r.run(), listener); - listener.expectOnComplete(); - assertThrows("Should not be able to set OEM prefs while per-profile pref is on", - IllegalStateException.class , () -> - mService.setOemNetworkPreference(emptyOemPref, oemPrefListener)); - } - - /** - * Make sure wrong preferences for per-profile default networking are rejected. - */ - @Test - public void testProfileNetworkPrefWrongPreference() throws Exception { - final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); - mServiceContext.setWorkProfile(testHandle, true); - assertThrows("Should not be able to set an illegal preference", - IllegalArgumentException.class, - () -> mCm.setProfileNetworkPreference(testHandle, - PROFILE_NETWORK_PREFERENCE_ENTERPRISE + 1, null, null)); - } - - /** - * Make sure requests for per-profile default networking for a non-work profile are - * rejected - */ - @Test - public void testProfileNetworkPrefWrongProfile() throws Exception { - final UserHandle testHandle = UserHandle.of(TEST_WORK_PROFILE_USER_ID); - mServiceContext.setWorkProfile(testHandle, false); - assertThrows("Should not be able to set a user pref for a non-work profile", - IllegalArgumentException.class , () -> - mCm.setProfileNetworkPreference(testHandle, - PROFILE_NETWORK_PREFERENCE_ENTERPRISE, null, null)); - } - - @Test - public void testSubIdsClearedWithoutNetworkFactoryPermission() throws Exception { - mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED); - final NetworkCapabilities nc = new NetworkCapabilities(); - nc.setSubscriptionIds(Collections.singleton(Process.myUid())); - - final NetworkCapabilities result = - mService.networkCapabilitiesRestrictedForCallerPermissions( - nc, Process.myPid(), Process.myUid()); - assertTrue(result.getSubscriptionIds().isEmpty()); - } - - @Test - public void testSubIdsExistWithNetworkFactoryPermission() throws Exception { - mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); - - final Set<Integer> subIds = Collections.singleton(Process.myUid()); - final NetworkCapabilities nc = new NetworkCapabilities(); - nc.setSubscriptionIds(subIds); - - final NetworkCapabilities result = - mService.networkCapabilitiesRestrictedForCallerPermissions( - nc, Process.myPid(), Process.myUid()); - assertEquals(subIds, result.getSubscriptionIds()); - } - - private NetworkRequest getRequestWithSubIds() { - return new NetworkRequest.Builder() - .setSubscriptionIds(Collections.singleton(Process.myUid())) - .build(); - } - - @Test - public void testNetworkRequestWithSubIdsWithNetworkFactoryPermission() throws Exception { - mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); - final PendingIntent pendingIntent = PendingIntent.getBroadcast( - mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); - final NetworkCallback networkCallback1 = new NetworkCallback(); - final NetworkCallback networkCallback2 = new NetworkCallback(); - - mCm.requestNetwork(getRequestWithSubIds(), networkCallback1); - mCm.requestNetwork(getRequestWithSubIds(), pendingIntent); - mCm.registerNetworkCallback(getRequestWithSubIds(), networkCallback2); - - mCm.unregisterNetworkCallback(networkCallback1); - mCm.releaseNetworkRequest(pendingIntent); - mCm.unregisterNetworkCallback(networkCallback2); - } - - @Test - public void testNetworkRequestWithSubIdsWithoutNetworkFactoryPermission() throws Exception { - mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED); - final PendingIntent pendingIntent = PendingIntent.getBroadcast( - mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE); - - final Class<SecurityException> expected = SecurityException.class; - assertThrows( - expected, () -> mCm.requestNetwork(getRequestWithSubIds(), new NetworkCallback())); - assertThrows(expected, () -> mCm.requestNetwork(getRequestWithSubIds(), pendingIntent)); - assertThrows( - expected, - () -> mCm.registerNetworkCallback(getRequestWithSubIds(), new NetworkCallback())); - } - - /** - * Validate request counts are counted accurately on setProfileNetworkPreference on set/replace. - */ - @Test - public void testProfileNetworkPrefCountsRequestsCorrectlyOnSet() throws Exception { - final UserHandle testHandle = setupEnterpriseNetwork(); - testRequestCountLimits(() -> { - // Set initially to test the limit prior to having existing requests. - final TestOnCompleteListener listener = new TestOnCompleteListener(); - mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, - Runnable::run, listener); - listener.expectOnComplete(); - - // re-set so as to test the limit as part of replacing existing requests. - mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, - Runnable::run, listener); - listener.expectOnComplete(); - }); - } - - /** - * Validate request counts are counted accurately on setOemNetworkPreference on set/replace. - */ - @Test - public void testSetOemNetworkPreferenceCountsRequestsCorrectlyOnSet() throws Exception { - mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; - testRequestCountLimits(() -> { - // Set initially to test the limit prior to having existing requests. - final TestOemListenerCallback listener = new TestOemListenerCallback(); - mService.setOemNetworkPreference( - createDefaultOemNetworkPreferences(networkPref), listener); - listener.expectOnComplete(); - - // re-set so as to test the limit as part of replacing existing requests. - mService.setOemNetworkPreference( - createDefaultOemNetworkPreferences(networkPref), listener); - listener.expectOnComplete(); - }); - } - - private void testRequestCountLimits(@NonNull final Runnable r) throws Exception { - final ArraySet<TestNetworkCallback> callbacks = new ArraySet<>(); - try { - final int requestCount = mService.mSystemNetworkRequestCounter - .mUidToNetworkRequestCount.get(Process.myUid()); - // The limit is hit when total requests <= limit. - final int maxCount = - ConnectivityService.MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - requestCount; - // Need permission so registerDefaultNetworkCallback uses mSystemNetworkRequestCounter - withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () -> { - for (int i = 1; i < maxCount - 1; i++) { - final TestNetworkCallback cb = new TestNetworkCallback(); - mCm.registerDefaultNetworkCallback(cb); - callbacks.add(cb); - } - - // Code to run to check if it triggers a max request count limit error. - r.run(); - }); - } finally { - for (final TestNetworkCallback cb : callbacks) { - mCm.unregisterNetworkCallback(cb); - } - } - } -} diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java deleted file mode 100644 index cf2c9c783ac7..000000000000 --- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java +++ /dev/null @@ -1,1004 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server; - -import static android.content.pm.PackageManager.PERMISSION_DENIED; -import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.net.INetd.IF_STATE_DOWN; -import static android.net.INetd.IF_STATE_UP; -import static android.net.IpSecManager.DIRECTION_FWD; -import static android.net.IpSecManager.DIRECTION_IN; -import static android.net.IpSecManager.DIRECTION_OUT; -import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; -import static android.system.OsConstants.AF_INET; -import static android.system.OsConstants.AF_INET6; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.AppOpsManager; -import android.content.Context; -import android.content.pm.PackageManager; -import android.net.ConnectivityManager; -import android.net.INetd; -import android.net.InetAddresses; -import android.net.InterfaceConfigurationParcel; -import android.net.IpSecAlgorithm; -import android.net.IpSecConfig; -import android.net.IpSecManager; -import android.net.IpSecSpiResponse; -import android.net.IpSecTransform; -import android.net.IpSecTransformResponse; -import android.net.IpSecTunnelInterfaceResponse; -import android.net.IpSecUdpEncapResponse; -import android.net.LinkAddress; -import android.net.LinkProperties; -import android.net.Network; -import android.os.Binder; -import android.os.ParcelFileDescriptor; -import android.system.Os; -import android.test.mock.MockContext; -import android.util.ArraySet; - -import androidx.test.filters.SmallTest; - -import com.android.server.IpSecService.TunnelInterfaceRecord; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.net.Inet4Address; -import java.net.Socket; -import java.util.Arrays; -import java.util.Collection; -import java.util.Set; - -/** Unit tests for {@link IpSecService}. */ -@SmallTest -@RunWith(Parameterized.class) -public class IpSecServiceParameterizedTest { - - private static final int TEST_SPI = 0xD1201D; - - private final String mSourceAddr; - private final String mDestinationAddr; - private final LinkAddress mLocalInnerAddress; - private final int mFamily; - - private static final int[] ADDRESS_FAMILIES = - new int[] {AF_INET, AF_INET6}; - - @Parameterized.Parameters - public static Collection ipSecConfigs() { - return Arrays.asList( - new Object[][] { - {"1.2.3.4", "8.8.4.4", "10.0.1.1/24", AF_INET}, - {"2601::2", "2601::10", "2001:db8::1/64", AF_INET6} - }); - } - - private static final byte[] AEAD_KEY = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x73, 0x61, 0x6C, 0x74 - }; - private static final byte[] CRYPT_KEY = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F - }; - private static final byte[] AUTH_KEY = { - 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, - 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F - }; - - AppOpsManager mMockAppOps = mock(AppOpsManager.class); - ConnectivityManager mMockConnectivityMgr = mock(ConnectivityManager.class); - - TestContext mTestContext = new TestContext(); - - private class TestContext extends MockContext { - private Set<String> mAllowedPermissions = new ArraySet<>(Arrays.asList( - android.Manifest.permission.MANAGE_IPSEC_TUNNELS, - android.Manifest.permission.NETWORK_STACK, - PERMISSION_MAINLINE_NETWORK_STACK)); - - private void setAllowedPermissions(String... permissions) { - mAllowedPermissions = new ArraySet<>(permissions); - } - - @Override - public Object getSystemService(String name) { - switch(name) { - case Context.APP_OPS_SERVICE: - return mMockAppOps; - case Context.CONNECTIVITY_SERVICE: - return mMockConnectivityMgr; - default: - return null; - } - } - - @Override - public String getSystemServiceName(Class<?> serviceClass) { - if (ConnectivityManager.class == serviceClass) { - return Context.CONNECTIVITY_SERVICE; - } - return null; - } - - @Override - public PackageManager getPackageManager() { - return mMockPkgMgr; - } - - @Override - public void enforceCallingOrSelfPermission(String permission, String message) { - if (mAllowedPermissions.contains(permission)) { - return; - } else { - throw new SecurityException("Unavailable permission requested"); - } - } - - @Override - public int checkCallingOrSelfPermission(String permission) { - if (mAllowedPermissions.contains(permission)) { - return PERMISSION_GRANTED; - } else { - return PERMISSION_DENIED; - } - } - } - - INetd mMockNetd; - PackageManager mMockPkgMgr; - IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig; - IpSecService mIpSecService; - Network fakeNetwork = new Network(0xAB); - int mUid = Os.getuid(); - - private static final IpSecAlgorithm AUTH_ALGO = - new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4); - private static final IpSecAlgorithm CRYPT_ALGO = - new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); - private static final IpSecAlgorithm AEAD_ALGO = - new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); - private static final int REMOTE_ENCAP_PORT = 4500; - - private static final String BLESSED_PACKAGE = "blessedPackage"; - private static final String SYSTEM_PACKAGE = "systemPackage"; - private static final String BAD_PACKAGE = "badPackage"; - - public IpSecServiceParameterizedTest( - String sourceAddr, String destAddr, String localInnerAddr, int family) { - mSourceAddr = sourceAddr; - mDestinationAddr = destAddr; - mLocalInnerAddress = new LinkAddress(localInnerAddr); - mFamily = family; - } - - @Before - public void setUp() throws Exception { - mMockNetd = mock(INetd.class); - mMockPkgMgr = mock(PackageManager.class); - mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class); - mIpSecService = new IpSecService(mTestContext, mMockIpSecSrvConfig); - - // Injecting mock netd - when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd); - - // PackageManager should always return true (feature flag tests in IpSecServiceTest) - when(mMockPkgMgr.hasSystemFeature(anyString())).thenReturn(true); - - // A package granted the AppOp for MANAGE_IPSEC_TUNNELS will be MODE_ALLOWED. - when(mMockAppOps.noteOp(anyInt(), anyInt(), eq(BLESSED_PACKAGE))) - .thenReturn(AppOpsManager.MODE_ALLOWED); - // A system package will not be granted the app op, so this should fall back to - // a permissions check, which should pass. - when(mMockAppOps.noteOp(anyInt(), anyInt(), eq(SYSTEM_PACKAGE))) - .thenReturn(AppOpsManager.MODE_DEFAULT); - // A mismatch between the package name and the UID will return MODE_IGNORED. - when(mMockAppOps.noteOp(anyInt(), anyInt(), eq(BAD_PACKAGE))) - .thenReturn(AppOpsManager.MODE_IGNORED); - } - - //TODO: Add a test to verify SPI. - - @Test - public void testIpSecServiceReserveSpi() throws Exception { - when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI))) - .thenReturn(TEST_SPI); - - IpSecSpiResponse spiResp = - mIpSecService.allocateSecurityParameterIndex( - mDestinationAddr, TEST_SPI, new Binder()); - assertEquals(IpSecManager.Status.OK, spiResp.status); - assertEquals(TEST_SPI, spiResp.spi); - } - - @Test - public void testReleaseSecurityParameterIndex() throws Exception { - when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI))) - .thenReturn(TEST_SPI); - - IpSecSpiResponse spiResp = - mIpSecService.allocateSecurityParameterIndex( - mDestinationAddr, TEST_SPI, new Binder()); - - mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId); - - verify(mMockNetd) - .ipSecDeleteSecurityAssociation( - eq(mUid), - anyString(), - anyString(), - eq(TEST_SPI), - anyInt(), - anyInt(), - anyInt()); - - // Verify quota and RefcountedResource objects cleaned up - IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); - assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent); - try { - userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId); - fail("Expected IllegalArgumentException on attempt to access deleted resource"); - } catch (IllegalArgumentException expected) { - - } - } - - @Test - public void testSecurityParameterIndexBinderDeath() throws Exception { - when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI))) - .thenReturn(TEST_SPI); - - IpSecSpiResponse spiResp = - mIpSecService.allocateSecurityParameterIndex( - mDestinationAddr, TEST_SPI, new Binder()); - - IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); - IpSecService.RefcountedResource refcountedRecord = - userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId); - - refcountedRecord.binderDied(); - - verify(mMockNetd) - .ipSecDeleteSecurityAssociation( - eq(mUid), - anyString(), - anyString(), - eq(TEST_SPI), - anyInt(), - anyInt(), - anyInt()); - - // Verify quota and RefcountedResource objects cleaned up - assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent); - try { - userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId); - fail("Expected IllegalArgumentException on attempt to access deleted resource"); - } catch (IllegalArgumentException expected) { - - } - } - - private int getNewSpiResourceId(String remoteAddress, int returnSpi) throws Exception { - when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), anyString(), anyInt())) - .thenReturn(returnSpi); - - IpSecSpiResponse spi = - mIpSecService.allocateSecurityParameterIndex( - InetAddresses.parseNumericAddress(remoteAddress).getHostAddress(), - IpSecManager.INVALID_SECURITY_PARAMETER_INDEX, - new Binder()); - return spi.resourceId; - } - - private void addDefaultSpisAndRemoteAddrToIpSecConfig(IpSecConfig config) throws Exception { - config.setSpiResourceId(getNewSpiResourceId(mDestinationAddr, TEST_SPI)); - config.setSourceAddress(mSourceAddr); - config.setDestinationAddress(mDestinationAddr); - } - - private void addAuthAndCryptToIpSecConfig(IpSecConfig config) throws Exception { - config.setEncryption(CRYPT_ALGO); - config.setAuthentication(AUTH_ALGO); - } - - private void addEncapSocketToIpSecConfig(int resourceId, IpSecConfig config) throws Exception { - config.setEncapType(IpSecTransform.ENCAP_ESPINUDP); - config.setEncapSocketResourceId(resourceId); - config.setEncapRemotePort(REMOTE_ENCAP_PORT); - } - - private void verifyTransformNetdCalledForCreatingSA( - IpSecConfig config, IpSecTransformResponse resp) throws Exception { - verifyTransformNetdCalledForCreatingSA(config, resp, 0); - } - - private void verifyTransformNetdCalledForCreatingSA( - IpSecConfig config, IpSecTransformResponse resp, int encapSocketPort) throws Exception { - IpSecAlgorithm auth = config.getAuthentication(); - IpSecAlgorithm crypt = config.getEncryption(); - IpSecAlgorithm authCrypt = config.getAuthenticatedEncryption(); - - verify(mMockNetd, times(1)) - .ipSecAddSecurityAssociation( - eq(mUid), - eq(config.getMode()), - eq(config.getSourceAddress()), - eq(config.getDestinationAddress()), - eq((config.getNetwork() != null) ? config.getNetwork().netId : 0), - eq(TEST_SPI), - eq(0), - eq(0), - eq((auth != null) ? auth.getName() : ""), - eq((auth != null) ? auth.getKey() : new byte[] {}), - eq((auth != null) ? auth.getTruncationLengthBits() : 0), - eq((crypt != null) ? crypt.getName() : ""), - eq((crypt != null) ? crypt.getKey() : new byte[] {}), - eq((crypt != null) ? crypt.getTruncationLengthBits() : 0), - eq((authCrypt != null) ? authCrypt.getName() : ""), - eq((authCrypt != null) ? authCrypt.getKey() : new byte[] {}), - eq((authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0), - eq(config.getEncapType()), - eq(encapSocketPort), - eq(config.getEncapRemotePort()), - eq(config.getXfrmInterfaceId())); - } - - @Test - public void testCreateTransform() throws Exception { - IpSecConfig ipSecConfig = new IpSecConfig(); - addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); - addAuthAndCryptToIpSecConfig(ipSecConfig); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - assertEquals(IpSecManager.Status.OK, createTransformResp.status); - - verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp); - } - - @Test - public void testCreateTransformAead() throws Exception { - IpSecConfig ipSecConfig = new IpSecConfig(); - addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); - - ipSecConfig.setAuthenticatedEncryption(AEAD_ALGO); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - assertEquals(IpSecManager.Status.OK, createTransformResp.status); - - verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp); - } - - @Test - public void testCreateTransportModeTransformWithEncap() throws Exception { - IpSecUdpEncapResponse udpSock = mIpSecService.openUdpEncapsulationSocket(0, new Binder()); - - IpSecConfig ipSecConfig = new IpSecConfig(); - ipSecConfig.setMode(IpSecTransform.MODE_TRANSPORT); - addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); - addAuthAndCryptToIpSecConfig(ipSecConfig); - addEncapSocketToIpSecConfig(udpSock.resourceId, ipSecConfig); - - if (mFamily == AF_INET) { - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - assertEquals(IpSecManager.Status.OK, createTransformResp.status); - - verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port); - } else { - try { - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6"); - } catch (IllegalArgumentException expected) { - } - } - } - - @Test - public void testCreateTunnelModeTransformWithEncap() throws Exception { - IpSecUdpEncapResponse udpSock = mIpSecService.openUdpEncapsulationSocket(0, new Binder()); - - IpSecConfig ipSecConfig = new IpSecConfig(); - ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL); - addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); - addAuthAndCryptToIpSecConfig(ipSecConfig); - addEncapSocketToIpSecConfig(udpSock.resourceId, ipSecConfig); - - if (mFamily == AF_INET) { - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - assertEquals(IpSecManager.Status.OK, createTransformResp.status); - - verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port); - } else { - try { - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6"); - } catch (IllegalArgumentException expected) { - } - } - } - - @Test - public void testCreateTwoTransformsWithSameSpis() throws Exception { - IpSecConfig ipSecConfig = new IpSecConfig(); - addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); - addAuthAndCryptToIpSecConfig(ipSecConfig); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - assertEquals(IpSecManager.Status.OK, createTransformResp.status); - - // Attempting to create transform a second time with the same SPIs should throw an error... - try { - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - fail("IpSecService should have thrown an error for reuse of SPI"); - } catch (IllegalStateException expected) { - } - - // ... even if the transform is deleted - mIpSecService.deleteTransform(createTransformResp.resourceId); - try { - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - fail("IpSecService should have thrown an error for reuse of SPI"); - } catch (IllegalStateException expected) { - } - } - - @Test - public void testReleaseOwnedSpi() throws Exception { - IpSecConfig ipSecConfig = new IpSecConfig(); - addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); - addAuthAndCryptToIpSecConfig(ipSecConfig); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); - assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent); - mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId()); - verify(mMockNetd, times(0)) - .ipSecDeleteSecurityAssociation( - eq(mUid), - anyString(), - anyString(), - eq(TEST_SPI), - anyInt(), - anyInt(), - anyInt()); - // quota is not released until the SPI is released by the Transform - assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent); - } - - @Test - public void testDeleteTransform() throws Exception { - IpSecConfig ipSecConfig = new IpSecConfig(); - addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); - addAuthAndCryptToIpSecConfig(ipSecConfig); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - mIpSecService.deleteTransform(createTransformResp.resourceId); - - verify(mMockNetd, times(1)) - .ipSecDeleteSecurityAssociation( - eq(mUid), - anyString(), - anyString(), - eq(TEST_SPI), - anyInt(), - anyInt(), - anyInt()); - - // Verify quota and RefcountedResource objects cleaned up - IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); - assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent); - assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent); - - mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId()); - // Verify that ipSecDeleteSa was not called when the SPI was released because the - // ownedByTransform property should prevent it; (note, the called count is cumulative). - verify(mMockNetd, times(1)) - .ipSecDeleteSecurityAssociation( - anyInt(), - anyString(), - anyString(), - anyInt(), - anyInt(), - anyInt(), - anyInt()); - assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent); - - try { - userRecord.mTransformRecords.getRefcountedResourceOrThrow( - createTransformResp.resourceId); - fail("Expected IllegalArgumentException on attempt to access deleted resource"); - } catch (IllegalArgumentException expected) { - - } - } - - @Test - public void testTransportModeTransformBinderDeath() throws Exception { - IpSecConfig ipSecConfig = new IpSecConfig(); - addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); - addAuthAndCryptToIpSecConfig(ipSecConfig); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - - IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); - IpSecService.RefcountedResource refcountedRecord = - userRecord.mTransformRecords.getRefcountedResourceOrThrow( - createTransformResp.resourceId); - - refcountedRecord.binderDied(); - - verify(mMockNetd) - .ipSecDeleteSecurityAssociation( - eq(mUid), - anyString(), - anyString(), - eq(TEST_SPI), - anyInt(), - anyInt(), - anyInt()); - - // Verify quota and RefcountedResource objects cleaned up - assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent); - try { - userRecord.mTransformRecords.getRefcountedResourceOrThrow( - createTransformResp.resourceId); - fail("Expected IllegalArgumentException on attempt to access deleted resource"); - } catch (IllegalArgumentException expected) { - - } - } - - @Test - public void testApplyTransportModeTransform() throws Exception { - verifyApplyTransportModeTransformCommon(false); - } - - @Test - public void testApplyTransportModeTransformReleasedSpi() throws Exception { - verifyApplyTransportModeTransformCommon(true); - } - - public void verifyApplyTransportModeTransformCommon( - boolean closeSpiBeforeApply) throws Exception { - IpSecConfig ipSecConfig = new IpSecConfig(); - addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); - addAuthAndCryptToIpSecConfig(ipSecConfig); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - - if (closeSpiBeforeApply) { - mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId()); - } - - Socket socket = new Socket(); - socket.bind(null); - ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket); - - int resourceId = createTransformResp.resourceId; - mIpSecService.applyTransportModeTransform(pfd, IpSecManager.DIRECTION_OUT, resourceId); - - verify(mMockNetd) - .ipSecApplyTransportModeTransform( - eq(pfd), - eq(mUid), - eq(IpSecManager.DIRECTION_OUT), - anyString(), - anyString(), - eq(TEST_SPI)); - } - - @Test - public void testApplyTransportModeTransformWithClosedSpi() throws Exception { - IpSecConfig ipSecConfig = new IpSecConfig(); - addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); - addAuthAndCryptToIpSecConfig(ipSecConfig); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - - // Close SPI record - mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId()); - - Socket socket = new Socket(); - socket.bind(null); - ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket); - - int resourceId = createTransformResp.resourceId; - mIpSecService.applyTransportModeTransform(pfd, IpSecManager.DIRECTION_OUT, resourceId); - - verify(mMockNetd) - .ipSecApplyTransportModeTransform( - eq(pfd), - eq(mUid), - eq(IpSecManager.DIRECTION_OUT), - anyString(), - anyString(), - eq(TEST_SPI)); - } - - @Test - public void testRemoveTransportModeTransform() throws Exception { - Socket socket = new Socket(); - socket.bind(null); - ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket); - mIpSecService.removeTransportModeTransforms(pfd); - - verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd); - } - - private IpSecTunnelInterfaceResponse createAndValidateTunnel( - String localAddr, String remoteAddr, String pkgName) throws Exception { - final InterfaceConfigurationParcel config = new InterfaceConfigurationParcel(); - config.flags = new String[] {IF_STATE_DOWN}; - when(mMockNetd.interfaceGetCfg(anyString())).thenReturn(config); - IpSecTunnelInterfaceResponse createTunnelResp = - mIpSecService.createTunnelInterface( - mSourceAddr, mDestinationAddr, fakeNetwork, new Binder(), pkgName); - - assertNotNull(createTunnelResp); - assertEquals(IpSecManager.Status.OK, createTunnelResp.status); - for (int direction : new int[] {DIRECTION_IN, DIRECTION_OUT, DIRECTION_FWD}) { - for (int selAddrFamily : ADDRESS_FAMILIES) { - verify(mMockNetd).ipSecAddSecurityPolicy( - eq(mUid), - eq(selAddrFamily), - eq(direction), - anyString(), - anyString(), - eq(0), - anyInt(), // iKey/oKey - anyInt(), // mask - eq(createTunnelResp.resourceId)); - } - } - - return createTunnelResp; - } - - @Test - public void testCreateTunnelInterface() throws Exception { - IpSecTunnelInterfaceResponse createTunnelResp = - createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE); - - // Check that we have stored the tracking object, and retrieve it - IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); - IpSecService.RefcountedResource refcountedRecord = - userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow( - createTunnelResp.resourceId); - - assertEquals(1, userRecord.mTunnelQuotaTracker.mCurrent); - verify(mMockNetd) - .ipSecAddTunnelInterface( - eq(createTunnelResp.interfaceName), - eq(mSourceAddr), - eq(mDestinationAddr), - anyInt(), - anyInt(), - anyInt()); - verify(mMockNetd).interfaceSetCfg(argThat( - config -> Arrays.asList(config.flags).contains(IF_STATE_UP))); - } - - @Test - public void testDeleteTunnelInterface() throws Exception { - IpSecTunnelInterfaceResponse createTunnelResp = - createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE); - - IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); - - mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, BLESSED_PACKAGE); - - // Verify quota and RefcountedResource objects cleaned up - assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent); - verify(mMockNetd).ipSecRemoveTunnelInterface(eq(createTunnelResp.interfaceName)); - try { - userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow( - createTunnelResp.resourceId); - fail("Expected IllegalArgumentException on attempt to access deleted resource"); - } catch (IllegalArgumentException expected) { - } - } - - private Network createFakeUnderlyingNetwork(String interfaceName) { - final Network fakeNetwork = new Network(1000); - final LinkProperties fakeLp = new LinkProperties(); - fakeLp.setInterfaceName(interfaceName); - when(mMockConnectivityMgr.getLinkProperties(eq(fakeNetwork))).thenReturn(fakeLp); - return fakeNetwork; - } - - @Test - public void testSetNetworkForTunnelInterface() throws Exception { - final IpSecTunnelInterfaceResponse createTunnelResp = - createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE); - final Network newFakeNetwork = createFakeUnderlyingNetwork("newFakeNetworkInterface"); - final int tunnelIfaceResourceId = createTunnelResp.resourceId; - mIpSecService.setNetworkForTunnelInterface( - tunnelIfaceResourceId, newFakeNetwork, BLESSED_PACKAGE); - - final IpSecService.UserRecord userRecord = - mIpSecService.mUserResourceTracker.getUserRecord(mUid); - assertEquals(1, userRecord.mTunnelQuotaTracker.mCurrent); - - final TunnelInterfaceRecord tunnelInterfaceInfo = - userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelIfaceResourceId); - assertEquals(newFakeNetwork, tunnelInterfaceInfo.getUnderlyingNetwork()); - } - - @Test - public void testSetNetworkForTunnelInterfaceFailsForInvalidResourceId() throws Exception { - final IpSecTunnelInterfaceResponse createTunnelResp = - createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE); - final Network newFakeNetwork = new Network(1000); - - try { - mIpSecService.setNetworkForTunnelInterface( - IpSecManager.INVALID_RESOURCE_ID, newFakeNetwork, BLESSED_PACKAGE); - fail("Expected an IllegalArgumentException for invalid resource ID."); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testSetNetworkForTunnelInterfaceFailsWhenSettingTunnelNetwork() throws Exception { - final IpSecTunnelInterfaceResponse createTunnelResp = - createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE); - final int tunnelIfaceResourceId = createTunnelResp.resourceId; - final IpSecService.UserRecord userRecord = - mIpSecService.mUserResourceTracker.getUserRecord(mUid); - final TunnelInterfaceRecord tunnelInterfaceInfo = - userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelIfaceResourceId); - - final Network newFakeNetwork = - createFakeUnderlyingNetwork(tunnelInterfaceInfo.getInterfaceName()); - - try { - mIpSecService.setNetworkForTunnelInterface( - tunnelIfaceResourceId, newFakeNetwork, BLESSED_PACKAGE); - fail( - "Expected an IllegalArgumentException because the underlying network is the" - + " network being exposed by this tunnel."); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testTunnelInterfaceBinderDeath() throws Exception { - IpSecTunnelInterfaceResponse createTunnelResp = - createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE); - - IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); - IpSecService.RefcountedResource refcountedRecord = - userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow( - createTunnelResp.resourceId); - - refcountedRecord.binderDied(); - - // Verify quota and RefcountedResource objects cleaned up - assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent); - verify(mMockNetd).ipSecRemoveTunnelInterface(eq(createTunnelResp.interfaceName)); - try { - userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow( - createTunnelResp.resourceId); - fail("Expected IllegalArgumentException on attempt to access deleted resource"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testApplyTunnelModeTransformOutbound() throws Exception { - verifyApplyTunnelModeTransformCommon(false /* closeSpiBeforeApply */, DIRECTION_OUT); - } - - @Test - public void testApplyTunnelModeTransformOutboundNonNetworkStack() throws Exception { - mTestContext.setAllowedPermissions(android.Manifest.permission.MANAGE_IPSEC_TUNNELS); - verifyApplyTunnelModeTransformCommon(false /* closeSpiBeforeApply */, DIRECTION_OUT); - } - - @Test - public void testApplyTunnelModeTransformOutboundReleasedSpi() throws Exception { - verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_OUT); - } - - @Test - public void testApplyTunnelModeTransformInbound() throws Exception { - verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_IN); - } - - @Test - public void testApplyTunnelModeTransformInboundNonNetworkStack() throws Exception { - mTestContext.setAllowedPermissions(android.Manifest.permission.MANAGE_IPSEC_TUNNELS); - verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_IN); - } - - @Test - public void testApplyTunnelModeTransformForward() throws Exception { - verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_FWD); - } - - @Test - public void testApplyTunnelModeTransformForwardNonNetworkStack() throws Exception { - mTestContext.setAllowedPermissions(android.Manifest.permission.MANAGE_IPSEC_TUNNELS); - - try { - verifyApplyTunnelModeTransformCommon(true /* closeSpiBeforeApply */, DIRECTION_FWD); - fail("Expected security exception due to use of forward policies without NETWORK_STACK" - + " or MAINLINE_NETWORK_STACK permission"); - } catch (SecurityException expected) { - } - } - - public void verifyApplyTunnelModeTransformCommon(boolean closeSpiBeforeApply, int direction) - throws Exception { - IpSecConfig ipSecConfig = new IpSecConfig(); - ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL); - addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); - addAuthAndCryptToIpSecConfig(ipSecConfig); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - IpSecTunnelInterfaceResponse createTunnelResp = - createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE); - - if (closeSpiBeforeApply) { - mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId()); - } - - int transformResourceId = createTransformResp.resourceId; - int tunnelResourceId = createTunnelResp.resourceId; - mIpSecService.applyTunnelModeTransform( - tunnelResourceId, direction, transformResourceId, BLESSED_PACKAGE); - - for (int selAddrFamily : ADDRESS_FAMILIES) { - verify(mMockNetd) - .ipSecUpdateSecurityPolicy( - eq(mUid), - eq(selAddrFamily), - eq(direction), - anyString(), - anyString(), - eq(direction == DIRECTION_OUT ? TEST_SPI : 0), - anyInt(), // iKey/oKey - anyInt(), // mask - eq(tunnelResourceId)); - } - - ipSecConfig.setXfrmInterfaceId(tunnelResourceId); - verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp); - } - - - @Test - public void testApplyTunnelModeTransformWithClosedSpi() throws Exception { - IpSecConfig ipSecConfig = new IpSecConfig(); - ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL); - addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig); - addAuthAndCryptToIpSecConfig(ipSecConfig); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE); - IpSecTunnelInterfaceResponse createTunnelResp = - createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE); - - // Close SPI record - mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId()); - - int transformResourceId = createTransformResp.resourceId; - int tunnelResourceId = createTunnelResp.resourceId; - mIpSecService.applyTunnelModeTransform( - tunnelResourceId, IpSecManager.DIRECTION_OUT, transformResourceId, BLESSED_PACKAGE); - - for (int selAddrFamily : ADDRESS_FAMILIES) { - verify(mMockNetd) - .ipSecUpdateSecurityPolicy( - eq(mUid), - eq(selAddrFamily), - eq(IpSecManager.DIRECTION_OUT), - anyString(), - anyString(), - eq(TEST_SPI), - anyInt(), // iKey/oKey - anyInt(), // mask - eq(tunnelResourceId)); - } - - ipSecConfig.setXfrmInterfaceId(tunnelResourceId); - verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp); - } - - @Test - public void testAddRemoveAddressFromTunnelInterface() throws Exception { - for (String pkgName : new String[] {BLESSED_PACKAGE, SYSTEM_PACKAGE}) { - IpSecTunnelInterfaceResponse createTunnelResp = - createAndValidateTunnel(mSourceAddr, mDestinationAddr, pkgName); - mIpSecService.addAddressToTunnelInterface( - createTunnelResp.resourceId, mLocalInnerAddress, pkgName); - verify(mMockNetd, times(1)) - .interfaceAddAddress( - eq(createTunnelResp.interfaceName), - eq(mLocalInnerAddress.getAddress().getHostAddress()), - eq(mLocalInnerAddress.getPrefixLength())); - mIpSecService.removeAddressFromTunnelInterface( - createTunnelResp.resourceId, mLocalInnerAddress, pkgName); - verify(mMockNetd, times(1)) - .interfaceDelAddress( - eq(createTunnelResp.interfaceName), - eq(mLocalInnerAddress.getAddress().getHostAddress()), - eq(mLocalInnerAddress.getPrefixLength())); - mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, pkgName); - } - } - - @Ignore - @Test - public void testAddTunnelFailsForBadPackageName() throws Exception { - try { - IpSecTunnelInterfaceResponse createTunnelResp = - createAndValidateTunnel(mSourceAddr, mDestinationAddr, BAD_PACKAGE); - fail("Expected a SecurityException for badPackage."); - } catch (SecurityException expected) { - } - } - - @Test - public void testFeatureFlagVerification() throws Exception { - when(mMockPkgMgr.hasSystemFeature(eq(PackageManager.FEATURE_IPSEC_TUNNELS))) - .thenReturn(false); - - try { - String addr = Inet4Address.getLoopbackAddress().getHostAddress(); - mIpSecService.createTunnelInterface( - addr, addr, new Network(0), new Binder(), BLESSED_PACKAGE); - fail("Expected UnsupportedOperationException for disabled feature"); - } catch (UnsupportedOperationException expected) { - } - } -} diff --git a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java b/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java deleted file mode 100644 index 22a2c94fc194..000000000000 --- a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import android.content.Context; -import android.os.Binder; -import android.os.IBinder; -import android.os.RemoteException; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.server.IpSecService.IResource; -import com.android.server.IpSecService.RefcountedResource; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ThreadLocalRandom; - -/** Unit tests for {@link IpSecService.RefcountedResource}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class IpSecServiceRefcountedResourceTest { - Context mMockContext; - IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig; - IpSecService mIpSecService; - - @Before - public void setUp() throws Exception { - mMockContext = mock(Context.class); - mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class); - mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig); - } - - private void assertResourceState( - RefcountedResource<IResource> resource, - int refCount, - int userReleaseCallCount, - int releaseReferenceCallCount, - int invalidateCallCount, - int freeUnderlyingResourcesCallCount) - throws RemoteException { - // Check refcount on RefcountedResource - assertEquals(refCount, resource.mRefCount); - - // Check call count of RefcountedResource - verify(resource, times(userReleaseCallCount)).userRelease(); - verify(resource, times(releaseReferenceCallCount)).releaseReference(); - - // Check call count of IResource - verify(resource.getResource(), times(invalidateCallCount)).invalidate(); - verify(resource.getResource(), times(freeUnderlyingResourcesCallCount)) - .freeUnderlyingResources(); - } - - /** Adds mockito instrumentation */ - private RefcountedResource<IResource> getTestRefcountedResource( - RefcountedResource... children) { - return getTestRefcountedResource(new Binder(), children); - } - - /** Adds mockito instrumentation with provided binder */ - private RefcountedResource<IResource> getTestRefcountedResource( - IBinder binder, RefcountedResource... children) { - return spy( - mIpSecService - .new RefcountedResource<IResource>(mock(IResource.class), binder, children)); - } - - @Test - public void testConstructor() throws RemoteException { - IBinder binderMock = mock(IBinder.class); - RefcountedResource<IResource> resource = getTestRefcountedResource(binderMock); - - // Verify resource's refcount starts at 1 (for user-reference) - assertResourceState(resource, 1, 0, 0, 0, 0); - - // Verify linking to binder death - verify(binderMock).linkToDeath(anyObject(), anyInt()); - } - - @Test - public void testConstructorWithChildren() throws RemoteException { - IBinder binderMockChild = mock(IBinder.class); - IBinder binderMockParent = mock(IBinder.class); - RefcountedResource<IResource> childResource = getTestRefcountedResource(binderMockChild); - RefcountedResource<IResource> parentResource = - getTestRefcountedResource(binderMockParent, childResource); - - // Verify parent's refcount starts at 1 (for user-reference) - assertResourceState(parentResource, 1, 0, 0, 0, 0); - - // Verify child's refcounts were incremented - assertResourceState(childResource, 2, 0, 0, 0, 0); - - // Verify linking to binder death - verify(binderMockChild).linkToDeath(anyObject(), anyInt()); - verify(binderMockParent).linkToDeath(anyObject(), anyInt()); - } - - @Test - public void testFailLinkToDeath() throws RemoteException { - IBinder binderMock = mock(IBinder.class); - doThrow(new RemoteException()).when(binderMock).linkToDeath(anyObject(), anyInt()); - - try { - getTestRefcountedResource(binderMock); - fail("Expected exception to propogate when binder fails to link to death"); - } catch (RuntimeException expected) { - } - } - - @Test - public void testCleanupAndRelease() throws RemoteException { - IBinder binderMock = mock(IBinder.class); - RefcountedResource<IResource> refcountedResource = getTestRefcountedResource(binderMock); - - // Verify user-initiated cleanup path decrements refcount and calls full cleanup flow - refcountedResource.userRelease(); - assertResourceState(refcountedResource, -1, 1, 1, 1, 1); - - // Verify user-initated cleanup path unlinks from binder - verify(binderMock).unlinkToDeath(eq(refcountedResource), eq(0)); - assertNull(refcountedResource.mBinder); - } - - @Test - public void testMultipleCallsToCleanupAndRelease() throws RemoteException { - RefcountedResource<IResource> refcountedResource = getTestRefcountedResource(); - - // Verify calling userRelease multiple times does not trigger any other cleanup - // methods - refcountedResource.userRelease(); - assertResourceState(refcountedResource, -1, 1, 1, 1, 1); - - refcountedResource.userRelease(); - refcountedResource.userRelease(); - assertResourceState(refcountedResource, -1, 3, 1, 1, 1); - } - - @Test - public void testBinderDeathAfterCleanupAndReleaseDoesNothing() throws RemoteException { - RefcountedResource<IResource> refcountedResource = getTestRefcountedResource(); - - refcountedResource.userRelease(); - assertResourceState(refcountedResource, -1, 1, 1, 1, 1); - - // Verify binder death call does not trigger any other cleanup methods if called after - // userRelease() - refcountedResource.binderDied(); - assertResourceState(refcountedResource, -1, 2, 1, 1, 1); - } - - @Test - public void testBinderDeath() throws RemoteException { - RefcountedResource<IResource> refcountedResource = getTestRefcountedResource(); - - // Verify binder death caused cleanup - refcountedResource.binderDied(); - verify(refcountedResource, times(1)).binderDied(); - assertResourceState(refcountedResource, -1, 1, 1, 1, 1); - assertNull(refcountedResource.mBinder); - } - - @Test - public void testCleanupParentDecrementsChildRefcount() throws RemoteException { - RefcountedResource<IResource> childResource = getTestRefcountedResource(); - RefcountedResource<IResource> parentResource = getTestRefcountedResource(childResource); - - parentResource.userRelease(); - - // Verify parent gets cleaned up properly, and triggers releaseReference on - // child - assertResourceState(childResource, 1, 0, 1, 0, 0); - assertResourceState(parentResource, -1, 1, 1, 1, 1); - } - - @Test - public void testCleanupReferencedChildDoesNotTriggerRelease() throws RemoteException { - RefcountedResource<IResource> childResource = getTestRefcountedResource(); - RefcountedResource<IResource> parentResource = getTestRefcountedResource(childResource); - - childResource.userRelease(); - - // Verify that child does not clean up kernel resources and quota. - assertResourceState(childResource, 1, 1, 1, 1, 0); - assertResourceState(parentResource, 1, 0, 0, 0, 0); - } - - @Test - public void testTwoParents() throws RemoteException { - RefcountedResource<IResource> childResource = getTestRefcountedResource(); - RefcountedResource<IResource> parentResource1 = getTestRefcountedResource(childResource); - RefcountedResource<IResource> parentResource2 = getTestRefcountedResource(childResource); - - // Verify that child does not cleanup kernel resources and quota until all references - // have been released. Assumption: parents release correctly based on - // testCleanupParentDecrementsChildRefcount() - childResource.userRelease(); - assertResourceState(childResource, 2, 1, 1, 1, 0); - - parentResource1.userRelease(); - assertResourceState(childResource, 1, 1, 2, 1, 0); - - parentResource2.userRelease(); - assertResourceState(childResource, -1, 1, 3, 1, 1); - } - - @Test - public void testTwoChildren() throws RemoteException { - RefcountedResource<IResource> childResource1 = getTestRefcountedResource(); - RefcountedResource<IResource> childResource2 = getTestRefcountedResource(); - RefcountedResource<IResource> parentResource = - getTestRefcountedResource(childResource1, childResource2); - - childResource1.userRelease(); - assertResourceState(childResource1, 1, 1, 1, 1, 0); - assertResourceState(childResource2, 2, 0, 0, 0, 0); - - parentResource.userRelease(); - assertResourceState(childResource1, -1, 1, 2, 1, 1); - assertResourceState(childResource2, 1, 0, 1, 0, 0); - - childResource2.userRelease(); - assertResourceState(childResource1, -1, 1, 2, 1, 1); - assertResourceState(childResource2, -1, 1, 2, 1, 1); - } - - @Test - public void testSampleUdpEncapTranform() throws RemoteException { - RefcountedResource<IResource> spi1 = getTestRefcountedResource(); - RefcountedResource<IResource> spi2 = getTestRefcountedResource(); - RefcountedResource<IResource> udpEncapSocket = getTestRefcountedResource(); - RefcountedResource<IResource> transform = - getTestRefcountedResource(spi1, spi2, udpEncapSocket); - - // Pretend one SPI goes out of reference (releaseManagedResource -> userRelease) - spi1.userRelease(); - - // User called releaseManagedResource on udpEncap socket - udpEncapSocket.userRelease(); - - // User dies, and binder kills the rest - spi2.binderDied(); - transform.binderDied(); - - // Check resource states - assertResourceState(spi1, -1, 1, 2, 1, 1); - assertResourceState(spi2, -1, 1, 2, 1, 1); - assertResourceState(udpEncapSocket, -1, 1, 2, 1, 1); - assertResourceState(transform, -1, 1, 1, 1, 1); - } - - @Test - public void testSampleDualTransformEncapSocket() throws RemoteException { - RefcountedResource<IResource> spi1 = getTestRefcountedResource(); - RefcountedResource<IResource> spi2 = getTestRefcountedResource(); - RefcountedResource<IResource> spi3 = getTestRefcountedResource(); - RefcountedResource<IResource> spi4 = getTestRefcountedResource(); - RefcountedResource<IResource> udpEncapSocket = getTestRefcountedResource(); - RefcountedResource<IResource> transform1 = - getTestRefcountedResource(spi1, spi2, udpEncapSocket); - RefcountedResource<IResource> transform2 = - getTestRefcountedResource(spi3, spi4, udpEncapSocket); - - // Pretend one SPIs goes out of reference (releaseManagedResource -> userRelease) - spi1.userRelease(); - - // User called releaseManagedResource on udpEncap socket and spi4 - udpEncapSocket.userRelease(); - spi4.userRelease(); - - // User dies, and binder kills the rest - spi2.binderDied(); - spi3.binderDied(); - transform2.binderDied(); - transform1.binderDied(); - - // Check resource states - assertResourceState(spi1, -1, 1, 2, 1, 1); - assertResourceState(spi2, -1, 1, 2, 1, 1); - assertResourceState(spi3, -1, 1, 2, 1, 1); - assertResourceState(spi4, -1, 1, 2, 1, 1); - assertResourceState(udpEncapSocket, -1, 1, 3, 1, 1); - assertResourceState(transform1, -1, 1, 1, 1, 1); - assertResourceState(transform2, -1, 1, 1, 1, 1); - } - - @Test - public void fuzzTest() throws RemoteException { - List<RefcountedResource<IResource>> resources = new ArrayList<>(); - - // Build a tree of resources - for (int i = 0; i < 100; i++) { - // Choose a random number of children from the existing list - int numChildren = ThreadLocalRandom.current().nextInt(0, resources.size() + 1); - - // Build a (random) list of children - Set<RefcountedResource<IResource>> children = new HashSet<>(); - for (int j = 0; j < numChildren; j++) { - int childIndex = ThreadLocalRandom.current().nextInt(0, resources.size()); - children.add(resources.get(childIndex)); - } - - RefcountedResource<IResource> newRefcountedResource = - getTestRefcountedResource( - children.toArray(new RefcountedResource[children.size()])); - resources.add(newRefcountedResource); - } - - // Cleanup all resources in a random order - List<RefcountedResource<IResource>> clonedResources = - new ArrayList<>(resources); // shallow copy - while (!clonedResources.isEmpty()) { - int index = ThreadLocalRandom.current().nextInt(0, clonedResources.size()); - RefcountedResource<IResource> refcountedResource = clonedResources.get(index); - refcountedResource.userRelease(); - clonedResources.remove(index); - } - - // Verify all resources were cleaned up properly - for (RefcountedResource<IResource> refcountedResource : resources) { - assertEquals(-1, refcountedResource.mRefCount); - } - } -} diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java deleted file mode 100644 index 6232423b4f9e..000000000000 --- a/tests/net/java/com/android/server/IpSecServiceTest.java +++ /dev/null @@ -1,670 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server; - -import static android.system.OsConstants.AF_INET; -import static android.system.OsConstants.EADDRINUSE; -import static android.system.OsConstants.IPPROTO_UDP; -import static android.system.OsConstants.SOCK_DGRAM; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.INetd; -import android.net.IpSecAlgorithm; -import android.net.IpSecConfig; -import android.net.IpSecManager; -import android.net.IpSecSpiResponse; -import android.net.IpSecUdpEncapResponse; -import android.os.Binder; -import android.os.ParcelFileDescriptor; -import android.os.Process; -import android.system.ErrnoException; -import android.system.Os; -import android.system.StructStat; -import android.util.Range; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import dalvik.system.SocketTagger; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentMatcher; - -import java.io.FileDescriptor; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.List; - -/** Unit tests for {@link IpSecService}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class IpSecServiceTest { - - private static final int DROID_SPI = 0xD1201D; - private static final int MAX_NUM_ENCAP_SOCKETS = 100; - private static final int MAX_NUM_SPIS = 100; - private static final int TEST_UDP_ENCAP_INVALID_PORT = 100; - private static final int TEST_UDP_ENCAP_PORT_OUT_RANGE = 100000; - - private static final InetAddress INADDR_ANY; - - private static final byte[] AEAD_KEY = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x73, 0x61, 0x6C, 0x74 - }; - private static final byte[] CRYPT_KEY = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F - }; - private static final byte[] AUTH_KEY = { - 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, - 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F - }; - - private static final IpSecAlgorithm AUTH_ALGO = - new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4); - private static final IpSecAlgorithm CRYPT_ALGO = - new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); - private static final IpSecAlgorithm AEAD_ALGO = - new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); - - static { - try { - INADDR_ANY = InetAddress.getByAddress(new byte[] {0, 0, 0, 0}); - } catch (UnknownHostException e) { - throw new RuntimeException(e); - } - } - - Context mMockContext; - INetd mMockNetd; - IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig; - IpSecService mIpSecService; - - @Before - public void setUp() throws Exception { - mMockContext = mock(Context.class); - mMockNetd = mock(INetd.class); - mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class); - mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig); - - // Injecting mock netd - when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd); - } - - @Test - public void testIpSecServiceCreate() throws InterruptedException { - IpSecService ipSecSrv = IpSecService.create(mMockContext); - assertNotNull(ipSecSrv); - } - - @Test - public void testReleaseInvalidSecurityParameterIndex() throws Exception { - try { - mIpSecService.releaseSecurityParameterIndex(1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - /** This function finds an available port */ - int findUnusedPort() throws Exception { - // Get an available port. - ServerSocket s = new ServerSocket(0); - int port = s.getLocalPort(); - s.close(); - return port; - } - - @Test - public void testOpenAndCloseUdpEncapsulationSocket() throws Exception { - int localport = -1; - IpSecUdpEncapResponse udpEncapResp = null; - - for (int i = 0; i < IpSecService.MAX_PORT_BIND_ATTEMPTS; i++) { - localport = findUnusedPort(); - - udpEncapResp = mIpSecService.openUdpEncapsulationSocket(localport, new Binder()); - assertNotNull(udpEncapResp); - if (udpEncapResp.status == IpSecManager.Status.OK) { - break; - } - - // Else retry to reduce possibility for port-bind failures. - } - - assertNotNull(udpEncapResp); - assertEquals(IpSecManager.Status.OK, udpEncapResp.status); - assertEquals(localport, udpEncapResp.port); - - mIpSecService.closeUdpEncapsulationSocket(udpEncapResp.resourceId); - udpEncapResp.fileDescriptor.close(); - - // Verify quota and RefcountedResource objects cleaned up - IpSecService.UserRecord userRecord = - mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); - assertEquals(0, userRecord.mSocketQuotaTracker.mCurrent); - try { - userRecord.mEncapSocketRecords.getRefcountedResourceOrThrow(udpEncapResp.resourceId); - fail("Expected IllegalArgumentException on attempt to access deleted resource"); - } catch (IllegalArgumentException expected) { - - } - } - - @Test - public void testUdpEncapsulationSocketBinderDeath() throws Exception { - IpSecUdpEncapResponse udpEncapResp = - mIpSecService.openUdpEncapsulationSocket(0, new Binder()); - - IpSecService.UserRecord userRecord = - mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); - IpSecService.RefcountedResource refcountedRecord = - userRecord.mEncapSocketRecords.getRefcountedResourceOrThrow( - udpEncapResp.resourceId); - - refcountedRecord.binderDied(); - - // Verify quota and RefcountedResource objects cleaned up - assertEquals(0, userRecord.mSocketQuotaTracker.mCurrent); - try { - userRecord.mEncapSocketRecords.getRefcountedResourceOrThrow(udpEncapResp.resourceId); - fail("Expected IllegalArgumentException on attempt to access deleted resource"); - } catch (IllegalArgumentException expected) { - - } - } - - @Test - public void testOpenUdpEncapsulationSocketAfterClose() throws Exception { - IpSecUdpEncapResponse udpEncapResp = - mIpSecService.openUdpEncapsulationSocket(0, new Binder()); - assertNotNull(udpEncapResp); - assertEquals(IpSecManager.Status.OK, udpEncapResp.status); - int localport = udpEncapResp.port; - - mIpSecService.closeUdpEncapsulationSocket(udpEncapResp.resourceId); - udpEncapResp.fileDescriptor.close(); - - /** Check if localport is available. */ - FileDescriptor newSocket = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - Os.bind(newSocket, INADDR_ANY, localport); - Os.close(newSocket); - } - - /** - * This function checks if the IpSecService holds the reserved port. If - * closeUdpEncapsulationSocket is not called, the socket cleanup should not be complete. - */ - @Test - public void testUdpEncapPortNotReleased() throws Exception { - IpSecUdpEncapResponse udpEncapResp = - mIpSecService.openUdpEncapsulationSocket(0, new Binder()); - assertNotNull(udpEncapResp); - assertEquals(IpSecManager.Status.OK, udpEncapResp.status); - int localport = udpEncapResp.port; - - udpEncapResp.fileDescriptor.close(); - - FileDescriptor newSocket = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - try { - Os.bind(newSocket, INADDR_ANY, localport); - fail("ErrnoException not thrown"); - } catch (ErrnoException e) { - assertEquals(EADDRINUSE, e.errno); - } - mIpSecService.closeUdpEncapsulationSocket(udpEncapResp.resourceId); - } - - @Test - public void testOpenUdpEncapsulationSocketOnRandomPort() throws Exception { - IpSecUdpEncapResponse udpEncapResp = - mIpSecService.openUdpEncapsulationSocket(0, new Binder()); - assertNotNull(udpEncapResp); - assertEquals(IpSecManager.Status.OK, udpEncapResp.status); - assertNotEquals(0, udpEncapResp.port); - mIpSecService.closeUdpEncapsulationSocket(udpEncapResp.resourceId); - udpEncapResp.fileDescriptor.close(); - } - - @Test - public void testOpenUdpEncapsulationSocketPortRange() throws Exception { - try { - mIpSecService.openUdpEncapsulationSocket(TEST_UDP_ENCAP_INVALID_PORT, new Binder()); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - - try { - mIpSecService.openUdpEncapsulationSocket(TEST_UDP_ENCAP_PORT_OUT_RANGE, new Binder()); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - @Test - public void testOpenUdpEncapsulationSocketTwice() throws Exception { - IpSecUdpEncapResponse udpEncapResp = - mIpSecService.openUdpEncapsulationSocket(0, new Binder()); - assertNotNull(udpEncapResp); - assertEquals(IpSecManager.Status.OK, udpEncapResp.status); - int localport = udpEncapResp.port; - - IpSecUdpEncapResponse testUdpEncapResp = - mIpSecService.openUdpEncapsulationSocket(localport, new Binder()); - assertEquals(IpSecManager.Status.RESOURCE_UNAVAILABLE, testUdpEncapResp.status); - - mIpSecService.closeUdpEncapsulationSocket(udpEncapResp.resourceId); - udpEncapResp.fileDescriptor.close(); - } - - @Test - public void testCloseInvalidUdpEncapsulationSocket() throws Exception { - try { - mIpSecService.closeUdpEncapsulationSocket(1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - @Test - public void testValidateAlgorithmsAuth() { - // Validate that correct algorithm type succeeds - IpSecConfig config = new IpSecConfig(); - config.setAuthentication(AUTH_ALGO); - mIpSecService.validateAlgorithms(config); - - // Validate that incorrect algorithm types fails - for (IpSecAlgorithm algo : new IpSecAlgorithm[] {CRYPT_ALGO, AEAD_ALGO}) { - try { - config = new IpSecConfig(); - config.setAuthentication(algo); - mIpSecService.validateAlgorithms(config); - fail("Did not throw exception on invalid algorithm type"); - } catch (IllegalArgumentException expected) { - } - } - } - - @Test - public void testValidateAlgorithmsCrypt() { - // Validate that correct algorithm type succeeds - IpSecConfig config = new IpSecConfig(); - config.setEncryption(CRYPT_ALGO); - mIpSecService.validateAlgorithms(config); - - // Validate that incorrect algorithm types fails - for (IpSecAlgorithm algo : new IpSecAlgorithm[] {AUTH_ALGO, AEAD_ALGO}) { - try { - config = new IpSecConfig(); - config.setEncryption(algo); - mIpSecService.validateAlgorithms(config); - fail("Did not throw exception on invalid algorithm type"); - } catch (IllegalArgumentException expected) { - } - } - } - - @Test - public void testValidateAlgorithmsAead() { - // Validate that correct algorithm type succeeds - IpSecConfig config = new IpSecConfig(); - config.setAuthenticatedEncryption(AEAD_ALGO); - mIpSecService.validateAlgorithms(config); - - // Validate that incorrect algorithm types fails - for (IpSecAlgorithm algo : new IpSecAlgorithm[] {AUTH_ALGO, CRYPT_ALGO}) { - try { - config = new IpSecConfig(); - config.setAuthenticatedEncryption(algo); - mIpSecService.validateAlgorithms(config); - fail("Did not throw exception on invalid algorithm type"); - } catch (IllegalArgumentException expected) { - } - } - } - - @Test - public void testValidateAlgorithmsAuthCrypt() { - // Validate that correct algorithm type succeeds - IpSecConfig config = new IpSecConfig(); - config.setAuthentication(AUTH_ALGO); - config.setEncryption(CRYPT_ALGO); - mIpSecService.validateAlgorithms(config); - } - - @Test - public void testValidateAlgorithmsNoAlgorithms() { - IpSecConfig config = new IpSecConfig(); - try { - mIpSecService.validateAlgorithms(config); - fail("Expected exception; no algorithms specified"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testValidateAlgorithmsAeadWithAuth() { - IpSecConfig config = new IpSecConfig(); - config.setAuthenticatedEncryption(AEAD_ALGO); - config.setAuthentication(AUTH_ALGO); - try { - mIpSecService.validateAlgorithms(config); - fail("Expected exception; both AEAD and auth algorithm specified"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testValidateAlgorithmsAeadWithCrypt() { - IpSecConfig config = new IpSecConfig(); - config.setAuthenticatedEncryption(AEAD_ALGO); - config.setEncryption(CRYPT_ALGO); - try { - mIpSecService.validateAlgorithms(config); - fail("Expected exception; both AEAD and crypt algorithm specified"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testValidateAlgorithmsAeadWithAuthAndCrypt() { - IpSecConfig config = new IpSecConfig(); - config.setAuthenticatedEncryption(AEAD_ALGO); - config.setAuthentication(AUTH_ALGO); - config.setEncryption(CRYPT_ALGO); - try { - mIpSecService.validateAlgorithms(config); - fail("Expected exception; AEAD, auth and crypt algorithm specified"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testDeleteInvalidTransform() throws Exception { - try { - mIpSecService.deleteTransform(1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - @Test - public void testRemoveTransportModeTransform() throws Exception { - Socket socket = new Socket(); - socket.bind(null); - ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket); - mIpSecService.removeTransportModeTransforms(pfd); - - verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd); - } - - @Test - public void testValidateIpAddresses() throws Exception { - String[] invalidAddresses = - new String[] {"www.google.com", "::", "2001::/64", "0.0.0.0", ""}; - for (String address : invalidAddresses) { - try { - IpSecSpiResponse spiResp = - mIpSecService.allocateSecurityParameterIndex( - address, DROID_SPI, new Binder()); - fail("Invalid address was passed through IpSecService validation: " + address); - } catch (IllegalArgumentException e) { - } catch (Exception e) { - fail( - "Invalid InetAddress was not caught in validation: " - + address - + ", Exception: " - + e); - } - } - } - - /** - * This function checks if the number of encap UDP socket that one UID can reserve has a - * reasonable limit. - */ - @Test - public void testSocketResourceTrackerLimitation() throws Exception { - List<IpSecUdpEncapResponse> openUdpEncapSockets = new ArrayList<IpSecUdpEncapResponse>(); - // Reserve sockets until it fails. - for (int i = 0; i < MAX_NUM_ENCAP_SOCKETS; i++) { - IpSecUdpEncapResponse newUdpEncapSocket = - mIpSecService.openUdpEncapsulationSocket(0, new Binder()); - assertNotNull(newUdpEncapSocket); - if (IpSecManager.Status.OK != newUdpEncapSocket.status) { - break; - } - openUdpEncapSockets.add(newUdpEncapSocket); - } - // Assert that the total sockets quota has a reasonable limit. - assertTrue("No UDP encap socket was open", !openUdpEncapSockets.isEmpty()); - assertTrue( - "Number of open UDP encap sockets is out of bound", - openUdpEncapSockets.size() < MAX_NUM_ENCAP_SOCKETS); - - // Try to reserve one more UDP encapsulation socket, and should fail. - IpSecUdpEncapResponse extraUdpEncapSocket = - mIpSecService.openUdpEncapsulationSocket(0, new Binder()); - assertNotNull(extraUdpEncapSocket); - assertEquals(IpSecManager.Status.RESOURCE_UNAVAILABLE, extraUdpEncapSocket.status); - - // Close one of the open UDP encapsulation sockets. - mIpSecService.closeUdpEncapsulationSocket(openUdpEncapSockets.get(0).resourceId); - openUdpEncapSockets.get(0).fileDescriptor.close(); - openUdpEncapSockets.remove(0); - - // Try to reserve one more UDP encapsulation socket, and should be successful. - extraUdpEncapSocket = mIpSecService.openUdpEncapsulationSocket(0, new Binder()); - assertNotNull(extraUdpEncapSocket); - assertEquals(IpSecManager.Status.OK, extraUdpEncapSocket.status); - openUdpEncapSockets.add(extraUdpEncapSocket); - - // Close open UDP sockets. - for (IpSecUdpEncapResponse openSocket : openUdpEncapSockets) { - mIpSecService.closeUdpEncapsulationSocket(openSocket.resourceId); - openSocket.fileDescriptor.close(); - } - } - - /** - * This function checks if the number of SPI that one UID can reserve has a reasonable limit. - * This test does not test for both address families or duplicate SPIs because resource tracking - * code does not depend on them. - */ - @Test - public void testSpiResourceTrackerLimitation() throws Exception { - List<IpSecSpiResponse> reservedSpis = new ArrayList<IpSecSpiResponse>(); - // Return the same SPI for all SPI allocation since IpSecService only - // tracks the resource ID. - when(mMockNetd.ipSecAllocateSpi( - anyInt(), - anyString(), - eq(InetAddress.getLoopbackAddress().getHostAddress()), - anyInt())) - .thenReturn(DROID_SPI); - // Reserve spis until it fails. - for (int i = 0; i < MAX_NUM_SPIS; i++) { - IpSecSpiResponse newSpi = - mIpSecService.allocateSecurityParameterIndex( - InetAddress.getLoopbackAddress().getHostAddress(), - DROID_SPI + i, - new Binder()); - assertNotNull(newSpi); - if (IpSecManager.Status.OK != newSpi.status) { - break; - } - reservedSpis.add(newSpi); - } - // Assert that the SPI quota has a reasonable limit. - assertTrue(reservedSpis.size() > 0 && reservedSpis.size() < MAX_NUM_SPIS); - - // Try to reserve one more SPI, and should fail. - IpSecSpiResponse extraSpi = - mIpSecService.allocateSecurityParameterIndex( - InetAddress.getLoopbackAddress().getHostAddress(), - DROID_SPI + MAX_NUM_SPIS, - new Binder()); - assertNotNull(extraSpi); - assertEquals(IpSecManager.Status.RESOURCE_UNAVAILABLE, extraSpi.status); - - // Release one reserved spi. - mIpSecService.releaseSecurityParameterIndex(reservedSpis.get(0).resourceId); - reservedSpis.remove(0); - - // Should successfully reserve one more spi. - extraSpi = - mIpSecService.allocateSecurityParameterIndex( - InetAddress.getLoopbackAddress().getHostAddress(), - DROID_SPI + MAX_NUM_SPIS, - new Binder()); - assertNotNull(extraSpi); - assertEquals(IpSecManager.Status.OK, extraSpi.status); - - // Release reserved SPIs. - for (IpSecSpiResponse spiResp : reservedSpis) { - mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId); - } - } - - @Test - public void testUidFdtagger() throws Exception { - SocketTagger actualSocketTagger = SocketTagger.get(); - - try { - FileDescriptor sockFd = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - - // Has to be done after socket creation because BlockGuardOS calls tag on new sockets - SocketTagger mockSocketTagger = mock(SocketTagger.class); - SocketTagger.set(mockSocketTagger); - - mIpSecService.mUidFdTagger.tag(sockFd, Process.LAST_APPLICATION_UID); - verify(mockSocketTagger).tag(eq(sockFd)); - } finally { - SocketTagger.set(actualSocketTagger); - } - } - - /** - * Checks if two file descriptors point to the same file. - * - * <p>According to stat.h documentation, the correct way to check for equivalent or duplicated - * file descriptors is to check their inode and device. These two entries uniquely identify any - * file. - */ - private boolean fileDescriptorsEqual(FileDescriptor fd1, FileDescriptor fd2) { - try { - StructStat fd1Stat = Os.fstat(fd1); - StructStat fd2Stat = Os.fstat(fd2); - - return fd1Stat.st_ino == fd2Stat.st_ino && fd1Stat.st_dev == fd2Stat.st_dev; - } catch (ErrnoException e) { - return false; - } - } - - @Test - public void testOpenUdpEncapSocketTagsSocket() throws Exception { - IpSecService.UidFdTagger mockTagger = mock(IpSecService.UidFdTagger.class); - IpSecService testIpSecService = new IpSecService( - mMockContext, mMockIpSecSrvConfig, mockTagger); - - IpSecUdpEncapResponse udpEncapResp = - testIpSecService.openUdpEncapsulationSocket(0, new Binder()); - assertNotNull(udpEncapResp); - assertEquals(IpSecManager.Status.OK, udpEncapResp.status); - - FileDescriptor sockFd = udpEncapResp.fileDescriptor.getFileDescriptor(); - ArgumentMatcher<FileDescriptor> fdMatcher = - (argFd) -> { - return fileDescriptorsEqual(sockFd, argFd); - }; - verify(mockTagger).tag(argThat(fdMatcher), eq(Os.getuid())); - - testIpSecService.closeUdpEncapsulationSocket(udpEncapResp.resourceId); - udpEncapResp.fileDescriptor.close(); - } - - @Test - public void testOpenUdpEncapsulationSocketCallsSetEncapSocketOwner() throws Exception { - IpSecUdpEncapResponse udpEncapResp = - mIpSecService.openUdpEncapsulationSocket(0, new Binder()); - - FileDescriptor sockFd = udpEncapResp.fileDescriptor.getFileDescriptor(); - ArgumentMatcher<ParcelFileDescriptor> fdMatcher = (arg) -> { - try { - StructStat sockStat = Os.fstat(sockFd); - StructStat argStat = Os.fstat(arg.getFileDescriptor()); - - return sockStat.st_ino == argStat.st_ino - && sockStat.st_dev == argStat.st_dev; - } catch (ErrnoException e) { - return false; - } - }; - - verify(mMockNetd).ipSecSetEncapSocketOwner(argThat(fdMatcher), eq(Os.getuid())); - mIpSecService.closeUdpEncapsulationSocket(udpEncapResp.resourceId); - } - - @Test - public void testReserveNetId() { - final Range<Integer> netIdRange = ConnectivityManager.getIpSecNetIdRange(); - for (int netId = netIdRange.getLower(); netId <= netIdRange.getUpper(); netId++) { - assertEquals(netId, mIpSecService.reserveNetId()); - } - - // Check that resource exhaustion triggers an exception - try { - mIpSecService.reserveNetId(); - fail("Did not throw error for all netIds reserved"); - } catch (IllegalStateException expected) { - } - - // Now release one and try again - int releasedNetId = - netIdRange.getLower() + (netIdRange.getUpper() - netIdRange.getLower()) / 2; - mIpSecService.releaseNetId(releasedNetId); - assertEquals(releasedNetId, mIpSecService.reserveNetId()); - } -} diff --git a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt deleted file mode 100644 index 5ec111954fcc..000000000000 --- a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Don't warn about deprecated types anywhere in this test, because LegacyTypeTracker's very reason -// for existence is to power deprecated APIs. The annotation has to apply to the whole file because -// otherwise warnings will be generated by the imports of deprecated constants like TYPE_xxx. -@file:Suppress("DEPRECATION") - -package com.android.server - -import android.content.Context -import android.content.pm.PackageManager -import android.content.pm.PackageManager.FEATURE_WIFI -import android.content.pm.PackageManager.FEATURE_WIFI_DIRECT -import android.net.ConnectivityManager.TYPE_ETHERNET -import android.net.ConnectivityManager.TYPE_MOBILE -import android.net.ConnectivityManager.TYPE_MOBILE_CBS -import android.net.ConnectivityManager.TYPE_MOBILE_DUN -import android.net.ConnectivityManager.TYPE_MOBILE_EMERGENCY -import android.net.ConnectivityManager.TYPE_MOBILE_FOTA -import android.net.ConnectivityManager.TYPE_MOBILE_HIPRI -import android.net.ConnectivityManager.TYPE_MOBILE_IA -import android.net.ConnectivityManager.TYPE_MOBILE_IMS -import android.net.ConnectivityManager.TYPE_MOBILE_MMS -import android.net.ConnectivityManager.TYPE_MOBILE_SUPL -import android.net.ConnectivityManager.TYPE_VPN -import android.net.ConnectivityManager.TYPE_WIFI -import android.net.ConnectivityManager.TYPE_WIFI_P2P -import android.net.ConnectivityManager.TYPE_WIMAX -import android.net.EthernetManager -import android.net.NetworkInfo.DetailedState.CONNECTED -import android.net.NetworkInfo.DetailedState.DISCONNECTED -import android.telephony.TelephonyManager -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.server.ConnectivityService.LegacyTypeTracker -import com.android.server.connectivity.NetworkAgentInfo -import org.junit.Assert.assertFalse -import org.junit.Assert.assertNull -import org.junit.Assert.assertSame -import org.junit.Assert.assertTrue -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.any -import org.mockito.ArgumentMatchers.anyInt -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.mock -import org.mockito.Mockito.never -import org.mockito.Mockito.reset -import org.mockito.Mockito.verify - -const val UNSUPPORTED_TYPE = TYPE_WIMAX - -@RunWith(AndroidJUnit4::class) -@SmallTest -class LegacyTypeTrackerTest { - private val supportedTypes = arrayOf(TYPE_WIFI, TYPE_WIFI_P2P, TYPE_ETHERNET, TYPE_MOBILE, - TYPE_MOBILE_SUPL, TYPE_MOBILE_MMS, TYPE_MOBILE_SUPL, TYPE_MOBILE_DUN, TYPE_MOBILE_HIPRI, - TYPE_MOBILE_FOTA, TYPE_MOBILE_IMS, TYPE_MOBILE_CBS, TYPE_MOBILE_IA, - TYPE_MOBILE_EMERGENCY, TYPE_VPN) - - private val mMockService = mock(ConnectivityService::class.java).apply { - doReturn(false).`when`(this).isDefaultNetwork(any()) - } - private val mPm = mock(PackageManager::class.java) - private val mContext = mock(Context::class.java).apply { - doReturn(true).`when`(mPm).hasSystemFeature(FEATURE_WIFI) - doReturn(true).`when`(mPm).hasSystemFeature(FEATURE_WIFI_DIRECT) - doReturn(mPm).`when`(this).packageManager - doReturn(mock(EthernetManager::class.java)).`when`(this).getSystemService( - Context.ETHERNET_SERVICE) - } - private val mTm = mock(TelephonyManager::class.java).apply { - doReturn(true).`when`(this).isDataCapable - } - - private fun makeTracker() = LegacyTypeTracker(mMockService).apply { - loadSupportedTypes(mContext, mTm) - } - - @Test - fun testSupportedTypes() { - val tracker = makeTracker() - supportedTypes.forEach { - assertTrue(tracker.isTypeSupported(it)) - } - assertFalse(tracker.isTypeSupported(UNSUPPORTED_TYPE)) - } - - @Test - fun testSupportedTypes_NoEthernet() { - doReturn(null).`when`(mContext).getSystemService(Context.ETHERNET_SERVICE) - assertFalse(makeTracker().isTypeSupported(TYPE_ETHERNET)) - } - - @Test - fun testSupportedTypes_NoTelephony() { - doReturn(false).`when`(mTm).isDataCapable - val tracker = makeTracker() - val nonMobileTypes = arrayOf(TYPE_WIFI, TYPE_WIFI_P2P, TYPE_ETHERNET, TYPE_VPN) - nonMobileTypes.forEach { - assertTrue(tracker.isTypeSupported(it)) - } - supportedTypes.toSet().minus(nonMobileTypes).forEach { - assertFalse(tracker.isTypeSupported(it)) - } - } - - @Test - fun testSupportedTypes_NoWifiDirect() { - doReturn(false).`when`(mPm).hasSystemFeature(FEATURE_WIFI_DIRECT) - val tracker = makeTracker() - assertFalse(tracker.isTypeSupported(TYPE_WIFI_P2P)) - supportedTypes.toSet().minus(TYPE_WIFI_P2P).forEach { - assertTrue(tracker.isTypeSupported(it)) - } - } - - @Test - fun testSupl() { - val tracker = makeTracker() - val mobileNai = mock(NetworkAgentInfo::class.java) - tracker.add(TYPE_MOBILE, mobileNai) - verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE) - reset(mMockService) - tracker.add(TYPE_MOBILE_SUPL, mobileNai) - verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE_SUPL) - reset(mMockService) - tracker.remove(TYPE_MOBILE_SUPL, mobileNai, false /* wasDefault */) - verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE_SUPL) - reset(mMockService) - tracker.add(TYPE_MOBILE_SUPL, mobileNai) - verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE_SUPL) - reset(mMockService) - tracker.remove(mobileNai, false) - verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE_SUPL) - verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE) - } - - @Test - fun testAddNetwork() { - val tracker = makeTracker() - val mobileNai = mock(NetworkAgentInfo::class.java) - val wifiNai = mock(NetworkAgentInfo::class.java) - tracker.add(TYPE_MOBILE, mobileNai) - tracker.add(TYPE_WIFI, wifiNai) - assertSame(tracker.getNetworkForType(TYPE_MOBILE), mobileNai) - assertSame(tracker.getNetworkForType(TYPE_WIFI), wifiNai) - // Make sure adding a second NAI does not change the results. - val secondMobileNai = mock(NetworkAgentInfo::class.java) - tracker.add(TYPE_MOBILE, secondMobileNai) - assertSame(tracker.getNetworkForType(TYPE_MOBILE), mobileNai) - assertSame(tracker.getNetworkForType(TYPE_WIFI), wifiNai) - // Make sure removing a network that wasn't added for this type is a no-op. - tracker.remove(TYPE_MOBILE, wifiNai, false /* wasDefault */) - assertSame(tracker.getNetworkForType(TYPE_MOBILE), mobileNai) - assertSame(tracker.getNetworkForType(TYPE_WIFI), wifiNai) - // Remove the top network for mobile and make sure the second one becomes the network - // of record for this type. - tracker.remove(TYPE_MOBILE, mobileNai, false /* wasDefault */) - assertSame(tracker.getNetworkForType(TYPE_MOBILE), secondMobileNai) - assertSame(tracker.getNetworkForType(TYPE_WIFI), wifiNai) - // Make sure adding a network for an unsupported type does not register it. - tracker.add(UNSUPPORTED_TYPE, mobileNai) - assertNull(tracker.getNetworkForType(UNSUPPORTED_TYPE)) - } - - @Test - fun testBroadcastOnDisconnect() { - val tracker = makeTracker() - val mobileNai1 = mock(NetworkAgentInfo::class.java) - val mobileNai2 = mock(NetworkAgentInfo::class.java) - doReturn(false).`when`(mMockService).isDefaultNetwork(mobileNai1) - tracker.add(TYPE_MOBILE, mobileNai1) - verify(mMockService).sendLegacyNetworkBroadcast(mobileNai1, CONNECTED, TYPE_MOBILE) - reset(mMockService) - doReturn(false).`when`(mMockService).isDefaultNetwork(mobileNai2) - tracker.add(TYPE_MOBILE, mobileNai2) - verify(mMockService, never()).sendLegacyNetworkBroadcast(any(), any(), anyInt()) - tracker.remove(TYPE_MOBILE, mobileNai1, false /* wasDefault */) - verify(mMockService).sendLegacyNetworkBroadcast(mobileNai1, DISCONNECTED, TYPE_MOBILE) - verify(mMockService).sendLegacyNetworkBroadcast(mobileNai2, CONNECTED, TYPE_MOBILE) - } -} diff --git a/tests/net/java/com/android/server/NetIdManagerTest.kt b/tests/net/java/com/android/server/NetIdManagerTest.kt deleted file mode 100644 index 6f5e740d344c..000000000000 --- a/tests/net/java/com/android/server/NetIdManagerTest.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server - -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.server.NetIdManager.MIN_NET_ID -import com.android.testutils.assertThrows -import com.android.testutils.ExceptionUtils.ThrowingRunnable -import org.junit.Test -import org.junit.runner.RunWith -import kotlin.test.assertEquals - -@RunWith(AndroidJUnit4::class) -@SmallTest -class NetIdManagerTest { - @Test - fun testReserveReleaseNetId() { - val manager = NetIdManager(MIN_NET_ID + 4) - assertEquals(MIN_NET_ID, manager.reserveNetId()) - assertEquals(MIN_NET_ID + 1, manager.reserveNetId()) - assertEquals(MIN_NET_ID + 2, manager.reserveNetId()) - assertEquals(MIN_NET_ID + 3, manager.reserveNetId()) - - manager.releaseNetId(MIN_NET_ID + 1) - manager.releaseNetId(MIN_NET_ID + 3) - // IDs only loop once there is no higher ID available - assertEquals(MIN_NET_ID + 4, manager.reserveNetId()) - assertEquals(MIN_NET_ID + 1, manager.reserveNetId()) - assertEquals(MIN_NET_ID + 3, manager.reserveNetId()) - assertThrows(IllegalStateException::class.java, ThrowingRunnable { manager.reserveNetId() }) - manager.releaseNetId(MIN_NET_ID + 5) - // Still no ID available: MIN_NET_ID + 5 was not reserved - assertThrows(IllegalStateException::class.java, ThrowingRunnable { manager.reserveNetId() }) - manager.releaseNetId(MIN_NET_ID + 2) - // Throwing an exception still leaves the manager in a working state - assertEquals(MIN_NET_ID + 2, manager.reserveNetId()) - } -}
\ No newline at end of file diff --git a/tests/net/java/com/android/server/NetworkManagementServiceTest.java b/tests/net/java/com/android/server/NetworkManagementServiceTest.java deleted file mode 100644 index 13516d75a50d..000000000000 --- a/tests/net/java/com/android/server/NetworkManagementServiceTest.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server; - -import static android.util.DebugUtils.valueToString; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -import android.annotation.NonNull; -import android.content.Context; -import android.net.INetd; -import android.net.INetdUnsolicitedEventListener; -import android.net.LinkAddress; -import android.net.NetworkPolicyManager; -import android.os.BatteryStats; -import android.os.Binder; -import android.os.IBinder; -import android.os.Process; -import android.os.RemoteException; -import android.test.suitebuilder.annotation.SmallTest; -import android.util.ArrayMap; - -import androidx.test.runner.AndroidJUnit4; - -import com.android.internal.app.IBatteryStats; -import com.android.server.NetworkManagementService.Dependencies; -import com.android.server.net.BaseNetworkObserver; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.function.BiFunction; - -/** - * Tests for {@link NetworkManagementService}. - */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetworkManagementServiceTest { - private NetworkManagementService mNMService; - @Mock private Context mContext; - @Mock private IBatteryStats.Stub mBatteryStatsService; - @Mock private INetd.Stub mNetdService; - - private static final int TEST_UID = 111; - - @NonNull - @Captor - private ArgumentCaptor<INetdUnsolicitedEventListener> mUnsolListenerCaptor; - - private final MockDependencies mDeps = new MockDependencies(); - - private final class MockDependencies extends Dependencies { - @Override - public IBinder getService(String name) { - switch (name) { - case BatteryStats.SERVICE_NAME: - return mBatteryStatsService; - default: - throw new UnsupportedOperationException("Unknown service " + name); - } - } - - @Override - public void registerLocalService(NetworkManagementInternal nmi) { - } - - @Override - public INetd getNetd() { - return mNetdService; - } - - @Override - public int getCallingUid() { - return Process.SYSTEM_UID; - } - } - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - doNothing().when(mNetdService) - .registerUnsolicitedEventListener(mUnsolListenerCaptor.capture()); - // Start the service and wait until it connects to our socket. - mNMService = NetworkManagementService.create(mContext, mDeps); - } - - @After - public void tearDown() throws Exception { - mNMService.shutdown(); - } - - private static <T> T expectSoon(T mock) { - return verify(mock, timeout(200)); - } - - /** - * Tests that network observers work properly. - */ - @Test - public void testNetworkObservers() throws Exception { - BaseNetworkObserver observer = mock(BaseNetworkObserver.class); - doReturn(new Binder()).when(observer).asBinder(); // Used by registerObserver. - mNMService.registerObserver(observer); - - // Forget everything that happened to the mock so far, so we can explicitly verify - // everything that happens and does not happen to it from now on. - - INetdUnsolicitedEventListener unsolListener = mUnsolListenerCaptor.getValue(); - reset(observer); - // Now call unsolListener methods and ensure that the observer methods are - // called. After every method we expect a callback soon after; to ensure that - // invalid messages don't cause any callbacks, we call verifyNoMoreInteractions at the end. - - /** - * Interface changes. - */ - unsolListener.onInterfaceAdded("rmnet12"); - expectSoon(observer).interfaceAdded("rmnet12"); - - unsolListener.onInterfaceRemoved("eth1"); - expectSoon(observer).interfaceRemoved("eth1"); - - unsolListener.onInterfaceChanged("clat4", true); - expectSoon(observer).interfaceStatusChanged("clat4", true); - - unsolListener.onInterfaceLinkStateChanged("rmnet0", false); - expectSoon(observer).interfaceLinkStateChanged("rmnet0", false); - - /** - * Bandwidth control events. - */ - unsolListener.onQuotaLimitReached("data", "rmnet_usb0"); - expectSoon(observer).limitReached("data", "rmnet_usb0"); - - /** - * Interface class activity. - */ - unsolListener.onInterfaceClassActivityChanged(true, 1, 1234, TEST_UID); - expectSoon(observer).interfaceClassDataActivityChanged(1, true, 1234, TEST_UID); - - unsolListener.onInterfaceClassActivityChanged(false, 9, 5678, TEST_UID); - expectSoon(observer).interfaceClassDataActivityChanged(9, false, 5678, TEST_UID); - - unsolListener.onInterfaceClassActivityChanged(false, 9, 4321, TEST_UID); - expectSoon(observer).interfaceClassDataActivityChanged(9, false, 4321, TEST_UID); - - /** - * IP address changes. - */ - unsolListener.onInterfaceAddressUpdated("fe80::1/64", "wlan0", 128, 253); - expectSoon(observer).addressUpdated("wlan0", new LinkAddress("fe80::1/64", 128, 253)); - - unsolListener.onInterfaceAddressRemoved("fe80::1/64", "wlan0", 128, 253); - expectSoon(observer).addressRemoved("wlan0", new LinkAddress("fe80::1/64", 128, 253)); - - unsolListener.onInterfaceAddressRemoved("2001:db8::1/64", "wlan0", 1, 0); - expectSoon(observer).addressRemoved("wlan0", new LinkAddress("2001:db8::1/64", 1, 0)); - - /** - * DNS information broadcasts. - */ - unsolListener.onInterfaceDnsServerInfo("rmnet_usb0", 3600, new String[]{"2001:db8::1"}); - expectSoon(observer).interfaceDnsServerInfo("rmnet_usb0", 3600, - new String[]{"2001:db8::1"}); - - unsolListener.onInterfaceDnsServerInfo("wlan0", 14400, - new String[]{"2001:db8::1", "2001:db8::2"}); - expectSoon(observer).interfaceDnsServerInfo("wlan0", 14400, - new String[]{"2001:db8::1", "2001:db8::2"}); - - // We don't check for negative lifetimes, only for parse errors. - unsolListener.onInterfaceDnsServerInfo("wlan0", -3600, new String[]{"::1"}); - expectSoon(observer).interfaceDnsServerInfo("wlan0", -3600, - new String[]{"::1"}); - - // No syntax checking on the addresses. - unsolListener.onInterfaceDnsServerInfo("wlan0", 600, - new String[]{"", "::", "", "foo", "::1"}); - expectSoon(observer).interfaceDnsServerInfo("wlan0", 600, - new String[]{"", "::", "", "foo", "::1"}); - - // Make sure nothing else was called. - verifyNoMoreInteractions(observer); - } - - @Test - public void testFirewallEnabled() { - mNMService.setFirewallEnabled(true); - assertTrue(mNMService.isFirewallEnabled()); - - mNMService.setFirewallEnabled(false); - assertFalse(mNMService.isFirewallEnabled()); - } - - @Test - public void testNetworkRestrictedDefault() { - assertFalse(mNMService.isNetworkRestricted(TEST_UID)); - } - - @Test - public void testMeteredNetworkRestrictions() throws RemoteException { - // Make sure the mocked netd method returns true. - doReturn(true).when(mNetdService).bandwidthEnableDataSaver(anyBoolean()); - - // Restrict usage of mobile data in background - mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, true); - assertTrue("Should be true since mobile data usage is restricted", - mNMService.isNetworkRestricted(TEST_UID)); - - mNMService.setDataSaverModeEnabled(true); - verify(mNetdService).bandwidthEnableDataSaver(true); - - mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, false); - assertTrue("Should be true since data saver is on and the uid is not allowlisted", - mNMService.isNetworkRestricted(TEST_UID)); - - mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, true); - assertFalse("Should be false since data saver is on and the uid is allowlisted", - mNMService.isNetworkRestricted(TEST_UID)); - - // remove uid from allowlist and turn datasaver off again - mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, false); - mNMService.setDataSaverModeEnabled(false); - verify(mNetdService).bandwidthEnableDataSaver(false); - assertFalse("Network should not be restricted when data saver is off", - mNMService.isNetworkRestricted(TEST_UID)); - } - - @Test - public void testFirewallChains() { - final ArrayMap<Integer, ArrayMap<Integer, Boolean>> expected = new ArrayMap<>(); - // Dozable chain - final ArrayMap<Integer, Boolean> isRestrictedForDozable = new ArrayMap<>(); - isRestrictedForDozable.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, true); - isRestrictedForDozable.put(INetd.FIREWALL_RULE_ALLOW, false); - isRestrictedForDozable.put(INetd.FIREWALL_RULE_DENY, true); - expected.put(INetd.FIREWALL_CHAIN_DOZABLE, isRestrictedForDozable); - // Powersaver chain - final ArrayMap<Integer, Boolean> isRestrictedForPowerSave = new ArrayMap<>(); - isRestrictedForPowerSave.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, true); - isRestrictedForPowerSave.put(INetd.FIREWALL_RULE_ALLOW, false); - isRestrictedForPowerSave.put(INetd.FIREWALL_RULE_DENY, true); - expected.put(INetd.FIREWALL_CHAIN_POWERSAVE, isRestrictedForPowerSave); - // Standby chain - final ArrayMap<Integer, Boolean> isRestrictedForStandby = new ArrayMap<>(); - isRestrictedForStandby.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, false); - isRestrictedForStandby.put(INetd.FIREWALL_RULE_ALLOW, false); - isRestrictedForStandby.put(INetd.FIREWALL_RULE_DENY, true); - expected.put(INetd.FIREWALL_CHAIN_STANDBY, isRestrictedForStandby); - // Restricted mode chain - final ArrayMap<Integer, Boolean> isRestrictedForRestrictedMode = new ArrayMap<>(); - isRestrictedForRestrictedMode.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, true); - isRestrictedForRestrictedMode.put(INetd.FIREWALL_RULE_ALLOW, false); - isRestrictedForRestrictedMode.put(INetd.FIREWALL_RULE_DENY, true); - expected.put(INetd.FIREWALL_CHAIN_RESTRICTED, isRestrictedForRestrictedMode); - - final int[] chains = { - INetd.FIREWALL_CHAIN_STANDBY, - INetd.FIREWALL_CHAIN_POWERSAVE, - INetd.FIREWALL_CHAIN_DOZABLE, - INetd.FIREWALL_CHAIN_RESTRICTED - }; - final int[] states = { - INetd.FIREWALL_RULE_ALLOW, - INetd.FIREWALL_RULE_DENY, - NetworkPolicyManager.FIREWALL_RULE_DEFAULT - }; - BiFunction<Integer, Integer, String> errorMsg = (chain, state) -> { - return String.format("Unexpected value for chain: %s and state: %s", - valueToString(INetd.class, "FIREWALL_CHAIN_", chain), - valueToString(INetd.class, "FIREWALL_RULE_", state)); - }; - for (int chain : chains) { - final ArrayMap<Integer, Boolean> expectedValues = expected.get(chain); - mNMService.setFirewallChainEnabled(chain, true); - for (int state : states) { - mNMService.setFirewallUidRule(chain, TEST_UID, state); - assertEquals(errorMsg.apply(chain, state), - expectedValues.get(state), mNMService.isNetworkRestricted(TEST_UID)); - } - mNMService.setFirewallChainEnabled(chain, false); - } - } -} diff --git a/tests/net/java/com/android/server/NsdServiceTest.java b/tests/net/java/com/android/server/NsdServiceTest.java deleted file mode 100644 index a90fa6882c25..000000000000 --- a/tests/net/java/com/android/server/NsdServiceTest.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.ContentResolver; -import android.content.Context; -import android.net.nsd.NsdManager; -import android.net.nsd.NsdServiceInfo; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.server.NsdService.DaemonConnection; -import com.android.server.NsdService.DaemonConnectionSupplier; -import com.android.server.NsdService.NativeCallbackReceiver; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -// TODOs: -// - test client can send requests and receive replies -// - test NSD_ON ENABLE/DISABLED listening -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NsdServiceTest { - - static final int PROTOCOL = NsdManager.PROTOCOL_DNS_SD; - - long mTimeoutMs = 100; // non-final so that tests can adjust the value. - - @Mock Context mContext; - @Mock ContentResolver mResolver; - @Mock NsdService.NsdSettings mSettings; - @Mock DaemonConnection mDaemon; - NativeCallbackReceiver mDaemonCallback; - HandlerThread mThread; - TestHandler mHandler; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mThread = new HandlerThread("mock-service-handler"); - mThread.start(); - mHandler = new TestHandler(mThread.getLooper()); - when(mContext.getContentResolver()).thenReturn(mResolver); - } - - @After - public void tearDown() throws Exception { - if (mThread != null) { - mThread.quit(); - mThread = null; - } - } - - @Test - public void testClientsCanConnectAndDisconnect() { - when(mSettings.isEnabled()).thenReturn(true); - - NsdService service = makeService(); - - NsdManager client1 = connectClient(service); - verify(mDaemon, timeout(100).times(1)).start(); - - NsdManager client2 = connectClient(service); - - client1.disconnect(); - client2.disconnect(); - - verify(mDaemon, timeout(mTimeoutMs).times(1)).stop(); - - client1.disconnect(); - client2.disconnect(); - } - - @Test - public void testClientRequestsAreGCedAtDisconnection() { - when(mSettings.isEnabled()).thenReturn(true); - when(mDaemon.execute(any())).thenReturn(true); - - NsdService service = makeService(); - NsdManager client = connectClient(service); - - verify(mDaemon, timeout(100).times(1)).start(); - - NsdServiceInfo request = new NsdServiceInfo("a_name", "a_type"); - request.setPort(2201); - - // Client registration request - NsdManager.RegistrationListener listener1 = mock(NsdManager.RegistrationListener.class); - client.registerService(request, PROTOCOL, listener1); - verifyDaemonCommand("register 2 a_name a_type 2201"); - - // Client discovery request - NsdManager.DiscoveryListener listener2 = mock(NsdManager.DiscoveryListener.class); - client.discoverServices("a_type", PROTOCOL, listener2); - verifyDaemonCommand("discover 3 a_type"); - - // Client resolve request - NsdManager.ResolveListener listener3 = mock(NsdManager.ResolveListener.class); - client.resolveService(request, listener3); - verifyDaemonCommand("resolve 4 a_name a_type local."); - - // Client disconnects - client.disconnect(); - verify(mDaemon, timeout(mTimeoutMs).times(1)).stop(); - - // checks that request are cleaned - verifyDaemonCommands("stop-register 2", "stop-discover 3", "stop-resolve 4"); - - client.disconnect(); - } - - NsdService makeService() { - DaemonConnectionSupplier supplier = (callback) -> { - mDaemonCallback = callback; - return mDaemon; - }; - NsdService service = new NsdService(mContext, mSettings, mHandler, supplier); - verify(mDaemon, never()).execute(any(String.class)); - return service; - } - - NsdManager connectClient(NsdService service) { - return new NsdManager(mContext, service); - } - - void verifyDaemonCommands(String... wants) { - verifyDaemonCommand(String.join(" ", wants), wants.length); - } - - void verifyDaemonCommand(String want) { - verifyDaemonCommand(want, 1); - } - - void verifyDaemonCommand(String want, int n) { - ArgumentCaptor<Object> argumentsCaptor = ArgumentCaptor.forClass(Object.class); - verify(mDaemon, timeout(mTimeoutMs).times(n)).execute(argumentsCaptor.capture()); - String got = ""; - for (Object o : argumentsCaptor.getAllValues()) { - got += o + " "; - } - assertEquals(want, got.trim()); - // rearm deamon for next command verification - reset(mDaemon); - when(mDaemon.execute(any())).thenReturn(true); - } - - public static class TestHandler extends Handler { - public Message lastMessage; - - TestHandler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - lastMessage = obtainMessage(); - lastMessage.copyFrom(msg); - } - } -} diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java deleted file mode 100644 index 0ffeec98cf90..000000000000 --- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (C) 2018, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.connectivity; - -import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE; -import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE; -import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF; -import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; -import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_SPECIFIER; -import static android.net.NetworkCapabilities.MAX_TRANSPORT; -import static android.net.NetworkCapabilities.MIN_TRANSPORT; -import static android.net.NetworkCapabilities.TRANSPORT_VPN; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI; -import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; -import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; - -import static com.android.testutils.MiscAsserts.assertContainsExactly; -import static com.android.testutils.MiscAsserts.assertContainsStringsExactly; -import static com.android.testutils.MiscAsserts.assertFieldCountEquals; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.annotation.NonNull; -import android.content.Context; -import android.net.ConnectivitySettingsManager; -import android.net.IDnsResolver; -import android.net.IpPrefix; -import android.net.LinkAddress; -import android.net.LinkProperties; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.ResolverOptionsParcel; -import android.net.ResolverParamsParcel; -import android.net.RouteInfo; -import android.net.shared.PrivateDnsConfig; -import android.provider.Settings; -import android.test.mock.MockContentResolver; -import android.util.SparseArray; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.internal.util.MessageUtils; -import com.android.internal.util.test.FakeSettingsProvider; - -import libcore.net.InetAddressUtils; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.net.InetAddress; -import java.util.Arrays; - -/** - * Tests for {@link DnsManager}. - * - * Build, install and run with: - * runtest frameworks-net -c com.android.server.connectivity.DnsManagerTest - */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class DnsManagerTest { - static final String TEST_IFACENAME = "test_wlan0"; - static final int TEST_NETID = 100; - static final int TEST_NETID_ALTERNATE = 101; - static final int TEST_NETID_UNTRACKED = 102; - static final int TEST_DEFAULT_SAMPLE_VALIDITY_SECONDS = 1800; - static final int TEST_DEFAULT_SUCCESS_THRESHOLD_PERCENT = 25; - static final int TEST_DEFAULT_MIN_SAMPLES = 8; - static final int TEST_DEFAULT_MAX_SAMPLES = 64; - static final int[] TEST_TRANSPORT_TYPES = {TRANSPORT_WIFI, TRANSPORT_VPN}; - - DnsManager mDnsManager; - MockContentResolver mContentResolver; - - @Mock Context mCtx; - @Mock IDnsResolver mMockDnsResolver; - - private void assertResolverOptionsEquals( - @NonNull ResolverOptionsParcel actual, - @NonNull ResolverOptionsParcel expected) { - assertEquals(actual.hosts, expected.hosts); - assertEquals(actual.tcMode, expected.tcMode); - assertEquals(actual.enforceDnsUid, expected.enforceDnsUid); - assertFieldCountEquals(3, ResolverOptionsParcel.class); - } - - private void assertResolverParamsEquals(@NonNull ResolverParamsParcel actual, - @NonNull ResolverParamsParcel expected) { - assertEquals(actual.netId, expected.netId); - assertEquals(actual.sampleValiditySeconds, expected.sampleValiditySeconds); - assertEquals(actual.successThreshold, expected.successThreshold); - assertEquals(actual.minSamples, expected.minSamples); - assertEquals(actual.maxSamples, expected.maxSamples); - assertEquals(actual.baseTimeoutMsec, expected.baseTimeoutMsec); - assertEquals(actual.retryCount, expected.retryCount); - assertContainsStringsExactly(actual.servers, expected.servers); - assertContainsStringsExactly(actual.domains, expected.domains); - assertEquals(actual.tlsName, expected.tlsName); - assertContainsStringsExactly(actual.tlsServers, expected.tlsServers); - assertContainsStringsExactly(actual.tlsFingerprints, expected.tlsFingerprints); - assertEquals(actual.caCertificate, expected.caCertificate); - assertEquals(actual.tlsConnectTimeoutMs, expected.tlsConnectTimeoutMs); - assertResolverOptionsEquals(actual.resolverOptions, expected.resolverOptions); - assertContainsExactly(actual.transportTypes, expected.transportTypes); - assertFieldCountEquals(16, ResolverParamsParcel.class); - } - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mContentResolver = new MockContentResolver(); - mContentResolver.addProvider(Settings.AUTHORITY, - new FakeSettingsProvider()); - when(mCtx.getContentResolver()).thenReturn(mContentResolver); - mDnsManager = new DnsManager(mCtx, mMockDnsResolver); - - // Clear the private DNS settings - Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, ""); - Settings.Global.putString(mContentResolver, PRIVATE_DNS_MODE, ""); - Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, ""); - } - - @Test - public void testTrackedValidationUpdates() throws Exception { - mDnsManager.updatePrivateDns(new Network(TEST_NETID), - mDnsManager.getPrivateDnsConfig()); - mDnsManager.updatePrivateDns(new Network(TEST_NETID_ALTERNATE), - mDnsManager.getPrivateDnsConfig()); - LinkProperties lp = new LinkProperties(); - lp.setInterfaceName(TEST_IFACENAME); - lp.addDnsServer(InetAddress.getByName("3.3.3.3")); - lp.addDnsServer(InetAddress.getByName("4.4.4.4")); - - // Send a validation event that is tracked on the alternate netId - mDnsManager.updateTransportsForNetwork(TEST_NETID, TEST_TRANSPORT_TYPES); - mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp); - mDnsManager.flushVmDnsCache(); - mDnsManager.updateTransportsForNetwork(TEST_NETID_ALTERNATE, TEST_TRANSPORT_TYPES); - mDnsManager.noteDnsServersForNetwork(TEST_NETID_ALTERNATE, lp); - mDnsManager.flushVmDnsCache(); - mDnsManager.updatePrivateDnsValidation( - new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_ALTERNATE, - InetAddress.parseNumericAddress("4.4.4.4"), "", - VALIDATION_RESULT_SUCCESS)); - LinkProperties fixedLp = new LinkProperties(lp); - mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp); - assertFalse(fixedLp.isPrivateDnsActive()); - assertNull(fixedLp.getPrivateDnsServerName()); - fixedLp = new LinkProperties(lp); - mDnsManager.updatePrivateDnsStatus(TEST_NETID_ALTERNATE, fixedLp); - assertTrue(fixedLp.isPrivateDnsActive()); - assertNull(fixedLp.getPrivateDnsServerName()); - assertEquals(Arrays.asList(InetAddress.getByName("4.4.4.4")), - fixedLp.getValidatedPrivateDnsServers()); - - // Set up addresses for strict mode and switch to it. - lp.addLinkAddress(new LinkAddress("192.0.2.4/24")); - lp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), - TEST_IFACENAME)); - lp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); - lp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), - TEST_IFACENAME)); - - ConnectivitySettingsManager.setPrivateDnsMode(mCtx, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); - ConnectivitySettingsManager.setPrivateDnsHostname(mCtx, "strictmode.com"); - mDnsManager.updatePrivateDns(new Network(TEST_NETID), - new PrivateDnsConfig("strictmode.com", new InetAddress[] { - InetAddress.parseNumericAddress("6.6.6.6"), - InetAddress.parseNumericAddress("2001:db8:66:66::1") - })); - mDnsManager.updateTransportsForNetwork(TEST_NETID, TEST_TRANSPORT_TYPES); - mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp); - mDnsManager.flushVmDnsCache(); - fixedLp = new LinkProperties(lp); - mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp); - assertTrue(fixedLp.isPrivateDnsActive()); - assertEquals("strictmode.com", fixedLp.getPrivateDnsServerName()); - // No validation events yet. - assertEquals(Arrays.asList(new InetAddress[0]), fixedLp.getValidatedPrivateDnsServers()); - // Validate one. - mDnsManager.updatePrivateDnsValidation( - new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("6.6.6.6"), "strictmode.com", - VALIDATION_RESULT_SUCCESS)); - fixedLp = new LinkProperties(lp); - mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp); - assertEquals(Arrays.asList(InetAddress.parseNumericAddress("6.6.6.6")), - fixedLp.getValidatedPrivateDnsServers()); - // Validate the 2nd one. - mDnsManager.updatePrivateDnsValidation( - new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("2001:db8:66:66::1"), "strictmode.com", - VALIDATION_RESULT_SUCCESS)); - fixedLp = new LinkProperties(lp); - mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp); - assertEquals(Arrays.asList( - InetAddress.parseNumericAddress("2001:db8:66:66::1"), - InetAddress.parseNumericAddress("6.6.6.6")), - fixedLp.getValidatedPrivateDnsServers()); - } - - @Test - public void testIgnoreUntrackedValidationUpdates() throws Exception { - // The PrivateDnsConfig map is empty, so no validation events will - // be tracked. - LinkProperties lp = new LinkProperties(); - lp.addDnsServer(InetAddress.getByName("3.3.3.3")); - mDnsManager.updateTransportsForNetwork(TEST_NETID, TEST_TRANSPORT_TYPES); - mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp); - mDnsManager.flushVmDnsCache(); - mDnsManager.updatePrivateDnsValidation( - new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("3.3.3.3"), "", - VALIDATION_RESULT_SUCCESS)); - mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); - assertFalse(lp.isPrivateDnsActive()); - assertNull(lp.getPrivateDnsServerName()); - - // Validation event has untracked netId - mDnsManager.updatePrivateDns(new Network(TEST_NETID), - mDnsManager.getPrivateDnsConfig()); - mDnsManager.updateTransportsForNetwork(TEST_NETID, TEST_TRANSPORT_TYPES); - mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp); - mDnsManager.flushVmDnsCache(); - mDnsManager.updatePrivateDnsValidation( - new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_UNTRACKED, - InetAddress.parseNumericAddress("3.3.3.3"), "", - VALIDATION_RESULT_SUCCESS)); - mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); - assertFalse(lp.isPrivateDnsActive()); - assertNull(lp.getPrivateDnsServerName()); - - // Validation event has untracked ipAddress - mDnsManager.updatePrivateDnsValidation( - new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("4.4.4.4"), "", - VALIDATION_RESULT_SUCCESS)); - mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); - assertFalse(lp.isPrivateDnsActive()); - assertNull(lp.getPrivateDnsServerName()); - - // Validation event has untracked hostname - mDnsManager.updatePrivateDnsValidation( - new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("3.3.3.3"), "hostname", - VALIDATION_RESULT_SUCCESS)); - mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); - assertFalse(lp.isPrivateDnsActive()); - assertNull(lp.getPrivateDnsServerName()); - - // Validation event failed - mDnsManager.updatePrivateDnsValidation( - new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("3.3.3.3"), "", - VALIDATION_RESULT_FAILURE)); - mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); - assertFalse(lp.isPrivateDnsActive()); - assertNull(lp.getPrivateDnsServerName()); - - // Network removed - mDnsManager.removeNetwork(new Network(TEST_NETID)); - mDnsManager.updatePrivateDnsValidation( - new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("3.3.3.3"), "", VALIDATION_RESULT_SUCCESS)); - mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); - assertFalse(lp.isPrivateDnsActive()); - assertNull(lp.getPrivateDnsServerName()); - - // Turn private DNS mode off - ConnectivitySettingsManager.setPrivateDnsMode(mCtx, PRIVATE_DNS_MODE_OFF); - mDnsManager.updatePrivateDns(new Network(TEST_NETID), - mDnsManager.getPrivateDnsConfig()); - mDnsManager.updateTransportsForNetwork(TEST_NETID, TEST_TRANSPORT_TYPES); - mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp); - mDnsManager.flushVmDnsCache(); - mDnsManager.updatePrivateDnsValidation( - new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, - InetAddress.parseNumericAddress("3.3.3.3"), "", - VALIDATION_RESULT_SUCCESS)); - mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); - assertFalse(lp.isPrivateDnsActive()); - assertNull(lp.getPrivateDnsServerName()); - } - - @Test - public void testOverrideDefaultMode() throws Exception { - // Hard-coded default is opportunistic mode. - final PrivateDnsConfig cfgAuto = DnsManager.getPrivateDnsConfig(mCtx); - assertTrue(cfgAuto.useTls); - assertEquals("", cfgAuto.hostname); - assertEquals(new InetAddress[0], cfgAuto.ips); - - // Pretend a gservices push sets the default to "off". - ConnectivitySettingsManager.setPrivateDnsDefaultMode(mCtx, PRIVATE_DNS_MODE_OFF); - final PrivateDnsConfig cfgOff = DnsManager.getPrivateDnsConfig(mCtx); - assertFalse(cfgOff.useTls); - assertEquals("", cfgOff.hostname); - assertEquals(new InetAddress[0], cfgOff.ips); - - // Strict mode still works. - ConnectivitySettingsManager.setPrivateDnsMode(mCtx, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); - ConnectivitySettingsManager.setPrivateDnsHostname(mCtx, "strictmode.com"); - final PrivateDnsConfig cfgStrict = DnsManager.getPrivateDnsConfig(mCtx); - assertTrue(cfgStrict.useTls); - assertEquals("strictmode.com", cfgStrict.hostname); - assertEquals(new InetAddress[0], cfgStrict.ips); - } - - @Test - public void testSendDnsConfiguration() throws Exception { - reset(mMockDnsResolver); - mDnsManager.updatePrivateDns(new Network(TEST_NETID), - mDnsManager.getPrivateDnsConfig()); - final LinkProperties lp = new LinkProperties(); - lp.setInterfaceName(TEST_IFACENAME); - lp.addDnsServer(InetAddress.getByName("3.3.3.3")); - lp.addDnsServer(InetAddress.getByName("4.4.4.4")); - mDnsManager.updateTransportsForNetwork(TEST_NETID, TEST_TRANSPORT_TYPES); - mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp); - mDnsManager.flushVmDnsCache(); - - final ArgumentCaptor<ResolverParamsParcel> resolverParamsParcelCaptor = - ArgumentCaptor.forClass(ResolverParamsParcel.class); - verify(mMockDnsResolver, times(1)).setResolverConfiguration( - resolverParamsParcelCaptor.capture()); - final ResolverParamsParcel actualParams = resolverParamsParcelCaptor.getValue(); - final ResolverParamsParcel expectedParams = new ResolverParamsParcel(); - expectedParams.netId = TEST_NETID; - expectedParams.sampleValiditySeconds = TEST_DEFAULT_SAMPLE_VALIDITY_SECONDS; - expectedParams.successThreshold = TEST_DEFAULT_SUCCESS_THRESHOLD_PERCENT; - expectedParams.minSamples = TEST_DEFAULT_MIN_SAMPLES; - expectedParams.maxSamples = TEST_DEFAULT_MAX_SAMPLES; - expectedParams.servers = new String[]{"3.3.3.3", "4.4.4.4"}; - expectedParams.domains = new String[]{}; - expectedParams.tlsName = ""; - expectedParams.tlsServers = new String[]{"3.3.3.3", "4.4.4.4"}; - expectedParams.transportTypes = TEST_TRANSPORT_TYPES; - expectedParams.resolverOptions = new ResolverOptionsParcel(); - assertResolverParamsEquals(actualParams, expectedParams); - } - - @Test - public void testTransportTypesEqual() throws Exception { - SparseArray<String> ncTransTypes = MessageUtils.findMessageNames( - new Class[] { NetworkCapabilities.class }, new String[]{ "TRANSPORT_" }); - SparseArray<String> dnsTransTypes = MessageUtils.findMessageNames( - new Class[] { IDnsResolver.class }, new String[]{ "TRANSPORT_" }); - assertEquals(0, MIN_TRANSPORT); - assertEquals(MAX_TRANSPORT + 1, ncTransTypes.size()); - // TRANSPORT_UNKNOWN in IDnsResolver is defined to -1 and only for resolver. - assertEquals("TRANSPORT_UNKNOWN", dnsTransTypes.get(-1)); - assertEquals(ncTransTypes.size(), dnsTransTypes.size() - 1); - for (int i = MIN_TRANSPORT; i < MAX_TRANSPORT; i++) { - String name = ncTransTypes.get(i, null); - assertNotNull("Could not find NetworkCapabilies.TRANSPORT_* constant equal to " - + i, name); - assertEquals(name, dnsTransTypes.get(i)); - } - } - - @Test - public void testGetPrivateDnsConfigForNetwork() throws Exception { - final Network network = new Network(TEST_NETID); - final InetAddress dnsAddr = InetAddressUtils.parseNumericAddress("3.3.3.3"); - final InetAddress[] tlsAddrs = new InetAddress[]{ - InetAddressUtils.parseNumericAddress("6.6.6.6"), - InetAddressUtils.parseNumericAddress("2001:db8:66:66::1") - }; - final String tlsName = "strictmode.com"; - LinkProperties lp = new LinkProperties(); - lp.addDnsServer(dnsAddr); - - // The PrivateDnsConfig map is empty, so the default PRIVATE_DNS_OFF is returned. - PrivateDnsConfig privateDnsCfg = mDnsManager.getPrivateDnsConfig(network); - assertFalse(privateDnsCfg.useTls); - assertEquals("", privateDnsCfg.hostname); - assertEquals(new InetAddress[0], privateDnsCfg.ips); - - // An entry with default PrivateDnsConfig is added to the PrivateDnsConfig map. - mDnsManager.updatePrivateDns(network, mDnsManager.getPrivateDnsConfig()); - mDnsManager.noteDnsServersForNetwork(TEST_NETID, lp); - mDnsManager.updatePrivateDnsValidation( - new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, dnsAddr, "", - VALIDATION_RESULT_SUCCESS)); - mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); - privateDnsCfg = mDnsManager.getPrivateDnsConfig(network); - assertTrue(privateDnsCfg.useTls); - assertEquals("", privateDnsCfg.hostname); - assertEquals(new InetAddress[0], privateDnsCfg.ips); - - // The original entry is overwritten by a new PrivateDnsConfig. - mDnsManager.updatePrivateDns(network, new PrivateDnsConfig(tlsName, tlsAddrs)); - mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); - privateDnsCfg = mDnsManager.getPrivateDnsConfig(network); - assertTrue(privateDnsCfg.useTls); - assertEquals(tlsName, privateDnsCfg.hostname); - assertEquals(tlsAddrs, privateDnsCfg.ips); - - // The network is removed, so the PrivateDnsConfig map becomes empty again. - mDnsManager.removeNetwork(network); - privateDnsCfg = mDnsManager.getPrivateDnsConfig(network); - assertFalse(privateDnsCfg.useTls); - assertEquals("", privateDnsCfg.hostname); - assertEquals(new InetAddress[0], privateDnsCfg.ips); - } -} diff --git a/tests/net/java/com/android/server/connectivity/FullScoreTest.kt b/tests/net/java/com/android/server/connectivity/FullScoreTest.kt deleted file mode 100644 index 45b575a4365d..000000000000 --- a/tests/net/java/com/android/server/connectivity/FullScoreTest.kt +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.connectivity - -import android.net.NetworkAgentConfig -import android.net.NetworkCapabilities -import android.net.NetworkScore.KEEP_CONNECTED_NONE -import android.text.TextUtils -import android.util.ArraySet -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import com.android.server.connectivity.FullScore.MAX_CS_MANAGED_POLICY -import com.android.server.connectivity.FullScore.POLICY_ACCEPT_UNVALIDATED -import com.android.server.connectivity.FullScore.POLICY_EVER_USER_SELECTED -import com.android.server.connectivity.FullScore.POLICY_IS_VALIDATED -import com.android.server.connectivity.FullScore.POLICY_IS_VPN -import org.junit.Test -import org.junit.runner.RunWith -import kotlin.collections.minOfOrNull -import kotlin.collections.maxOfOrNull -import kotlin.reflect.full.staticProperties -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertFalse -import kotlin.test.assertTrue - -@RunWith(AndroidJUnit4::class) -@SmallTest -class FullScoreTest { - // Convenience methods - fun FullScore.withPolicies( - validated: Boolean = false, - vpn: Boolean = false, - onceChosen: Boolean = false, - acceptUnvalidated: Boolean = false - ): FullScore { - val nac = NetworkAgentConfig.Builder().apply { - setUnvalidatedConnectivityAcceptable(acceptUnvalidated) - setExplicitlySelected(onceChosen) - }.build() - val nc = NetworkCapabilities.Builder().apply { - if (vpn) addTransportType(NetworkCapabilities.TRANSPORT_VPN) - if (validated) addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) - }.build() - return mixInScore(nc, nac, validated, false /* yieldToBadWifi */) - } - - @Test - fun testGetLegacyInt() { - val ns = FullScore(50, 0L /* policy */, KEEP_CONNECTED_NONE) - assertEquals(10, ns.legacyInt) // -40 penalty for not being validated - assertEquals(50, ns.legacyIntAsValidated) - - val vpnNs = FullScore(101, 0L /* policy */, KEEP_CONNECTED_NONE).withPolicies(vpn = true) - assertEquals(101, vpnNs.legacyInt) // VPNs are not subject to unvalidation penalty - assertEquals(101, vpnNs.legacyIntAsValidated) - assertEquals(101, vpnNs.withPolicies(validated = true).legacyInt) - assertEquals(101, vpnNs.withPolicies(validated = true).legacyIntAsValidated) - - val validatedNs = ns.withPolicies(validated = true) - assertEquals(50, validatedNs.legacyInt) // No penalty, this is validated - assertEquals(50, validatedNs.legacyIntAsValidated) - - val chosenNs = ns.withPolicies(onceChosen = true) - assertEquals(10, chosenNs.legacyInt) - assertEquals(100, chosenNs.legacyIntAsValidated) - assertEquals(10, chosenNs.withPolicies(acceptUnvalidated = true).legacyInt) - assertEquals(50, chosenNs.withPolicies(acceptUnvalidated = true).legacyIntAsValidated) - } - - @Test - fun testToString() { - val string = FullScore(10, 0L /* policy */, KEEP_CONNECTED_NONE) - .withPolicies(vpn = true, acceptUnvalidated = true).toString() - assertTrue(string.contains("Score(10"), string) - assertTrue(string.contains("ACCEPT_UNVALIDATED"), string) - assertTrue(string.contains("IS_VPN"), string) - assertFalse(string.contains("IS_VALIDATED"), string) - val foundNames = ArraySet<String>() - getAllPolicies().forEach { - val name = FullScore.policyNameOf(it.get() as Int) - assertFalse(TextUtils.isEmpty(name)) - assertFalse(foundNames.contains(name)) - foundNames.add(name) - } - assertFailsWith<IllegalArgumentException> { - FullScore.policyNameOf(MAX_CS_MANAGED_POLICY + 1) - } - } - - fun getAllPolicies() = Regex("POLICY_.*").let { nameRegex -> - FullScore::class.staticProperties.filter { it.name.matches(nameRegex) } - } - - @Test - fun testHasPolicy() { - val ns = FullScore(50, 0L /* policy */, KEEP_CONNECTED_NONE) - assertFalse(ns.hasPolicy(POLICY_IS_VALIDATED)) - assertFalse(ns.hasPolicy(POLICY_IS_VPN)) - assertFalse(ns.hasPolicy(POLICY_EVER_USER_SELECTED)) - assertFalse(ns.hasPolicy(POLICY_ACCEPT_UNVALIDATED)) - assertTrue(ns.withPolicies(validated = true).hasPolicy(POLICY_IS_VALIDATED)) - assertTrue(ns.withPolicies(vpn = true).hasPolicy(POLICY_IS_VPN)) - assertTrue(ns.withPolicies(onceChosen = true).hasPolicy(POLICY_EVER_USER_SELECTED)) - assertTrue(ns.withPolicies(acceptUnvalidated = true).hasPolicy(POLICY_ACCEPT_UNVALIDATED)) - } - - @Test - fun testMinMaxPolicyConstants() { - val policies = getAllPolicies() - - policies.forEach { policy -> - assertTrue(policy.get() as Int >= FullScore.MIN_CS_MANAGED_POLICY) - assertTrue(policy.get() as Int <= FullScore.MAX_CS_MANAGED_POLICY) - } - assertEquals(FullScore.MIN_CS_MANAGED_POLICY, - policies.minOfOrNull { it.get() as Int }) - assertEquals(FullScore.MAX_CS_MANAGED_POLICY, - policies.maxOfOrNull { it.get() as Int }) - } -} diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java deleted file mode 100644 index 70495cced536..000000000000 --- a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java +++ /dev/null @@ -1,561 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.connectivity; - -import static com.android.server.connectivity.MetricsTestUtil.aLong; -import static com.android.server.connectivity.MetricsTestUtil.aString; -import static com.android.server.connectivity.MetricsTestUtil.aType; -import static com.android.server.connectivity.MetricsTestUtil.anInt; -import static com.android.server.connectivity.MetricsTestUtil.describeIpEvent; -import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.BLUETOOTH; -import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.CELLULAR; -import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog; -import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.MULTIPLE; -import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.WIFI; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import android.net.ConnectivityMetricsEvent; -import android.net.metrics.ApfProgramEvent; -import android.net.metrics.ApfStats; -import android.net.metrics.DefaultNetworkEvent; -import android.net.metrics.DhcpClientEvent; -import android.net.metrics.DhcpErrorEvent; -import android.net.metrics.IpManagerEvent; -import android.net.metrics.IpReachabilityEvent; -import android.net.metrics.NetworkEvent; -import android.net.metrics.RaEvent; -import android.net.metrics.ValidationProbeEvent; -import android.net.metrics.WakeupStats; -import android.test.suitebuilder.annotation.SmallTest; - -import androidx.test.runner.AndroidJUnit4; - -import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.Arrays; -import java.util.List; - -// TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto. -@RunWith(AndroidJUnit4.class) -@SmallTest -public class IpConnectivityEventBuilderTest { - - @Test - public void testLinkLayerInferrence() { - ConnectivityMetricsEvent ev = describeIpEvent( - aType(IpReachabilityEvent.class), - anInt(IpReachabilityEvent.NUD_FAILED)); - - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 0", - " network_id: 0", - " time_ms: 1", - " transports: 0", - " ip_reachability_event <", - " event_type: 512", - " if_name: \"\"", - " >", - ">", - "version: 2\n"); - verifySerialization(want, ev); - - ev.netId = 123; - ev.transports = 3; // transports have priority for inferrence of link layer - ev.ifname = "wlan0"; - want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - String.format(" link_layer: %d", MULTIPLE), - " network_id: 123", - " time_ms: 1", - " transports: 3", - " ip_reachability_event <", - " event_type: 512", - " if_name: \"\"", - " >", - ">", - "version: 2\n"); - verifySerialization(want, ev); - - ev.transports = 1; - ev.ifname = null; - want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - String.format(" link_layer: %d", CELLULAR), - " network_id: 123", - " time_ms: 1", - " transports: 1", - " ip_reachability_event <", - " event_type: 512", - " if_name: \"\"", - " >", - ">", - "version: 2\n"); - verifySerialization(want, ev); - - ev.transports = 0; - ev.ifname = "not_inferred"; - want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"not_inferred\"", - " link_layer: 0", - " network_id: 123", - " time_ms: 1", - " transports: 0", - " ip_reachability_event <", - " event_type: 512", - " if_name: \"\"", - " >", - ">", - "version: 2\n"); - verifySerialization(want, ev); - - ev.ifname = "bt-pan"; - want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - String.format(" link_layer: %d", BLUETOOTH), - " network_id: 123", - " time_ms: 1", - " transports: 0", - " ip_reachability_event <", - " event_type: 512", - " if_name: \"\"", - " >", - ">", - "version: 2\n"); - verifySerialization(want, ev); - - ev.ifname = "rmnet_ipa0"; - want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - String.format(" link_layer: %d", CELLULAR), - " network_id: 123", - " time_ms: 1", - " transports: 0", - " ip_reachability_event <", - " event_type: 512", - " if_name: \"\"", - " >", - ">", - "version: 2\n"); - verifySerialization(want, ev); - - ev.ifname = "wlan0"; - want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - String.format(" link_layer: %d", WIFI), - " network_id: 123", - " time_ms: 1", - " transports: 0", - " ip_reachability_event <", - " event_type: 512", - " if_name: \"\"", - " >", - ">", - "version: 2\n"); - verifySerialization(want, ev); - } - - @Test - public void testDefaultNetworkEventSerialization() { - DefaultNetworkEvent ev = new DefaultNetworkEvent(1001); - ev.netId = 102; - ev.transports = 2; - ev.previousTransports = 4; - ev.ipv4 = true; - ev.initialScore = 20; - ev.finalScore = 60; - ev.durationMs = 54; - ev.validatedMs = 27; - - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 102", - " time_ms: 0", - " transports: 2", - " default_network_event <", - " default_network_duration_ms: 54", - " final_score: 60", - " initial_score: 20", - " ip_support: 1", - " no_default_network_duration_ms: 0", - " previous_default_network_link_layer: 1", - " previous_network_ip_support: 0", - " validation_duration_ms: 27", - " >", - ">", - "version: 2\n"); - - verifySerialization(want, IpConnectivityEventBuilder.toProto(ev)); - } - - @Test - public void testDhcpClientEventSerialization() { - ConnectivityMetricsEvent ev = describeIpEvent( - aType(DhcpClientEvent.class), - aString("SomeState"), - anInt(192)); - - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 0", - " network_id: 0", - " time_ms: 1", - " transports: 0", - " dhcp_event <", - " duration_ms: 192", - " if_name: \"\"", - " state_transition: \"SomeState\"", - " >", - ">", - "version: 2\n"); - - verifySerialization(want, ev); - } - - @Test - public void testDhcpErrorEventSerialization() { - ConnectivityMetricsEvent ev = describeIpEvent( - aType(DhcpErrorEvent.class), - anInt(DhcpErrorEvent.L4_NOT_UDP)); - - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 0", - " network_id: 0", - " time_ms: 1", - " transports: 0", - " dhcp_event <", - " duration_ms: 0", - " if_name: \"\"", - " error_code: 50397184", - " >", - ">", - "version: 2\n"); - - verifySerialization(want, ev); - } - - @Test - public void testIpManagerEventSerialization() { - ConnectivityMetricsEvent ev = describeIpEvent( - aType(IpManagerEvent.class), - anInt(IpManagerEvent.PROVISIONING_OK), - aLong(5678)); - - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 0", - " network_id: 0", - " time_ms: 1", - " transports: 0", - " ip_provisioning_event <", - " event_type: 1", - " if_name: \"\"", - " latency_ms: 5678", - " >", - ">", - "version: 2\n"); - - verifySerialization(want, ev); - } - - @Test - public void testIpReachabilityEventSerialization() { - ConnectivityMetricsEvent ev = describeIpEvent( - aType(IpReachabilityEvent.class), - anInt(IpReachabilityEvent.NUD_FAILED)); - - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 0", - " network_id: 0", - " time_ms: 1", - " transports: 0", - " ip_reachability_event <", - " event_type: 512", - " if_name: \"\"", - " >", - ">", - "version: 2\n"); - - verifySerialization(want, ev); - } - - @Test - public void testNetworkEventSerialization() { - ConnectivityMetricsEvent ev = describeIpEvent( - aType(NetworkEvent.class), - anInt(5), - aLong(20410)); - - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 0", - " network_id: 0", - " time_ms: 1", - " transports: 0", - " network_event <", - " event_type: 5", - " latency_ms: 20410", - " >", - ">", - "version: 2\n"); - - verifySerialization(want, ev); - } - - @Test - public void testValidationProbeEventSerialization() { - ConnectivityMetricsEvent ev = describeIpEvent( - aType(ValidationProbeEvent.class), - aLong(40730), - anInt(ValidationProbeEvent.PROBE_HTTP), - anInt(204)); - - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 0", - " network_id: 0", - " time_ms: 1", - " transports: 0", - " validation_probe_event <", - " latency_ms: 40730", - " probe_result: 204", - " probe_type: 1", - " >", - ">", - "version: 2\n"); - - verifySerialization(want, ev); - } - - @Test - public void testApfProgramEventSerialization() { - ConnectivityMetricsEvent ev = describeIpEvent( - aType(ApfProgramEvent.class), - aLong(200), - aLong(18), - anInt(7), - anInt(9), - anInt(2048), - anInt(3)); - - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 0", - " network_id: 0", - " time_ms: 1", - " transports: 0", - " apf_program_event <", - " current_ras: 9", - " drop_multicast: true", - " effective_lifetime: 18", - " filtered_ras: 7", - " has_ipv4_addr: true", - " lifetime: 200", - " program_length: 2048", - " >", - ">", - "version: 2\n"); - - verifySerialization(want, ev); - } - - @Test - public void testApfStatsSerialization() { - ConnectivityMetricsEvent ev = describeIpEvent( - aType(ApfStats.class), - aLong(45000), - anInt(10), - anInt(2), - anInt(2), - anInt(1), - anInt(2), - anInt(4), - anInt(7), - anInt(3), - anInt(2048)); - - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 0", - " network_id: 0", - " time_ms: 1", - " transports: 0", - " apf_statistics <", - " dropped_ras: 2", - " duration_ms: 45000", - " matching_ras: 2", - " max_program_size: 2048", - " parse_errors: 2", - " program_updates: 4", - " program_updates_all: 7", - " program_updates_allowing_multicast: 3", - " received_ras: 10", - " total_packet_dropped: 0", - " total_packet_processed: 0", - " zero_lifetime_ras: 1", - " >", - ">", - "version: 2\n"); - - verifySerialization(want, ev); - } - - @Test - public void testRaEventSerialization() { - ConnectivityMetricsEvent ev = describeIpEvent( - aType(RaEvent.class), - aLong(2000), - aLong(400), - aLong(300), - aLong(-1), - aLong(1000), - aLong(-1)); - - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 0", - " network_id: 0", - " time_ms: 1", - " transports: 0", - " ra_event <", - " dnssl_lifetime: -1", - " prefix_preferred_lifetime: 300", - " prefix_valid_lifetime: 400", - " rdnss_lifetime: 1000", - " route_info_lifetime: -1", - " router_lifetime: 2000", - " >", - ">", - "version: 2\n"); - - verifySerialization(want, ev); - } - - @Test - public void testWakeupStatsSerialization() { - WakeupStats stats = new WakeupStats("wlan0"); - stats.totalWakeups = 14; - stats.applicationWakeups = 5; - stats.nonApplicationWakeups = 1; - stats.rootWakeups = 2; - stats.systemWakeups = 3; - stats.noUidWakeups = 3; - stats.l2UnicastCount = 5; - stats.l2MulticastCount = 1; - stats.l2BroadcastCount = 2; - stats.ethertypes.put(0x800, 3); - stats.ethertypes.put(0x86dd, 3); - stats.ipNextHeaders.put(6, 5); - - - IpConnectivityEvent got = IpConnectivityEventBuilder.toProto(stats); - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 0", - " time_ms: 0", - " transports: 0", - " wakeup_stats <", - " application_wakeups: 5", - " duration_sec: 0", - " ethertype_counts <", - " key: 2048", - " value: 3", - " >", - " ethertype_counts <", - " key: 34525", - " value: 3", - " >", - " ip_next_header_counts <", - " key: 6", - " value: 5", - " >", - " l2_broadcast_count: 2", - " l2_multicast_count: 1", - " l2_unicast_count: 5", - " no_uid_wakeups: 3", - " non_application_wakeups: 1", - " root_wakeups: 2", - " system_wakeups: 3", - " total_wakeups: 14", - " >", - ">", - "version: 2\n"); - - verifySerialization(want, got); - } - - static void verifySerialization(String want, ConnectivityMetricsEvent... input) { - List<IpConnectivityEvent> protoInput = - IpConnectivityEventBuilder.toProto(Arrays.asList(input)); - verifySerialization(want, protoInput.toArray(new IpConnectivityEvent[0])); - } - - static void verifySerialization(String want, IpConnectivityEvent... input) { - try { - byte[] got = IpConnectivityEventBuilder.serialize(0, Arrays.asList(input)); - IpConnectivityLog log = IpConnectivityLog.parseFrom(got); - assertEquals(want, log.toString()); - } catch (Exception e) { - fail(e.toString()); - } - } -} diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java deleted file mode 100644 index 8b072c49de82..000000000000 --- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java +++ /dev/null @@ -1,645 +0,0 @@ -/* - * Copyright (C) 2016, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.connectivity; - -import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO; -import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.ConnectivityMetricsEvent; -import android.net.IIpConnectivityMetrics; -import android.net.IpPrefix; -import android.net.LinkAddress; -import android.net.LinkProperties; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.RouteInfo; -import android.net.metrics.ApfProgramEvent; -import android.net.metrics.ApfStats; -import android.net.metrics.DhcpClientEvent; -import android.net.metrics.IpConnectivityLog; -import android.net.metrics.IpManagerEvent; -import android.net.metrics.IpReachabilityEvent; -import android.net.metrics.RaEvent; -import android.net.metrics.ValidationProbeEvent; -import android.os.Parcelable; -import android.system.OsConstants; -import android.test.suitebuilder.annotation.SmallTest; -import android.util.Base64; - -import androidx.test.runner.AndroidJUnit4; - -import com.android.internal.util.BitUtils; -import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.io.PrintWriter; -import java.io.StringWriter; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class IpConnectivityMetricsTest { - static final IpReachabilityEvent FAKE_EV = - new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED); - - private static final String EXAMPLE_IPV4 = "192.0.2.1"; - private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1"; - - private static final byte[] MAC_ADDR = - {(byte)0x84, (byte)0xc9, (byte)0xb2, (byte)0x6a, (byte)0xed, (byte)0x4b}; - - @Mock Context mCtx; - @Mock IIpConnectivityMetrics mMockService; - @Mock ConnectivityManager mCm; - - IpConnectivityMetrics mService; - NetdEventListenerService mNetdListener; - private static final NetworkCapabilities CAPABILITIES_WIFI = new NetworkCapabilities.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .build(); - private static final NetworkCapabilities CAPABILITIES_CELL = new NetworkCapabilities.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) - .build(); - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mService = new IpConnectivityMetrics(mCtx, (ctx) -> 2000); - mNetdListener = new NetdEventListenerService(mCm); - mService.mNetdListener = mNetdListener; - } - - @Test - public void testBufferFlushing() { - String output1 = getdump("flush"); - assertEquals("", output1); - - new IpConnectivityLog(mService.impl).log(1, FAKE_EV); - String output2 = getdump("flush"); - assertFalse("".equals(output2)); - - String output3 = getdump("flush"); - assertEquals("", output3); - } - - @Test - public void testRateLimiting() { - final IpConnectivityLog logger = new IpConnectivityLog(mService.impl); - final ApfProgramEvent ev = new ApfProgramEvent.Builder().build(); - final long fakeTimestamp = 1; - - int attempt = 100; // More than burst quota, but less than buffer size. - for (int i = 0; i < attempt; i++) { - logger.log(ev); - } - - String output1 = getdump("flush"); - assertFalse("".equals(output1)); - - for (int i = 0; i < attempt; i++) { - assertFalse("expected event to be dropped", logger.log(fakeTimestamp, ev)); - } - - String output2 = getdump("flush"); - assertEquals("", output2); - } - - private void logDefaultNetworkEvent(long timeMs, NetworkAgentInfo nai, - NetworkAgentInfo oldNai) { - final Network network = (nai != null) ? nai.network() : null; - final int score = (nai != null) ? nai.getCurrentScore() : 0; - final boolean validated = (nai != null) ? nai.lastValidated : false; - final LinkProperties lp = (nai != null) ? nai.linkProperties : null; - final NetworkCapabilities nc = (nai != null) ? nai.networkCapabilities : null; - - final Network prevNetwork = (oldNai != null) ? oldNai.network() : null; - final int prevScore = (oldNai != null) ? oldNai.getCurrentScore() : 0; - final LinkProperties prevLp = (oldNai != null) ? oldNai.linkProperties : null; - final NetworkCapabilities prevNc = (oldNai != null) ? oldNai.networkCapabilities : null; - - mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs, network, score, validated, - lp, nc, prevNetwork, prevScore, prevLp, prevNc); - } - @Test - public void testDefaultNetworkEvents() throws Exception { - final long cell = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_CELLULAR}); - final long wifi = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_WIFI}); - - NetworkAgentInfo[][] defaultNetworks = { - // nothing -> cell - {null, makeNai(100, 10, false, true, cell)}, - // cell -> wifi - {makeNai(100, 50, true, true, cell), makeNai(101, 20, true, false, wifi)}, - // wifi -> nothing - {makeNai(101, 60, true, false, wifi), null}, - // nothing -> cell - {null, makeNai(102, 10, true, true, cell)}, - // cell -> wifi - {makeNai(102, 50, true, true, cell), makeNai(103, 20, true, false, wifi)}, - }; - - long timeMs = mService.mDefaultNetworkMetrics.creationTimeMs; - long durationMs = 1001; - for (NetworkAgentInfo[] pair : defaultNetworks) { - timeMs += durationMs; - durationMs += durationMs; - logDefaultNetworkEvent(timeMs, pair[1], pair[0]); - } - - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 5", - " network_id: 0", - " time_ms: 0", - " transports: 0", - " default_network_event <", - " default_network_duration_ms: 1001", - " final_score: 0", - " initial_score: 0", - " ip_support: 0", - " no_default_network_duration_ms: 0", - " previous_default_network_link_layer: 0", - " previous_network_ip_support: 0", - " validation_duration_ms: 0", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 2", - " network_id: 100", - " time_ms: 0", - " transports: 1", - " default_network_event <", - " default_network_duration_ms: 2002", - " final_score: 50", - " initial_score: 10", - " ip_support: 3", - " no_default_network_duration_ms: 0", - " previous_default_network_link_layer: 0", - " previous_network_ip_support: 0", - " validation_duration_ms: 2002", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 101", - " time_ms: 0", - " transports: 2", - " default_network_event <", - " default_network_duration_ms: 4004", - " final_score: 60", - " initial_score: 20", - " ip_support: 1", - " no_default_network_duration_ms: 0", - " previous_default_network_link_layer: 2", - " previous_network_ip_support: 0", - " validation_duration_ms: 4004", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 5", - " network_id: 0", - " time_ms: 0", - " transports: 0", - " default_network_event <", - " default_network_duration_ms: 8008", - " final_score: 0", - " initial_score: 0", - " ip_support: 0", - " no_default_network_duration_ms: 0", - " previous_default_network_link_layer: 4", - " previous_network_ip_support: 0", - " validation_duration_ms: 0", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 2", - " network_id: 102", - " time_ms: 0", - " transports: 1", - " default_network_event <", - " default_network_duration_ms: 16016", - " final_score: 50", - " initial_score: 10", - " ip_support: 3", - " no_default_network_duration_ms: 0", - " previous_default_network_link_layer: 4", - " previous_network_ip_support: 0", - " validation_duration_ms: 16016", - " >", - ">", - "version: 2\n"); - - verifySerialization(want, getdump("flush")); - } - - @Test - public void testEndToEndLogging() throws Exception { - // TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto. - IpConnectivityLog logger = new IpConnectivityLog(mService.impl); - - ApfStats apfStats = new ApfStats.Builder() - .setDurationMs(45000) - .setReceivedRas(10) - .setMatchingRas(2) - .setDroppedRas(2) - .setParseErrors(2) - .setZeroLifetimeRas(1) - .setProgramUpdates(4) - .setProgramUpdatesAll(7) - .setProgramUpdatesAllowingMulticast(3) - .setMaxProgramSize(2048) - .build(); - - final ValidationProbeEvent validationEv = new ValidationProbeEvent.Builder() - .setDurationMs(40730) - .setProbeType(ValidationProbeEvent.PROBE_HTTP, true) - .setReturnCode(204) - .build(); - - final DhcpClientEvent event = new DhcpClientEvent.Builder() - .setMsg("SomeState") - .setDurationMs(192) - .build(); - Parcelable[] events = { - new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED), event, - new IpManagerEvent(IpManagerEvent.PROVISIONING_OK, 5678), - validationEv, - apfStats, - new RaEvent(2000, 400, 300, -1, 1000, -1) - }; - - for (int i = 0; i < events.length; i++) { - ConnectivityMetricsEvent ev = new ConnectivityMetricsEvent(); - ev.timestamp = 100 * (i + 1); - ev.ifname = "wlan0"; - ev.data = events[i]; - logger.log(ev); - } - - // netId, errno, latency, destination - connectEvent(100, OsConstants.EALREADY, 0, EXAMPLE_IPV4); - connectEvent(100, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6); - connectEvent(100, 0, 110, EXAMPLE_IPV4); - connectEvent(101, 0, 23, EXAMPLE_IPV4); - connectEvent(101, 0, 45, EXAMPLE_IPV6); - connectEvent(100, OsConstants.EAGAIN, 0, EXAMPLE_IPV4); - - // netId, type, return code, latency - dnsEvent(100, EVENT_GETADDRINFO, 0, 3456); - dnsEvent(100, EVENT_GETADDRINFO, 3, 45); - dnsEvent(100, EVENT_GETHOSTBYNAME, 0, 638); - dnsEvent(101, EVENT_GETADDRINFO, 0, 56); - dnsEvent(101, EVENT_GETHOSTBYNAME, 0, 34); - - // iface, uid - final byte[] mac = {0x48, 0x7c, 0x2b, 0x6a, 0x3e, 0x4b}; - final String srcIp = "192.168.2.1"; - final String dstIp = "192.168.2.23"; - final int sport = 2356; - final int dport = 13489; - final long now = 1001L; - final int v4 = 0x800; - final int tcp = 6; - final int udp = 17; - wakeupEvent("wlan0", 1000, v4, tcp, mac, srcIp, dstIp, sport, dport, 1001L); - wakeupEvent("wlan0", 10123, v4, tcp, mac, srcIp, dstIp, sport, dport, 1001L); - wakeupEvent("wlan0", 1000, v4, udp, mac, srcIp, dstIp, sport, dport, 1001L); - wakeupEvent("wlan0", 10008, v4, udp, mac, srcIp, dstIp, sport, dport, 1001L); - wakeupEvent("wlan0", -1, v4, udp, mac, srcIp, dstIp, sport, dport, 1001L); - wakeupEvent("wlan0", 10008, v4, tcp, mac, srcIp, dstIp, sport, dport, 1001L); - - long timeMs = mService.mDefaultNetworkMetrics.creationTimeMs; - final long cell = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_CELLULAR}); - final long wifi = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_WIFI}); - NetworkAgentInfo cellNai = makeNai(100, 50, false, true, cell); - NetworkAgentInfo wifiNai = makeNai(101, 60, true, false, wifi); - logDefaultNetworkEvent(timeMs + 200L, cellNai, null); - logDefaultNetworkEvent(timeMs + 300L, wifiNai, cellNai); - - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 0", - " time_ms: 100", - " transports: 0", - " ip_reachability_event <", - " event_type: 512", - " if_name: \"\"", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 0", - " time_ms: 200", - " transports: 0", - " dhcp_event <", - " duration_ms: 192", - " if_name: \"\"", - " state_transition: \"SomeState\"", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 0", - " time_ms: 300", - " transports: 0", - " ip_provisioning_event <", - " event_type: 1", - " if_name: \"\"", - " latency_ms: 5678", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 0", - " time_ms: 400", - " transports: 0", - " validation_probe_event <", - " latency_ms: 40730", - " probe_result: 204", - " probe_type: 257", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 0", - " time_ms: 500", - " transports: 0", - " apf_statistics <", - " dropped_ras: 2", - " duration_ms: 45000", - " matching_ras: 2", - " max_program_size: 2048", - " parse_errors: 2", - " program_updates: 4", - " program_updates_all: 7", - " program_updates_allowing_multicast: 3", - " received_ras: 10", - " total_packet_dropped: 0", - " total_packet_processed: 0", - " zero_lifetime_ras: 1", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 0", - " time_ms: 600", - " transports: 0", - " ra_event <", - " dnssl_lifetime: -1", - " prefix_preferred_lifetime: 300", - " prefix_valid_lifetime: 400", - " rdnss_lifetime: 1000", - " route_info_lifetime: -1", - " router_lifetime: 2000", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 5", - " network_id: 0", - " time_ms: 0", - " transports: 0", - " default_network_event <", - " default_network_duration_ms: 200", - " final_score: 0", - " initial_score: 0", - " ip_support: 0", - " no_default_network_duration_ms: 0", - " previous_default_network_link_layer: 0", - " previous_network_ip_support: 0", - " validation_duration_ms: 0", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 2", - " network_id: 100", - " time_ms: 0", - " transports: 1", - " default_network_event <", - " default_network_duration_ms: 100", - " final_score: 50", - " initial_score: 50", - " ip_support: 2", - " no_default_network_duration_ms: 0", - " previous_default_network_link_layer: 0", - " previous_network_ip_support: 0", - " validation_duration_ms: 100", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 100", - " time_ms: 0", - " transports: 2", - " connect_statistics <", - " connect_blocking_count: 1", - " connect_count: 3", - " errnos_counters <", - " key: 11", - " value: 1", - " >", - " ipv6_addr_count: 1", - " latencies_ms: 110", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 2", - " network_id: 101", - " time_ms: 0", - " transports: 1", - " connect_statistics <", - " connect_blocking_count: 2", - " connect_count: 2", - " ipv6_addr_count: 1", - " latencies_ms: 23", - " latencies_ms: 45", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 100", - " time_ms: 0", - " transports: 2", - " dns_lookup_batch <", - " event_types: 1", - " event_types: 1", - " event_types: 2", - " getaddrinfo_error_count: 0", - " getaddrinfo_query_count: 0", - " gethostbyname_error_count: 0", - " gethostbyname_query_count: 0", - " latencies_ms: 3456", - " latencies_ms: 45", - " latencies_ms: 638", - " return_codes: 0", - " return_codes: 3", - " return_codes: 0", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 2", - " network_id: 101", - " time_ms: 0", - " transports: 1", - " dns_lookup_batch <", - " event_types: 1", - " event_types: 2", - " getaddrinfo_error_count: 0", - " getaddrinfo_query_count: 0", - " gethostbyname_error_count: 0", - " gethostbyname_query_count: 0", - " latencies_ms: 56", - " latencies_ms: 34", - " return_codes: 0", - " return_codes: 0", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 0", - " time_ms: 0", - " transports: 0", - " wakeup_stats <", - " application_wakeups: 3", - " duration_sec: 0", - " ethertype_counts <", - " key: 2048", - " value: 6", - " >", - " ip_next_header_counts <", - " key: 6", - " value: 3", - " >", - " ip_next_header_counts <", - " key: 17", - " value: 3", - " >", - " l2_broadcast_count: 0", - " l2_multicast_count: 0", - " l2_unicast_count: 6", - " no_uid_wakeups: 1", - " non_application_wakeups: 0", - " root_wakeups: 0", - " system_wakeups: 2", - " total_wakeups: 6", - " >", - ">", - "version: 2\n"); - - verifySerialization(want, getdump("flush")); - } - - String getdump(String ... command) { - StringWriter buffer = new StringWriter(); - PrintWriter writer = new PrintWriter(buffer); - mService.impl.dump(null, writer, command); - return buffer.toString(); - } - - private void setCapabilities(int netId) { - final ArgumentCaptor<ConnectivityManager.NetworkCallback> networkCallback = - ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class); - verify(mCm).registerNetworkCallback(any(), networkCallback.capture()); - networkCallback.getValue().onCapabilitiesChanged(new Network(netId), - netId == 100 ? CAPABILITIES_WIFI : CAPABILITIES_CELL); - } - - void connectEvent(int netId, int error, int latencyMs, String ipAddr) throws Exception { - setCapabilities(netId); - mNetdListener.onConnectEvent(netId, error, latencyMs, ipAddr, 80, 1); - } - - void dnsEvent(int netId, int type, int result, int latency) throws Exception { - setCapabilities(netId); - mNetdListener.onDnsEvent(netId, type, result, latency, "", null, 0, 0); - } - - void wakeupEvent(String iface, int uid, int ether, int ip, byte[] mac, String srcIp, - String dstIp, int sport, int dport, long now) throws Exception { - String prefix = NetdEventListenerService.WAKEUP_EVENT_IFACE_PREFIX + iface; - mNetdListener.onWakeupEvent(prefix, uid, ether, ip, mac, srcIp, dstIp, sport, dport, now); - } - - NetworkAgentInfo makeNai(int netId, int score, boolean ipv4, boolean ipv6, long transports) { - NetworkAgentInfo nai = mock(NetworkAgentInfo.class); - when(nai.network()).thenReturn(new Network(netId)); - when(nai.getCurrentScore()).thenReturn(score); - nai.linkProperties = new LinkProperties(); - nai.networkCapabilities = new NetworkCapabilities(); - nai.lastValidated = true; - for (int t : BitUtils.unpackBits(transports)) { - nai.networkCapabilities.addTransportType(t); - } - if (ipv4) { - nai.linkProperties.addLinkAddress(new LinkAddress("192.0.2.12/24")); - nai.linkProperties.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"))); - } - if (ipv6) { - nai.linkProperties.addLinkAddress(new LinkAddress("2001:db8:dead:beef:f00::a0/64")); - nai.linkProperties.addRoute(new RouteInfo(new IpPrefix("::/0"))); - } - return nai; - } - - - - static void verifySerialization(String want, String output) { - try { - byte[] got = Base64.decode(output, Base64.DEFAULT); - IpConnectivityLogClass.IpConnectivityLog log = - IpConnectivityLogClass.IpConnectivityLog.parseFrom(got); - assertEquals(want, log.toString()); - } catch (Exception e) { - fail(e.toString()); - } - } -} diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java deleted file mode 100644 index 36e229d8aa73..000000000000 --- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright (C) 2016, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.connectivity; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyBoolean; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.PendingIntent; -import android.content.Context; -import android.content.res.Resources; -import android.net.ConnectivityManager; -import android.net.ConnectivityResources; -import android.net.IDnsResolver; -import android.net.INetd; -import android.net.LinkProperties; -import android.net.Network; -import android.net.NetworkAgentConfig; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import android.net.NetworkProvider; -import android.net.NetworkScore; -import android.os.Binder; -import android.text.format.DateUtils; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.connectivity.resources.R; -import com.android.server.ConnectivityService; -import com.android.server.connectivity.NetworkNotificationManager.NotificationType; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class LingerMonitorTest { - static final String CELLULAR = "CELLULAR"; - static final String WIFI = "WIFI"; - - static final long LOW_RATE_LIMIT = DateUtils.MINUTE_IN_MILLIS; - static final long HIGH_RATE_LIMIT = 0; - - static final int LOW_DAILY_LIMIT = 2; - static final int HIGH_DAILY_LIMIT = 1000; - - private static final int TEST_LINGER_DELAY_MS = 400; - - LingerMonitor mMonitor; - - @Mock ConnectivityService mConnService; - @Mock IDnsResolver mDnsResolver; - @Mock INetd mNetd; - @Mock Context mCtx; - @Mock NetworkNotificationManager mNotifier; - @Mock Resources mResources; - @Mock QosCallbackTracker mQosCallbackTracker; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - when(mCtx.getResources()).thenReturn(mResources); - when(mCtx.getPackageName()).thenReturn("com.android.server.connectivity"); - ConnectivityResources.setResourcesContextForTest(mCtx); - - mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT); - } - - @After - public void tearDown() { - ConnectivityResources.setResourcesContextForTest(null); - } - - @Test - public void testTransitions() { - setNotificationSwitch(transition(WIFI, CELLULAR)); - NetworkAgentInfo nai1 = wifiNai(100); - NetworkAgentInfo nai2 = cellNai(101); - - assertTrue(mMonitor.isNotificationEnabled(nai1, nai2)); - assertFalse(mMonitor.isNotificationEnabled(nai2, nai1)); - } - - @Test - public void testNotificationOnLinger() { - setNotificationSwitch(transition(WIFI, CELLULAR)); - setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); - NetworkAgentInfo from = wifiNai(100); - NetworkAgentInfo to = cellNai(101); - - mMonitor.noteLingerDefaultNetwork(from, to); - verifyNotification(from, to); - } - - @Test - public void testToastOnLinger() { - setNotificationSwitch(transition(WIFI, CELLULAR)); - setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); - NetworkAgentInfo from = wifiNai(100); - NetworkAgentInfo to = cellNai(101); - - mMonitor.noteLingerDefaultNetwork(from, to); - verifyToast(from, to); - } - - @Test - public void testNotificationClearedAfterDisconnect() { - setNotificationSwitch(transition(WIFI, CELLULAR)); - setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); - NetworkAgentInfo from = wifiNai(100); - NetworkAgentInfo to = cellNai(101); - - mMonitor.noteLingerDefaultNetwork(from, to); - verifyNotification(from, to); - - mMonitor.noteDisconnect(to); - verify(mNotifier, times(1)).clearNotification(100); - } - - @Test - public void testNotificationClearedAfterSwitchingBack() { - setNotificationSwitch(transition(WIFI, CELLULAR)); - setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); - NetworkAgentInfo from = wifiNai(100); - NetworkAgentInfo to = cellNai(101); - - mMonitor.noteLingerDefaultNetwork(from, to); - verifyNotification(from, to); - - mMonitor.noteLingerDefaultNetwork(to, from); - verify(mNotifier, times(1)).clearNotification(100); - } - - @Test - public void testUniqueToast() { - setNotificationSwitch(transition(WIFI, CELLULAR)); - setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); - NetworkAgentInfo from = wifiNai(100); - NetworkAgentInfo to = cellNai(101); - - mMonitor.noteLingerDefaultNetwork(from, to); - verifyToast(from, to); - - mMonitor.noteLingerDefaultNetwork(to, from); - verify(mNotifier, times(1)).clearNotification(100); - - reset(mNotifier); - mMonitor.noteLingerDefaultNetwork(from, to); - verifyNoNotifications(); - } - - @Test - public void testMultipleNotifications() { - setNotificationSwitch(transition(WIFI, CELLULAR)); - setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); - NetworkAgentInfo wifi1 = wifiNai(100); - NetworkAgentInfo wifi2 = wifiNai(101); - NetworkAgentInfo cell = cellNai(102); - - mMonitor.noteLingerDefaultNetwork(wifi1, cell); - verifyNotification(wifi1, cell); - - mMonitor.noteLingerDefaultNetwork(cell, wifi2); - verify(mNotifier, times(1)).clearNotification(100); - - reset(mNotifier); - mMonitor.noteLingerDefaultNetwork(wifi2, cell); - verifyNotification(wifi2, cell); - } - - @Test - public void testRateLimiting() throws InterruptedException { - mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, LOW_RATE_LIMIT); - - setNotificationSwitch(transition(WIFI, CELLULAR)); - setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); - NetworkAgentInfo wifi1 = wifiNai(100); - NetworkAgentInfo wifi2 = wifiNai(101); - NetworkAgentInfo wifi3 = wifiNai(102); - NetworkAgentInfo cell = cellNai(103); - - mMonitor.noteLingerDefaultNetwork(wifi1, cell); - verifyNotification(wifi1, cell); - reset(mNotifier); - - Thread.sleep(50); - mMonitor.noteLingerDefaultNetwork(cell, wifi2); - mMonitor.noteLingerDefaultNetwork(wifi2, cell); - verifyNoNotifications(); - - Thread.sleep(50); - mMonitor.noteLingerDefaultNetwork(cell, wifi3); - mMonitor.noteLingerDefaultNetwork(wifi3, cell); - verifyNoNotifications(); - } - - @Test - public void testDailyLimiting() throws InterruptedException { - mMonitor = new TestableLingerMonitor(mCtx, mNotifier, LOW_DAILY_LIMIT, HIGH_RATE_LIMIT); - - setNotificationSwitch(transition(WIFI, CELLULAR)); - setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); - NetworkAgentInfo wifi1 = wifiNai(100); - NetworkAgentInfo wifi2 = wifiNai(101); - NetworkAgentInfo wifi3 = wifiNai(102); - NetworkAgentInfo cell = cellNai(103); - - mMonitor.noteLingerDefaultNetwork(wifi1, cell); - verifyNotification(wifi1, cell); - reset(mNotifier); - - Thread.sleep(50); - mMonitor.noteLingerDefaultNetwork(cell, wifi2); - mMonitor.noteLingerDefaultNetwork(wifi2, cell); - verifyNotification(wifi2, cell); - reset(mNotifier); - - Thread.sleep(50); - mMonitor.noteLingerDefaultNetwork(cell, wifi3); - mMonitor.noteLingerDefaultNetwork(wifi3, cell); - verifyNoNotifications(); - } - - @Test - public void testUniqueNotification() { - setNotificationSwitch(transition(WIFI, CELLULAR)); - setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); - NetworkAgentInfo from = wifiNai(100); - NetworkAgentInfo to = cellNai(101); - - mMonitor.noteLingerDefaultNetwork(from, to); - verifyNotification(from, to); - - mMonitor.noteLingerDefaultNetwork(to, from); - verify(mNotifier, times(1)).clearNotification(100); - - mMonitor.noteLingerDefaultNetwork(from, to); - verifyNotification(from, to); - } - - @Test - public void testIgnoreNeverValidatedNetworks() { - setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); - setNotificationSwitch(transition(WIFI, CELLULAR)); - NetworkAgentInfo from = wifiNai(100); - NetworkAgentInfo to = cellNai(101); - from.everValidated = false; - - mMonitor.noteLingerDefaultNetwork(from, to); - verifyNoNotifications(); - } - - @Test - public void testIgnoreCurrentlyValidatedNetworks() { - setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); - setNotificationSwitch(transition(WIFI, CELLULAR)); - NetworkAgentInfo from = wifiNai(100); - NetworkAgentInfo to = cellNai(101); - from.lastValidated = true; - - mMonitor.noteLingerDefaultNetwork(from, to); - verifyNoNotifications(); - } - - @Test - public void testNoNotificationType() { - setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); - setNotificationSwitch(); - NetworkAgentInfo from = wifiNai(100); - NetworkAgentInfo to = cellNai(101); - - mMonitor.noteLingerDefaultNetwork(from, to); - verifyNoNotifications(); - } - - @Test - public void testNoTransitionToNotify() { - setNotificationType(LingerMonitor.NOTIFY_TYPE_NONE); - setNotificationSwitch(transition(WIFI, CELLULAR)); - NetworkAgentInfo from = wifiNai(100); - NetworkAgentInfo to = cellNai(101); - - mMonitor.noteLingerDefaultNetwork(from, to); - verifyNoNotifications(); - } - - @Test - public void testDifferentTransitionToNotify() { - setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); - setNotificationSwitch(transition(CELLULAR, WIFI)); - NetworkAgentInfo from = wifiNai(100); - NetworkAgentInfo to = cellNai(101); - - mMonitor.noteLingerDefaultNetwork(from, to); - verifyNoNotifications(); - } - - void setNotificationSwitch(String... transitions) { - when(mResources.getStringArray(R.array.config_networkNotifySwitches)) - .thenReturn(transitions); - } - - String transition(String from, String to) { - return from + "-" + to; - } - - void setNotificationType(int type) { - when(mResources.getInteger(R.integer.config_networkNotifySwitchType)).thenReturn(type); - } - - void verifyNoToast() { - verify(mNotifier, never()).showToast(any(), any()); - } - - void verifyNoNotification() { - verify(mNotifier, never()) - .showNotification(anyInt(), any(), any(), any(), any(), anyBoolean()); - } - - void verifyNoNotifications() { - verifyNoToast(); - verifyNoNotification(); - } - - void verifyToast(NetworkAgentInfo from, NetworkAgentInfo to) { - verifyNoNotification(); - verify(mNotifier, times(1)).showToast(from, to); - } - - void verifyNotification(NetworkAgentInfo from, NetworkAgentInfo to) { - verifyNoToast(); - verify(mNotifier, times(1)).showNotification(eq(from.network.netId), - eq(NotificationType.NETWORK_SWITCH), eq(from), eq(to), any(), eq(true)); - } - - NetworkAgentInfo nai(int netId, int transport, int networkType, String networkTypeName) { - NetworkInfo info = new NetworkInfo(networkType, 0, networkTypeName, ""); - NetworkCapabilities caps = new NetworkCapabilities(); - caps.addCapability(0); - caps.addTransportType(transport); - NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info, - new LinkProperties(), caps, new NetworkScore.Builder().setLegacyInt(50).build(), - mCtx, null, new NetworkAgentConfig.Builder().build(), mConnService, mNetd, - mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(), TEST_LINGER_DELAY_MS, - mQosCallbackTracker, new ConnectivityService.Dependencies()); - nai.everValidated = true; - return nai; - } - - NetworkAgentInfo wifiNai(int netId) { - return nai(netId, NetworkCapabilities.TRANSPORT_WIFI, - ConnectivityManager.TYPE_WIFI, WIFI); - } - - NetworkAgentInfo cellNai(int netId) { - return nai(netId, NetworkCapabilities.TRANSPORT_CELLULAR, - ConnectivityManager.TYPE_MOBILE, CELLULAR); - } - - public static class TestableLingerMonitor extends LingerMonitor { - public TestableLingerMonitor(Context c, NetworkNotificationManager n, int l, long r) { - super(c, n, l, r); - } - @Override protected PendingIntent createNotificationIntent() { - return null; - } - } -} diff --git a/tests/net/java/com/android/server/connectivity/MetricsTestUtil.java b/tests/net/java/com/android/server/connectivity/MetricsTestUtil.java deleted file mode 100644 index 5064b9bd91b9..000000000000 --- a/tests/net/java/com/android/server/connectivity/MetricsTestUtil.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.connectivity; - -import android.net.ConnectivityMetricsEvent; -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.function.Consumer; - -abstract public class MetricsTestUtil { - private MetricsTestUtil() { - } - - static ConnectivityMetricsEvent ev(Parcelable p) { - ConnectivityMetricsEvent ev = new ConnectivityMetricsEvent(); - ev.timestamp = 1L; - ev.data = p; - return ev; - } - - static ConnectivityMetricsEvent describeIpEvent(Consumer<Parcel>... fs) { - Parcel p = Parcel.obtain(); - for (Consumer<Parcel> f : fs) { - f.accept(p); - } - p.setDataPosition(0); - return ev(p.readParcelable(ClassLoader.getSystemClassLoader())); - } - - static Consumer<Parcel> aType(Class<?> c) { - return aString(c.getName()); - } - - static Consumer<Parcel> aBool(boolean b) { - return aByte((byte) (b ? 1 : 0)); - } - - static Consumer<Parcel> aByte(byte b) { - return (p) -> p.writeByte(b); - } - - static Consumer<Parcel> anInt(int i) { - return (p) -> p.writeInt(i); - } - - static Consumer<Parcel> aLong(long l) { - return (p) -> p.writeLong(l); - } - - static Consumer<Parcel> aString(String s) { - return (p) -> p.writeString(s); - } - - static Consumer<Parcel> aByteArray(byte... ary) { - return (p) -> p.writeByteArray(ary); - } - - static Consumer<Parcel> anIntArray(int... ary) { - return (p) -> p.writeIntArray(ary); - } - - static byte b(int i) { - return (byte) i; - } -} diff --git a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java b/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java deleted file mode 100644 index 38f6d7f3172d..000000000000 --- a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.connectivity; - -import static android.content.Intent.ACTION_CONFIGURATION_CHANGED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; -import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; -import static android.net.NetworkPolicy.LIMIT_DISABLED; -import static android.net.NetworkPolicy.SNOOZE_NEVER; -import static android.net.NetworkPolicy.WARNING_DISABLED; -import static android.provider.Settings.Global.NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES; - -import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH; -import static com.android.server.net.NetworkPolicyManagerService.OPPORTUNISTIC_QUOTA_UNKNOWN; - -import static junit.framework.TestCase.assertNotNull; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.usage.NetworkStatsManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.res.Resources; -import android.net.ConnectivityManager; -import android.net.EthernetNetworkSpecifier; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkPolicy; -import android.net.NetworkPolicyManager; -import android.net.NetworkTemplate; -import android.net.TelephonyNetworkSpecifier; -import android.os.Handler; -import android.os.UserHandle; -import android.provider.Settings; -import android.telephony.TelephonyManager; -import android.test.mock.MockContentResolver; -import android.util.DataUnit; -import android.util.RecurrenceRule; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.internal.R; -import com.android.internal.util.test.FakeSettingsProvider; -import com.android.server.LocalServices; -import com.android.server.net.NetworkPolicyManagerInternal; -import com.android.server.net.NetworkStatsManagerInternal; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -import java.time.Clock; -import java.time.Instant; -import java.time.Period; -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.time.temporal.ChronoUnit; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class MultipathPolicyTrackerTest { - private static final Network TEST_NETWORK = new Network(123); - private static final int POLICY_SNOOZED = -100; - - @Mock private Context mContext; - @Mock private Context mUserAllContext; - @Mock private Resources mResources; - @Mock private Handler mHandler; - @Mock private MultipathPolicyTracker.Dependencies mDeps; - @Mock private Clock mClock; - @Mock private ConnectivityManager mCM; - @Mock private NetworkPolicyManager mNPM; - @Mock private NetworkStatsManager mStatsManager; - @Mock private NetworkPolicyManagerInternal mNPMI; - @Mock private NetworkStatsManagerInternal mNetworkStatsManagerInternal; - @Mock private TelephonyManager mTelephonyManager; - private MockContentResolver mContentResolver; - - private ArgumentCaptor<BroadcastReceiver> mConfigChangeReceiverCaptor; - - private MultipathPolicyTracker mTracker; - - private Clock mPreviousRecurrenceRuleClock; - private boolean mRecurrenceRuleClockMocked; - - private <T> void mockService(String serviceName, Class<T> serviceClass, T service) { - when(mContext.getSystemServiceName(serviceClass)).thenReturn(serviceName); - when(mContext.getSystemService(serviceName)).thenReturn(service); - } - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mPreviousRecurrenceRuleClock = RecurrenceRule.sClock; - RecurrenceRule.sClock = mClock; - mRecurrenceRuleClockMocked = true; - - mConfigChangeReceiverCaptor = ArgumentCaptor.forClass(BroadcastReceiver.class); - - when(mContext.getResources()).thenReturn(mResources); - when(mContext.getApplicationInfo()).thenReturn(new ApplicationInfo()); - // Mock user id to all users that Context#registerReceiver will register with all users too. - doReturn(UserHandle.ALL.getIdentifier()).when(mUserAllContext).getUserId(); - when(mContext.createContextAsUser(eq(UserHandle.ALL), anyInt())) - .thenReturn(mUserAllContext); - when(mUserAllContext.registerReceiver(mConfigChangeReceiverCaptor.capture(), - argThat(f -> f.hasAction(ACTION_CONFIGURATION_CHANGED)), any(), any())) - .thenReturn(null); - - when(mDeps.getClock()).thenReturn(mClock); - - when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); - - mContentResolver = Mockito.spy(new MockContentResolver(mContext)); - mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); - Settings.Global.clearProviderForTest(); - when(mContext.getContentResolver()).thenReturn(mContentResolver); - - mockService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class, mCM); - mockService(Context.NETWORK_POLICY_SERVICE, NetworkPolicyManager.class, mNPM); - mockService(Context.NETWORK_STATS_SERVICE, NetworkStatsManager.class, mStatsManager); - mockService(Context.TELEPHONY_SERVICE, TelephonyManager.class, mTelephonyManager); - - LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class); - LocalServices.addService(NetworkPolicyManagerInternal.class, mNPMI); - - LocalServices.removeServiceForTest(NetworkStatsManagerInternal.class); - LocalServices.addService(NetworkStatsManagerInternal.class, mNetworkStatsManagerInternal); - - mTracker = new MultipathPolicyTracker(mContext, mHandler, mDeps); - } - - @After - public void tearDown() { - // Avoid setting static clock to null (which should normally not be the case) - // if MockitoAnnotations.initMocks threw an exception - if (mRecurrenceRuleClockMocked) { - RecurrenceRule.sClock = mPreviousRecurrenceRuleClock; - } - mRecurrenceRuleClockMocked = false; - } - - private void setDefaultQuotaGlobalSetting(long setting) { - Settings.Global.putInt(mContentResolver, NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES, - (int) setting); - } - - private void testGetMultipathPreference( - long usedBytesToday, long subscriptionQuota, long policyWarning, long policyLimit, - long defaultGlobalSetting, long defaultResSetting, boolean roaming) { - - // TODO: tests should not use ZoneId.systemDefault() once code handles TZ correctly. - final ZonedDateTime now = ZonedDateTime.ofInstant( - Instant.parse("2017-04-02T10:11:12Z"), ZoneId.systemDefault()); - final ZonedDateTime startOfDay = now.truncatedTo(ChronoUnit.DAYS); - when(mClock.millis()).thenReturn(now.toInstant().toEpochMilli()); - when(mClock.instant()).thenReturn(now.toInstant()); - when(mClock.getZone()).thenReturn(ZoneId.systemDefault()); - - // Setup plan quota - when(mNPMI.getSubscriptionOpportunisticQuota(TEST_NETWORK, QUOTA_TYPE_MULTIPATH)) - .thenReturn(subscriptionQuota); - - // Setup user policy warning / limit - if (policyWarning != WARNING_DISABLED || policyLimit != LIMIT_DISABLED) { - final Instant recurrenceStart = Instant.parse("2017-04-01T00:00:00Z"); - final RecurrenceRule recurrenceRule = new RecurrenceRule( - ZonedDateTime.ofInstant( - recurrenceStart, - ZoneId.systemDefault()), - null /* end */, - Period.ofMonths(1)); - final boolean snoozeWarning = policyWarning == POLICY_SNOOZED; - final boolean snoozeLimit = policyLimit == POLICY_SNOOZED; - when(mNPM.getNetworkPolicies()).thenReturn(new NetworkPolicy[] { - new NetworkPolicy( - NetworkTemplate.buildTemplateMobileWildcard(), - recurrenceRule, - snoozeWarning ? 0 : policyWarning, - snoozeLimit ? 0 : policyLimit, - snoozeWarning ? recurrenceStart.toEpochMilli() + 1 : SNOOZE_NEVER, - snoozeLimit ? recurrenceStart.toEpochMilli() + 1 : SNOOZE_NEVER, - SNOOZE_NEVER, - true /* metered */, - false /* inferred */) - }); - } else { - when(mNPM.getNetworkPolicies()).thenReturn(new NetworkPolicy[0]); - } - - // Setup default quota in settings and resources - if (defaultGlobalSetting > 0) { - setDefaultQuotaGlobalSetting(defaultGlobalSetting); - } - when(mResources.getInteger(R.integer.config_networkDefaultDailyMultipathQuotaBytes)) - .thenReturn((int) defaultResSetting); - - when(mNetworkStatsManagerInternal.getNetworkTotalBytes( - any(), - eq(startOfDay.toInstant().toEpochMilli()), - eq(now.toInstant().toEpochMilli()))).thenReturn(usedBytesToday); - - ArgumentCaptor<ConnectivityManager.NetworkCallback> networkCallback = - ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class); - mTracker.start(); - verify(mCM).registerNetworkCallback(any(), networkCallback.capture(), any()); - - // Simulate callback after capability changes - NetworkCapabilities capabilities = new NetworkCapabilities() - .addCapability(NET_CAPABILITY_INTERNET) - .addTransportType(TRANSPORT_CELLULAR) - .setNetworkSpecifier(new EthernetNetworkSpecifier("eth234")); - if (!roaming) { - capabilities.addCapability(NET_CAPABILITY_NOT_ROAMING); - } - networkCallback.getValue().onCapabilitiesChanged( - TEST_NETWORK, - capabilities); - - // make sure it also works with the new introduced TelephonyNetworkSpecifier - capabilities = new NetworkCapabilities() - .addCapability(NET_CAPABILITY_INTERNET) - .addTransportType(TRANSPORT_CELLULAR) - .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() - .setSubscriptionId(234).build()); - if (!roaming) { - capabilities.addCapability(NET_CAPABILITY_NOT_ROAMING); - } - networkCallback.getValue().onCapabilitiesChanged( - TEST_NETWORK, - capabilities); - } - - @Test - public void testGetMultipathPreference_SubscriptionQuota() { - testGetMultipathPreference( - DataUnit.MEGABYTES.toBytes(2) /* usedBytesToday */, - DataUnit.MEGABYTES.toBytes(14) /* subscriptionQuota */, - DataUnit.MEGABYTES.toBytes(100) /* policyWarning */, - LIMIT_DISABLED, - DataUnit.MEGABYTES.toBytes(12) /* defaultGlobalSetting */, - 2_500_000 /* defaultResSetting */, - false /* roaming */); - - verify(mStatsManager, times(1)).registerUsageCallback( - any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(12)), any(), any()); - } - - @Test - public void testGetMultipathPreference_UserWarningQuota() { - testGetMultipathPreference( - DataUnit.MEGABYTES.toBytes(7) /* usedBytesToday */, - OPPORTUNISTIC_QUOTA_UNKNOWN, - // 29 days from Apr. 2nd to May 1st - DataUnit.MEGABYTES.toBytes(15 * 29 * 20) /* policyWarning */, - LIMIT_DISABLED, - DataUnit.MEGABYTES.toBytes(12) /* defaultGlobalSetting */, - 2_500_000 /* defaultResSetting */, - false /* roaming */); - - // Daily budget should be 15MB (5% of daily quota), 7MB used today: callback set for 8MB - verify(mStatsManager, times(1)).registerUsageCallback( - any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(8)), any(), any()); - } - - @Test - public void testGetMultipathPreference_SnoozedWarningQuota() { - testGetMultipathPreference( - DataUnit.MEGABYTES.toBytes(7) /* usedBytesToday */, - OPPORTUNISTIC_QUOTA_UNKNOWN, - // 29 days from Apr. 2nd to May 1st - POLICY_SNOOZED /* policyWarning */, - DataUnit.MEGABYTES.toBytes(15 * 29 * 20) /* policyLimit */, - DataUnit.MEGABYTES.toBytes(12) /* defaultGlobalSetting */, - 2_500_000 /* defaultResSetting */, - false /* roaming */); - - // Daily budget should be 15MB (5% of daily quota), 7MB used today: callback set for 8MB - verify(mStatsManager, times(1)).registerUsageCallback( - any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(8)), any(), any()); - } - - @Test - public void testGetMultipathPreference_SnoozedBothQuota() { - testGetMultipathPreference( - DataUnit.MEGABYTES.toBytes(7) /* usedBytesToday */, - OPPORTUNISTIC_QUOTA_UNKNOWN, - // 29 days from Apr. 2nd to May 1st - POLICY_SNOOZED /* policyWarning */, - POLICY_SNOOZED /* policyLimit */, - DataUnit.MEGABYTES.toBytes(12) /* defaultGlobalSetting */, - 2_500_000 /* defaultResSetting */, - false /* roaming */); - - // Default global setting should be used: 12 - 7 = 5 - verify(mStatsManager, times(1)).registerUsageCallback( - any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(5)), any(), any()); - } - - @Test - public void testGetMultipathPreference_SettingChanged() { - testGetMultipathPreference( - DataUnit.MEGABYTES.toBytes(2) /* usedBytesToday */, - OPPORTUNISTIC_QUOTA_UNKNOWN, - WARNING_DISABLED, - LIMIT_DISABLED, - -1 /* defaultGlobalSetting */, - DataUnit.MEGABYTES.toBytes(10) /* defaultResSetting */, - false /* roaming */); - - verify(mStatsManager, times(1)).registerUsageCallback( - any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(8)), any(), any()); - - // Update setting - setDefaultQuotaGlobalSetting(DataUnit.MEGABYTES.toBytes(14)); - mTracker.mSettingsObserver.onChange( - false, Settings.Global.getUriFor(NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES)); - - // Callback must have been re-registered with new setting - verify(mStatsManager, times(1)).unregisterUsageCallback(any()); - verify(mStatsManager, times(1)).registerUsageCallback( - any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(12)), any(), any()); - } - - @Test - public void testGetMultipathPreference_ResourceChanged() { - testGetMultipathPreference( - DataUnit.MEGABYTES.toBytes(2) /* usedBytesToday */, - OPPORTUNISTIC_QUOTA_UNKNOWN, - WARNING_DISABLED, - LIMIT_DISABLED, - -1 /* defaultGlobalSetting */, - DataUnit.MEGABYTES.toBytes(14) /* defaultResSetting */, - false /* roaming */); - - verify(mStatsManager, times(1)).registerUsageCallback( - any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(12)), any(), any()); - - when(mResources.getInteger(R.integer.config_networkDefaultDailyMultipathQuotaBytes)) - .thenReturn((int) DataUnit.MEGABYTES.toBytes(16)); - - final BroadcastReceiver configChangeReceiver = mConfigChangeReceiverCaptor.getValue(); - assertNotNull(configChangeReceiver); - configChangeReceiver.onReceive(mContext, new Intent()); - - // Uses the new setting (16 - 2 = 14MB) - verify(mStatsManager, times(1)).registerUsageCallback( - any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(14)), any(), any()); - } -} diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java deleted file mode 100644 index 9b2a638f8b39..000000000000 --- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java +++ /dev/null @@ -1,555 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.connectivity; - -import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.net.ConnectivityManager; -import android.net.IDnsResolver; -import android.net.INetd; -import android.net.InterfaceConfigurationParcel; -import android.net.IpPrefix; -import android.net.LinkAddress; -import android.net.LinkProperties; -import android.net.NetworkAgentConfig; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import android.os.Handler; -import android.os.test.TestLooper; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.server.ConnectivityService; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class Nat464XlatTest { - - static final String BASE_IFACE = "test0"; - static final String STACKED_IFACE = "v4-test0"; - static final LinkAddress V6ADDR = new LinkAddress("2001:db8:1::f00/64"); - static final LinkAddress ADDR = new LinkAddress("192.0.2.5/29"); - static final String NAT64_PREFIX = "64:ff9b::/96"; - static final String OTHER_NAT64_PREFIX = "2001:db8:0:64::/96"; - static final int NETID = 42; - - @Mock ConnectivityService mConnectivity; - @Mock IDnsResolver mDnsResolver; - @Mock INetd mNetd; - @Mock NetworkAgentInfo mNai; - - TestLooper mLooper; - Handler mHandler; - NetworkAgentConfig mAgentConfig = new NetworkAgentConfig(); - - Nat464Xlat makeNat464Xlat(boolean isCellular464XlatEnabled) { - return new Nat464Xlat(mNai, mNetd, mDnsResolver, new ConnectivityService.Dependencies()) { - @Override protected int getNetId() { - return NETID; - } - - @Override protected boolean isCellular464XlatEnabled() { - return isCellular464XlatEnabled; - } - }; - } - - private void markNetworkConnected() { - mNai.networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); - } - - private void markNetworkDisconnected() { - mNai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, "", ""); - } - - @Before - public void setUp() throws Exception { - mLooper = new TestLooper(); - mHandler = new Handler(mLooper.getLooper()); - - MockitoAnnotations.initMocks(this); - - mNai.linkProperties = new LinkProperties(); - mNai.linkProperties.setInterfaceName(BASE_IFACE); - mNai.networkInfo = new NetworkInfo(null); - mNai.networkInfo.setType(ConnectivityManager.TYPE_WIFI); - mNai.networkCapabilities = new NetworkCapabilities(); - markNetworkConnected(); - when(mNai.connService()).thenReturn(mConnectivity); - when(mNai.netAgentConfig()).thenReturn(mAgentConfig); - when(mNai.handler()).thenReturn(mHandler); - final InterfaceConfigurationParcel mConfig = new InterfaceConfigurationParcel(); - when(mNetd.interfaceGetCfg(eq(STACKED_IFACE))).thenReturn(mConfig); - mConfig.ipv4Addr = ADDR.getAddress().getHostAddress(); - mConfig.prefixLength = ADDR.getPrefixLength(); - } - - private void assertRequiresClat(boolean expected, NetworkAgentInfo nai) { - Nat464Xlat nat = makeNat464Xlat(true); - String msg = String.format("requiresClat expected %b for type=%d state=%s skip=%b " - + "nat64Prefix=%s addresses=%s", expected, nai.networkInfo.getType(), - nai.networkInfo.getDetailedState(), - mAgentConfig.skip464xlat, nai.linkProperties.getNat64Prefix(), - nai.linkProperties.getLinkAddresses()); - assertEquals(msg, expected, nat.requiresClat(nai)); - } - - private void assertShouldStartClat(boolean expected, NetworkAgentInfo nai) { - Nat464Xlat nat = makeNat464Xlat(true); - String msg = String.format("shouldStartClat expected %b for type=%d state=%s skip=%b " - + "nat64Prefix=%s addresses=%s", expected, nai.networkInfo.getType(), - nai.networkInfo.getDetailedState(), - mAgentConfig.skip464xlat, nai.linkProperties.getNat64Prefix(), - nai.linkProperties.getLinkAddresses()); - assertEquals(msg, expected, nat.shouldStartClat(nai)); - } - - @Test - public void testRequiresClat() throws Exception { - final int[] supportedTypes = { - ConnectivityManager.TYPE_MOBILE, - ConnectivityManager.TYPE_WIFI, - ConnectivityManager.TYPE_ETHERNET, - }; - - // NetworkInfo doesn't allow setting the State directly, but rather - // requires setting DetailedState in order set State as a side-effect. - final NetworkInfo.DetailedState[] supportedDetailedStates = { - NetworkInfo.DetailedState.CONNECTED, - NetworkInfo.DetailedState.SUSPENDED, - }; - - LinkProperties oldLp = new LinkProperties(mNai.linkProperties); - for (int type : supportedTypes) { - mNai.networkInfo.setType(type); - for (NetworkInfo.DetailedState state : supportedDetailedStates) { - mNai.networkInfo.setDetailedState(state, "reason", "extraInfo"); - - mNai.linkProperties.setNat64Prefix(new IpPrefix(OTHER_NAT64_PREFIX)); - assertRequiresClat(false, mNai); - assertShouldStartClat(false, mNai); - - mNai.linkProperties.addLinkAddress(new LinkAddress("fc00::1/64")); - assertRequiresClat(false, mNai); - assertShouldStartClat(false, mNai); - - mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64")); - assertRequiresClat(true, mNai); - assertShouldStartClat(true, mNai); - - mAgentConfig.skip464xlat = true; - assertRequiresClat(false, mNai); - assertShouldStartClat(false, mNai); - - mAgentConfig.skip464xlat = false; - assertRequiresClat(true, mNai); - assertShouldStartClat(true, mNai); - - mNai.linkProperties.addLinkAddress(new LinkAddress("192.0.2.2/24")); - assertRequiresClat(false, mNai); - assertShouldStartClat(false, mNai); - - mNai.linkProperties.removeLinkAddress(new LinkAddress("192.0.2.2/24")); - assertRequiresClat(true, mNai); - assertShouldStartClat(true, mNai); - - mNai.linkProperties.setNat64Prefix(null); - assertRequiresClat(true, mNai); - assertShouldStartClat(false, mNai); - - mNai.linkProperties = new LinkProperties(oldLp); - } - } - } - - private void makeClatUnnecessary(boolean dueToDisconnect) { - if (dueToDisconnect) { - markNetworkDisconnected(); - } else { - mNai.linkProperties.addLinkAddress(ADDR); - } - } - - private void checkNormalStartAndStop(boolean dueToDisconnect) throws Exception { - Nat464Xlat nat = makeNat464Xlat(true); - ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class); - - mNai.linkProperties.addLinkAddress(V6ADDR); - - nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); - - // Start clat. - nat.start(); - - verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX)); - - // Stacked interface up notification arrives. - nat.interfaceLinkStateChanged(STACKED_IFACE, true); - mLooper.dispatchNext(); - - verify(mNetd).interfaceGetCfg(eq(STACKED_IFACE)); - verify(mConnectivity).handleUpdateLinkProperties(eq(mNai), c.capture()); - assertFalse(c.getValue().getStackedLinks().isEmpty()); - assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); - assertRunning(nat); - - // Stop clat (Network disconnects, IPv4 addr appears, ...). - makeClatUnnecessary(dueToDisconnect); - nat.stop(); - - verify(mNetd).clatdStop(eq(BASE_IFACE)); - verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture()); - assertTrue(c.getValue().getStackedLinks().isEmpty()); - assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); - verify(mDnsResolver).stopPrefix64Discovery(eq(NETID)); - assertIdle(nat); - - // Stacked interface removed notification arrives and is ignored. - nat.interfaceRemoved(STACKED_IFACE); - mLooper.dispatchNext(); - - verifyNoMoreInteractions(mNetd, mConnectivity); - } - - @Test - public void testNormalStartAndStopDueToDisconnect() throws Exception { - checkNormalStartAndStop(true); - } - - @Test - public void testNormalStartAndStopDueToIpv4Addr() throws Exception { - checkNormalStartAndStop(false); - } - - private void checkStartStopStart(boolean interfaceRemovedFirst) throws Exception { - Nat464Xlat nat = makeNat464Xlat(true); - ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class); - InOrder inOrder = inOrder(mNetd, mConnectivity); - - mNai.linkProperties.addLinkAddress(V6ADDR); - - nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); - - nat.start(); - - inOrder.verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX)); - - // Stacked interface up notification arrives. - nat.interfaceLinkStateChanged(STACKED_IFACE, true); - mLooper.dispatchNext(); - - inOrder.verify(mConnectivity).handleUpdateLinkProperties(eq(mNai), c.capture()); - assertFalse(c.getValue().getStackedLinks().isEmpty()); - assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); - assertRunning(nat); - - // ConnectivityService stops clat (Network disconnects, IPv4 addr appears, ...). - nat.stop(); - - inOrder.verify(mNetd).clatdStop(eq(BASE_IFACE)); - - inOrder.verify(mConnectivity, times(1)).handleUpdateLinkProperties(eq(mNai), c.capture()); - assertTrue(c.getValue().getStackedLinks().isEmpty()); - assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); - assertIdle(nat); - - if (interfaceRemovedFirst) { - // Stacked interface removed notification arrives and is ignored. - nat.interfaceRemoved(STACKED_IFACE); - mLooper.dispatchNext(); - nat.interfaceLinkStateChanged(STACKED_IFACE, false); - mLooper.dispatchNext(); - } - - assertTrue(c.getValue().getStackedLinks().isEmpty()); - assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); - assertIdle(nat); - inOrder.verifyNoMoreInteractions(); - - nat.start(); - - inOrder.verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX)); - - if (!interfaceRemovedFirst) { - // Stacked interface removed notification arrives and is ignored. - nat.interfaceRemoved(STACKED_IFACE); - mLooper.dispatchNext(); - nat.interfaceLinkStateChanged(STACKED_IFACE, false); - mLooper.dispatchNext(); - } - - // Stacked interface up notification arrives. - nat.interfaceLinkStateChanged(STACKED_IFACE, true); - mLooper.dispatchNext(); - - inOrder.verify(mConnectivity).handleUpdateLinkProperties(eq(mNai), c.capture()); - assertFalse(c.getValue().getStackedLinks().isEmpty()); - assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); - assertRunning(nat); - - // ConnectivityService stops clat again. - nat.stop(); - - inOrder.verify(mNetd).clatdStop(eq(BASE_IFACE)); - - inOrder.verify(mConnectivity, times(1)).handleUpdateLinkProperties(eq(mNai), c.capture()); - assertTrue(c.getValue().getStackedLinks().isEmpty()); - assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); - assertIdle(nat); - - inOrder.verifyNoMoreInteractions(); - } - - @Test - public void testStartStopStart() throws Exception { - checkStartStopStart(true); - } - - @Test - public void testStartStopStartBeforeInterfaceRemoved() throws Exception { - checkStartStopStart(false); - } - - @Test - public void testClatdCrashWhileRunning() throws Exception { - Nat464Xlat nat = makeNat464Xlat(true); - ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class); - - nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); - - nat.start(); - - verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX)); - - // Stacked interface up notification arrives. - nat.interfaceLinkStateChanged(STACKED_IFACE, true); - mLooper.dispatchNext(); - - verify(mNetd).interfaceGetCfg(eq(STACKED_IFACE)); - verify(mConnectivity, times(1)).handleUpdateLinkProperties(eq(mNai), c.capture()); - assertFalse(c.getValue().getStackedLinks().isEmpty()); - assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); - assertRunning(nat); - - // Stacked interface removed notification arrives (clatd crashed, ...). - nat.interfaceRemoved(STACKED_IFACE); - mLooper.dispatchNext(); - - verify(mNetd).clatdStop(eq(BASE_IFACE)); - verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture()); - verify(mDnsResolver).stopPrefix64Discovery(eq(NETID)); - assertTrue(c.getValue().getStackedLinks().isEmpty()); - assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); - assertIdle(nat); - - // ConnectivityService stops clat: no-op. - nat.stop(); - - verifyNoMoreInteractions(mNetd, mConnectivity); - } - - private void checkStopBeforeClatdStarts(boolean dueToDisconnect) throws Exception { - Nat464Xlat nat = makeNat464Xlat(true); - - mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64")); - - nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); - - nat.start(); - - verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX)); - - // ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...) - makeClatUnnecessary(dueToDisconnect); - nat.stop(); - - verify(mNetd).clatdStop(eq(BASE_IFACE)); - verify(mDnsResolver).stopPrefix64Discovery(eq(NETID)); - assertIdle(nat); - - // In-flight interface up notification arrives: no-op - nat.interfaceLinkStateChanged(STACKED_IFACE, true); - mLooper.dispatchNext(); - - // Interface removed notification arrives after stopClatd() takes effect: no-op. - nat.interfaceRemoved(STACKED_IFACE); - mLooper.dispatchNext(); - - assertIdle(nat); - - verifyNoMoreInteractions(mNetd, mConnectivity); - } - - @Test - public void testStopDueToDisconnectBeforeClatdStarts() throws Exception { - checkStopBeforeClatdStarts(true); - } - - @Test - public void testStopDueToIpv4AddrBeforeClatdStarts() throws Exception { - checkStopBeforeClatdStarts(false); - } - - private void checkStopAndClatdNeverStarts(boolean dueToDisconnect) throws Exception { - Nat464Xlat nat = makeNat464Xlat(true); - - mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64")); - - nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX)); - - nat.start(); - - verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX)); - - // ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...) - makeClatUnnecessary(dueToDisconnect); - nat.stop(); - - verify(mNetd).clatdStop(eq(BASE_IFACE)); - verify(mDnsResolver).stopPrefix64Discovery(eq(NETID)); - assertIdle(nat); - - verifyNoMoreInteractions(mNetd, mConnectivity); - } - - @Test - public void testStopDueToDisconnectAndClatdNeverStarts() throws Exception { - checkStopAndClatdNeverStarts(true); - } - - @Test - public void testStopDueToIpv4AddressAndClatdNeverStarts() throws Exception { - checkStopAndClatdNeverStarts(false); - } - - @Test - public void testNat64PrefixPreference() throws Exception { - final IpPrefix prefixFromDns = new IpPrefix(NAT64_PREFIX); - final IpPrefix prefixFromRa = new IpPrefix(OTHER_NAT64_PREFIX); - - Nat464Xlat nat = makeNat464Xlat(true); - - final LinkProperties emptyLp = new LinkProperties(); - LinkProperties fixedupLp; - - fixedupLp = new LinkProperties(); - nat.setNat64PrefixFromDns(prefixFromDns); - nat.fixupLinkProperties(emptyLp, fixedupLp); - assertEquals(prefixFromDns, fixedupLp.getNat64Prefix()); - - fixedupLp = new LinkProperties(); - nat.setNat64PrefixFromRa(prefixFromRa); - nat.fixupLinkProperties(emptyLp, fixedupLp); - assertEquals(prefixFromRa, fixedupLp.getNat64Prefix()); - - fixedupLp = new LinkProperties(); - nat.setNat64PrefixFromRa(null); - nat.fixupLinkProperties(emptyLp, fixedupLp); - assertEquals(prefixFromDns, fixedupLp.getNat64Prefix()); - - fixedupLp = new LinkProperties(); - nat.setNat64PrefixFromRa(prefixFromRa); - nat.fixupLinkProperties(emptyLp, fixedupLp); - assertEquals(prefixFromRa, fixedupLp.getNat64Prefix()); - - fixedupLp = new LinkProperties(); - nat.setNat64PrefixFromDns(null); - nat.fixupLinkProperties(emptyLp, fixedupLp); - assertEquals(prefixFromRa, fixedupLp.getNat64Prefix()); - - fixedupLp = new LinkProperties(); - nat.setNat64PrefixFromRa(null); - nat.fixupLinkProperties(emptyLp, fixedupLp); - assertEquals(null, fixedupLp.getNat64Prefix()); - } - - private void checkClatDisabledOnCellular(boolean onCellular) throws Exception { - // Disable 464xlat on cellular networks. - Nat464Xlat nat = makeNat464Xlat(false); - mNai.linkProperties.addLinkAddress(V6ADDR); - mNai.networkCapabilities.setTransportType(TRANSPORT_CELLULAR, onCellular); - nat.update(); - - final IpPrefix nat64Prefix = new IpPrefix(NAT64_PREFIX); - if (onCellular) { - // Prefix discovery is never started. - verify(mDnsResolver, never()).startPrefix64Discovery(eq(NETID)); - assertIdle(nat); - - // If a NAT64 prefix comes in from an RA, clat is not started either. - mNai.linkProperties.setNat64Prefix(nat64Prefix); - nat.setNat64PrefixFromRa(nat64Prefix); - nat.update(); - verify(mNetd, never()).clatdStart(anyString(), anyString()); - assertIdle(nat); - } else { - // Prefix discovery is started. - verify(mDnsResolver).startPrefix64Discovery(eq(NETID)); - assertIdle(nat); - - // If a NAT64 prefix comes in from an RA, clat is started. - mNai.linkProperties.setNat64Prefix(nat64Prefix); - nat.setNat64PrefixFromRa(nat64Prefix); - nat.update(); - verify(mNetd).clatdStart(BASE_IFACE, NAT64_PREFIX); - assertStarting(nat); - } - } - - @Test - public void testClatDisabledOnCellular() throws Exception { - checkClatDisabledOnCellular(true); - } - - @Test - public void testClatDisabledOnNonCellular() throws Exception { - checkClatDisabledOnCellular(false); - } - - static void assertIdle(Nat464Xlat nat) { - assertTrue("Nat464Xlat was not IDLE", !nat.isStarted()); - } - - static void assertStarting(Nat464Xlat nat) { - assertTrue("Nat464Xlat was not STARTING", nat.isStarting()); - } - - static void assertRunning(Nat464Xlat nat) { - assertTrue("Nat464Xlat was not RUNNING", nat.isRunning()); - } -} diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java deleted file mode 100644 index 50aaaee24418..000000000000 --- a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java +++ /dev/null @@ -1,554 +0,0 @@ -/* - * Copyright (C) 2016, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.connectivity; - -import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO; -import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME; - -import static com.android.testutils.MiscAsserts.assertStringContains; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.system.OsConstants; -import android.test.suitebuilder.annotation.SmallTest; -import android.util.Base64; - -import androidx.test.runner.AndroidJUnit4; - -import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent; -import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; - -import java.io.FileOutputStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetdEventListenerServiceTest { - private static final String EXAMPLE_IPV4 = "192.0.2.1"; - private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1"; - - private static final byte[] MAC_ADDR = - {(byte)0x84, (byte)0xc9, (byte)0xb2, (byte)0x6a, (byte)0xed, (byte)0x4b}; - - NetdEventListenerService mService; - ConnectivityManager mCm; - private static final NetworkCapabilities CAPABILITIES_WIFI = new NetworkCapabilities.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .build(); - private static final NetworkCapabilities CAPABILITIES_CELL = new NetworkCapabilities.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) - .build(); - - @Before - public void setUp() { - mCm = mock(ConnectivityManager.class); - mService = new NetdEventListenerService(mCm); - } - - @Test - public void testWakeupEventLogging() throws Exception { - final int BUFFER_LENGTH = NetdEventListenerService.WAKEUP_EVENT_BUFFER_LENGTH; - final long now = System.currentTimeMillis(); - final String iface = "wlan0"; - final byte[] mac = MAC_ADDR; - final String srcIp = "192.168.2.1"; - final String dstIp = "192.168.2.23"; - final String srcIp6 = "2001:db8:4:fd00:a585:13d1:6a23:4fb4"; - final String dstIp6 = "2001:db8:4006:807::200a"; - final int sport = 2356; - final int dport = 13489; - - final int v4 = 0x800; - final int v6 = 0x86dd; - final int tcp = 6; - final int udp = 17; - final int icmp6 = 58; - - // Baseline without any event - String[] baseline = listNetdEvent(); - - int[] uids = {10001, 10002, 10004, 1000, 10052, 10023, 10002, 10123, 10004}; - wakeupEvent(iface, uids[0], v4, tcp, mac, srcIp, dstIp, sport, dport, now); - wakeupEvent(iface, uids[1], v6, udp, mac, srcIp6, dstIp6, sport, dport, now); - wakeupEvent(iface, uids[2], v6, udp, mac, srcIp6, dstIp6, sport, dport, now); - wakeupEvent(iface, uids[3], v4, icmp6, mac, srcIp, dstIp, sport, dport, now); - wakeupEvent(iface, uids[4], v6, tcp, mac, srcIp6, dstIp6, sport, dport, now); - wakeupEvent(iface, uids[5], v4, tcp, mac, srcIp, dstIp, sport, dport, now); - wakeupEvent(iface, uids[6], v6, udp, mac, srcIp6, dstIp6, sport, dport, now); - wakeupEvent(iface, uids[7], v6, tcp, mac, srcIp6, dstIp6, sport, dport, now); - wakeupEvent(iface, uids[8], v6, udp, mac, srcIp6, dstIp6, sport, dport, now); - - String[] events2 = remove(listNetdEvent(), baseline); - int expectedLength2 = uids.length + 1; // +1 for the WakeupStats line - assertEquals(expectedLength2, events2.length); - assertStringContains(events2[0], "WakeupStats"); - assertStringContains(events2[0], "wlan0"); - assertStringContains(events2[0], "0x800"); - assertStringContains(events2[0], "0x86dd"); - for (int i = 0; i < uids.length; i++) { - String got = events2[i+1]; - assertStringContains(got, "WakeupEvent"); - assertStringContains(got, "wlan0"); - assertStringContains(got, "uid: " + uids[i]); - } - - int uid = 20000; - for (int i = 0; i < BUFFER_LENGTH * 2; i++) { - long ts = now + 10; - wakeupEvent(iface, uid, 0x800, 6, mac, srcIp, dstIp, 23, 24, ts); - } - - String[] events3 = remove(listNetdEvent(), baseline); - int expectedLength3 = BUFFER_LENGTH + 1; // +1 for the WakeupStats line - assertEquals(expectedLength3, events3.length); - assertStringContains(events2[0], "WakeupStats"); - assertStringContains(events2[0], "wlan0"); - for (int i = 1; i < expectedLength3; i++) { - String got = events3[i]; - assertStringContains(got, "WakeupEvent"); - assertStringContains(got, "wlan0"); - assertStringContains(got, "uid: " + uid); - } - - uid = 45678; - wakeupEvent(iface, uid, 0x800, 6, mac, srcIp, dstIp, 23, 24, now); - - String[] events4 = remove(listNetdEvent(), baseline); - String lastEvent = events4[events4.length - 1]; - assertStringContains(lastEvent, "WakeupEvent"); - assertStringContains(lastEvent, "wlan0"); - assertStringContains(lastEvent, "uid: " + uid); - } - - @Test - public void testWakeupStatsLogging() throws Exception { - final byte[] mac = MAC_ADDR; - final String srcIp = "192.168.2.1"; - final String dstIp = "192.168.2.23"; - final String srcIp6 = "2401:fa00:4:fd00:a585:13d1:6a23:4fb4"; - final String dstIp6 = "2404:6800:4006:807::200a"; - final int sport = 2356; - final int dport = 13489; - final long now = 1001L; - - final int v4 = 0x800; - final int v6 = 0x86dd; - final int tcp = 6; - final int udp = 17; - final int icmp6 = 58; - - wakeupEvent("wlan0", 1000, v4, tcp, mac, srcIp, dstIp, sport, dport, now); - wakeupEvent("rmnet0", 10123, v4, tcp, mac, srcIp, dstIp, sport, dport, now); - wakeupEvent("wlan0", 1000, v4, udp, mac, srcIp, dstIp, sport, dport, now); - wakeupEvent("rmnet0", 10008, v4, tcp, mac, srcIp, dstIp, sport, dport, now); - wakeupEvent("wlan0", -1, v6, icmp6, mac, srcIp6, dstIp6, sport, dport, now); - wakeupEvent("wlan0", 10008, v4, tcp, mac, srcIp, dstIp, sport, dport, now); - wakeupEvent("rmnet0", 1000, v4, tcp, mac, srcIp, dstIp, sport, dport, now); - wakeupEvent("wlan0", 10004, v4, udp, mac, srcIp, dstIp, sport, dport, now); - wakeupEvent("wlan0", 1000, v6, tcp, mac, srcIp6, dstIp6, sport, dport, now); - wakeupEvent("wlan0", 0, v6, udp, mac, srcIp6, dstIp6, sport, dport, now); - wakeupEvent("wlan0", -1, v6, icmp6, mac, srcIp6, dstIp6, sport, dport, now); - wakeupEvent("rmnet0", 10052, v4, tcp, mac, srcIp, dstIp, sport, dport, now); - wakeupEvent("wlan0", 0, v6, udp, mac, srcIp6, dstIp6, sport, dport, now); - wakeupEvent("rmnet0", 1000, v6, tcp, mac, srcIp6, dstIp6, sport, dport, now); - wakeupEvent("wlan0", 1010, v4, udp, mac, srcIp, dstIp, sport, dport, now); - - String got = flushStatistics(); - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 2", - " network_id: 0", - " time_ms: 0", - " transports: 0", - " wakeup_stats <", - " application_wakeups: 3", - " duration_sec: 0", - " ethertype_counts <", - " key: 2048", - " value: 4", - " >", - " ethertype_counts <", - " key: 34525", - " value: 1", - " >", - " ip_next_header_counts <", - " key: 6", - " value: 5", - " >", - " l2_broadcast_count: 0", - " l2_multicast_count: 0", - " l2_unicast_count: 5", - " no_uid_wakeups: 0", - " non_application_wakeups: 0", - " root_wakeups: 0", - " system_wakeups: 2", - " total_wakeups: 5", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 0", - " time_ms: 0", - " transports: 0", - " wakeup_stats <", - " application_wakeups: 2", - " duration_sec: 0", - " ethertype_counts <", - " key: 2048", - " value: 5", - " >", - " ethertype_counts <", - " key: 34525", - " value: 5", - " >", - " ip_next_header_counts <", - " key: 6", - " value: 3", - " >", - " ip_next_header_counts <", - " key: 17", - " value: 5", - " >", - " ip_next_header_counts <", - " key: 58", - " value: 2", - " >", - " l2_broadcast_count: 0", - " l2_multicast_count: 0", - " l2_unicast_count: 10", - " no_uid_wakeups: 2", - " non_application_wakeups: 1", - " root_wakeups: 2", - " system_wakeups: 3", - " total_wakeups: 10", - " >", - ">", - "version: 2\n"); - assertEquals(want, got); - } - - @Test - public void testDnsLogging() throws Exception { - asyncDump(100); - - dnsEvent(100, EVENT_GETADDRINFO, 0, 3456); - dnsEvent(100, EVENT_GETADDRINFO, 0, 267); - dnsEvent(100, EVENT_GETHOSTBYNAME, 22, 1230); - dnsEvent(100, EVENT_GETADDRINFO, 3, 45); - dnsEvent(100, EVENT_GETADDRINFO, 1, 2111); - dnsEvent(100, EVENT_GETADDRINFO, 0, 450); - dnsEvent(100, EVENT_GETHOSTBYNAME, 200, 638); - dnsEvent(100, EVENT_GETHOSTBYNAME, 178, 1300); - dnsEvent(101, EVENT_GETADDRINFO, 0, 56); - dnsEvent(101, EVENT_GETADDRINFO, 0, 78); - dnsEvent(101, EVENT_GETADDRINFO, 0, 14); - dnsEvent(101, EVENT_GETHOSTBYNAME, 0, 56); - dnsEvent(101, EVENT_GETADDRINFO, 0, 78); - dnsEvent(101, EVENT_GETADDRINFO, 0, 14); - - String got = flushStatistics(); - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 100", - " time_ms: 0", - " transports: 2", - " dns_lookup_batch <", - " event_types: 1", - " event_types: 1", - " event_types: 2", - " event_types: 1", - " event_types: 1", - " event_types: 1", - " event_types: 2", - " event_types: 2", - " getaddrinfo_error_count: 0", - " getaddrinfo_query_count: 0", - " gethostbyname_error_count: 0", - " gethostbyname_query_count: 0", - " latencies_ms: 3456", - " latencies_ms: 267", - " latencies_ms: 1230", - " latencies_ms: 45", - " latencies_ms: 2111", - " latencies_ms: 450", - " latencies_ms: 638", - " latencies_ms: 1300", - " return_codes: 0", - " return_codes: 0", - " return_codes: 22", - " return_codes: 3", - " return_codes: 1", - " return_codes: 0", - " return_codes: 200", - " return_codes: 178", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 2", - " network_id: 101", - " time_ms: 0", - " transports: 1", - " dns_lookup_batch <", - " event_types: 1", - " event_types: 1", - " event_types: 1", - " event_types: 2", - " event_types: 1", - " event_types: 1", - " getaddrinfo_error_count: 0", - " getaddrinfo_query_count: 0", - " gethostbyname_error_count: 0", - " gethostbyname_query_count: 0", - " latencies_ms: 56", - " latencies_ms: 78", - " latencies_ms: 14", - " latencies_ms: 56", - " latencies_ms: 78", - " latencies_ms: 14", - " return_codes: 0", - " return_codes: 0", - " return_codes: 0", - " return_codes: 0", - " return_codes: 0", - " return_codes: 0", - " >", - ">", - "version: 2\n"); - assertEquals(want, got); - } - - @Test - public void testConnectLogging() throws Exception { - asyncDump(100); - - final int OK = 0; - Thread[] logActions = { - // ignored - connectEventAction(100, OsConstants.EALREADY, 0, EXAMPLE_IPV4), - connectEventAction(100, OsConstants.EALREADY, 0, EXAMPLE_IPV6), - connectEventAction(100, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV4), - connectEventAction(101, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6), - connectEventAction(101, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6), - // valid latencies - connectEventAction(100, OK, 110, EXAMPLE_IPV4), - connectEventAction(100, OK, 23, EXAMPLE_IPV4), - connectEventAction(100, OK, 45, EXAMPLE_IPV4), - connectEventAction(101, OK, 56, EXAMPLE_IPV4), - connectEventAction(101, OK, 523, EXAMPLE_IPV6), - connectEventAction(101, OK, 214, EXAMPLE_IPV6), - connectEventAction(101, OK, 67, EXAMPLE_IPV6), - // errors - connectEventAction(100, OsConstants.EPERM, 0, EXAMPLE_IPV4), - connectEventAction(101, OsConstants.EPERM, 0, EXAMPLE_IPV4), - connectEventAction(100, OsConstants.EAGAIN, 0, EXAMPLE_IPV4), - connectEventAction(100, OsConstants.EACCES, 0, EXAMPLE_IPV4), - connectEventAction(101, OsConstants.EACCES, 0, EXAMPLE_IPV4), - connectEventAction(101, OsConstants.EACCES, 0, EXAMPLE_IPV6), - connectEventAction(100, OsConstants.EADDRINUSE, 0, EXAMPLE_IPV4), - connectEventAction(101, OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV4), - connectEventAction(100, OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6), - connectEventAction(100, OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6), - connectEventAction(101, OsConstants.ECONNREFUSED, 0, EXAMPLE_IPV4), - }; - - for (Thread t : logActions) { - t.start(); - } - for (Thread t : logActions) { - t.join(); - } - - String got = flushStatistics(); - String want = String.join("\n", - "dropped_events: 0", - "events <", - " if_name: \"\"", - " link_layer: 4", - " network_id: 100", - " time_ms: 0", - " transports: 2", - " connect_statistics <", - " connect_blocking_count: 3", - " connect_count: 6", - " errnos_counters <", - " key: 1", - " value: 1", - " >", - " errnos_counters <", - " key: 11", - " value: 1", - " >", - " errnos_counters <", - " key: 13", - " value: 1", - " >", - " errnos_counters <", - " key: 98", - " value: 1", - " >", - " errnos_counters <", - " key: 110", - " value: 2", - " >", - " ipv6_addr_count: 1", - " latencies_ms: 23", - " latencies_ms: 45", - " latencies_ms: 110", - " >", - ">", - "events <", - " if_name: \"\"", - " link_layer: 2", - " network_id: 101", - " time_ms: 0", - " transports: 1", - " connect_statistics <", - " connect_blocking_count: 4", - " connect_count: 6", - " errnos_counters <", - " key: 1", - " value: 1", - " >", - " errnos_counters <", - " key: 13", - " value: 2", - " >", - " errnos_counters <", - " key: 110", - " value: 1", - " >", - " errnos_counters <", - " key: 111", - " value: 1", - " >", - " ipv6_addr_count: 5", - " latencies_ms: 56", - " latencies_ms: 67", - " latencies_ms: 214", - " latencies_ms: 523", - " >", - ">", - "version: 2\n"); - assertEquals(want, got); - } - - private void setCapabilities(int netId) { - final ArgumentCaptor<ConnectivityManager.NetworkCallback> networkCallback = - ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class); - verify(mCm).registerNetworkCallback(any(), networkCallback.capture()); - networkCallback.getValue().onCapabilitiesChanged(new Network(netId), - netId == 100 ? CAPABILITIES_WIFI : CAPABILITIES_CELL); - } - - Thread connectEventAction(int netId, int error, int latencyMs, String ipAddr) { - setCapabilities(netId); - return new Thread(() -> { - try { - mService.onConnectEvent(netId, error, latencyMs, ipAddr, 80, 1); - } catch (Exception e) { - fail(e.toString()); - } - }); - } - - void dnsEvent(int netId, int type, int result, int latency) throws Exception { - setCapabilities(netId); - mService.onDnsEvent(netId, type, result, latency, "", null, 0, 0); - } - - void wakeupEvent(String iface, int uid, int ether, int ip, byte[] mac, String srcIp, - String dstIp, int sport, int dport, long now) throws Exception { - String prefix = NetdEventListenerService.WAKEUP_EVENT_IFACE_PREFIX + iface; - mService.onWakeupEvent(prefix, uid, ether, ip, mac, srcIp, dstIp, sport, dport, now); - } - - void asyncDump(long durationMs) throws Exception { - final long stop = System.currentTimeMillis() + durationMs; - final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null")); - new Thread(() -> { - while (System.currentTimeMillis() < stop) { - mService.list(pw); - } - }).start(); - } - - // TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto. - String flushStatistics() throws Exception { - IpConnectivityMetrics metricsService = - new IpConnectivityMetrics(mock(Context.class), (ctx) -> 2000); - metricsService.mNetdListener = mService; - - StringWriter buffer = new StringWriter(); - PrintWriter writer = new PrintWriter(buffer); - metricsService.impl.dump(null, writer, new String[]{"flush"}); - byte[] bytes = Base64.decode(buffer.toString(), Base64.DEFAULT); - IpConnectivityLog log = IpConnectivityLog.parseFrom(bytes); - for (IpConnectivityEvent ev : log.events) { - if (ev.getConnectStatistics() == null) { - continue; - } - // Sort repeated fields of connect() events arriving in non-deterministic order. - Arrays.sort(ev.getConnectStatistics().latenciesMs); - Arrays.sort(ev.getConnectStatistics().errnosCounters, - Comparator.comparingInt((p) -> p.key)); - } - return log.toString(); - } - - String[] listNetdEvent() throws Exception { - StringWriter buffer = new StringWriter(); - PrintWriter writer = new PrintWriter(buffer); - mService.list(writer); - return buffer.toString().split("\\n"); - } - - static <T> T[] remove(T[] array, T[] filtered) { - List<T> c = Arrays.asList(filtered); - int next = 0; - for (int i = 0; i < array.length; i++) { - if (c.contains(array[i])) { - continue; - } - array[next++] = array[i]; - } - return Arrays.copyOf(array, next); - } -} diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java deleted file mode 100644 index c353cea266bb..000000000000 --- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.connectivity; - -import static android.app.Notification.FLAG_ONGOING_EVENT; - -import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.LOST_INTERNET; -import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.NETWORK_SWITCH; -import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.NO_INTERNET; -import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.PARTIAL_CONNECTIVITY; -import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.PRIVATE_DNS_BROKEN; -import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.SIGN_IN; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.clearInvocations; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Notification; -import android.app.NotificationManager; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.res.Resources; -import android.net.ConnectivityResources; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import android.os.UserHandle; -import android.telephony.TelephonyManager; -import android.util.DisplayMetrics; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.connectivity.resources.R; -import com.android.server.connectivity.NetworkNotificationManager.NotificationType; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.AdditionalAnswers; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetworkNotificationManagerTest { - - private static final String TEST_SSID = "Test SSID"; - private static final String TEST_EXTRA_INFO = "extra"; - static final NetworkCapabilities CELL_CAPABILITIES = new NetworkCapabilities(); - static final NetworkCapabilities WIFI_CAPABILITIES = new NetworkCapabilities(); - static final NetworkCapabilities VPN_CAPABILITIES = new NetworkCapabilities(); - static { - CELL_CAPABILITIES.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); - CELL_CAPABILITIES.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); - - WIFI_CAPABILITIES.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); - WIFI_CAPABILITIES.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); - WIFI_CAPABILITIES.setSSID(TEST_SSID); - - // Set the underyling network to wifi. - VPN_CAPABILITIES.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); - VPN_CAPABILITIES.addTransportType(NetworkCapabilities.TRANSPORT_VPN); - VPN_CAPABILITIES.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); - VPN_CAPABILITIES.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN); - } - - @Mock Context mCtx; - @Mock Resources mResources; - @Mock DisplayMetrics mDisplayMetrics; - @Mock PackageManager mPm; - @Mock TelephonyManager mTelephonyManager; - @Mock NotificationManager mNotificationManager; - @Mock NetworkAgentInfo mWifiNai; - @Mock NetworkAgentInfo mCellNai; - @Mock NetworkAgentInfo mVpnNai; - @Mock NetworkInfo mNetworkInfo; - ArgumentCaptor<Notification> mCaptor; - - NetworkNotificationManager mManager; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mCaptor = ArgumentCaptor.forClass(Notification.class); - mWifiNai.networkCapabilities = WIFI_CAPABILITIES; - mWifiNai.networkInfo = mNetworkInfo; - mCellNai.networkCapabilities = CELL_CAPABILITIES; - mCellNai.networkInfo = mNetworkInfo; - mVpnNai.networkCapabilities = VPN_CAPABILITIES; - mVpnNai.networkInfo = mNetworkInfo; - mDisplayMetrics.density = 2.275f; - doReturn(true).when(mVpnNai).isVPN(); - when(mCtx.getResources()).thenReturn(mResources); - when(mCtx.getPackageManager()).thenReturn(mPm); - when(mCtx.getApplicationInfo()).thenReturn(new ApplicationInfo()); - final Context asUserCtx = mock(Context.class, AdditionalAnswers.delegatesTo(mCtx)); - doReturn(UserHandle.ALL).when(asUserCtx).getUser(); - when(mCtx.createContextAsUser(eq(UserHandle.ALL), anyInt())).thenReturn(asUserCtx); - when(mCtx.getSystemService(eq(Context.NOTIFICATION_SERVICE))) - .thenReturn(mNotificationManager); - when(mNetworkInfo.getExtraInfo()).thenReturn(TEST_EXTRA_INFO); - ConnectivityResources.setResourcesContextForTest(mCtx); - when(mResources.getColor(anyInt(), any())).thenReturn(0xFF607D8B); - when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics); - - // Come up with some credible-looking transport names. The actual values do not matter. - String[] transportNames = new String[NetworkCapabilities.MAX_TRANSPORT + 1]; - for (int transport = 0; transport <= NetworkCapabilities.MAX_TRANSPORT; transport++) { - transportNames[transport] = NetworkCapabilities.transportNameOf(transport); - } - when(mResources.getStringArray(R.array.network_switch_type_name)) - .thenReturn(transportNames); - - mManager = new NetworkNotificationManager(mCtx, mTelephonyManager); - } - - @After - public void tearDown() { - ConnectivityResources.setResourcesContextForTest(null); - } - - private void verifyTitleByNetwork(final int id, final NetworkAgentInfo nai, final int title) { - final String tag = NetworkNotificationManager.tagFor(id); - mManager.showNotification(id, PRIVATE_DNS_BROKEN, nai, null, null, true); - verify(mNotificationManager, times(1)) - .notify(eq(tag), eq(PRIVATE_DNS_BROKEN.eventId), any()); - final int transportType = NetworkNotificationManager.approximateTransportType(nai); - if (transportType == NetworkCapabilities.TRANSPORT_WIFI) { - verify(mResources, times(1)).getString(eq(title), eq(TEST_EXTRA_INFO)); - } else { - verify(mResources, times(1)).getString(title); - } - verify(mResources, times(1)).getString(eq(R.string.private_dns_broken_detailed)); - } - - @Test - public void testTitleOfPrivateDnsBroken() { - // Test the title of mobile data. - verifyTitleByNetwork(100, mCellNai, R.string.mobile_no_internet); - clearInvocations(mResources); - - // Test the title of wifi. - verifyTitleByNetwork(101, mWifiNai, R.string.wifi_no_internet); - clearInvocations(mResources); - - // Test the title of other networks. - verifyTitleByNetwork(102, mVpnNai, R.string.other_networks_no_internet); - clearInvocations(mResources); - } - - @Test - public void testNotificationsShownAndCleared() { - final int NETWORK_ID_BASE = 100; - List<NotificationType> types = Arrays.asList(NotificationType.values()); - List<Integer> ids = new ArrayList<>(types.size()); - for (int i = 0; i < types.size(); i++) { - ids.add(NETWORK_ID_BASE + i); - } - Collections.shuffle(ids); - Collections.shuffle(types); - - for (int i = 0; i < ids.size(); i++) { - mManager.showNotification(ids.get(i), types.get(i), mWifiNai, mCellNai, null, false); - } - - List<Integer> idsToClear = new ArrayList<>(ids); - Collections.shuffle(idsToClear); - for (int i = 0; i < ids.size(); i++) { - mManager.clearNotification(idsToClear.get(i)); - } - - for (int i = 0; i < ids.size(); i++) { - final int id = ids.get(i); - final int eventId = types.get(i).eventId; - final String tag = NetworkNotificationManager.tagFor(id); - verify(mNotificationManager, times(1)).notify(eq(tag), eq(eventId), any()); - verify(mNotificationManager, times(1)).cancel(eq(tag), eq(eventId)); - } - } - - @Test - @Ignore - // Ignored because the code under test calls Log.wtf, which crashes the tests on eng builds. - // TODO: re-enable after fixing this (e.g., turn Log.wtf into exceptions that this test catches) - public void testNoInternetNotificationsNotShownForCellular() { - mManager.showNotification(100, NO_INTERNET, mCellNai, mWifiNai, null, false); - mManager.showNotification(101, LOST_INTERNET, mCellNai, mWifiNai, null, false); - - verify(mNotificationManager, never()).notify(any(), anyInt(), any()); - - mManager.showNotification(102, NO_INTERNET, mWifiNai, mCellNai, null, false); - - final int eventId = NO_INTERNET.eventId; - final String tag = NetworkNotificationManager.tagFor(102); - verify(mNotificationManager, times(1)).notify(eq(tag), eq(eventId), any()); - } - - @Test - public void testNotificationsNotShownIfNoInternetCapability() { - mWifiNai.networkCapabilities = new NetworkCapabilities(); - mWifiNai.networkCapabilities .addTransportType(NetworkCapabilities.TRANSPORT_WIFI); - mManager.showNotification(102, NO_INTERNET, mWifiNai, mCellNai, null, false); - mManager.showNotification(103, LOST_INTERNET, mWifiNai, mCellNai, null, false); - mManager.showNotification(104, NETWORK_SWITCH, mWifiNai, mCellNai, null, false); - - verify(mNotificationManager, never()).notify(any(), anyInt(), any()); - } - - private void assertNotification(NotificationType type, boolean ongoing) { - final int id = 101; - final String tag = NetworkNotificationManager.tagFor(id); - final ArgumentCaptor<Notification> noteCaptor = ArgumentCaptor.forClass(Notification.class); - mManager.showNotification(id, type, mWifiNai, mCellNai, null, false); - verify(mNotificationManager, times(1)).notify(eq(tag), eq(type.eventId), - noteCaptor.capture()); - - assertEquals("Notification ongoing flag should be " + (ongoing ? "set" : "unset"), - ongoing, (noteCaptor.getValue().flags & FLAG_ONGOING_EVENT) != 0); - } - - @Test - public void testDuplicatedNotificationsNoInternetThenSignIn() { - final int id = 101; - final String tag = NetworkNotificationManager.tagFor(id); - - // Show first NO_INTERNET - assertNotification(NO_INTERNET, false /* ongoing */); - - // Captive portal detection triggers SIGN_IN a bit later, clearing the previous NO_INTERNET - assertNotification(SIGN_IN, false /* ongoing */); - verify(mNotificationManager, times(1)).cancel(eq(tag), eq(NO_INTERNET.eventId)); - - // Network disconnects - mManager.clearNotification(id); - verify(mNotificationManager, times(1)).cancel(eq(tag), eq(SIGN_IN.eventId)); - } - - @Test - public void testOngoingSignInNotification() { - doReturn(true).when(mResources).getBoolean(R.bool.config_ongoingSignInNotification); - final int id = 101; - final String tag = NetworkNotificationManager.tagFor(id); - - // Show first NO_INTERNET - assertNotification(NO_INTERNET, false /* ongoing */); - - // Captive portal detection triggers SIGN_IN a bit later, clearing the previous NO_INTERNET - assertNotification(SIGN_IN, true /* ongoing */); - verify(mNotificationManager, times(1)).cancel(eq(tag), eq(NO_INTERNET.eventId)); - - // Network disconnects - mManager.clearNotification(id); - verify(mNotificationManager, times(1)).cancel(eq(tag), eq(SIGN_IN.eventId)); - } - - @Test - public void testDuplicatedNotificationsSignInThenNoInternet() { - final int id = 101; - final String tag = NetworkNotificationManager.tagFor(id); - - // Show first SIGN_IN - mManager.showNotification(id, SIGN_IN, mWifiNai, mCellNai, null, false); - verify(mNotificationManager, times(1)).notify(eq(tag), eq(SIGN_IN.eventId), any()); - reset(mNotificationManager); - - // NO_INTERNET arrives after, but is ignored. - mManager.showNotification(id, NO_INTERNET, mWifiNai, mCellNai, null, false); - verify(mNotificationManager, never()).cancel(any(), anyInt()); - verify(mNotificationManager, never()).notify(any(), anyInt(), any()); - - // Network disconnects - mManager.clearNotification(id); - verify(mNotificationManager, times(1)).cancel(eq(tag), eq(SIGN_IN.eventId)); - } - - @Test - public void testClearNotificationByType() { - final int id = 101; - final String tag = NetworkNotificationManager.tagFor(id); - - // clearNotification(int id, NotificationType notifyType) will check if given type is equal - // to previous type or not. If they are equal then clear the notification; if they are not - // equal then return. - mManager.showNotification(id, NO_INTERNET, mWifiNai, mCellNai, null, false); - verify(mNotificationManager, times(1)).notify(eq(tag), eq(NO_INTERNET.eventId), any()); - - // Previous notification is NO_INTERNET and given type is NO_INTERNET too. The notification - // should be cleared. - mManager.clearNotification(id, NO_INTERNET); - verify(mNotificationManager, times(1)).cancel(eq(tag), eq(NO_INTERNET.eventId)); - - // SIGN_IN is popped-up. - mManager.showNotification(id, SIGN_IN, mWifiNai, mCellNai, null, false); - verify(mNotificationManager, times(1)).notify(eq(tag), eq(SIGN_IN.eventId), any()); - - // The notification type is not matching previous one, PARTIAL_CONNECTIVITY won't be - // cleared. - mManager.clearNotification(id, PARTIAL_CONNECTIVITY); - verify(mNotificationManager, never()).cancel(eq(tag), eq(PARTIAL_CONNECTIVITY.eventId)); - } -} diff --git a/tests/net/java/com/android/server/connectivity/NetworkOfferTest.kt b/tests/net/java/com/android/server/connectivity/NetworkOfferTest.kt deleted file mode 100644 index 409f8c309935..000000000000 --- a/tests/net/java/com/android/server/connectivity/NetworkOfferTest.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.connectivity - -import android.net.INetworkOfferCallback -import android.net.NetworkCapabilities -import android.net.NetworkRequest -import android.net.NetworkScore.KEEP_CONNECTED_NONE -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.eq -import org.mockito.Mockito.mock -import org.mockito.Mockito.verify -import kotlin.test.assertFalse -import kotlin.test.assertTrue - -const val POLICY_NONE = 0L - -@RunWith(AndroidJUnit4::class) -@SmallTest -class NetworkOfferTest { - val mockCallback = mock(INetworkOfferCallback::class.java) - - @Test - fun testOfferNeededUnneeded() { - val score = FullScore(50, POLICY_NONE, KEEP_CONNECTED_NONE) - val offer = NetworkOffer(score, NetworkCapabilities.Builder().build(), mockCallback, - 1 /* providerId */) - val request1 = mock(NetworkRequest::class.java) - val request2 = mock(NetworkRequest::class.java) - offer.onNetworkNeeded(request1) - verify(mockCallback).onNetworkNeeded(eq(request1)) - assertTrue(offer.neededFor(request1)) - assertFalse(offer.neededFor(request2)) - - offer.onNetworkNeeded(request2) - verify(mockCallback).onNetworkNeeded(eq(request2)) - assertTrue(offer.neededFor(request1)) - assertTrue(offer.neededFor(request2)) - - // Note that the framework never calls onNetworkNeeded multiple times with the same - // request without calling onNetworkUnneeded first. It would be incorrect usage and the - // behavior would be undefined, so there is nothing to test. - - offer.onNetworkUnneeded(request1) - verify(mockCallback).onNetworkUnneeded(eq(request1)) - assertFalse(offer.neededFor(request1)) - assertTrue(offer.neededFor(request2)) - - offer.onNetworkUnneeded(request2) - verify(mockCallback).onNetworkUnneeded(eq(request2)) - assertFalse(offer.neededFor(request1)) - assertFalse(offer.neededFor(request2)) - } -} diff --git a/tests/net/java/com/android/server/connectivity/NetworkRankerTest.kt b/tests/net/java/com/android/server/connectivity/NetworkRankerTest.kt deleted file mode 100644 index 551b94c7668e..000000000000 --- a/tests/net/java/com/android/server/connectivity/NetworkRankerTest.kt +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.connectivity - -import android.net.NetworkCapabilities -import android.net.NetworkRequest -import android.net.NetworkScore.KEEP_CONNECTED_NONE -import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.any -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.mock -import kotlin.test.assertEquals -import kotlin.test.assertNull - -@RunWith(AndroidJUnit4::class) -@SmallTest -class NetworkRankerTest { - private val ranker = NetworkRanker() - - private fun makeNai(satisfy: Boolean, legacyScore: Int) = - mock(NetworkAgentInfo::class.java).also { - doReturn(satisfy).`when`(it).satisfies(any()) - val fs = FullScore(legacyScore, 0 /* policies */, KEEP_CONNECTED_NONE) - doReturn(fs).`when`(it).getScore() - val nc = NetworkCapabilities.Builder().build() - doReturn(nc).`when`(it).getCapsNoCopy() - } - - @Test - fun testGetBestNetwork() { - val scores = listOf(20, 50, 90, 60, 23, 68) - val nais = scores.map { makeNai(true, it) } - val bestNetwork = nais[2] // The one with the top score - val someRequest = mock(NetworkRequest::class.java) - assertEquals(bestNetwork, ranker.getBestNetwork(someRequest, nais, bestNetwork)) - } - - @Test - fun testIgnoreNonSatisfying() { - val nais = listOf(makeNai(true, 20), makeNai(true, 50), makeNai(false, 90), - makeNai(false, 60), makeNai(true, 23), makeNai(false, 68)) - val bestNetwork = nais[1] // Top score that's satisfying - val someRequest = mock(NetworkRequest::class.java) - assertEquals(bestNetwork, ranker.getBestNetwork(someRequest, nais, nais[1])) - } - - @Test - fun testNoMatch() { - val nais = listOf(makeNai(false, 20), makeNai(false, 50), makeNai(false, 90)) - val someRequest = mock(NetworkRequest::class.java) - assertNull(ranker.getBestNetwork(someRequest, nais, null)) - } - - @Test - fun testEmpty() { - val someRequest = mock(NetworkRequest::class.java) - assertNull(ranker.getBestNetwork(someRequest, emptyList(), null)) - } - - // Make sure the ranker is "stable" (as in stable sort), that is, it always returns the FIRST - // network satisfying the request if multiple of them have the same score. - @Test - fun testStable() { - val nais1 = listOf(makeNai(true, 30), makeNai(true, 30), makeNai(true, 30), - makeNai(true, 30), makeNai(true, 30), makeNai(true, 30)) - val someRequest = mock(NetworkRequest::class.java) - assertEquals(nais1[0], ranker.getBestNetwork(someRequest, nais1, nais1[0])) - - val nais2 = listOf(makeNai(true, 30), makeNai(true, 50), makeNai(true, 20), - makeNai(true, 50), makeNai(true, 50), makeNai(true, 40)) - assertEquals(nais2[1], ranker.getBestNetwork(someRequest, nais2, nais2[1])) - } -} diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java deleted file mode 100644 index 02a58080fefd..000000000000 --- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java +++ /dev/null @@ -1,803 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server.connectivity; - -import static android.Manifest.permission.CHANGE_NETWORK_STATE; -import static android.Manifest.permission.CHANGE_WIFI_STATE; -import static android.Manifest.permission.CONNECTIVITY_INTERNAL; -import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; -import static android.Manifest.permission.INTERNET; -import static android.Manifest.permission.NETWORK_STACK; -import static android.Manifest.permission.UPDATE_DEVICE_STATS; -import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_OEM; -import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRODUCT; -import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_VENDOR; -import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; -import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_REQUIRED; -import static android.content.pm.PackageManager.GET_PERMISSIONS; -import static android.content.pm.PackageManager.MATCH_ANY_USER; -import static android.os.Process.SYSTEM_UID; - -import static com.android.server.connectivity.PermissionMonitor.NETWORK; -import static com.android.server.connectivity.PermissionMonitor.SYSTEM; - -import static junit.framework.Assert.fail; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.AdditionalMatchers.aryEq; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.net.INetd; -import android.net.UidRange; -import android.net.Uri; -import android.os.Build; -import android.os.SystemConfigManager; -import android.os.UserHandle; -import android.os.UserManager; -import android.util.SparseIntArray; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.AdditionalAnswers; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.invocation.InvocationOnMock; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class PermissionMonitorTest { - private static final UserHandle MOCK_USER1 = UserHandle.of(0); - private static final UserHandle MOCK_USER2 = UserHandle.of(1); - private static final int MOCK_UID1 = 10001; - private static final int MOCK_UID2 = 10086; - private static final int SYSTEM_UID1 = 1000; - private static final int SYSTEM_UID2 = 1008; - private static final int VPN_UID = 10002; - private static final String REAL_SYSTEM_PACKAGE_NAME = "android"; - private static final String MOCK_PACKAGE1 = "appName1"; - private static final String MOCK_PACKAGE2 = "appName2"; - private static final String SYSTEM_PACKAGE1 = "sysName1"; - private static final String SYSTEM_PACKAGE2 = "sysName2"; - private static final String PARTITION_SYSTEM = "system"; - private static final String PARTITION_OEM = "oem"; - private static final String PARTITION_PRODUCT = "product"; - private static final String PARTITION_VENDOR = "vendor"; - private static final int VERSION_P = Build.VERSION_CODES.P; - private static final int VERSION_Q = Build.VERSION_CODES.Q; - - @Mock private Context mContext; - @Mock private PackageManager mPackageManager; - @Mock private INetd mNetdService; - @Mock private UserManager mUserManager; - @Mock private PermissionMonitor.Dependencies mDeps; - @Mock private SystemConfigManager mSystemConfigManager; - - private PermissionMonitor mPermissionMonitor; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - when(mContext.getPackageManager()).thenReturn(mPackageManager); - when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager); - when(mUserManager.getUserHandles(eq(true))).thenReturn( - Arrays.asList(new UserHandle[] { MOCK_USER1, MOCK_USER2 })); - when(mContext.getSystemServiceName(SystemConfigManager.class)) - .thenReturn(Context.SYSTEM_CONFIG_SERVICE); - when(mContext.getSystemService(Context.SYSTEM_CONFIG_SERVICE)) - .thenReturn(mSystemConfigManager); - when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]); - final Context asUserCtx = mock(Context.class, AdditionalAnswers.delegatesTo(mContext)); - doReturn(UserHandle.ALL).when(asUserCtx).getUser(); - when(mContext.createContextAsUser(eq(UserHandle.ALL), anyInt())).thenReturn(asUserCtx); - - mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps)); - - when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(/* empty app list */ null); - mPermissionMonitor.startMonitoring(); - } - - private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion, int uid, - String... permissions) { - final PackageInfo packageInfo = - packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, permissions, partition); - packageInfo.applicationInfo.targetSdkVersion = targetSdkVersion; - packageInfo.applicationInfo.uid = uid; - return mPermissionMonitor.hasRestrictedNetworkPermission(packageInfo); - } - - private static PackageInfo systemPackageInfoWithPermissions(String... permissions) { - return packageInfoWithPermissions( - REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM); - } - - private static PackageInfo vendorPackageInfoWithPermissions(String... permissions) { - return packageInfoWithPermissions( - REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_VENDOR); - } - - private static PackageInfo packageInfoWithPermissions(int permissionsFlags, - String[] permissions, String partition) { - int[] requestedPermissionsFlags = new int[permissions.length]; - for (int i = 0; i < permissions.length; i++) { - requestedPermissionsFlags[i] = permissionsFlags; - } - final PackageInfo packageInfo = new PackageInfo(); - packageInfo.requestedPermissions = permissions; - packageInfo.applicationInfo = new ApplicationInfo(); - packageInfo.requestedPermissionsFlags = requestedPermissionsFlags; - int privateFlags = 0; - switch (partition) { - case PARTITION_OEM: - privateFlags = PRIVATE_FLAG_OEM; - break; - case PARTITION_PRODUCT: - privateFlags = PRIVATE_FLAG_PRODUCT; - break; - case PARTITION_VENDOR: - privateFlags = PRIVATE_FLAG_VENDOR; - break; - } - packageInfo.applicationInfo.privateFlags = privateFlags; - return packageInfo; - } - - private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid, - UserHandle user) { - final PackageInfo pkgInfo; - if (hasSystemPermission) { - pkgInfo = systemPackageInfoWithPermissions( - CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_USE_RESTRICTED_NETWORKS); - } else { - pkgInfo = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, new String[] {}, ""); - } - pkgInfo.applicationInfo.uid = user.getUid(UserHandle.getAppId(uid)); - return pkgInfo; - } - - @Test - public void testHasPermission() { - PackageInfo app = systemPackageInfoWithPermissions(); - assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE)); - assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK)); - assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS)); - assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL)); - - app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE, NETWORK_STACK); - assertTrue(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE)); - assertTrue(mPermissionMonitor.hasPermission(app, NETWORK_STACK)); - assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS)); - assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL)); - - app = systemPackageInfoWithPermissions( - CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL); - assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE)); - assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK)); - assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS)); - assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL)); - - app = packageInfoWithPermissions(REQUESTED_PERMISSION_REQUIRED, new String[] { - CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL, NETWORK_STACK }, - PARTITION_SYSTEM); - assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE)); - assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK)); - assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS)); - assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL)); - - app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE); - app.requestedPermissions = null; - assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE)); - - app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE); - app.requestedPermissionsFlags = null; - assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE)); - } - - @Test - public void testIsVendorApp() { - PackageInfo app = systemPackageInfoWithPermissions(); - assertFalse(mPermissionMonitor.isVendorApp(app.applicationInfo)); - app = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, - new String[] {}, PARTITION_OEM); - assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo)); - app = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, - new String[] {}, PARTITION_PRODUCT); - assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo)); - app = vendorPackageInfoWithPermissions(); - assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo)); - } - - @Test - public void testHasNetworkPermission() { - PackageInfo app = systemPackageInfoWithPermissions(); - assertFalse(mPermissionMonitor.hasNetworkPermission(app)); - app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE); - assertTrue(mPermissionMonitor.hasNetworkPermission(app)); - app = systemPackageInfoWithPermissions(NETWORK_STACK); - assertFalse(mPermissionMonitor.hasNetworkPermission(app)); - app = systemPackageInfoWithPermissions(CONNECTIVITY_USE_RESTRICTED_NETWORKS); - assertFalse(mPermissionMonitor.hasNetworkPermission(app)); - app = systemPackageInfoWithPermissions(CONNECTIVITY_INTERNAL); - assertFalse(mPermissionMonitor.hasNetworkPermission(app)); - } - - @Test - public void testHasRestrictedNetworkPermission() { - assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, MOCK_UID1)); - assertFalse(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CHANGE_NETWORK_STATE)); - assertTrue(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, MOCK_UID1, NETWORK_STACK)); - assertFalse(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CONNECTIVITY_INTERNAL)); - assertTrue(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS)); - assertFalse(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CHANGE_WIFI_STATE)); - - assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1)); - assertFalse(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_Q, MOCK_UID1, CONNECTIVITY_INTERNAL)); - } - - @Test - public void testHasRestrictedNetworkPermissionSystemUid() { - doReturn(VERSION_P).when(mDeps).getDeviceFirstSdkInt(); - assertTrue(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID)); - assertTrue(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_INTERNAL)); - assertTrue(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS)); - - doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt(); - assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID)); - assertFalse(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CONNECTIVITY_INTERNAL)); - assertTrue(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS)); - } - - @Test - public void testHasRestrictedNetworkPermissionVendorApp() { - assertTrue(hasRestrictedNetworkPermission(PARTITION_VENDOR, VERSION_P, MOCK_UID1)); - assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_P, MOCK_UID1, CHANGE_NETWORK_STATE)); - assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_P, MOCK_UID1, NETWORK_STACK)); - assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_P, MOCK_UID1, CONNECTIVITY_INTERNAL)); - assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_P, MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS)); - assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_P, MOCK_UID1, CHANGE_WIFI_STATE)); - - assertFalse(hasRestrictedNetworkPermission(PARTITION_VENDOR, VERSION_Q, MOCK_UID1)); - assertFalse(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_Q, MOCK_UID1, CONNECTIVITY_INTERNAL)); - assertFalse(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_Q, MOCK_UID1, CHANGE_NETWORK_STATE)); - } - - private void assertBackgroundPermission(boolean hasPermission, String name, int uid, - String... permissions) throws Exception { - when(mPackageManager.getPackageInfo(eq(name), anyInt())) - .thenReturn(packageInfoWithPermissions( - REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM)); - mPermissionMonitor.onPackageAdded(name, uid); - assertEquals(hasPermission, mPermissionMonitor.hasUseBackgroundNetworksPermission(uid)); - } - - @Test - public void testHasUseBackgroundNetworksPermission() throws Exception { - assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(SYSTEM_UID)); - assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID); - assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID, CONNECTIVITY_INTERNAL); - assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, CHANGE_NETWORK_STATE); - assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, NETWORK_STACK); - - assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID1)); - assertBackgroundPermission(false, MOCK_PACKAGE1, MOCK_UID1); - assertBackgroundPermission(true, MOCK_PACKAGE1, MOCK_UID1, - CONNECTIVITY_USE_RESTRICTED_NETWORKS); - - assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID2)); - assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID2); - assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID2, - CONNECTIVITY_INTERNAL); - assertBackgroundPermission(true, MOCK_PACKAGE2, MOCK_UID2, NETWORK_STACK); - } - - private class NetdMonitor { - private final HashMap<Integer, Boolean> mApps = new HashMap<>(); - - NetdMonitor(INetd mockNetd) throws Exception { - // Add hook to verify and track result of setPermission. - doAnswer((InvocationOnMock invocation) -> { - final Object[] args = invocation.getArguments(); - final Boolean isSystem = args[0].equals(INetd.PERMISSION_SYSTEM); - for (final int uid : (int[]) args[1]) { - // TODO: Currently, permission monitor will send duplicate commands for each uid - // corresponding to each user. Need to fix that and uncomment below test. - // if (mApps.containsKey(uid) && mApps.get(uid) == isSystem) { - // fail("uid " + uid + " is already set to " + isSystem); - // } - mApps.put(uid, isSystem); - } - return null; - }).when(mockNetd).networkSetPermissionForUser(anyInt(), any(int[].class)); - - // Add hook to verify and track result of clearPermission. - doAnswer((InvocationOnMock invocation) -> { - final Object[] args = invocation.getArguments(); - for (final int uid : (int[]) args[0]) { - // TODO: Currently, permission monitor will send duplicate commands for each uid - // corresponding to each user. Need to fix that and uncomment below test. - // if (!mApps.containsKey(uid)) { - // fail("uid " + uid + " does not exist."); - // } - mApps.remove(uid); - } - return null; - }).when(mockNetd).networkClearPermissionForUser(any(int[].class)); - } - - public void expectPermission(Boolean permission, UserHandle[] users, int[] apps) { - for (final UserHandle user : users) { - for (final int app : apps) { - final int uid = user.getUid(app); - if (!mApps.containsKey(uid)) { - fail("uid " + uid + " does not exist."); - } - if (mApps.get(uid) != permission) { - fail("uid " + uid + " has wrong permission: " + permission); - } - } - } - } - - public void expectNoPermission(UserHandle[] users, int[] apps) { - for (final UserHandle user : users) { - for (final int app : apps) { - final int uid = user.getUid(app); - if (mApps.containsKey(uid)) { - fail("uid " + uid + " has listed permissions, expected none."); - } - } - } - } - } - - @Test - public void testUserAndPackageAddRemove() throws Exception { - final NetdMonitor mNetdMonitor = new NetdMonitor(mNetdService); - - // MOCK_UID1: MOCK_PACKAGE1 only has network permission. - // SYSTEM_UID: SYSTEM_PACKAGE1 has system permission. - // SYSTEM_UID: SYSTEM_PACKAGE2 only has network permission. - doReturn(SYSTEM).when(mPermissionMonitor).highestPermissionForUid(eq(SYSTEM), anyString()); - doReturn(SYSTEM).when(mPermissionMonitor).highestPermissionForUid(any(), - eq(SYSTEM_PACKAGE1)); - doReturn(NETWORK).when(mPermissionMonitor).highestPermissionForUid(any(), - eq(SYSTEM_PACKAGE2)); - doReturn(NETWORK).when(mPermissionMonitor).highestPermissionForUid(any(), - eq(MOCK_PACKAGE1)); - - // Add SYSTEM_PACKAGE2, expect only have network permission. - mPermissionMonitor.onUserAdded(MOCK_USER1); - addPackageForUsers(new UserHandle[]{MOCK_USER1}, SYSTEM_PACKAGE2, SYSTEM_UID); - mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{SYSTEM_UID}); - - // Add SYSTEM_PACKAGE1, expect permission escalate. - addPackageForUsers(new UserHandle[]{MOCK_USER1}, SYSTEM_PACKAGE1, SYSTEM_UID); - mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{SYSTEM_UID}); - - mPermissionMonitor.onUserAdded(MOCK_USER2); - mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2}, - new int[]{SYSTEM_UID}); - - addPackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_UID1); - mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2}, - new int[]{SYSTEM_UID}); - mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2}, - new int[]{MOCK_UID1}); - - // Remove MOCK_UID1, expect no permission left for all user. - mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); - removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_UID1); - mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2}, - new int[]{MOCK_UID1}); - - // Remove SYSTEM_PACKAGE1, expect permission downgrade. - when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{SYSTEM_PACKAGE2}); - removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, - SYSTEM_PACKAGE1, SYSTEM_UID); - mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2}, - new int[]{SYSTEM_UID}); - - mPermissionMonitor.onUserRemoved(MOCK_USER1); - mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER2}, new int[]{SYSTEM_UID}); - - // Remove all packages, expect no permission left. - when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{}); - removePackageForUsers(new UserHandle[]{MOCK_USER2}, SYSTEM_PACKAGE2, SYSTEM_UID); - mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2}, - new int[]{SYSTEM_UID, MOCK_UID1}); - - // Remove last user, expect no redundant clearPermission is invoked. - mPermissionMonitor.onUserRemoved(MOCK_USER2); - mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2}, - new int[]{SYSTEM_UID, MOCK_UID1}); - } - - @Test - public void testUidFilteringDuringVpnConnectDisconnectAndUidUpdates() throws Exception { - when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( - Arrays.asList(new PackageInfo[] { - buildPackageInfo(true /* hasSystemPermission */, SYSTEM_UID1, MOCK_USER1), - buildPackageInfo(false /* hasSystemPermission */, MOCK_UID1, MOCK_USER1), - buildPackageInfo(false /* hasSystemPermission */, MOCK_UID2, MOCK_USER1), - buildPackageInfo(false /* hasSystemPermission */, VPN_UID, MOCK_USER1) - })); - when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), - eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( - buildPackageInfo(false /* hasSystemPermission */, MOCK_UID1, MOCK_USER1)); - mPermissionMonitor.startMonitoring(); - // Every app on user 0 except MOCK_UID2 are under VPN. - final Set<UidRange> vpnRange1 = new HashSet<>(Arrays.asList(new UidRange[] { - new UidRange(0, MOCK_UID2 - 1), - new UidRange(MOCK_UID2 + 1, UserHandle.PER_USER_RANGE - 1)})); - final Set<UidRange> vpnRange2 = Collections.singleton(new UidRange(MOCK_UID2, MOCK_UID2)); - - // When VPN is connected, expect a rule to be set up for user app MOCK_UID1 - mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange1, VPN_UID); - verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), - aryEq(new int[] {MOCK_UID1})); - - reset(mNetdService); - - // When MOCK_UID1 package is uninstalled and reinstalled, expect Netd to be updated - mPermissionMonitor.onPackageRemoved( - MOCK_PACKAGE1, MOCK_USER1.getUid(MOCK_UID1)); - verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1})); - mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, MOCK_USER1.getUid(MOCK_UID1)); - verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), - aryEq(new int[] {MOCK_UID1})); - - reset(mNetdService); - - // During VPN uid update (vpnRange1 -> vpnRange2), ConnectivityService first deletes the - // old UID rules then adds the new ones. Expect netd to be updated - mPermissionMonitor.onVpnUidRangesRemoved("tun0", vpnRange1, VPN_UID); - verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1})); - mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange2, VPN_UID); - verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), - aryEq(new int[] {MOCK_UID2})); - - reset(mNetdService); - - // When VPN is disconnected, expect rules to be torn down - mPermissionMonitor.onVpnUidRangesRemoved("tun0", vpnRange2, VPN_UID); - verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID2})); - assertNull(mPermissionMonitor.getVpnUidRanges("tun0")); - } - - @Test - public void testUidFilteringDuringPackageInstallAndUninstall() throws Exception { - when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( - Arrays.asList(new PackageInfo[] { - buildPackageInfo(true /* hasSystemPermission */, SYSTEM_UID1, MOCK_USER1), - buildPackageInfo(false /* hasSystemPermission */, VPN_UID, MOCK_USER1) - })); - when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), - eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( - buildPackageInfo(false /* hasSystemPermission */, MOCK_UID1, MOCK_USER1)); - - mPermissionMonitor.startMonitoring(); - final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(MOCK_USER1)); - mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange, VPN_UID); - - // Newly-installed package should have uid rules added - mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, MOCK_USER1.getUid(MOCK_UID1)); - verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), - aryEq(new int[] {MOCK_UID1})); - - // Removed package should have its uid rules removed - mPermissionMonitor.onPackageRemoved( - MOCK_PACKAGE1, MOCK_USER1.getUid(MOCK_UID1)); - verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1})); - } - - - // Normal package add/remove operations will trigger multiple intent for uids corresponding to - // each user. To simulate generic package operations, the onPackageAdded/Removed will need to be - // called multiple times with the uid corresponding to each user. - private void addPackageForUsers(UserHandle[] users, String packageName, int uid) { - for (final UserHandle user : users) { - mPermissionMonitor.onPackageAdded(packageName, user.getUid(uid)); - } - } - - private void removePackageForUsers(UserHandle[] users, String packageName, int uid) { - for (final UserHandle user : users) { - mPermissionMonitor.onPackageRemoved(packageName, user.getUid(uid)); - } - } - - private class NetdServiceMonitor { - private final HashMap<Integer, Integer> mPermissions = new HashMap<>(); - - NetdServiceMonitor(INetd mockNetdService) throws Exception { - // Add hook to verify and track result of setPermission. - doAnswer((InvocationOnMock invocation) -> { - final Object[] args = invocation.getArguments(); - final int permission = (int) args[0]; - for (final int uid : (int[]) args[1]) { - mPermissions.put(uid, permission); - } - return null; - }).when(mockNetdService).trafficSetNetPermForUids(anyInt(), any(int[].class)); - } - - public void expectPermission(int permission, int[] apps) { - for (final int app : apps) { - if (!mPermissions.containsKey(app)) { - fail("uid " + app + " does not exist."); - } - if (mPermissions.get(app) != permission) { - fail("uid " + app + " has wrong permission: " + mPermissions.get(app)); - } - } - } - } - - @Test - public void testPackagePermissionUpdate() throws Exception { - final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService); - // MOCK_UID1: MOCK_PACKAGE1 only has internet permission. - // MOCK_UID2: MOCK_PACKAGE2 does not have any permission. - // SYSTEM_UID1: SYSTEM_PACKAGE1 has internet permission and update device stats permission. - // SYSTEM_UID2: SYSTEM_PACKAGE2 has only update device stats permission. - - SparseIntArray netdPermissionsAppIds = new SparseIntArray(); - netdPermissionsAppIds.put(MOCK_UID1, INetd.PERMISSION_INTERNET); - netdPermissionsAppIds.put(MOCK_UID2, INetd.PERMISSION_NONE); - netdPermissionsAppIds.put(SYSTEM_UID1, INetd.PERMISSION_INTERNET - | INetd.PERMISSION_UPDATE_DEVICE_STATS); - netdPermissionsAppIds.put(SYSTEM_UID2, INetd.PERMISSION_UPDATE_DEVICE_STATS); - - // Send the permission information to netd, expect permission updated. - mPermissionMonitor.sendPackagePermissionsToNetd(netdPermissionsAppIds); - - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, - new int[]{MOCK_UID1}); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID2}); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET - | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{SYSTEM_UID1}); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UPDATE_DEVICE_STATS, - new int[]{SYSTEM_UID2}); - - // Update permission of MOCK_UID1, expect new permission show up. - mPermissionMonitor.sendPackagePermissionsForUid(MOCK_UID1, - INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET - | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1}); - - // Change permissions of SYSTEM_UID2, expect new permission show up and old permission - // revoked. - mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID2, - INetd.PERMISSION_INTERNET); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{SYSTEM_UID2}); - - // Revoke permission from SYSTEM_UID1, expect no permission stored. - mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID1, INetd.PERMISSION_NONE); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{SYSTEM_UID1}); - } - - private PackageInfo setPackagePermissions(String packageName, int uid, String[] permissions) - throws Exception { - PackageInfo packageInfo = packageInfoWithPermissions( - REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM); - when(mPackageManager.getPackageInfo(eq(packageName), anyInt())).thenReturn(packageInfo); - when(mPackageManager.getPackagesForUid(eq(uid))).thenReturn(new String[]{packageName}); - return packageInfo; - } - - private PackageInfo addPackage(String packageName, int uid, String[] permissions) - throws Exception { - PackageInfo packageInfo = setPackagePermissions(packageName, uid, permissions); - mPermissionMonitor.onPackageAdded(packageName, uid); - return packageInfo; - } - - @Test - public void testPackageInstall() throws Exception { - final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService); - - addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS}); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET - | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1}); - - addPackage(MOCK_PACKAGE2, MOCK_UID2, new String[] {INTERNET}); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID2}); - } - - @Test - public void testPackageInstallSharedUid() throws Exception { - final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService); - - PackageInfo packageInfo1 = addPackage(MOCK_PACKAGE1, MOCK_UID1, - new String[] {INTERNET, UPDATE_DEVICE_STATS}); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET - | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1}); - - // Install another package with the same uid and no permissions should not cause the UID to - // lose permissions. - PackageInfo packageInfo2 = systemPackageInfoWithPermissions(); - when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2); - when(mPackageManager.getPackagesForUid(MOCK_UID1)) - .thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2}); - mPermissionMonitor.onPackageAdded(MOCK_PACKAGE2, MOCK_UID1); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET - | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1}); - } - - @Test - public void testPackageUninstallBasic() throws Exception { - final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService); - - addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS}); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET - | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1}); - - when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{}); - mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1}); - } - - @Test - public void testPackageRemoveThenAdd() throws Exception { - final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService); - - addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS}); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET - | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1}); - - when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{}); - mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1}); - - addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET}); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1}); - } - - @Test - public void testPackageUpdate() throws Exception { - final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService); - - addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {}); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID1}); - - addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET}); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1}); - } - - @Test - public void testPackageUninstallWithMultiplePackages() throws Exception { - final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService); - - addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS}); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET - | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1}); - - // Mock another package with the same uid but different permissions. - PackageInfo packageInfo2 = systemPackageInfoWithPermissions(INTERNET); - when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2); - when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{ - MOCK_PACKAGE2}); - - mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1}); - } - - @Test - public void testRealSystemPermission() throws Exception { - // Use the real context as this test must ensure the *real* system package holds the - // necessary permission. - final Context realContext = InstrumentationRegistry.getContext(); - final PermissionMonitor monitor = new PermissionMonitor(realContext, mNetdService); - final PackageManager manager = realContext.getPackageManager(); - final PackageInfo systemInfo = manager.getPackageInfo(REAL_SYSTEM_PACKAGE_NAME, - GET_PERMISSIONS | MATCH_ANY_USER); - assertTrue(monitor.hasPermission(systemInfo, CONNECTIVITY_USE_RESTRICTED_NETWORKS)); - } - - @Test - public void testUpdateUidPermissionsFromSystemConfig() throws Exception { - final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService); - when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(new ArrayList<>()); - when(mSystemConfigManager.getSystemPermissionUids(eq(INTERNET))) - .thenReturn(new int[]{ MOCK_UID1, MOCK_UID2 }); - when(mSystemConfigManager.getSystemPermissionUids(eq(UPDATE_DEVICE_STATS))) - .thenReturn(new int[]{ MOCK_UID2 }); - - mPermissionMonitor.startMonitoring(); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{ MOCK_UID1 }); - mNetdServiceMonitor.expectPermission( - INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS, - new int[]{ MOCK_UID2 }); - } - - @Test - public void testIntentReceiver() throws Exception { - final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService); - final ArgumentCaptor<BroadcastReceiver> receiverCaptor = - ArgumentCaptor.forClass(BroadcastReceiver.class); - verify(mContext, times(1)).registerReceiver(receiverCaptor.capture(), any(), any(), any()); - final BroadcastReceiver receiver = receiverCaptor.getValue(); - - // Verify receiving PACKAGE_ADDED intent. - final Intent addedIntent = new Intent(Intent.ACTION_PACKAGE_ADDED, - Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */)); - addedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID1); - setPackagePermissions(MOCK_PACKAGE1, MOCK_UID1, - new String[] { INTERNET, UPDATE_DEVICE_STATS }); - receiver.onReceive(mContext, addedIntent); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET - | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[] { MOCK_UID1 }); - - // Verify receiving PACKAGE_REMOVED intent. - when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(null); - final Intent removedIntent = new Intent(Intent.ACTION_PACKAGE_REMOVED, - Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */)); - removedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID1); - receiver.onReceive(mContext, removedIntent); - mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[] { MOCK_UID1 }); - } - -} diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java deleted file mode 100644 index b725b826b14f..000000000000 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ /dev/null @@ -1,1283 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.connectivity; - -import static android.content.pm.UserInfo.FLAG_ADMIN; -import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE; -import static android.content.pm.UserInfo.FLAG_PRIMARY; -import static android.content.pm.UserInfo.FLAG_RESTRICTED; -import static android.net.ConnectivityManager.NetworkCallback; -import static android.net.INetd.IF_STATE_DOWN; -import static android.net.INetd.IF_STATE_UP; -import static android.os.UserHandle.PER_USER_RANGE; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.annotation.NonNull; -import android.annotation.UserIdInt; -import android.app.AppOpsManager; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.pm.ServiceInfo; -import android.content.pm.UserInfo; -import android.content.res.Resources; -import android.net.ConnectivityManager; -import android.net.INetd; -import android.net.Ikev2VpnProfile; -import android.net.InetAddresses; -import android.net.InterfaceConfigurationParcel; -import android.net.IpPrefix; -import android.net.IpSecManager; -import android.net.IpSecTunnelInterfaceResponse; -import android.net.LinkProperties; -import android.net.LocalSocket; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo.DetailedState; -import android.net.RouteInfo; -import android.net.UidRangeParcel; -import android.net.VpnManager; -import android.net.VpnService; -import android.net.VpnTransportInfo; -import android.net.ipsec.ike.IkeSessionCallback; -import android.net.ipsec.ike.exceptions.IkeProtocolException; -import android.os.Build.VERSION_CODES; -import android.os.Bundle; -import android.os.ConditionVariable; -import android.os.INetworkManagementService; -import android.os.Process; -import android.os.UserHandle; -import android.os.UserManager; -import android.os.test.TestLooper; -import android.provider.Settings; -import android.security.Credentials; -import android.util.ArrayMap; -import android.util.ArraySet; -import android.util.Range; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.internal.R; -import com.android.internal.net.LegacyVpnInfo; -import com.android.internal.net.VpnConfig; -import com.android.internal.net.VpnProfile; -import com.android.server.IpSecService; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.AdditionalAnswers; -import org.mockito.Answers; -import org.mockito.ArgumentCaptor; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.net.Inet4Address; -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; -import java.util.stream.Stream; - -/** - * Tests for {@link Vpn}. - * - * Build, install and run with: - * runtest frameworks-net -c com.android.server.connectivity.VpnTest - */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class VpnTest { - private static final String TAG = "VpnTest"; - - // Mock users - static final UserInfo primaryUser = new UserInfo(27, "Primary", FLAG_ADMIN | FLAG_PRIMARY); - static final UserInfo secondaryUser = new UserInfo(15, "Secondary", FLAG_ADMIN); - static final UserInfo restrictedProfileA = new UserInfo(40, "RestrictedA", FLAG_RESTRICTED); - static final UserInfo restrictedProfileB = new UserInfo(42, "RestrictedB", FLAG_RESTRICTED); - static final UserInfo managedProfileA = new UserInfo(45, "ManagedA", FLAG_MANAGED_PROFILE); - static { - restrictedProfileA.restrictedProfileParentId = primaryUser.id; - restrictedProfileB.restrictedProfileParentId = secondaryUser.id; - managedProfileA.profileGroupId = primaryUser.id; - } - - static final Network EGRESS_NETWORK = new Network(101); - static final String EGRESS_IFACE = "wlan0"; - static final String TEST_VPN_PKG = "com.testvpn.vpn"; - private static final String TEST_VPN_SERVER = "1.2.3.4"; - private static final String TEST_VPN_IDENTITY = "identity"; - private static final byte[] TEST_VPN_PSK = "psk".getBytes(); - - private static final Network TEST_NETWORK = new Network(Integer.MAX_VALUE); - private static final String TEST_IFACE_NAME = "TEST_IFACE"; - private static final int TEST_TUNNEL_RESOURCE_ID = 0x2345; - private static final long TEST_TIMEOUT_MS = 500L; - - /** - * Names and UIDs for some fake packages. Important points: - * - UID is ordered increasing. - * - One pair of packages have consecutive UIDs. - */ - static final String[] PKGS = {"com.example", "org.example", "net.example", "web.vpn"}; - static final int[] PKG_UIDS = {66, 77, 78, 400}; - - // Mock packages - static final Map<String, Integer> mPackages = new ArrayMap<>(); - static { - for (int i = 0; i < PKGS.length; i++) { - mPackages.put(PKGS[i], PKG_UIDS[i]); - } - } - private static final Range<Integer> PRI_USER_RANGE = uidRangeForUser(primaryUser.id); - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; - @Mock private UserManager mUserManager; - @Mock private PackageManager mPackageManager; - @Mock private INetworkManagementService mNetService; - @Mock private INetd mNetd; - @Mock private AppOpsManager mAppOps; - @Mock private NotificationManager mNotificationManager; - @Mock private Vpn.SystemServices mSystemServices; - @Mock private Vpn.Ikev2SessionCreator mIkev2SessionCreator; - @Mock private ConnectivityManager mConnectivityManager; - @Mock private IpSecService mIpSecService; - @Mock private VpnProfileStore mVpnProfileStore; - private final VpnProfile mVpnProfile; - - private IpSecManager mIpSecManager; - - public VpnTest() throws Exception { - // Build an actual VPN profile that is capable of being converted to and from an - // Ikev2VpnProfile - final Ikev2VpnProfile.Builder builder = - new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY); - builder.setAuthPsk(TEST_VPN_PSK); - mVpnProfile = builder.build().toVpnProfile(); - } - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - mIpSecManager = new IpSecManager(mContext, mIpSecService); - - when(mContext.getPackageManager()).thenReturn(mPackageManager); - setMockedPackages(mPackages); - - when(mContext.getPackageName()).thenReturn(TEST_VPN_PKG); - when(mContext.getOpPackageName()).thenReturn(TEST_VPN_PKG); - when(mContext.getSystemServiceName(UserManager.class)) - .thenReturn(Context.USER_SERVICE); - when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager); - when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps); - when(mContext.getSystemServiceName(NotificationManager.class)) - .thenReturn(Context.NOTIFICATION_SERVICE); - when(mContext.getSystemService(eq(Context.NOTIFICATION_SERVICE))) - .thenReturn(mNotificationManager); - when(mContext.getSystemService(eq(Context.CONNECTIVITY_SERVICE))) - .thenReturn(mConnectivityManager); - when(mContext.getSystemServiceName(eq(ConnectivityManager.class))) - .thenReturn(Context.CONNECTIVITY_SERVICE); - when(mContext.getSystemService(eq(Context.IPSEC_SERVICE))).thenReturn(mIpSecManager); - when(mContext.getString(R.string.config_customVpnAlwaysOnDisconnectedDialogComponent)) - .thenReturn(Resources.getSystem().getString( - R.string.config_customVpnAlwaysOnDisconnectedDialogComponent)); - when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS)) - .thenReturn(true); - - // Used by {@link Notification.Builder} - ApplicationInfo applicationInfo = new ApplicationInfo(); - applicationInfo.targetSdkVersion = VERSION_CODES.CUR_DEVELOPMENT; - when(mContext.getApplicationInfo()).thenReturn(applicationInfo); - when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) - .thenReturn(applicationInfo); - - doNothing().when(mNetService).registerObserver(any()); - - // Deny all appops by default. - when(mAppOps.noteOpNoThrow(anyString(), anyInt(), anyString(), any(), any())) - .thenReturn(AppOpsManager.MODE_IGNORED); - - // Setup IpSecService - final IpSecTunnelInterfaceResponse tunnelResp = - new IpSecTunnelInterfaceResponse( - IpSecManager.Status.OK, TEST_TUNNEL_RESOURCE_ID, TEST_IFACE_NAME); - when(mIpSecService.createTunnelInterface(any(), any(), any(), any(), any())) - .thenReturn(tunnelResp); - } - - private Set<Range<Integer>> rangeSet(Range<Integer> ... ranges) { - final Set<Range<Integer>> range = new ArraySet<>(); - for (Range<Integer> r : ranges) range.add(r); - - return range; - } - - private static Range<Integer> uidRangeForUser(int userId) { - return new Range<Integer>(userId * PER_USER_RANGE, (userId + 1) * PER_USER_RANGE - 1); - } - - private Range<Integer> uidRange(int start, int stop) { - return new Range<Integer>(start, stop); - } - - @Test - public void testRestrictedProfilesAreAddedToVpn() { - setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB); - - final Vpn vpn = createVpn(primaryUser.id); - - // Assume the user can have restricted profiles. - doReturn(true).when(mUserManager).canHaveRestrictedProfile(); - final Set<Range<Integer>> ranges = - vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, null, null); - - assertEquals(rangeSet(PRI_USER_RANGE, uidRangeForUser(restrictedProfileA.id)), ranges); - } - - @Test - public void testManagedProfilesAreNotAddedToVpn() { - setMockedUsers(primaryUser, managedProfileA); - - final Vpn vpn = createVpn(primaryUser.id); - final Set<Range<Integer>> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, - null, null); - - assertEquals(rangeSet(PRI_USER_RANGE), ranges); - } - - @Test - public void testAddUserToVpnOnlyAddsOneUser() { - setMockedUsers(primaryUser, restrictedProfileA, managedProfileA); - - final Vpn vpn = createVpn(primaryUser.id); - final Set<Range<Integer>> ranges = new ArraySet<>(); - vpn.addUserToRanges(ranges, primaryUser.id, null, null); - - assertEquals(rangeSet(PRI_USER_RANGE), ranges); - } - - @Test - public void testUidAllowAndDenylist() throws Exception { - final Vpn vpn = createVpn(primaryUser.id); - final Range<Integer> user = PRI_USER_RANGE; - final int userStart = user.getLower(); - final int userStop = user.getUpper(); - final String[] packages = {PKGS[0], PKGS[1], PKGS[2]}; - - // Allowed list - final Set<Range<Integer>> allow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, - Arrays.asList(packages), null /* disallowedApplications */); - assertEquals(rangeSet( - uidRange(userStart + PKG_UIDS[0], userStart + PKG_UIDS[0]), - uidRange(userStart + PKG_UIDS[1], userStart + PKG_UIDS[2])), - allow); - - // Denied list - final Set<Range<Integer>> disallow = - vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, - null /* allowedApplications */, Arrays.asList(packages)); - assertEquals(rangeSet( - uidRange(userStart, userStart + PKG_UIDS[0] - 1), - uidRange(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1), - /* Empty range between UIDS[1] and UIDS[2], should be excluded, */ - uidRange(userStart + PKG_UIDS[2] + 1, userStop)), - disallow); - } - - @Test - public void testGetAlwaysAndOnGetLockDown() throws Exception { - final Vpn vpn = createVpn(primaryUser.id); - - // Default state. - assertFalse(vpn.getAlwaysOn()); - assertFalse(vpn.getLockdown()); - - // Set always-on without lockdown. - assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, Collections.emptyList())); - assertTrue(vpn.getAlwaysOn()); - assertFalse(vpn.getLockdown()); - - // Set always-on with lockdown. - assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, Collections.emptyList())); - assertTrue(vpn.getAlwaysOn()); - assertTrue(vpn.getLockdown()); - - // Remove always-on configuration. - assertTrue(vpn.setAlwaysOnPackage(null, false, Collections.emptyList())); - assertFalse(vpn.getAlwaysOn()); - assertFalse(vpn.getLockdown()); - } - - @Test - public void testLockdownChangingPackage() throws Exception { - final Vpn vpn = createVpn(primaryUser.id); - final Range<Integer> user = PRI_USER_RANGE; - final int userStart = user.getLower(); - final int userStop = user.getUpper(); - // Set always-on without lockdown. - assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, null)); - - // Set always-on with lockdown. - assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, null)); - verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), - new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop) - })); - - // Switch to another app. - assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null)); - verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), - new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop) - })); - verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart, userStart + PKG_UIDS[3] - 1), - new UidRangeParcel(userStart + PKG_UIDS[3] + 1, userStop) - })); - } - - @Test - public void testLockdownAllowlist() throws Exception { - final Vpn vpn = createVpn(primaryUser.id); - final Range<Integer> user = PRI_USER_RANGE; - final int userStart = user.getLower(); - final int userStop = user.getUpper(); - // Set always-on with lockdown and allow app PKGS[2] from lockdown. - assertTrue(vpn.setAlwaysOnPackage( - PKGS[1], true, Collections.singletonList(PKGS[2]))); - verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), - new UidRangeParcel(userStart + PKG_UIDS[2] + 1, userStop) - })); - // Change allowed app list to PKGS[3]. - assertTrue(vpn.setAlwaysOnPackage( - PKGS[1], true, Collections.singletonList(PKGS[3]))); - verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart + PKG_UIDS[2] + 1, userStop) - })); - verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStart + PKG_UIDS[3] - 1), - new UidRangeParcel(userStart + PKG_UIDS[3] + 1, userStop) - })); - - // Change the VPN app. - assertTrue(vpn.setAlwaysOnPackage( - PKGS[0], true, Collections.singletonList(PKGS[3]))); - verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), - new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStart + PKG_UIDS[3] - 1) - })); - verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart, userStart + PKG_UIDS[0] - 1), - new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[3] - 1) - })); - - // Remove the list of allowed packages. - assertTrue(vpn.setAlwaysOnPackage(PKGS[0], true, null)); - verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[3] - 1), - new UidRangeParcel(userStart + PKG_UIDS[3] + 1, userStop) - })); - verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStop), - })); - - // Add the list of allowed packages. - assertTrue(vpn.setAlwaysOnPackage( - PKGS[0], true, Collections.singletonList(PKGS[1]))); - verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStop) - })); - verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1), - new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop) - })); - - // Try allowing a package with a comma, should be rejected. - assertFalse(vpn.setAlwaysOnPackage( - PKGS[0], true, Collections.singletonList("a.b,c.d"))); - - // Pass a non-existent packages in the allowlist, they (and only they) should be ignored. - // allowed package should change from PGKS[1] to PKGS[2]. - assertTrue(vpn.setAlwaysOnPackage( - PKGS[0], true, Arrays.asList("com.foo.app", PKGS[2], "com.bar.app"))); - verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1), - new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop) - })); - verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { - new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[2] - 1), - new UidRangeParcel(userStart + PKG_UIDS[2] + 1, userStop) - })); - } - - @Test - public void testLockdownRuleRepeatability() throws Exception { - final Vpn vpn = createVpn(primaryUser.id); - final UidRangeParcel[] primaryUserRangeParcel = new UidRangeParcel[] { - new UidRangeParcel(PRI_USER_RANGE.getLower(), PRI_USER_RANGE.getUpper())}; - // Given legacy lockdown is already enabled, - vpn.setLockdown(true); - verify(mConnectivityManager, times(1)).setRequireVpnForUids(true, - toRanges(primaryUserRangeParcel)); - - // Enabling legacy lockdown twice should do nothing. - vpn.setLockdown(true); - verify(mConnectivityManager, times(1)).setRequireVpnForUids(anyBoolean(), any()); - - // And disabling should remove the rules exactly once. - vpn.setLockdown(false); - verify(mConnectivityManager, times(1)).setRequireVpnForUids(false, - toRanges(primaryUserRangeParcel)); - - // Removing the lockdown again should have no effect. - vpn.setLockdown(false); - verify(mConnectivityManager, times(2)).setRequireVpnForUids(anyBoolean(), any()); - } - - private ArrayList<Range<Integer>> toRanges(UidRangeParcel[] ranges) { - ArrayList<Range<Integer>> rangesArray = new ArrayList<>(ranges.length); - for (int i = 0; i < ranges.length; i++) { - rangesArray.add(new Range<>(ranges[i].start, ranges[i].stop)); - } - return rangesArray; - } - - @Test - public void testLockdownRuleReversibility() throws Exception { - final Vpn vpn = createVpn(primaryUser.id); - final UidRangeParcel[] entireUser = { - new UidRangeParcel(PRI_USER_RANGE.getLower(), PRI_USER_RANGE.getUpper()) - }; - final UidRangeParcel[] exceptPkg0 = { - new UidRangeParcel(entireUser[0].start, entireUser[0].start + PKG_UIDS[0] - 1), - new UidRangeParcel(entireUser[0].start + PKG_UIDS[0] + 1, entireUser[0].stop) - }; - - final InOrder order = inOrder(mConnectivityManager); - - // Given lockdown is enabled with no package (legacy VPN), - vpn.setLockdown(true); - order.verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(entireUser)); - - // When a new VPN package is set the rules should change to cover that package. - vpn.prepare(null, PKGS[0], VpnManager.TYPE_VPN_SERVICE); - order.verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(entireUser)); - order.verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(exceptPkg0)); - - // When that VPN package is unset, everything should be undone again in reverse. - vpn.prepare(null, VpnConfig.LEGACY_VPN, VpnManager.TYPE_VPN_SERVICE); - order.verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(exceptPkg0)); - order.verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(entireUser)); - } - - @Test - public void testIsAlwaysOnPackageSupported() throws Exception { - final Vpn vpn = createVpn(primaryUser.id); - - ApplicationInfo appInfo = new ApplicationInfo(); - when(mPackageManager.getApplicationInfoAsUser(eq(PKGS[0]), anyInt(), eq(primaryUser.id))) - .thenReturn(appInfo); - - ServiceInfo svcInfo = new ServiceInfo(); - ResolveInfo resInfo = new ResolveInfo(); - resInfo.serviceInfo = svcInfo; - when(mPackageManager.queryIntentServicesAsUser(any(), eq(PackageManager.GET_META_DATA), - eq(primaryUser.id))) - .thenReturn(Collections.singletonList(resInfo)); - - // null package name should return false - assertFalse(vpn.isAlwaysOnPackageSupported(null)); - - // Pre-N apps are not supported - appInfo.targetSdkVersion = VERSION_CODES.M; - assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0])); - - // N+ apps are supported by default - appInfo.targetSdkVersion = VERSION_CODES.N; - assertTrue(vpn.isAlwaysOnPackageSupported(PKGS[0])); - - // Apps that opt out explicitly are not supported - appInfo.targetSdkVersion = VERSION_CODES.CUR_DEVELOPMENT; - Bundle metaData = new Bundle(); - metaData.putBoolean(VpnService.SERVICE_META_DATA_SUPPORTS_ALWAYS_ON, false); - svcInfo.metaData = metaData; - assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0])); - } - - @Test - public void testNotificationShownForAlwaysOnApp() throws Exception { - final UserHandle userHandle = UserHandle.of(primaryUser.id); - final Vpn vpn = createVpn(primaryUser.id); - setMockedUsers(primaryUser); - - final InOrder order = inOrder(mNotificationManager); - - // Don't show a notification for regular disconnected states. - vpn.updateState(DetailedState.DISCONNECTED, TAG); - order.verify(mNotificationManager, atLeastOnce()).cancel(anyString(), anyInt()); - - // Start showing a notification for disconnected once always-on. - vpn.setAlwaysOnPackage(PKGS[0], false, null); - order.verify(mNotificationManager).notify(anyString(), anyInt(), any()); - - // Stop showing the notification once connected. - vpn.updateState(DetailedState.CONNECTED, TAG); - order.verify(mNotificationManager).cancel(anyString(), anyInt()); - - // Show the notification if we disconnect again. - vpn.updateState(DetailedState.DISCONNECTED, TAG); - order.verify(mNotificationManager).notify(anyString(), anyInt(), any()); - - // Notification should be cleared after unsetting always-on package. - vpn.setAlwaysOnPackage(null, false, null); - order.verify(mNotificationManager).cancel(anyString(), anyInt()); - } - - /** - * The profile name should NOT change between releases for backwards compatibility - * - * <p>If this is changed between releases, the {@link Vpn#getVpnProfilePrivileged()} method MUST - * be updated to ensure backward compatibility. - */ - @Test - public void testGetProfileNameForPackage() throws Exception { - final Vpn vpn = createVpn(primaryUser.id); - setMockedUsers(primaryUser); - - final String expected = Credentials.PLATFORM_VPN + primaryUser.id + "_" + TEST_VPN_PKG; - assertEquals(expected, vpn.getProfileNameForPackage(TEST_VPN_PKG)); - } - - private Vpn createVpnAndSetupUidChecks(String... grantedOps) throws Exception { - return createVpnAndSetupUidChecks(primaryUser, grantedOps); - } - - private Vpn createVpnAndSetupUidChecks(UserInfo user, String... grantedOps) throws Exception { - final Vpn vpn = createVpn(user.id); - setMockedUsers(user); - - when(mPackageManager.getPackageUidAsUser(eq(TEST_VPN_PKG), anyInt())) - .thenReturn(Process.myUid()); - - for (final String opStr : grantedOps) { - when(mAppOps.noteOpNoThrow(opStr, Process.myUid(), TEST_VPN_PKG, - null /* attributionTag */, null /* message */)) - .thenReturn(AppOpsManager.MODE_ALLOWED); - } - - return vpn; - } - - private void checkProvisionVpnProfile(Vpn vpn, boolean expectedResult, String... checkedOps) { - assertEquals(expectedResult, vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile)); - - // The profile should always be stored, whether or not consent has been previously granted. - verify(mVpnProfileStore) - .put( - eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)), - eq(mVpnProfile.encode())); - - for (final String checkedOpStr : checkedOps) { - verify(mAppOps).noteOpNoThrow(checkedOpStr, Process.myUid(), TEST_VPN_PKG, - null /* attributionTag */, null /* message */); - } - } - - @Test - public void testProvisionVpnProfileNoIpsecTunnels() throws Exception { - when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS)) - .thenReturn(false); - final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); - - try { - checkProvisionVpnProfile( - vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); - fail("Expected exception due to missing feature"); - } catch (UnsupportedOperationException expected) { - } - } - - @Test - public void testProvisionVpnProfilePreconsented() throws Exception { - final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); - - checkProvisionVpnProfile( - vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); - } - - @Test - public void testProvisionVpnProfileNotPreconsented() throws Exception { - final Vpn vpn = createVpnAndSetupUidChecks(); - - // Expect that both the ACTIVATE_VPN and ACTIVATE_PLATFORM_VPN were tried, but the caller - // had neither. - checkProvisionVpnProfile(vpn, false /* expectedResult */, - AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN, AppOpsManager.OPSTR_ACTIVATE_VPN); - } - - @Test - public void testProvisionVpnProfileVpnServicePreconsented() throws Exception { - final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_VPN); - - checkProvisionVpnProfile(vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_VPN); - } - - @Test - public void testProvisionVpnProfileTooLarge() throws Exception { - final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); - - final VpnProfile bigProfile = new VpnProfile(""); - bigProfile.name = new String(new byte[Vpn.MAX_VPN_PROFILE_SIZE_BYTES + 1]); - - try { - vpn.provisionVpnProfile(TEST_VPN_PKG, bigProfile); - fail("Expected IAE due to profile size"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testProvisionVpnProfileRestrictedUser() throws Exception { - final Vpn vpn = - createVpnAndSetupUidChecks( - restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); - - try { - vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile); - fail("Expected SecurityException due to restricted user"); - } catch (SecurityException expected) { - } - } - - @Test - public void testDeleteVpnProfile() throws Exception { - final Vpn vpn = createVpnAndSetupUidChecks(); - - vpn.deleteVpnProfile(TEST_VPN_PKG); - - verify(mVpnProfileStore) - .remove(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); - } - - @Test - public void testDeleteVpnProfileRestrictedUser() throws Exception { - final Vpn vpn = - createVpnAndSetupUidChecks( - restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); - - try { - vpn.deleteVpnProfile(TEST_VPN_PKG); - fail("Expected SecurityException due to restricted user"); - } catch (SecurityException expected) { - } - } - - @Test - public void testGetVpnProfilePrivileged() throws Exception { - final Vpn vpn = createVpnAndSetupUidChecks(); - - when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) - .thenReturn(new VpnProfile("").encode()); - - vpn.getVpnProfilePrivileged(TEST_VPN_PKG); - - verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); - } - - @Test - public void testStartVpnProfile() throws Exception { - final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); - - when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) - .thenReturn(mVpnProfile.encode()); - - vpn.startVpnProfile(TEST_VPN_PKG); - - verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); - verify(mAppOps) - .noteOpNoThrow( - eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), - eq(Process.myUid()), - eq(TEST_VPN_PKG), - eq(null) /* attributionTag */, - eq(null) /* message */); - } - - @Test - public void testStartVpnProfileVpnServicePreconsented() throws Exception { - final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_VPN); - - when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) - .thenReturn(mVpnProfile.encode()); - - vpn.startVpnProfile(TEST_VPN_PKG); - - // Verify that the the ACTIVATE_VPN appop was checked, but no error was thrown. - verify(mAppOps).noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_VPN, Process.myUid(), - TEST_VPN_PKG, null /* attributionTag */, null /* message */); - } - - @Test - public void testStartVpnProfileNotConsented() throws Exception { - final Vpn vpn = createVpnAndSetupUidChecks(); - - try { - vpn.startVpnProfile(TEST_VPN_PKG); - fail("Expected failure due to no user consent"); - } catch (SecurityException expected) { - } - - // Verify both appops were checked. - verify(mAppOps) - .noteOpNoThrow( - eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), - eq(Process.myUid()), - eq(TEST_VPN_PKG), - eq(null) /* attributionTag */, - eq(null) /* message */); - verify(mAppOps).noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_VPN, Process.myUid(), - TEST_VPN_PKG, null /* attributionTag */, null /* message */); - - // Keystore should never have been accessed. - verify(mVpnProfileStore, never()).get(any()); - } - - @Test - public void testStartVpnProfileMissingProfile() throws Exception { - final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); - - when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))).thenReturn(null); - - try { - vpn.startVpnProfile(TEST_VPN_PKG); - fail("Expected failure due to missing profile"); - } catch (IllegalArgumentException expected) { - } - - verify(mVpnProfileStore).get(vpn.getProfileNameForPackage(TEST_VPN_PKG)); - verify(mAppOps) - .noteOpNoThrow( - eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), - eq(Process.myUid()), - eq(TEST_VPN_PKG), - eq(null) /* attributionTag */, - eq(null) /* message */); - } - - @Test - public void testStartVpnProfileRestrictedUser() throws Exception { - final Vpn vpn = - createVpnAndSetupUidChecks( - restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); - - try { - vpn.startVpnProfile(TEST_VPN_PKG); - fail("Expected SecurityException due to restricted user"); - } catch (SecurityException expected) { - } - } - - @Test - public void testStopVpnProfileRestrictedUser() throws Exception { - final Vpn vpn = - createVpnAndSetupUidChecks( - restrictedProfileA, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); - - try { - vpn.stopVpnProfile(TEST_VPN_PKG); - fail("Expected SecurityException due to restricted user"); - } catch (SecurityException expected) { - } - } - - @Test - public void testSetPackageAuthorizationVpnService() throws Exception { - final Vpn vpn = createVpnAndSetupUidChecks(); - - assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_SERVICE)); - verify(mAppOps) - .setMode( - eq(AppOpsManager.OPSTR_ACTIVATE_VPN), - eq(Process.myUid()), - eq(TEST_VPN_PKG), - eq(AppOpsManager.MODE_ALLOWED)); - } - - @Test - public void testSetPackageAuthorizationPlatformVpn() throws Exception { - final Vpn vpn = createVpnAndSetupUidChecks(); - - assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_PLATFORM)); - verify(mAppOps) - .setMode( - eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), - eq(Process.myUid()), - eq(TEST_VPN_PKG), - eq(AppOpsManager.MODE_ALLOWED)); - } - - @Test - public void testSetPackageAuthorizationRevokeAuthorization() throws Exception { - final Vpn vpn = createVpnAndSetupUidChecks(); - - assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_NONE)); - verify(mAppOps) - .setMode( - eq(AppOpsManager.OPSTR_ACTIVATE_VPN), - eq(Process.myUid()), - eq(TEST_VPN_PKG), - eq(AppOpsManager.MODE_IGNORED)); - verify(mAppOps) - .setMode( - eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), - eq(Process.myUid()), - eq(TEST_VPN_PKG), - eq(AppOpsManager.MODE_IGNORED)); - } - - private NetworkCallback triggerOnAvailableAndGetCallback() throws Exception { - final ArgumentCaptor<NetworkCallback> networkCallbackCaptor = - ArgumentCaptor.forClass(NetworkCallback.class); - verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)) - .requestNetwork(any(), networkCallbackCaptor.capture()); - - // onAvailable() will trigger onDefaultNetworkChanged(), so NetdUtils#setInterfaceUp will be - // invoked. Set the return value of INetd#interfaceGetCfg to prevent NullPointerException. - final InterfaceConfigurationParcel config = new InterfaceConfigurationParcel(); - config.flags = new String[] {IF_STATE_DOWN}; - when(mNetd.interfaceGetCfg(anyString())).thenReturn(config); - final NetworkCallback cb = networkCallbackCaptor.getValue(); - cb.onAvailable(TEST_NETWORK); - return cb; - } - - private void verifyInterfaceSetCfgWithFlags(String flag) throws Exception { - // Add a timeout for waiting for interfaceSetCfg to be called. - verify(mNetd, timeout(TEST_TIMEOUT_MS)).interfaceSetCfg(argThat( - config -> Arrays.asList(config.flags).contains(flag))); - } - - @Test - public void testStartPlatformVpnAuthenticationFailed() throws Exception { - final ArgumentCaptor<IkeSessionCallback> captor = - ArgumentCaptor.forClass(IkeSessionCallback.class); - final IkeProtocolException exception = mock(IkeProtocolException.class); - when(exception.getErrorType()) - .thenReturn(IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED); - - final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), (mVpnProfile)); - final NetworkCallback cb = triggerOnAvailableAndGetCallback(); - - verifyInterfaceSetCfgWithFlags(IF_STATE_UP); - - // Wait for createIkeSession() to be called before proceeding in order to ensure consistent - // state - verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS)) - .createIkeSession(any(), any(), any(), any(), captor.capture(), any()); - final IkeSessionCallback ikeCb = captor.getValue(); - ikeCb.onClosedExceptionally(exception); - - verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb)); - assertEquals(LegacyVpnInfo.STATE_FAILED, vpn.getLegacyVpnInfo().state); - } - - @Test - public void testStartPlatformVpnIllegalArgumentExceptionInSetup() throws Exception { - when(mIkev2SessionCreator.createIkeSession(any(), any(), any(), any(), any(), any())) - .thenThrow(new IllegalArgumentException()); - final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), mVpnProfile); - final NetworkCallback cb = triggerOnAvailableAndGetCallback(); - - verifyInterfaceSetCfgWithFlags(IF_STATE_UP); - - // Wait for createIkeSession() to be called before proceeding in order to ensure consistent - // state - verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb)); - assertEquals(LegacyVpnInfo.STATE_FAILED, vpn.getLegacyVpnInfo().state); - } - - private void setAndVerifyAlwaysOnPackage(Vpn vpn, int uid, boolean lockdownEnabled) { - assertTrue(vpn.setAlwaysOnPackage(TEST_VPN_PKG, lockdownEnabled, null)); - - verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); - verify(mAppOps).setMode( - eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), eq(uid), eq(TEST_VPN_PKG), - eq(AppOpsManager.MODE_ALLOWED)); - - verify(mSystemServices).settingsSecurePutStringForUser( - eq(Settings.Secure.ALWAYS_ON_VPN_APP), eq(TEST_VPN_PKG), eq(primaryUser.id)); - verify(mSystemServices).settingsSecurePutIntForUser( - eq(Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN), eq(lockdownEnabled ? 1 : 0), - eq(primaryUser.id)); - verify(mSystemServices).settingsSecurePutStringForUser( - eq(Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN_WHITELIST), eq(""), eq(primaryUser.id)); - } - - @Test - public void testSetAndStartAlwaysOnVpn() throws Exception { - final Vpn vpn = createVpn(primaryUser.id); - setMockedUsers(primaryUser); - - // UID checks must return a different UID; otherwise it'll be treated as already prepared. - final int uid = Process.myUid() + 1; - when(mPackageManager.getPackageUidAsUser(eq(TEST_VPN_PKG), anyInt())) - .thenReturn(uid); - when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) - .thenReturn(mVpnProfile.encode()); - - setAndVerifyAlwaysOnPackage(vpn, uid, false); - assertTrue(vpn.startAlwaysOnVpn()); - - // TODO: Test the Ikev2VpnRunner started up properly. Relies on utility methods added in - // a subsequent CL. - } - - private Vpn startLegacyVpn(final Vpn vpn, final VpnProfile vpnProfile) throws Exception { - setMockedUsers(primaryUser); - - // Dummy egress interface - final LinkProperties lp = new LinkProperties(); - lp.setInterfaceName(EGRESS_IFACE); - - final RouteInfo defaultRoute = new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), - InetAddresses.parseNumericAddress("192.0.2.0"), EGRESS_IFACE); - lp.addRoute(defaultRoute); - - vpn.startLegacyVpn(vpnProfile, EGRESS_NETWORK, lp); - return vpn; - } - - @Test - public void testStartPlatformVpn() throws Exception { - startLegacyVpn(createVpn(primaryUser.id), mVpnProfile); - // TODO: Test the Ikev2VpnRunner started up properly. Relies on utility methods added in - // a subsequent patch. - } - - @Test - public void testStartRacoonNumericAddress() throws Exception { - startRacoon("1.2.3.4", "1.2.3.4"); - } - - @Test - public void testStartRacoonHostname() throws Exception { - startRacoon("hostname", "5.6.7.8"); // address returned by deps.resolve - } - - private void assertTransportInfoMatches(NetworkCapabilities nc, int type) { - assertNotNull(nc); - VpnTransportInfo ti = (VpnTransportInfo) nc.getTransportInfo(); - assertNotNull(ti); - assertEquals(type, ti.getType()); - } - - public void startRacoon(final String serverAddr, final String expectedAddr) - throws Exception { - final ConditionVariable legacyRunnerReady = new ConditionVariable(); - final VpnProfile profile = new VpnProfile("testProfile" /* key */); - profile.type = VpnProfile.TYPE_L2TP_IPSEC_PSK; - profile.name = "testProfileName"; - profile.username = "userName"; - profile.password = "thePassword"; - profile.server = serverAddr; - profile.ipsecIdentifier = "id"; - profile.ipsecSecret = "secret"; - profile.l2tpSecret = "l2tpsecret"; - - when(mConnectivityManager.getAllNetworks()) - .thenReturn(new Network[] { new Network(101) }); - - when(mConnectivityManager.registerNetworkAgent(any(), any(), any(), any(), - any(), any(), anyInt())).thenAnswer(invocation -> { - // The runner has registered an agent and is now ready. - legacyRunnerReady.open(); - return new Network(102); - }); - final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), profile); - final TestDeps deps = (TestDeps) vpn.mDeps; - try { - // udppsk and 1701 are the values for TYPE_L2TP_IPSEC_PSK - assertArrayEquals( - new String[] { EGRESS_IFACE, expectedAddr, "udppsk", - profile.ipsecIdentifier, profile.ipsecSecret, "1701" }, - deps.racoonArgs.get(10, TimeUnit.SECONDS)); - // literal values are hardcoded in Vpn.java for mtpd args - assertArrayEquals( - new String[] { EGRESS_IFACE, "l2tp", expectedAddr, "1701", profile.l2tpSecret, - "name", profile.username, "password", profile.password, - "linkname", "vpn", "refuse-eap", "nodefaultroute", "usepeerdns", - "idle", "1800", "mtu", "1270", "mru", "1270" }, - deps.mtpdArgs.get(10, TimeUnit.SECONDS)); - - // Now wait for the runner to be ready before testing for the route. - ArgumentCaptor<LinkProperties> lpCaptor = ArgumentCaptor.forClass(LinkProperties.class); - ArgumentCaptor<NetworkCapabilities> ncCaptor = - ArgumentCaptor.forClass(NetworkCapabilities.class); - verify(mConnectivityManager, timeout(10_000)).registerNetworkAgent(any(), any(), - lpCaptor.capture(), ncCaptor.capture(), any(), any(), anyInt()); - - // In this test the expected address is always v4 so /32. - // Note that the interface needs to be specified because RouteInfo objects stored in - // LinkProperties objects always acquire the LinkProperties' interface. - final RouteInfo expectedRoute = new RouteInfo(new IpPrefix(expectedAddr + "/32"), - null, EGRESS_IFACE, RouteInfo.RTN_THROW); - final List<RouteInfo> actualRoutes = lpCaptor.getValue().getRoutes(); - assertTrue("Expected throw route (" + expectedRoute + ") not found in " + actualRoutes, - actualRoutes.contains(expectedRoute)); - - assertTransportInfoMatches(ncCaptor.getValue(), VpnManager.TYPE_VPN_LEGACY); - } finally { - // Now interrupt the thread, unblock the runner and clean up. - vpn.mVpnRunner.exitVpnRunner(); - deps.getStateFile().delete(); // set to delete on exit, but this deletes it earlier - vpn.mVpnRunner.join(10_000); // wait for up to 10s for the runner to die and cleanup - } - } - - private static final class TestDeps extends Vpn.Dependencies { - public final CompletableFuture<String[]> racoonArgs = new CompletableFuture(); - public final CompletableFuture<String[]> mtpdArgs = new CompletableFuture(); - public final File mStateFile; - - private final HashMap<String, Boolean> mRunningServices = new HashMap<>(); - - TestDeps() { - try { - mStateFile = File.createTempFile("vpnTest", ".tmp"); - mStateFile.deleteOnExit(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public boolean isCallerSystem() { - return true; - } - - @Override - public void startService(final String serviceName) { - mRunningServices.put(serviceName, true); - } - - @Override - public void stopService(final String serviceName) { - mRunningServices.put(serviceName, false); - } - - @Override - public boolean isServiceRunning(final String serviceName) { - return mRunningServices.getOrDefault(serviceName, false); - } - - @Override - public boolean isServiceStopped(final String serviceName) { - return !isServiceRunning(serviceName); - } - - @Override - public File getStateFile() { - return mStateFile; - } - - @Override - public PendingIntent getIntentForStatusPanel(Context context) { - return null; - } - - @Override - public void sendArgumentsToDaemon( - final String daemon, final LocalSocket socket, final String[] arguments, - final Vpn.RetryScheduler interruptChecker) throws IOException { - if ("racoon".equals(daemon)) { - racoonArgs.complete(arguments); - } else if ("mtpd".equals(daemon)) { - writeStateFile(arguments); - mtpdArgs.complete(arguments); - } else { - throw new UnsupportedOperationException("Unsupported daemon : " + daemon); - } - } - - private void writeStateFile(final String[] arguments) throws IOException { - mStateFile.delete(); - mStateFile.createNewFile(); - mStateFile.deleteOnExit(); - final BufferedWriter writer = new BufferedWriter( - new FileWriter(mStateFile, false /* append */)); - writer.write(EGRESS_IFACE); - writer.write("\n"); - // addresses - writer.write("10.0.0.1/24\n"); - // routes - writer.write("192.168.6.0/24\n"); - // dns servers - writer.write("192.168.6.1\n"); - // search domains - writer.write("vpn.searchdomains.com\n"); - // endpoint - intentionally empty - writer.write("\n"); - writer.flush(); - writer.close(); - } - - @Override - @NonNull - public InetAddress resolve(final String endpoint) { - try { - // If a numeric IP address, return it. - return InetAddress.parseNumericAddress(endpoint); - } catch (IllegalArgumentException e) { - // Otherwise, return some token IP to test for. - return InetAddress.parseNumericAddress("5.6.7.8"); - } - } - - @Override - public boolean isInterfacePresent(final Vpn vpn, final String iface) { - return true; - } - } - - /** - * Mock some methods of vpn object. - */ - private Vpn createVpn(@UserIdInt int userId) { - final Context asUserContext = mock(Context.class, AdditionalAnswers.delegatesTo(mContext)); - doReturn(UserHandle.of(userId)).when(asUserContext).getUser(); - when(mContext.createContextAsUser(eq(UserHandle.of(userId)), anyInt())) - .thenReturn(asUserContext); - final TestLooper testLooper = new TestLooper(); - final Vpn vpn = new Vpn(testLooper.getLooper(), mContext, new TestDeps(), mNetService, - mNetd, userId, mVpnProfileStore, mSystemServices, mIkev2SessionCreator); - verify(mConnectivityManager, times(1)).registerNetworkProvider(argThat( - provider -> provider.getName().contains("VpnNetworkProvider") - )); - return vpn; - } - - /** - * Populate {@link #mUserManager} with a list of fake users. - */ - private void setMockedUsers(UserInfo... users) { - final Map<Integer, UserInfo> userMap = new ArrayMap<>(); - for (UserInfo user : users) { - userMap.put(user.id, user); - } - - /** - * @see UserManagerService#getUsers(boolean) - */ - doAnswer(invocation -> { - final ArrayList<UserInfo> result = new ArrayList<>(users.length); - for (UserInfo ui : users) { - if (ui.isEnabled() && !ui.partial) { - result.add(ui); - } - } - return result; - }).when(mUserManager).getAliveUsers(); - - doAnswer(invocation -> { - final int id = (int) invocation.getArguments()[0]; - return userMap.get(id); - }).when(mUserManager).getUserInfo(anyInt()); - } - - /** - * Populate {@link #mPackageManager} with a fake packageName-to-UID mapping. - */ - private void setMockedPackages(final Map<String, Integer> packages) { - try { - doAnswer(invocation -> { - final String appName = (String) invocation.getArguments()[0]; - final int userId = (int) invocation.getArguments()[1]; - Integer appId = packages.get(appName); - if (appId == null) throw new PackageManager.NameNotFoundException(appName); - return UserHandle.getUid(userId, appId); - }).when(mPackageManager).getPackageUidAsUser(anyString(), anyInt()); - } catch (Exception e) { - } - } - - private void setMockedNetworks(final Map<Network, NetworkCapabilities> networks) { - doAnswer(invocation -> { - final Network network = (Network) invocation.getArguments()[0]; - return networks.get(network); - }).when(mConnectivityManager).getNetworkCapabilities(any()); - } - - // Need multiple copies of this, but Java's Stream objects can't be reused or - // duplicated. - private Stream<String> publicIpV4Routes() { - return Stream.of( - "0.0.0.0/5", "8.0.0.0/7", "11.0.0.0/8", "12.0.0.0/6", "16.0.0.0/4", - "32.0.0.0/3", "64.0.0.0/2", "128.0.0.0/3", "160.0.0.0/5", "168.0.0.0/6", - "172.0.0.0/12", "172.32.0.0/11", "172.64.0.0/10", "172.128.0.0/9", - "173.0.0.0/8", "174.0.0.0/7", "176.0.0.0/4", "192.0.0.0/9", "192.128.0.0/11", - "192.160.0.0/13", "192.169.0.0/16", "192.170.0.0/15", "192.172.0.0/14", - "192.176.0.0/12", "192.192.0.0/10", "193.0.0.0/8", "194.0.0.0/7", - "196.0.0.0/6", "200.0.0.0/5", "208.0.0.0/4"); - } - - private Stream<String> publicIpV6Routes() { - return Stream.of( - "::/1", "8000::/2", "c000::/3", "e000::/4", "f000::/5", "f800::/6", - "fe00::/8", "2605:ef80:e:af1d::/64"); - } -} diff --git a/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java b/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java deleted file mode 100644 index 8b730af76951..000000000000 --- a/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server.net; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.when; - -import android.Manifest; -import android.Manifest.permission; -import android.app.AppOpsManager; -import android.app.admin.DevicePolicyManagerInternal; -import android.content.Context; -import android.content.pm.PackageManager; -import android.telephony.TelephonyManager; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.server.LocalServices; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetworkStatsAccessTest { - private static final String TEST_PKG = "com.example.test"; - private static final int TEST_UID = 12345; - - @Mock private Context mContext; - @Mock private DevicePolicyManagerInternal mDpmi; - @Mock private TelephonyManager mTm; - @Mock private AppOpsManager mAppOps; - - // Hold the real service so we can restore it when tearing down the test. - private DevicePolicyManagerInternal mSystemDpmi; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - mSystemDpmi = LocalServices.getService(DevicePolicyManagerInternal.class); - LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); - LocalServices.addService(DevicePolicyManagerInternal.class, mDpmi); - - when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTm); - when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOps); - } - - @After - public void tearDown() throws Exception { - LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); - LocalServices.addService(DevicePolicyManagerInternal.class, mSystemDpmi); - } - - @Test - public void testCheckAccessLevel_hasCarrierPrivileges() throws Exception { - setHasCarrierPrivileges(true); - setIsDeviceOwner(false); - setIsProfileOwner(false); - setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false); - setHasReadHistoryPermission(false); - assertEquals(NetworkStatsAccess.Level.DEVICE, - NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG)); - } - - @Test - public void testCheckAccessLevel_isDeviceOwner() throws Exception { - setHasCarrierPrivileges(false); - setIsDeviceOwner(true); - setIsProfileOwner(false); - setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false); - setHasReadHistoryPermission(false); - assertEquals(NetworkStatsAccess.Level.DEVICE, - NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG)); - } - - @Test - public void testCheckAccessLevel_isProfileOwner() throws Exception { - setHasCarrierPrivileges(false); - setIsDeviceOwner(false); - setIsProfileOwner(true); - setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false); - setHasReadHistoryPermission(false); - assertEquals(NetworkStatsAccess.Level.USER, - NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG)); - } - - @Test - public void testCheckAccessLevel_hasAppOpsBitAllowed() throws Exception { - setHasCarrierPrivileges(false); - setIsDeviceOwner(false); - setIsProfileOwner(true); - setHasAppOpsPermission(AppOpsManager.MODE_ALLOWED, false); - setHasReadHistoryPermission(false); - assertEquals(NetworkStatsAccess.Level.DEVICESUMMARY, - NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG)); - } - - @Test - public void testCheckAccessLevel_hasAppOpsBitDefault_grantedPermission() throws Exception { - setHasCarrierPrivileges(false); - setIsDeviceOwner(false); - setIsProfileOwner(true); - setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, true); - setHasReadHistoryPermission(false); - assertEquals(NetworkStatsAccess.Level.DEVICESUMMARY, - NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG)); - } - - @Test - public void testCheckAccessLevel_hasReadHistoryPermission() throws Exception { - setHasCarrierPrivileges(false); - setIsDeviceOwner(false); - setIsProfileOwner(true); - setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false); - setHasReadHistoryPermission(true); - assertEquals(NetworkStatsAccess.Level.DEVICESUMMARY, - NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG)); - } - - @Test - public void testCheckAccessLevel_deniedAppOpsBit() throws Exception { - setHasCarrierPrivileges(false); - setIsDeviceOwner(false); - setIsProfileOwner(false); - setHasAppOpsPermission(AppOpsManager.MODE_ERRORED, true); - setHasReadHistoryPermission(false); - assertEquals(NetworkStatsAccess.Level.DEFAULT, - NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG)); - } - - @Test - public void testCheckAccessLevel_deniedAppOpsBit_deniedPermission() throws Exception { - setHasCarrierPrivileges(false); - setIsDeviceOwner(false); - setIsProfileOwner(false); - setHasAppOpsPermission(AppOpsManager.MODE_DEFAULT, false); - setHasReadHistoryPermission(false); - assertEquals(NetworkStatsAccess.Level.DEFAULT, - NetworkStatsAccess.checkAccessLevel(mContext, TEST_UID, TEST_PKG)); - } - - private void setHasCarrierPrivileges(boolean hasPrivileges) { - when(mTm.checkCarrierPrivilegesForPackageAnyPhone(TEST_PKG)).thenReturn( - hasPrivileges ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS - : TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS); - } - - private void setIsDeviceOwner(boolean isOwner) { - when(mDpmi.isActiveDeviceOwner(TEST_UID)).thenReturn(isOwner); - } - - private void setIsProfileOwner(boolean isOwner) { - when(mDpmi.isActiveProfileOwner(TEST_UID)).thenReturn(isOwner); - } - - private void setHasAppOpsPermission(int appOpsMode, boolean hasPermission) { - when(mAppOps.noteOp(AppOpsManager.OP_GET_USAGE_STATS, TEST_UID, TEST_PKG)) - .thenReturn(appOpsMode); - when(mContext.checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)).thenReturn( - hasPermission ? PackageManager.PERMISSION_GRANTED - : PackageManager.PERMISSION_DENIED); - } - - private void setHasReadHistoryPermission(boolean hasPermission) { - when(mContext.checkCallingOrSelfPermission(permission.READ_NETWORK_USAGE_HISTORY)) - .thenReturn(hasPermission ? PackageManager.PERMISSION_GRANTED - : PackageManager.PERMISSION_DENIED); - } -} diff --git a/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java b/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java deleted file mode 100644 index a058a466a4ff..000000000000 --- a/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.net; - -import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; -import static android.net.NetworkStats.DEFAULT_NETWORK_NO; -import static android.net.NetworkStats.DEFAULT_NETWORK_YES; -import static android.net.NetworkStats.METERED_ALL; -import static android.net.NetworkStats.METERED_NO; -import static android.net.NetworkStats.METERED_YES; -import static android.net.NetworkStats.ROAMING_ALL; -import static android.net.NetworkStats.ROAMING_NO; -import static android.net.NetworkStats.ROAMING_YES; -import static android.net.NetworkStats.SET_ALL; -import static android.net.NetworkStats.SET_DEFAULT; -import static android.net.NetworkStats.SET_FOREGROUND; -import static android.net.NetworkStats.TAG_NONE; - -import static org.junit.Assert.assertEquals; - -import android.net.NetworkStats; -import android.net.UnderlyingNetworkInfo; - -import java.util.Arrays; - -/** Superclass with utilities for NetworkStats(Service|Factory)Test */ -abstract class NetworkStatsBaseTest { - static final String TEST_IFACE = "test0"; - static final String TEST_IFACE2 = "test1"; - static final String TUN_IFACE = "test_nss_tun0"; - static final String TUN_IFACE2 = "test_nss_tun1"; - - static final int UID_RED = 1001; - static final int UID_BLUE = 1002; - static final int UID_GREEN = 1003; - static final int UID_VPN = 1004; - - void assertValues(NetworkStats stats, String iface, int uid, long rxBytes, - long rxPackets, long txBytes, long txPackets) { - assertValues( - stats, iface, uid, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, - rxBytes, rxPackets, txBytes, txPackets, 0); - } - - void assertValues(NetworkStats stats, String iface, int uid, int set, int tag, - int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets, - long txBytes, long txPackets, long operations) { - final NetworkStats.Entry entry = new NetworkStats.Entry(); - final int[] sets; - if (set == SET_ALL) { - sets = new int[] {SET_ALL, SET_DEFAULT, SET_FOREGROUND}; - } else { - sets = new int[] {set}; - } - - final int[] roamings; - if (roaming == ROAMING_ALL) { - roamings = new int[] {ROAMING_ALL, ROAMING_YES, ROAMING_NO}; - } else { - roamings = new int[] {roaming}; - } - - final int[] meterings; - if (metered == METERED_ALL) { - meterings = new int[] {METERED_ALL, METERED_YES, METERED_NO}; - } else { - meterings = new int[] {metered}; - } - - final int[] defaultNetworks; - if (defaultNetwork == DEFAULT_NETWORK_ALL) { - defaultNetworks = - new int[] {DEFAULT_NETWORK_ALL, DEFAULT_NETWORK_YES, DEFAULT_NETWORK_NO}; - } else { - defaultNetworks = new int[] {defaultNetwork}; - } - - for (int s : sets) { - for (int r : roamings) { - for (int m : meterings) { - for (int d : defaultNetworks) { - final int i = stats.findIndex(iface, uid, s, tag, m, r, d); - if (i != -1) { - entry.add(stats.getValues(i, null)); - } - } - } - } - } - - assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); - assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets); - assertEquals("unexpected txBytes", txBytes, entry.txBytes); - assertEquals("unexpected txPackets", txPackets, entry.txPackets); - assertEquals("unexpected operations", operations, entry.operations); - } - - static UnderlyingNetworkInfo createVpnInfo(String[] underlyingIfaces) { - return createVpnInfo(TUN_IFACE, underlyingIfaces); - } - - static UnderlyingNetworkInfo createVpnInfo(String vpnIface, String[] underlyingIfaces) { - return new UnderlyingNetworkInfo(UID_VPN, vpnIface, Arrays.asList(underlyingIfaces)); - } -} diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java deleted file mode 100644 index 505ff9b6a34b..000000000000 --- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java +++ /dev/null @@ -1,594 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.net; - -import static android.net.ConnectivityManager.TYPE_MOBILE; -import static android.net.NetworkIdentity.OEM_NONE; -import static android.net.NetworkStats.SET_ALL; -import static android.net.NetworkStats.SET_DEFAULT; -import static android.net.NetworkStats.TAG_NONE; -import static android.net.NetworkStats.UID_ALL; -import static android.net.NetworkStatsHistory.FIELD_ALL; -import static android.net.NetworkTemplate.buildTemplateMobileAll; -import static android.os.Process.myUid; -import static android.text.format.DateUtils.HOUR_IN_MILLIS; -import static android.text.format.DateUtils.MINUTE_IN_MILLIS; - -import static com.android.internal.net.NetworkUtilsInternal.multiplySafeByRational; -import static com.android.testutils.MiscAsserts.assertThrows; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - -import android.content.res.Resources; -import android.net.ConnectivityManager; -import android.net.NetworkIdentity; -import android.net.NetworkStats; -import android.net.NetworkStatsHistory; -import android.net.NetworkTemplate; -import android.os.Process; -import android.os.UserHandle; -import android.telephony.SubscriptionPlan; -import android.telephony.TelephonyManager; -import android.text.format.DateUtils; -import android.util.RecurrenceRule; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.frameworks.tests.net.R; - -import libcore.io.IoUtils; -import libcore.io.Streams; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.time.Clock; -import java.time.Instant; -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.List; - -/** - * Tests for {@link NetworkStatsCollection}. - */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetworkStatsCollectionTest { - - private static final String TEST_FILE = "test.bin"; - private static final String TEST_IMSI = "310260000000000"; - - private static final long TIME_A = 1326088800000L; // UTC: Monday 9th January 2012 06:00:00 AM - private static final long TIME_B = 1326110400000L; // UTC: Monday 9th January 2012 12:00:00 PM - private static final long TIME_C = 1326132000000L; // UTC: Monday 9th January 2012 06:00:00 PM - - private static Clock sOriginalClock; - - @Before - public void setUp() throws Exception { - sOriginalClock = RecurrenceRule.sClock; - // ignore any device overlay while testing - NetworkTemplate.forceAllNetworkTypes(); - } - - @After - public void tearDown() throws Exception { - RecurrenceRule.sClock = sOriginalClock; - NetworkTemplate.resetForceAllNetworkTypes(); - } - - private void setClock(Instant instant) { - RecurrenceRule.sClock = Clock.fixed(instant, ZoneId.systemDefault()); - } - - @Test - public void testReadLegacyNetwork() throws Exception { - final File testFile = - new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE); - stageFile(R.raw.netstats_v1, testFile); - - final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS); - collection.readLegacyNetwork(testFile); - - // verify that history read correctly - assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), - 636016770L, 709306L, 88038768L, 518836L, NetworkStatsAccess.Level.DEVICE); - - // now export into a unified format - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - collection.write(bos); - - // clear structure completely - collection.reset(); - assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), - 0L, 0L, 0L, 0L, NetworkStatsAccess.Level.DEVICE); - - // and read back into structure, verifying that totals are same - collection.read(new ByteArrayInputStream(bos.toByteArray())); - assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), - 636016770L, 709306L, 88038768L, 518836L, NetworkStatsAccess.Level.DEVICE); - } - - @Test - public void testReadLegacyUid() throws Exception { - final File testFile = - new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE); - stageFile(R.raw.netstats_uid_v4, testFile); - - final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS); - collection.readLegacyUid(testFile, false); - - // verify that history read correctly - assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), - 637076152L, 711413L, 88343717L, 521022L, NetworkStatsAccess.Level.DEVICE); - - // now export into a unified format - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - collection.write(bos); - - // clear structure completely - collection.reset(); - assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), - 0L, 0L, 0L, 0L, NetworkStatsAccess.Level.DEVICE); - - // and read back into structure, verifying that totals are same - collection.read(new ByteArrayInputStream(bos.toByteArray())); - assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), - 637076152L, 711413L, 88343717L, 521022L, NetworkStatsAccess.Level.DEVICE); - } - - @Test - public void testReadLegacyUidTags() throws Exception { - final File testFile = - new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE); - stageFile(R.raw.netstats_uid_v4, testFile); - - final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS); - collection.readLegacyUid(testFile, true); - - // verify that history read correctly - assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI), - 77017831L, 100995L, 35436758L, 92344L); - - // now export into a unified format - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - collection.write(bos); - - // clear structure completely - collection.reset(); - assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI), - 0L, 0L, 0L, 0L); - - // and read back into structure, verifying that totals are same - collection.read(new ByteArrayInputStream(bos.toByteArray())); - assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI), - 77017831L, 100995L, 35436758L, 92344L); - } - - @Test - public void testStartEndAtomicBuckets() throws Exception { - final NetworkStatsCollection collection = new NetworkStatsCollection(HOUR_IN_MILLIS); - - // record empty data straddling between buckets - final NetworkStats.Entry entry = new NetworkStats.Entry(); - entry.rxBytes = 32; - collection.recordData(null, UID_ALL, SET_DEFAULT, TAG_NONE, 30 * MINUTE_IN_MILLIS, - 90 * MINUTE_IN_MILLIS, entry); - - // assert that we report boundary in atomic buckets - assertEquals(0, collection.getStartMillis()); - assertEquals(2 * HOUR_IN_MILLIS, collection.getEndMillis()); - } - - @Test - public void testAccessLevels() throws Exception { - final NetworkStatsCollection collection = new NetworkStatsCollection(HOUR_IN_MILLIS); - final NetworkStats.Entry entry = new NetworkStats.Entry(); - final NetworkIdentitySet identSet = new NetworkIdentitySet(); - identSet.add(new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - TEST_IMSI, null, false, true, true, OEM_NONE)); - - int myUid = Process.myUid(); - int otherUidInSameUser = Process.myUid() + 1; - int uidInDifferentUser = Process.myUid() + UserHandle.PER_USER_RANGE; - - // Record one entry for the current UID. - entry.rxBytes = 32; - collection.recordData(identSet, myUid, SET_DEFAULT, TAG_NONE, 0, 60 * MINUTE_IN_MILLIS, - entry); - - // Record one entry for another UID in this user. - entry.rxBytes = 64; - collection.recordData(identSet, otherUidInSameUser, SET_DEFAULT, TAG_NONE, 0, - 60 * MINUTE_IN_MILLIS, entry); - - // Record one entry for the system UID. - entry.rxBytes = 128; - collection.recordData(identSet, Process.SYSTEM_UID, SET_DEFAULT, TAG_NONE, 0, - 60 * MINUTE_IN_MILLIS, entry); - - // Record one entry for a UID in a different user. - entry.rxBytes = 256; - collection.recordData(identSet, uidInDifferentUser, SET_DEFAULT, TAG_NONE, 0, - 60 * MINUTE_IN_MILLIS, entry); - - // Verify the set of relevant UIDs for each access level. - assertArrayEquals(new int[] { myUid }, - collection.getRelevantUids(NetworkStatsAccess.Level.DEFAULT)); - assertArrayEquals(new int[] { Process.SYSTEM_UID, myUid, otherUidInSameUser }, - collection.getRelevantUids(NetworkStatsAccess.Level.USER)); - assertArrayEquals( - new int[] { Process.SYSTEM_UID, myUid, otherUidInSameUser, uidInDifferentUser }, - collection.getRelevantUids(NetworkStatsAccess.Level.DEVICE)); - - // Verify security check in getHistory. - assertNotNull(collection.getHistory(buildTemplateMobileAll(TEST_IMSI), null, myUid, SET_DEFAULT, - TAG_NONE, 0, 0L, 0L, NetworkStatsAccess.Level.DEFAULT, myUid)); - try { - collection.getHistory(buildTemplateMobileAll(TEST_IMSI), null, otherUidInSameUser, - SET_DEFAULT, TAG_NONE, 0, 0L, 0L, NetworkStatsAccess.Level.DEFAULT, myUid); - fail("Should have thrown SecurityException for accessing different UID"); - } catch (SecurityException e) { - // expected - } - - // Verify appropriate aggregation in getSummary. - assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), 32, 0, 0, 0, - NetworkStatsAccess.Level.DEFAULT); - assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), 32 + 64 + 128, 0, 0, 0, - NetworkStatsAccess.Level.USER); - assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), 32 + 64 + 128 + 256, 0, 0, - 0, NetworkStatsAccess.Level.DEVICE); - } - - @Test - public void testAugmentPlan() throws Exception { - final File testFile = - new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE); - stageFile(R.raw.netstats_v1, testFile); - - final NetworkStatsCollection emptyCollection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS); - final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS); - collection.readLegacyNetwork(testFile); - - // We're in the future, but not that far off - setClock(Instant.parse("2012-06-01T00:00:00.00Z")); - - // Test a bunch of plans that should result in no augmentation - final List<SubscriptionPlan> plans = new ArrayList<>(); - - // No plan - plans.add(null); - // No usage anchor - plans.add(SubscriptionPlan.Builder - .createRecurringMonthly(ZonedDateTime.parse("2011-01-14T00:00:00.00Z")).build()); - // Usage anchor far in past - plans.add(SubscriptionPlan.Builder - .createRecurringMonthly(ZonedDateTime.parse("2011-01-14T00:00:00.00Z")) - .setDataUsage(1000L, TIME_A - DateUtils.YEAR_IN_MILLIS).build()); - // Usage anchor far in future - plans.add(SubscriptionPlan.Builder - .createRecurringMonthly(ZonedDateTime.parse("2011-01-14T00:00:00.00Z")) - .setDataUsage(1000L, TIME_A + DateUtils.YEAR_IN_MILLIS).build()); - // Usage anchor near but outside cycle - plans.add(SubscriptionPlan.Builder - .createNonrecurring(ZonedDateTime.parse("2012-01-09T09:00:00.00Z"), - ZonedDateTime.parse("2012-01-09T15:00:00.00Z")) - .setDataUsage(1000L, TIME_C).build()); - - for (SubscriptionPlan plan : plans) { - int i; - NetworkStatsHistory history; - - // Empty collection should be untouched - history = getHistory(emptyCollection, plan, TIME_A, TIME_C); - assertEquals(0L, history.getTotalBytes()); - - // Normal collection should be untouched - history = getHistory(collection, plan, TIME_A, TIME_C); i = 0; - assertEntry(100647, 197, 23649, 185, history.getValues(i++, null)); - assertEntry(100647, 196, 23648, 185, history.getValues(i++, null)); - assertEntry(18323, 76, 15032, 76, history.getValues(i++, null)); - assertEntry(18322, 75, 15031, 75, history.getValues(i++, null)); - assertEntry(527798, 761, 78570, 652, history.getValues(i++, null)); - assertEntry(527797, 760, 78570, 651, history.getValues(i++, null)); - assertEntry(10747, 50, 16839, 55, history.getValues(i++, null)); - assertEntry(10747, 49, 16837, 54, history.getValues(i++, null)); - assertEntry(89191, 151, 18021, 140, history.getValues(i++, null)); - assertEntry(89190, 150, 18020, 139, history.getValues(i++, null)); - assertEntry(3821, 23, 4525, 26, history.getValues(i++, null)); - assertEntry(3820, 21, 4524, 26, history.getValues(i++, null)); - assertEntry(91686, 159, 18576, 146, history.getValues(i++, null)); - assertEntry(91685, 159, 18574, 146, history.getValues(i++, null)); - assertEntry(8289, 36, 6864, 39, history.getValues(i++, null)); - assertEntry(8289, 34, 6862, 37, history.getValues(i++, null)); - assertEntry(113914, 174, 18364, 157, history.getValues(i++, null)); - assertEntry(113913, 173, 18364, 157, history.getValues(i++, null)); - assertEntry(11378, 49, 9261, 50, history.getValues(i++, null)); - assertEntry(11377, 48, 9261, 48, history.getValues(i++, null)); - assertEntry(201766, 328, 41808, 291, history.getValues(i++, null)); - assertEntry(201764, 328, 41807, 290, history.getValues(i++, null)); - assertEntry(106106, 219, 39918, 202, history.getValues(i++, null)); - assertEntry(106105, 216, 39916, 200, history.getValues(i++, null)); - assertEquals(history.size(), i); - - // Slice from middle should be untouched - history = getHistory(collection, plan, TIME_B - HOUR_IN_MILLIS, - TIME_B + HOUR_IN_MILLIS); i = 0; - assertEntry(3821, 23, 4525, 26, history.getValues(i++, null)); - assertEntry(3820, 21, 4524, 26, history.getValues(i++, null)); - assertEntry(91686, 159, 18576, 146, history.getValues(i++, null)); - assertEntry(91685, 159, 18574, 146, history.getValues(i++, null)); - assertEquals(history.size(), i); - } - - // Lower anchor in the middle of plan - { - int i; - NetworkStatsHistory history; - - final SubscriptionPlan plan = SubscriptionPlan.Builder - .createNonrecurring(ZonedDateTime.parse("2012-01-09T09:00:00.00Z"), - ZonedDateTime.parse("2012-01-09T15:00:00.00Z")) - .setDataUsage(200000L, TIME_B).build(); - - // Empty collection should be augmented - history = getHistory(emptyCollection, plan, TIME_A, TIME_C); - assertEquals(200000L, history.getTotalBytes()); - - // Normal collection should be augmented - history = getHistory(collection, plan, TIME_A, TIME_C); i = 0; - assertEntry(100647, 197, 23649, 185, history.getValues(i++, null)); - assertEntry(100647, 196, 23648, 185, history.getValues(i++, null)); - assertEntry(18323, 76, 15032, 76, history.getValues(i++, null)); - assertEntry(18322, 75, 15031, 75, history.getValues(i++, null)); - assertEntry(527798, 761, 78570, 652, history.getValues(i++, null)); - assertEntry(527797, 760, 78570, 651, history.getValues(i++, null)); - // Cycle point; start data normalization - assertEntry(7507, 0, 11763, 0, history.getValues(i++, null)); - assertEntry(7507, 0, 11762, 0, history.getValues(i++, null)); - assertEntry(62309, 0, 12589, 0, history.getValues(i++, null)); - assertEntry(62309, 0, 12588, 0, history.getValues(i++, null)); - assertEntry(2669, 0, 3161, 0, history.getValues(i++, null)); - assertEntry(2668, 0, 3160, 0, history.getValues(i++, null)); - // Anchor point; end data normalization - assertEntry(91686, 159, 18576, 146, history.getValues(i++, null)); - assertEntry(91685, 159, 18574, 146, history.getValues(i++, null)); - assertEntry(8289, 36, 6864, 39, history.getValues(i++, null)); - assertEntry(8289, 34, 6862, 37, history.getValues(i++, null)); - assertEntry(113914, 174, 18364, 157, history.getValues(i++, null)); - assertEntry(113913, 173, 18364, 157, history.getValues(i++, null)); - // Cycle point - assertEntry(11378, 49, 9261, 50, history.getValues(i++, null)); - assertEntry(11377, 48, 9261, 48, history.getValues(i++, null)); - assertEntry(201766, 328, 41808, 291, history.getValues(i++, null)); - assertEntry(201764, 328, 41807, 290, history.getValues(i++, null)); - assertEntry(106106, 219, 39918, 202, history.getValues(i++, null)); - assertEntry(106105, 216, 39916, 200, history.getValues(i++, null)); - assertEquals(history.size(), i); - - // Slice from middle should be augmented - history = getHistory(collection, plan, TIME_B - HOUR_IN_MILLIS, - TIME_B + HOUR_IN_MILLIS); i = 0; - assertEntry(2669, 0, 3161, 0, history.getValues(i++, null)); - assertEntry(2668, 0, 3160, 0, history.getValues(i++, null)); - assertEntry(91686, 159, 18576, 146, history.getValues(i++, null)); - assertEntry(91685, 159, 18574, 146, history.getValues(i++, null)); - assertEquals(history.size(), i); - } - - // Higher anchor in the middle of plan - { - int i; - NetworkStatsHistory history; - - final SubscriptionPlan plan = SubscriptionPlan.Builder - .createNonrecurring(ZonedDateTime.parse("2012-01-09T09:00:00.00Z"), - ZonedDateTime.parse("2012-01-09T15:00:00.00Z")) - .setDataUsage(400000L, TIME_B + MINUTE_IN_MILLIS).build(); - - // Empty collection should be augmented - history = getHistory(emptyCollection, plan, TIME_A, TIME_C); - assertEquals(400000L, history.getTotalBytes()); - - // Normal collection should be augmented - history = getHistory(collection, plan, TIME_A, TIME_C); i = 0; - assertEntry(100647, 197, 23649, 185, history.getValues(i++, null)); - assertEntry(100647, 196, 23648, 185, history.getValues(i++, null)); - assertEntry(18323, 76, 15032, 76, history.getValues(i++, null)); - assertEntry(18322, 75, 15031, 75, history.getValues(i++, null)); - assertEntry(527798, 761, 78570, 652, history.getValues(i++, null)); - assertEntry(527797, 760, 78570, 651, history.getValues(i++, null)); - // Cycle point; start data normalization - assertEntry(15015, 0, 23527, 0, history.getValues(i++, null)); - assertEntry(15015, 0, 23524, 0, history.getValues(i++, null)); - assertEntry(124619, 0, 25179, 0, history.getValues(i++, null)); - assertEntry(124618, 0, 25177, 0, history.getValues(i++, null)); - assertEntry(5338, 0, 6322, 0, history.getValues(i++, null)); - assertEntry(5337, 0, 6320, 0, history.getValues(i++, null)); - // Anchor point; end data normalization - assertEntry(91686, 159, 18576, 146, history.getValues(i++, null)); - assertEntry(91685, 159, 18574, 146, history.getValues(i++, null)); - assertEntry(8289, 36, 6864, 39, history.getValues(i++, null)); - assertEntry(8289, 34, 6862, 37, history.getValues(i++, null)); - assertEntry(113914, 174, 18364, 157, history.getValues(i++, null)); - assertEntry(113913, 173, 18364, 157, history.getValues(i++, null)); - // Cycle point - assertEntry(11378, 49, 9261, 50, history.getValues(i++, null)); - assertEntry(11377, 48, 9261, 48, history.getValues(i++, null)); - assertEntry(201766, 328, 41808, 291, history.getValues(i++, null)); - assertEntry(201764, 328, 41807, 290, history.getValues(i++, null)); - assertEntry(106106, 219, 39918, 202, history.getValues(i++, null)); - assertEntry(106105, 216, 39916, 200, history.getValues(i++, null)); - - // Slice from middle should be augmented - history = getHistory(collection, plan, TIME_B - HOUR_IN_MILLIS, - TIME_B + HOUR_IN_MILLIS); i = 0; - assertEntry(5338, 0, 6322, 0, history.getValues(i++, null)); - assertEntry(5337, 0, 6320, 0, history.getValues(i++, null)); - assertEntry(91686, 159, 18576, 146, history.getValues(i++, null)); - assertEntry(91685, 159, 18574, 146, history.getValues(i++, null)); - assertEquals(history.size(), i); - } - } - - @Test - public void testAugmentPlanGigantic() throws Exception { - // We're in the future, but not that far off - setClock(Instant.parse("2012-06-01T00:00:00.00Z")); - - // Create a simple history with a ton of measured usage - final NetworkStatsCollection large = new NetworkStatsCollection(HOUR_IN_MILLIS); - final NetworkIdentitySet ident = new NetworkIdentitySet(); - ident.add(new NetworkIdentity(ConnectivityManager.TYPE_MOBILE, -1, TEST_IMSI, null, - false, true, true, OEM_NONE)); - large.recordData(ident, UID_ALL, SET_ALL, TAG_NONE, TIME_A, TIME_B, - new NetworkStats.Entry(12_730_893_164L, 1, 0, 0, 0)); - - // Verify untouched total - assertEquals(12_730_893_164L, getHistory(large, null, TIME_A, TIME_C).getTotalBytes()); - - // Verify anchor that might cause overflows - final SubscriptionPlan plan = SubscriptionPlan.Builder - .createRecurringMonthly(ZonedDateTime.parse("2012-01-09T00:00:00.00Z")) - .setDataUsage(4_939_212_390L, TIME_B).build(); - assertEquals(4_939_212_386L, getHistory(large, plan, TIME_A, TIME_C).getTotalBytes()); - } - - @Test - public void testRounding() throws Exception { - final NetworkStatsCollection coll = new NetworkStatsCollection(HOUR_IN_MILLIS); - - // Special values should remain unchanged - for (long time : new long[] { - Long.MIN_VALUE, Long.MAX_VALUE, SubscriptionPlan.TIME_UNKNOWN - }) { - assertEquals(time, coll.roundUp(time)); - assertEquals(time, coll.roundDown(time)); - } - - assertEquals(TIME_A, coll.roundUp(TIME_A)); - assertEquals(TIME_A, coll.roundDown(TIME_A)); - - assertEquals(TIME_A + HOUR_IN_MILLIS, coll.roundUp(TIME_A + 1)); - assertEquals(TIME_A, coll.roundDown(TIME_A + 1)); - - assertEquals(TIME_A, coll.roundUp(TIME_A - 1)); - assertEquals(TIME_A - HOUR_IN_MILLIS, coll.roundDown(TIME_A - 1)); - } - - @Test - public void testMultiplySafeRational() { - assertEquals(25, multiplySafeByRational(50, 1, 2)); - assertEquals(100, multiplySafeByRational(50, 2, 1)); - - assertEquals(-10, multiplySafeByRational(30, -1, 3)); - assertEquals(0, multiplySafeByRational(30, 0, 3)); - assertEquals(10, multiplySafeByRational(30, 1, 3)); - assertEquals(20, multiplySafeByRational(30, 2, 3)); - assertEquals(30, multiplySafeByRational(30, 3, 3)); - assertEquals(40, multiplySafeByRational(30, 4, 3)); - - assertEquals(100_000_000_000L, - multiplySafeByRational(300_000_000_000L, 10_000_000_000L, 30_000_000_000L)); - assertEquals(100_000_000_010L, - multiplySafeByRational(300_000_000_000L, 10_000_000_001L, 30_000_000_000L)); - assertEquals(823_202_048L, - multiplySafeByRational(4_939_212_288L, 2_121_815_528L, 12_730_893_165L)); - - assertThrows(ArithmeticException.class, () -> multiplySafeByRational(30, 3, 0)); - } - - /** - * Copy a {@link Resources#openRawResource(int)} into {@link File} for - * testing purposes. - */ - private void stageFile(int rawId, File file) throws Exception { - new File(file.getParent()).mkdirs(); - InputStream in = null; - OutputStream out = null; - try { - in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId); - out = new FileOutputStream(file); - Streams.copy(in, out); - } finally { - IoUtils.closeQuietly(in); - IoUtils.closeQuietly(out); - } - } - - private static NetworkStatsHistory getHistory(NetworkStatsCollection collection, - SubscriptionPlan augmentPlan, long start, long end) { - return collection.getHistory(buildTemplateMobileAll(TEST_IMSI), augmentPlan, UID_ALL, - SET_ALL, TAG_NONE, FIELD_ALL, start, end, NetworkStatsAccess.Level.DEVICE, myUid()); - } - - private static void assertSummaryTotal(NetworkStatsCollection collection, - NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets, - @NetworkStatsAccess.Level int accessLevel) { - final NetworkStats.Entry actual = collection.getSummary( - template, Long.MIN_VALUE, Long.MAX_VALUE, accessLevel, myUid()) - .getTotal(null); - assertEntry(rxBytes, rxPackets, txBytes, txPackets, actual); - } - - private static void assertSummaryTotalIncludingTags(NetworkStatsCollection collection, - NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets) { - final NetworkStats.Entry actual = collection.getSummary( - template, Long.MIN_VALUE, Long.MAX_VALUE, NetworkStatsAccess.Level.DEVICE, myUid()) - .getTotalIncludingTags(null); - assertEntry(rxBytes, rxPackets, txBytes, txPackets, actual); - } - - private static void assertEntry(long rxBytes, long rxPackets, long txBytes, long txPackets, - NetworkStats.Entry actual) { - assertEntry(new NetworkStats.Entry(rxBytes, rxPackets, txBytes, txPackets, 0L), actual); - } - - private static void assertEntry(long rxBytes, long rxPackets, long txBytes, long txPackets, - NetworkStatsHistory.Entry actual) { - assertEntry(new NetworkStats.Entry(rxBytes, rxPackets, txBytes, txPackets, 0L), actual); - } - - private static void assertEntry(NetworkStats.Entry expected, - NetworkStatsHistory.Entry actual) { - assertEntry(expected, new NetworkStats.Entry(actual.rxBytes, actual.rxPackets, - actual.txBytes, actual.txPackets, 0L)); - } - - private static void assertEntry(NetworkStats.Entry expected, - NetworkStats.Entry actual) { - assertEquals("unexpected rxBytes", expected.rxBytes, actual.rxBytes); - assertEquals("unexpected rxPackets", expected.rxPackets, actual.rxPackets); - assertEquals("unexpected txBytes", expected.txBytes, actual.txBytes); - assertEquals("unexpected txPackets", expected.txPackets, actual.txPackets); - } -} diff --git a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java deleted file mode 100644 index f3ae9b051e7c..000000000000 --- a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.net; - -import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; -import static android.net.NetworkStats.DEFAULT_NETWORK_NO; -import static android.net.NetworkStats.METERED_ALL; -import static android.net.NetworkStats.METERED_NO; -import static android.net.NetworkStats.ROAMING_ALL; -import static android.net.NetworkStats.ROAMING_NO; -import static android.net.NetworkStats.SET_ALL; -import static android.net.NetworkStats.SET_DEFAULT; -import static android.net.NetworkStats.SET_FOREGROUND; -import static android.net.NetworkStats.TAG_NONE; -import static android.net.NetworkStats.UID_ALL; - -import static com.android.server.NetworkManagementSocketTagger.kernelToTag; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import android.content.res.Resources; -import android.net.NetworkStats; -import android.net.TrafficStats; -import android.net.UnderlyingNetworkInfo; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.frameworks.tests.net.R; - -import libcore.io.IoUtils; -import libcore.io.Streams; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.InputStream; -import java.io.OutputStream; - -/** Tests for {@link NetworkStatsFactory}. */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetworkStatsFactoryTest extends NetworkStatsBaseTest { - private static final String CLAT_PREFIX = "v4-"; - - private File mTestProc; - private NetworkStatsFactory mFactory; - - @Before - public void setUp() throws Exception { - mTestProc = new File(InstrumentationRegistry.getContext().getFilesDir(), "proc"); - if (mTestProc.exists()) { - IoUtils.deleteContents(mTestProc); - } - - // The libandroid_servers which have the native method is not available to - // applications. So in order to have a test support native library, the native code - // related to networkStatsFactory is compiled to a minimal native library and loaded here. - System.loadLibrary("networkstatsfactorytestjni"); - mFactory = new NetworkStatsFactory(mTestProc, false); - mFactory.updateUnderlyingNetworkInfos(new UnderlyingNetworkInfo[0]); - } - - @After - public void tearDown() throws Exception { - mFactory = null; - - if (mTestProc.exists()) { - IoUtils.deleteContents(mTestProc); - } - } - - @Test - public void testNetworkStatsDetail() throws Exception { - final NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_typical); - - assertEquals(70, stats.size()); - assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, 18621L, 2898L); - assertStatsEntry(stats, "wlan0", 10011, SET_DEFAULT, 0x0, 35777L, 5718L); - assertStatsEntry(stats, "wlan0", 10021, SET_DEFAULT, 0x7fffff01, 562386L, 49228L); - assertStatsEntry(stats, "rmnet1", 10021, SET_DEFAULT, 0x30100000, 219110L, 227423L); - assertStatsEntry(stats, "rmnet2", 10001, SET_DEFAULT, 0x0, 1125899906842624L, 984L); - } - - @Test - public void testVpnRewriteTrafficThroughItself() throws Exception { - UnderlyingNetworkInfo[] underlyingNetworkInfos = - new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; - mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos); - - // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption - // overhead per packet): - // - // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED - // over VPN. - // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE - // over VPN. - // - // VPN UID rewrites packets read from TUN back to TUN, plus some of its own traffic - - final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_rewrite_through_self); - - assertValues(tunStats, TUN_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL, 2000L, 200L, 1000L, 100L, 0); - assertValues(tunStats, TUN_IFACE, UID_BLUE, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL, 1000L, 100L, 500L, 50L, 0); - assertValues(tunStats, TUN_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL, 0L, 0L, 1600L, 160L, 0); - - assertValues(tunStats, TEST_IFACE, UID_RED, 2000L, 200L, 1000L, 100L); - assertValues(tunStats, TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L); - assertValues(tunStats, TEST_IFACE, UID_VPN, 300L, 0L, 260L, 26L); - } - - @Test - public void testVpnWithClat() throws Exception { - final UnderlyingNetworkInfo[] underlyingNetworkInfos = new UnderlyingNetworkInfo[] { - createVpnInfo(new String[] {CLAT_PREFIX + TEST_IFACE})}; - mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos); - mFactory.noteStackedIface(CLAT_PREFIX + TEST_IFACE, TEST_IFACE); - - // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption - // overhead per packet): - // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED - // over VPN. - // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE - // over VPN. - // VPN sent 1650 bytes (150 packets), and received 3300 (300 packets) over v4-WiFi, and clat - // added 20 bytes per packet of extra overhead - // - // For 1650 bytes sent over v4-WiFi, 4650 bytes were actually sent over WiFi, which is - // expected to be split as follows: - // UID_RED: 1000 bytes, 100 packets - // UID_BLUE: 500 bytes, 50 packets - // UID_VPN: 3150 bytes, 0 packets - // - // For 3300 bytes received over v4-WiFi, 9300 bytes were actually sent over WiFi, which is - // expected to be split as follows: - // UID_RED: 2000 bytes, 200 packets - // UID_BLUE: 1000 bytes, 100 packets - // UID_VPN: 6300 bytes, 0 packets - final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_with_clat); - - assertValues(tunStats, CLAT_PREFIX + TEST_IFACE, UID_RED, 2000L, 200L, 1000, 100L); - assertValues(tunStats, CLAT_PREFIX + TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L); - assertValues(tunStats, CLAT_PREFIX + TEST_IFACE, UID_VPN, 6300L, 0L, 3150L, 0L); - } - - @Test - public void testVpnWithOneUnderlyingIface() throws Exception { - final UnderlyingNetworkInfo[] underlyingNetworkInfos = - new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; - mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos); - - // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption - // overhead per packet): - // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED - // over VPN. - // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE - // over VPN. - // VPN sent 1650 bytes (150 packets), and received 3300 (300 packets) over WiFi. - // Of 1650 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes - // attributed to UID_BLUE, and 150 bytes attributed to UID_VPN. - // Of 3300 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes - // attributed to UID_BLUE, and 300 bytes attributed to UID_VPN. - final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_one_underlying); - - assertValues(tunStats, TEST_IFACE, UID_RED, 2000L, 200L, 1000L, 100L); - assertValues(tunStats, TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L); - assertValues(tunStats, TEST_IFACE, UID_VPN, 300L, 0L, 150L, 0L); - } - - @Test - public void testVpnWithOneUnderlyingIfaceAndOwnTraffic() throws Exception { - // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE). - final UnderlyingNetworkInfo[] underlyingNetworkInfos = - new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; - mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos); - - // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption - // overhead per packet): - // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED - // over VPN. - // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE - // over VPN. - // Additionally, the VPN sends 6000 bytes (600 packets) of its own traffic into the tun - // interface (passing that traffic to the VPN endpoint), and receives 5000 bytes (500 - // packets) from it. Including overhead that is 6600/5500 bytes. - // VPN sent 8250 bytes (750 packets), and received 8800 (800 packets) over WiFi. - // Of 8250 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes - // attributed to UID_BLUE, and 6750 bytes attributed to UID_VPN. - // Of 8800 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes - // attributed to UID_BLUE, and 5800 bytes attributed to UID_VPN. - final NetworkStats tunStats = - parseDetailedStats(R.raw.xt_qtaguid_vpn_one_underlying_own_traffic); - - assertValues(tunStats, TEST_IFACE, UID_RED, 2000L, 200L, 1000L, 100L); - assertValues(tunStats, TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L); - assertValues(tunStats, TEST_IFACE, UID_VPN, 5800L, 500L, 6750L, 600L); - } - - @Test - public void testVpnWithOneUnderlyingIface_withCompression() throws Exception { - // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE). - final UnderlyingNetworkInfo[] underlyingNetworkInfos = - new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; - mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos); - - // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption - // overhead per packet): - // 1000 bytes (100 packets) were sent/received by UID_RED over VPN. - // 3000 bytes (300 packets) were sent/received by UID_BLUE over VPN. - // VPN sent/received 1000 bytes (100 packets) over WiFi. - // Of 1000 bytes over WiFi, expect 250 bytes attributed UID_RED and 750 bytes to UID_BLUE, - // with nothing attributed to UID_VPN for both rx/tx traffic. - final NetworkStats tunStats = - parseDetailedStats(R.raw.xt_qtaguid_vpn_one_underlying_compression); - - assertValues(tunStats, TEST_IFACE, UID_RED, 250L, 25L, 250L, 25L); - assertValues(tunStats, TEST_IFACE, UID_BLUE, 750L, 75L, 750L, 75L); - assertValues(tunStats, TEST_IFACE, UID_VPN, 0L, 0L, 0L, 0L); - } - - @Test - public void testVpnWithTwoUnderlyingIfaces_packetDuplication() throws Exception { - // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and - // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set. - // Additionally, VPN is duplicating traffic across both WiFi and Cell. - final UnderlyingNetworkInfo[] underlyingNetworkInfos = - new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})}; - mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos); - - // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption - // overhead per packet): - // 1000 bytes (100 packets) were sent/received by UID_RED and UID_BLUE over VPN. - // VPN sent/received 4400 bytes (400 packets) over both WiFi and Cell (8800 bytes in total). - // Of 8800 bytes over WiFi/Cell, expect: - // - 500 bytes rx/tx each over WiFi/Cell attributed to both UID_RED and UID_BLUE. - // - 1200 bytes rx/tx each over WiFi/Cell for VPN_UID. - final NetworkStats tunStats = - parseDetailedStats(R.raw.xt_qtaguid_vpn_two_underlying_duplication); - - assertValues(tunStats, TEST_IFACE, UID_RED, 500L, 50L, 500L, 50L); - assertValues(tunStats, TEST_IFACE, UID_BLUE, 500L, 50L, 500L, 50L); - assertValues(tunStats, TEST_IFACE, UID_VPN, 1200L, 100L, 1200L, 100L); - assertValues(tunStats, TEST_IFACE2, UID_RED, 500L, 50L, 500L, 50L); - assertValues(tunStats, TEST_IFACE2, UID_BLUE, 500L, 50L, 500L, 50L); - assertValues(tunStats, TEST_IFACE2, UID_VPN, 1200L, 100L, 1200L, 100L); - } - - @Test - public void testConcurrentVpns() throws Exception { - // Assume two VPNs are connected on two different network interfaces. VPN1 is using - // TEST_IFACE and VPN2 is using TEST_IFACE2. - final UnderlyingNetworkInfo[] underlyingNetworkInfos = new UnderlyingNetworkInfo[] { - createVpnInfo(TUN_IFACE, new String[] {TEST_IFACE}), - createVpnInfo(TUN_IFACE2, new String[] {TEST_IFACE2})}; - mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos); - - // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption - // overhead per packet): - // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED - // over VPN1. - // 700 bytes (70 packets) were sent, and 3000 bytes (300 packets) were received by UID_RED - // over VPN2. - // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE - // over VPN1. - // 250 bytes (25 packets) were sent, and 500 bytes (50 packets) were received by UID_BLUE - // over VPN2. - // VPN1 sent 1650 bytes (150 packets), and received 3300 (300 packets) over TEST_IFACE. - // Of 1650 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes - // attributed to UID_BLUE, and 150 bytes attributed to UID_VPN. - // Of 3300 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes - // attributed to UID_BLUE, and 300 bytes attributed to UID_VPN. - // VPN2 sent 1045 bytes (95 packets), and received 3850 (350 packets) over TEST_IFACE2. - // Of 1045 bytes sent over Cell, expect 700 bytes attributed to UID_RED, 250 bytes - // attributed to UID_BLUE, and 95 bytes attributed to UID_VPN. - // Of 3850 bytes received over Cell, expect 3000 bytes attributed to UID_RED, 500 bytes - // attributed to UID_BLUE, and 350 bytes attributed to UID_VPN. - final NetworkStats tunStats = - parseDetailedStats(R.raw.xt_qtaguid_vpn_one_underlying_two_vpn); - - assertValues(tunStats, TEST_IFACE, UID_RED, 2000L, 200L, 1000L, 100L); - assertValues(tunStats, TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L); - assertValues(tunStats, TEST_IFACE2, UID_RED, 3000L, 300L, 700L, 70L); - assertValues(tunStats, TEST_IFACE2, UID_BLUE, 500L, 50L, 250L, 25L); - assertValues(tunStats, TEST_IFACE, UID_VPN, 300L, 0L, 150L, 0L); - assertValues(tunStats, TEST_IFACE2, UID_VPN, 350L, 0L, 95L, 0L); - } - - @Test - public void testVpnWithTwoUnderlyingIfaces_splitTraffic() throws Exception { - // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and - // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set. - // Additionally, VPN is arbitrarily splitting traffic across WiFi and Cell. - final UnderlyingNetworkInfo[] underlyingNetworkInfos = - new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})}; - mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos); - - // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption - // overhead per packet): - // 1000 bytes (100 packets) were sent, and 500 bytes (50 packets) received by UID_RED over - // VPN. - // VPN sent 660 bytes (60 packets) over WiFi and 440 bytes (40 packets) over Cell. - // And, it received 330 bytes (30 packets) over WiFi and 220 bytes (20 packets) over Cell. - // For UID_RED, expect 600 bytes attributed over WiFi and 400 bytes over Cell for sent (tx) - // traffic. For received (rx) traffic, expect 300 bytes over WiFi and 200 bytes over Cell. - // - // For UID_VPN, expect 60 bytes attributed over WiFi and 40 bytes over Cell for tx traffic. - // And, 30 bytes over WiFi and 20 bytes over Cell for rx traffic. - final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_two_underlying_split); - - assertValues(tunStats, TEST_IFACE, UID_RED, 300L, 30L, 600L, 60L); - assertValues(tunStats, TEST_IFACE, UID_VPN, 30L, 0L, 60L, 0L); - assertValues(tunStats, TEST_IFACE2, UID_RED, 200L, 20L, 400L, 40L); - assertValues(tunStats, TEST_IFACE2, UID_VPN, 20L, 0L, 40L, 0L); - } - - @Test - public void testVpnWithTwoUnderlyingIfaces_splitTrafficWithCompression() throws Exception { - // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and - // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set. - // Additionally, VPN is arbitrarily splitting compressed traffic across WiFi and Cell. - final UnderlyingNetworkInfo[] underlyingNetworkInfos = - new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})}; - mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos); - - // create some traffic (assume 10 bytes of MTU for VPN interface: - // 1000 bytes (100 packets) were sent/received by UID_RED over VPN. - // VPN sent/received 600 bytes (60 packets) over WiFi and 200 bytes (20 packets) over Cell. - // For UID_RED, expect 600 bytes attributed over WiFi and 200 bytes over Cell for both - // rx/tx. - // UID_VPN gets nothing attributed to it (avoiding negative stats). - final NetworkStats tunStats = - parseDetailedStats(R.raw.xt_qtaguid_vpn_two_underlying_split_compression); - - assertValues(tunStats, TEST_IFACE, UID_RED, 600L, 60L, 600L, 60L); - assertValues(tunStats, TEST_IFACE, UID_VPN, 0L, 0L, 0L, 0L); - assertValues(tunStats, TEST_IFACE2, UID_RED, 200L, 20L, 200L, 20L); - assertValues(tunStats, TEST_IFACE2, UID_VPN, 0L, 0L, 0L, 0L); - } - - @Test - public void testVpnWithIncorrectUnderlyingIface() throws Exception { - // WiFi and Cell networks are connected and VPN is using Cell (which has TEST_IFACE2), - // but has declared only WiFi (TEST_IFACE) in its underlying network set. - final UnderlyingNetworkInfo[] underlyingNetworkInfos = - new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; - mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos); - - // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption - // overhead per packet): - // 1000 bytes (100 packets) were sent/received by UID_RED over VPN. - // VPN sent/received 1100 bytes (100 packets) over Cell. - // Of 1100 bytes over Cell, expect all of it attributed to UID_VPN for both rx/tx traffic. - final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_incorrect_iface); - - assertValues(tunStats, TEST_IFACE, UID_RED, 0L, 0L, 0L, 0L); - assertValues(tunStats, TEST_IFACE, UID_VPN, 0L, 0L, 0L, 0L); - assertValues(tunStats, TEST_IFACE2, UID_RED, 0L, 0L, 0L, 0L); - assertValues(tunStats, TEST_IFACE2, UID_VPN, 1100L, 100L, 1100L, 100L); - } - - @Test - public void testKernelTags() throws Exception { - assertEquals(0, kernelToTag("0x0000000000000000")); - assertEquals(0x32, kernelToTag("0x0000003200000000")); - assertEquals(2147483647, kernelToTag("0x7fffffff00000000")); - assertEquals(0, kernelToTag("0x0000000000000000")); - assertEquals(2147483136, kernelToTag("0x7FFFFE0000000000")); - - assertEquals(0, kernelToTag("0x0")); - assertEquals(0, kernelToTag("0xf00d")); - assertEquals(1, kernelToTag("0x100000000")); - assertEquals(14438007, kernelToTag("0xdc4e7700000000")); - assertEquals(TrafficStats.TAG_SYSTEM_DOWNLOAD, kernelToTag("0xffffff0100000000")); - } - - @Test - public void testNetworkStatsWithSet() throws Exception { - final NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_typical); - assertEquals(70, stats.size()); - assertStatsEntry(stats, "rmnet1", 10021, SET_DEFAULT, 0x30100000, 219110L, 578L, 227423L, - 676L); - assertStatsEntry(stats, "rmnet1", 10021, SET_FOREGROUND, 0x30100000, 742L, 3L, 1265L, 3L); - } - - @Test - public void testNetworkStatsSingle() throws Exception { - stageFile(R.raw.xt_qtaguid_iface_typical, file("net/xt_qtaguid/iface_stat_all")); - - final NetworkStats stats = mFactory.readNetworkStatsSummaryDev(); - assertEquals(6, stats.size()); - assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 2112L, 24L, 700L, 10L); - assertStatsEntry(stats, "test1", UID_ALL, SET_ALL, TAG_NONE, 6L, 8L, 10L, 12L); - assertStatsEntry(stats, "test2", UID_ALL, SET_ALL, TAG_NONE, 1L, 2L, 3L, 4L); - } - - @Test - public void testNetworkStatsXt() throws Exception { - stageFile(R.raw.xt_qtaguid_iface_fmt_typical, file("net/xt_qtaguid/iface_stat_fmt")); - - final NetworkStats stats = mFactory.readNetworkStatsSummaryXt(); - assertEquals(3, stats.size()); - assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 6824L, 16L, 5692L, 10L); - assertStatsEntry(stats, "rmnet1", UID_ALL, SET_ALL, TAG_NONE, 11153922L, 8051L, 190226L, - 2468L); - assertStatsEntry(stats, "rmnet2", UID_ALL, SET_ALL, TAG_NONE, 4968L, 35L, 3081L, 39L); - } - - @Test - public void testDoubleClatAccountingSimple() throws Exception { - mFactory.noteStackedIface("v4-wlan0", "wlan0"); - - // xt_qtaguid_with_clat_simple is a synthetic file that simulates - // - 213 received 464xlat packets of size 200 bytes - // - 41 sent 464xlat packets of size 100 bytes - // - no other traffic on base interface for root uid. - NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_simple); - assertEquals(3, stats.size()); - - assertStatsEntry(stats, "v4-wlan0", 10060, SET_DEFAULT, 0x0, 46860L, 4920L); - assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, 0L, 0L); - } - - @Test - public void testDoubleClatAccounting() throws Exception { - mFactory.noteStackedIface("v4-wlan0", "wlan0"); - - NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat); - assertEquals(42, stats.size()); - - assertStatsEntry(stats, "v4-wlan0", 0, SET_DEFAULT, 0x0, 356L, 276L); - assertStatsEntry(stats, "v4-wlan0", 1000, SET_DEFAULT, 0x0, 30812L, 2310L); - assertStatsEntry(stats, "v4-wlan0", 10102, SET_DEFAULT, 0x0, 10022L, 3330L); - assertStatsEntry(stats, "v4-wlan0", 10060, SET_DEFAULT, 0x0, 9532772L, 254112L); - assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, 0L, 0L); - assertStatsEntry(stats, "wlan0", 1000, SET_DEFAULT, 0x0, 6126L, 2013L); - assertStatsEntry(stats, "wlan0", 10013, SET_DEFAULT, 0x0, 0L, 144L); - assertStatsEntry(stats, "wlan0", 10018, SET_DEFAULT, 0x0, 5980263L, 167667L); - assertStatsEntry(stats, "wlan0", 10060, SET_DEFAULT, 0x0, 134356L, 8705L); - assertStatsEntry(stats, "wlan0", 10079, SET_DEFAULT, 0x0, 10926L, 1507L); - assertStatsEntry(stats, "wlan0", 10102, SET_DEFAULT, 0x0, 25038L, 8245L); - assertStatsEntry(stats, "wlan0", 10103, SET_DEFAULT, 0x0, 0L, 192L); - assertStatsEntry(stats, "dummy0", 0, SET_DEFAULT, 0x0, 0L, 168L); - assertStatsEntry(stats, "lo", 0, SET_DEFAULT, 0x0, 1288L, 1288L); - - assertNoStatsEntry(stats, "wlan0", 1029, SET_DEFAULT, 0x0); - } - - @Test - public void testDoubleClatAccounting100MBDownload() throws Exception { - // Downloading 100mb from an ipv4 only destination in a foreground activity - - long appRxBytesBefore = 328684029L; - long appRxBytesAfter = 439237478L; - assertEquals("App traffic should be ~100MB", 110553449, appRxBytesAfter - appRxBytesBefore); - - long rootRxBytes = 330187296L; - - mFactory.noteStackedIface("v4-wlan0", "wlan0"); - NetworkStats stats; - - // Stats snapshot before the download - stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_100mb_download_before); - assertStatsEntry(stats, "v4-wlan0", 10106, SET_FOREGROUND, 0x0, appRxBytesBefore, 5199872L); - assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, rootRxBytes, 0L); - - // Stats snapshot after the download - stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_100mb_download_after); - assertStatsEntry(stats, "v4-wlan0", 10106, SET_FOREGROUND, 0x0, appRxBytesAfter, 7867488L); - assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, rootRxBytes, 0L); - } - - /** - * Copy a {@link Resources#openRawResource(int)} into {@link File} for - * testing purposes. - */ - private void stageFile(int rawId, File file) throws Exception { - new File(file.getParent()).mkdirs(); - InputStream in = null; - OutputStream out = null; - try { - in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId); - out = new FileOutputStream(file); - Streams.copy(in, out); - } finally { - IoUtils.closeQuietly(in); - IoUtils.closeQuietly(out); - } - } - - private void stageLong(long value, File file) throws Exception { - new File(file.getParent()).mkdirs(); - FileWriter out = null; - try { - out = new FileWriter(file); - out.write(Long.toString(value)); - } finally { - IoUtils.closeQuietly(out); - } - } - - private File file(String path) throws Exception { - return new File(mTestProc, path); - } - - private NetworkStats parseDetailedStats(int resourceId) throws Exception { - stageFile(resourceId, file("net/xt_qtaguid/stats")); - return mFactory.readNetworkStatsDetail(); - } - - private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set, - int tag, long rxBytes, long txBytes) { - final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO); - if (i < 0) { - fail(String.format("no NetworkStats for (iface: %s, uid: %d, set: %d, tag: %d)", - iface, uid, set, tag)); - } - final NetworkStats.Entry entry = stats.getValues(i, null); - assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); - assertEquals("unexpected txBytes", txBytes, entry.txBytes); - } - - private static void assertNoStatsEntry(NetworkStats stats, String iface, int uid, int set, - int tag) { - final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO); - if (i >= 0) { - fail("unexpected NetworkStats entry at " + i); - } - } - - private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set, - int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) { - assertStatsEntry(stats, iface, uid, set, tag, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, - rxBytes, rxPackets, txBytes, txPackets); - } - - private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set, - int tag, int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets, - long txBytes, long txPackets) { - final int i = stats.findIndex(iface, uid, set, tag, metered, roaming, defaultNetwork); - - if (i < 0) { - fail(String.format("no NetworkStats for (iface: %s, uid: %d, set: %d, tag: %d, metered:" - + " %d, roaming: %d, defaultNetwork: %d)", - iface, uid, set, tag, metered, roaming, defaultNetwork)); - } - final NetworkStats.Entry entry = stats.getValues(i, null); - assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); - assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets); - assertEquals("unexpected txBytes", txBytes, entry.txBytes); - assertEquals("unexpected txPackets", txPackets, entry.txPackets); - } -} diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java deleted file mode 100644 index 9fa1c50423d9..000000000000 --- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.net; - -import static android.net.ConnectivityManager.TYPE_MOBILE; -import static android.net.NetworkIdentity.OEM_NONE; -import static android.net.NetworkStats.DEFAULT_NETWORK_NO; -import static android.net.NetworkStats.DEFAULT_NETWORK_YES; -import static android.net.NetworkStats.METERED_NO; -import static android.net.NetworkStats.ROAMING_NO; -import static android.net.NetworkStats.SET_DEFAULT; -import static android.net.NetworkStats.TAG_NONE; -import static android.net.NetworkTemplate.buildTemplateMobileAll; -import static android.net.NetworkTemplate.buildTemplateWifiWildcard; -import static android.net.TrafficStats.MB_IN_BYTES; -import static android.text.format.DateUtils.MINUTE_IN_MILLIS; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; - -import android.app.usage.NetworkStatsManager; -import android.net.DataUsageRequest; -import android.net.NetworkIdentity; -import android.net.NetworkStats; -import android.net.NetworkTemplate; -import android.os.ConditionVariable; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.os.Looper; -import android.os.Messenger; -import android.os.Process; -import android.os.UserHandle; -import android.telephony.TelephonyManager; -import android.util.ArrayMap; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.server.net.NetworkStatsServiceTest.LatchedHandler; -import com.android.testutils.HandlerUtils; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -import java.util.Objects; - -/** - * Tests for {@link NetworkStatsObservers}. - */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetworkStatsObserversTest { - private static final String TEST_IFACE = "test0"; - private static final String TEST_IFACE2 = "test1"; - private static final long TEST_START = 1194220800000L; - - private static final String IMSI_1 = "310004"; - private static final String IMSI_2 = "310260"; - private static final String TEST_SSID = "AndroidAP"; - - private static NetworkTemplate sTemplateWifi = buildTemplateWifiWildcard(); - private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1); - private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2); - - private static final int UID_RED = UserHandle.PER_USER_RANGE + 1; - private static final int UID_BLUE = UserHandle.PER_USER_RANGE + 2; - private static final int UID_GREEN = UserHandle.PER_USER_RANGE + 3; - private static final int UID_ANOTHER_USER = 2 * UserHandle.PER_USER_RANGE + 4; - - private static final long WAIT_TIMEOUT_MS = 500; - private static final long THRESHOLD_BYTES = 2 * MB_IN_BYTES; - private static final long BASE_BYTES = 7 * MB_IN_BYTES; - private static final int INVALID_TYPE = -1; - - private long mElapsedRealtime; - - private HandlerThread mObserverHandlerThread; - private Handler mObserverNoopHandler; - - private LatchedHandler mHandler; - - private NetworkStatsObservers mStatsObservers; - private Messenger mMessenger; - private ArrayMap<String, NetworkIdentitySet> mActiveIfaces; - private ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces; - - @Mock private IBinder mockBinder; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - mObserverHandlerThread = new HandlerThread("HandlerThread"); - mObserverHandlerThread.start(); - final Looper observerLooper = mObserverHandlerThread.getLooper(); - mStatsObservers = new NetworkStatsObservers() { - @Override - protected Looper getHandlerLooperLocked() { - return observerLooper; - } - }; - - mHandler = new LatchedHandler(Looper.getMainLooper(), new ConditionVariable()); - mMessenger = new Messenger(mHandler); - - mActiveIfaces = new ArrayMap<>(); - mActiveUidIfaces = new ArrayMap<>(); - } - - @Test - public void testRegister_thresholdTooLow_setsDefaultThreshold() throws Exception { - long thresholdTooLowBytes = 1L; - DataUsageRequest inputRequest = new DataUsageRequest( - DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, thresholdTooLowBytes); - - DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, - Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); - assertTrue(request.requestId > 0); - assertTrue(Objects.equals(sTemplateWifi, request.template)); - assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); - } - - @Test - public void testRegister_highThreshold_accepted() throws Exception { - long highThresholdBytes = 2 * THRESHOLD_BYTES; - DataUsageRequest inputRequest = new DataUsageRequest( - DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, highThresholdBytes); - - DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, - Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); - assertTrue(request.requestId > 0); - assertTrue(Objects.equals(sTemplateWifi, request.template)); - assertEquals(highThresholdBytes, request.thresholdInBytes); - } - - @Test - public void testRegister_twoRequests_twoIds() throws Exception { - DataUsageRequest inputRequest = new DataUsageRequest( - DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, THRESHOLD_BYTES); - - DataUsageRequest request1 = mStatsObservers.register(inputRequest, mMessenger, mockBinder, - Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); - assertTrue(request1.requestId > 0); - assertTrue(Objects.equals(sTemplateWifi, request1.template)); - assertEquals(THRESHOLD_BYTES, request1.thresholdInBytes); - - DataUsageRequest request2 = mStatsObservers.register(inputRequest, mMessenger, mockBinder, - Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); - assertTrue(request2.requestId > request1.requestId); - assertTrue(Objects.equals(sTemplateWifi, request2.template)); - assertEquals(THRESHOLD_BYTES, request2.thresholdInBytes); - } - - @Test - public void testUnregister_unknownRequest_noop() throws Exception { - DataUsageRequest unknownRequest = new DataUsageRequest( - 123456 /* id */, sTemplateWifi, THRESHOLD_BYTES); - - mStatsObservers.unregister(unknownRequest, UID_RED); - } - - @Test - public void testUnregister_knownRequest_releasesCaller() throws Exception { - DataUsageRequest inputRequest = new DataUsageRequest( - DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); - - DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, - Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); - assertTrue(request.requestId > 0); - assertTrue(Objects.equals(sTemplateImsi1, request.template)); - assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); - Mockito.verify(mockBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt()); - - mStatsObservers.unregister(request, Process.SYSTEM_UID); - waitForObserverToIdle(); - - Mockito.verify(mockBinder).unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt()); - } - - @Test - public void testUnregister_knownRequest_invalidUid_doesNotUnregister() throws Exception { - DataUsageRequest inputRequest = new DataUsageRequest( - DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); - - DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, - UID_RED, NetworkStatsAccess.Level.DEVICE); - assertTrue(request.requestId > 0); - assertTrue(Objects.equals(sTemplateImsi1, request.template)); - assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); - Mockito.verify(mockBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt()); - - mStatsObservers.unregister(request, UID_BLUE); - waitForObserverToIdle(); - - Mockito.verifyZeroInteractions(mockBinder); - } - - private NetworkIdentitySet makeTestIdentSet() { - NetworkIdentitySet identSet = new NetworkIdentitySet(); - identSet.add(new NetworkIdentity( - TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - IMSI_1, null /* networkId */, false /* roaming */, true /* metered */, - true /* defaultNetwork */, OEM_NONE)); - return identSet; - } - - @Test - public void testUpdateStats_initialSample_doesNotNotify() throws Exception { - DataUsageRequest inputRequest = new DataUsageRequest( - DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); - - DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, - Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); - assertTrue(request.requestId > 0); - assertTrue(Objects.equals(sTemplateImsi1, request.template)); - assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); - - NetworkIdentitySet identSet = makeTestIdentSet(); - mActiveIfaces.put(TEST_IFACE, identSet); - - // Baseline - NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) - .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); - NetworkStats uidSnapshot = null; - - mStatsObservers.updateStats( - xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); - waitForObserverToIdle(); - } - - @Test - public void testUpdateStats_belowThreshold_doesNotNotify() throws Exception { - DataUsageRequest inputRequest = new DataUsageRequest( - DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); - - DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, - Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); - assertTrue(request.requestId > 0); - assertTrue(Objects.equals(sTemplateImsi1, request.template)); - assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); - - NetworkIdentitySet identSet = makeTestIdentSet(); - mActiveIfaces.put(TEST_IFACE, identSet); - - // Baseline - NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) - .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); - NetworkStats uidSnapshot = null; - mStatsObservers.updateStats( - xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); - - // Delta - xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) - .insertEntry(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L); - mStatsObservers.updateStats( - xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); - waitForObserverToIdle(); - } - - - @Test - public void testUpdateStats_deviceAccess_notifies() throws Exception { - DataUsageRequest inputRequest = new DataUsageRequest( - DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); - - DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, - Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE); - assertTrue(request.requestId > 0); - assertTrue(Objects.equals(sTemplateImsi1, request.template)); - assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); - - NetworkIdentitySet identSet = makeTestIdentSet(); - mActiveIfaces.put(TEST_IFACE, identSet); - - // Baseline - NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) - .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); - NetworkStats uidSnapshot = null; - mStatsObservers.updateStats( - xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); - - // Delta - xtSnapshot = new NetworkStats(TEST_START + MINUTE_IN_MILLIS, 1 /* initialSize */) - .insertEntry(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L, - BASE_BYTES + THRESHOLD_BYTES, 22L); - mStatsObservers.updateStats( - xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); - waitForObserverToIdle(); - assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType); - } - - @Test - public void testUpdateStats_defaultAccess_notifiesSameUid() throws Exception { - DataUsageRequest inputRequest = new DataUsageRequest( - DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); - - DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, - UID_RED, NetworkStatsAccess.Level.DEFAULT); - assertTrue(request.requestId > 0); - assertTrue(Objects.equals(sTemplateImsi1, request.template)); - assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); - - NetworkIdentitySet identSet = makeTestIdentSet(); - mActiveUidIfaces.put(TEST_IFACE, identSet); - - // Baseline - NetworkStats xtSnapshot = null; - NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); - mStatsObservers.updateStats( - xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); - - // Delta - uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, - BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); - mStatsObservers.updateStats( - xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); - waitForObserverToIdle(); - assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType); - } - - @Test - public void testUpdateStats_defaultAccess_usageOtherUid_doesNotNotify() throws Exception { - DataUsageRequest inputRequest = new DataUsageRequest( - DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); - - DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, - UID_BLUE, NetworkStatsAccess.Level.DEFAULT); - assertTrue(request.requestId > 0); - assertTrue(Objects.equals(sTemplateImsi1, request.template)); - assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); - - NetworkIdentitySet identSet = makeTestIdentSet(); - mActiveUidIfaces.put(TEST_IFACE, identSet); - - // Baseline - NetworkStats xtSnapshot = null; - NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); - mStatsObservers.updateStats( - xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); - - // Delta - uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, - BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); - mStatsObservers.updateStats( - xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); - waitForObserverToIdle(); - } - - @Test - public void testUpdateStats_userAccess_usageSameUser_notifies() throws Exception { - DataUsageRequest inputRequest = new DataUsageRequest( - DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); - - DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, - UID_BLUE, NetworkStatsAccess.Level.USER); - assertTrue(request.requestId > 0); - assertTrue(Objects.equals(sTemplateImsi1, request.template)); - assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); - - NetworkIdentitySet identSet = makeTestIdentSet(); - mActiveUidIfaces.put(TEST_IFACE, identSet); - - // Baseline - NetworkStats xtSnapshot = null; - NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); - mStatsObservers.updateStats( - xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); - - // Delta - uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, BASE_BYTES + THRESHOLD_BYTES, 2L, - BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); - mStatsObservers.updateStats( - xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); - waitForObserverToIdle(); - assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType); - } - - @Test - public void testUpdateStats_userAccess_usageAnotherUser_doesNotNotify() throws Exception { - DataUsageRequest inputRequest = new DataUsageRequest( - DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES); - - DataUsageRequest request = mStatsObservers.register(inputRequest, mMessenger, mockBinder, - UID_RED, NetworkStatsAccess.Level.USER); - assertTrue(request.requestId > 0); - assertTrue(Objects.equals(sTemplateImsi1, request.template)); - assertEquals(THRESHOLD_BYTES, request.thresholdInBytes); - - NetworkIdentitySet identSet = makeTestIdentSet(); - mActiveUidIfaces.put(TEST_IFACE, identSet); - - // Baseline - NetworkStats xtSnapshot = null; - NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) - .insertEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); - mStatsObservers.updateStats( - xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); - - // Delta - uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) - .insertEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO, - ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, - BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); - mStatsObservers.updateStats( - xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); - waitForObserverToIdle(); - } - - private void waitForObserverToIdle() { - HandlerUtils.waitForIdle(mObserverHandlerThread, WAIT_TIMEOUT_MS); - HandlerUtils.waitForIdle(mHandler, WAIT_TIMEOUT_MS); - } -} diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java deleted file mode 100644 index fd374bc9e68f..000000000000 --- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +++ /dev/null @@ -1,1767 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.net; - -import static android.content.Intent.ACTION_UID_REMOVED; -import static android.content.Intent.EXTRA_UID; -import static android.net.ConnectivityManager.TYPE_MOBILE; -import static android.net.ConnectivityManager.TYPE_WIFI; -import static android.net.NetworkIdentity.OEM_PAID; -import static android.net.NetworkIdentity.OEM_PRIVATE; -import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; -import static android.net.NetworkStats.DEFAULT_NETWORK_NO; -import static android.net.NetworkStats.DEFAULT_NETWORK_YES; -import static android.net.NetworkStats.IFACE_ALL; -import static android.net.NetworkStats.INTERFACES_ALL; -import static android.net.NetworkStats.METERED_ALL; -import static android.net.NetworkStats.METERED_NO; -import static android.net.NetworkStats.METERED_YES; -import static android.net.NetworkStats.ROAMING_ALL; -import static android.net.NetworkStats.ROAMING_NO; -import static android.net.NetworkStats.ROAMING_YES; -import static android.net.NetworkStats.SET_ALL; -import static android.net.NetworkStats.SET_DEFAULT; -import static android.net.NetworkStats.SET_FOREGROUND; -import static android.net.NetworkStats.STATS_PER_UID; -import static android.net.NetworkStats.TAG_ALL; -import static android.net.NetworkStats.TAG_NONE; -import static android.net.NetworkStats.UID_ALL; -import static android.net.NetworkStatsHistory.FIELD_ALL; -import static android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD; -import static android.net.NetworkTemplate.NETWORK_TYPE_ALL; -import static android.net.NetworkTemplate.OEM_MANAGED_NO; -import static android.net.NetworkTemplate.OEM_MANAGED_YES; -import static android.net.NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT; -import static android.net.NetworkTemplate.buildTemplateMobileAll; -import static android.net.NetworkTemplate.buildTemplateMobileWithRatType; -import static android.net.NetworkTemplate.buildTemplateWifi; -import static android.net.NetworkTemplate.buildTemplateWifiWildcard; -import static android.net.TrafficStats.MB_IN_BYTES; -import static android.net.TrafficStats.UID_REMOVED; -import static android.net.TrafficStats.UID_TETHERING; -import static android.text.format.DateUtils.DAY_IN_MILLIS; -import static android.text.format.DateUtils.HOUR_IN_MILLIS; -import static android.text.format.DateUtils.MINUTE_IN_MILLIS; -import static android.text.format.DateUtils.WEEK_IN_MILLIS; - -import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.annotation.NonNull; -import android.app.AlarmManager; -import android.app.usage.NetworkStatsManager; -import android.content.Context; -import android.content.Intent; -import android.database.ContentObserver; -import android.net.DataUsageRequest; -import android.net.INetworkManagementEventObserver; -import android.net.INetworkStatsSession; -import android.net.LinkProperties; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkStateSnapshot; -import android.net.NetworkStats; -import android.net.NetworkStatsHistory; -import android.net.NetworkTemplate; -import android.net.TelephonyNetworkSpecifier; -import android.net.UnderlyingNetworkInfo; -import android.net.netstats.provider.INetworkStatsProviderCallback; -import android.os.ConditionVariable; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.os.INetworkManagementService; -import android.os.Looper; -import android.os.Message; -import android.os.Messenger; -import android.os.PowerManager; -import android.os.SimpleClock; -import android.provider.Settings; -import android.telephony.TelephonyManager; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.internal.util.ArrayUtils; -import com.android.internal.util.test.BroadcastInterceptingContext; -import com.android.server.net.NetworkStatsService.NetworkStatsSettings; -import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config; -import com.android.testutils.HandlerUtils; -import com.android.testutils.TestableNetworkStatsProviderBinder; - -import libcore.io.IoUtils; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.io.File; -import java.time.Clock; -import java.time.ZoneOffset; -import java.util.Objects; -import java.util.concurrent.Executor; - -/** - * Tests for {@link NetworkStatsService}. - * - * TODO: This test used to be really brittle because it used Easymock - it uses Mockito now, but - * still uses the Easymock structure, which could be simplified. - */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class NetworkStatsServiceTest extends NetworkStatsBaseTest { - private static final String TAG = "NetworkStatsServiceTest"; - - private static final long TEST_START = 1194220800000L; - - private static final String IMSI_1 = "310004"; - private static final String IMSI_2 = "310260"; - private static final String TEST_SSID = "AndroidAP"; - - private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_SSID); - private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1); - private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2); - - private static final Network WIFI_NETWORK = new Network(100); - private static final Network MOBILE_NETWORK = new Network(101); - private static final Network VPN_NETWORK = new Network(102); - - private static final Network[] NETWORKS_WIFI = new Network[]{ WIFI_NETWORK }; - private static final Network[] NETWORKS_MOBILE = new Network[]{ MOBILE_NETWORK }; - - private static final long WAIT_TIMEOUT = 2 * 1000; // 2 secs - private static final int INVALID_TYPE = -1; - - private long mElapsedRealtime; - - private File mStatsDir; - private MockContext mServiceContext; - private @Mock TelephonyManager mTelephonyManager; - private @Mock INetworkManagementService mNetManager; - private @Mock NetworkStatsFactory mStatsFactory; - private @Mock NetworkStatsSettings mSettings; - private @Mock IBinder mBinder; - private @Mock AlarmManager mAlarmManager; - @Mock - private NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor; - private HandlerThread mHandlerThread; - - private NetworkStatsService mService; - private INetworkStatsSession mSession; - private INetworkManagementEventObserver mNetworkObserver; - private ContentObserver mContentObserver; - private Handler mHandler; - - private class MockContext extends BroadcastInterceptingContext { - private final Context mBaseContext; - - MockContext(Context base) { - super(base); - mBaseContext = base; - } - - @Override - public Object getSystemService(String name) { - if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; - return mBaseContext.getSystemService(name); - } - } - - private final Clock mClock = new SimpleClock(ZoneOffset.UTC) { - @Override - public long millis() { - return currentTimeMillis(); - } - }; - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - final Context context = InstrumentationRegistry.getContext(); - mServiceContext = new MockContext(context); - mStatsDir = context.getFilesDir(); - if (mStatsDir.exists()) { - IoUtils.deleteContents(mStatsDir); - } - - PowerManager powerManager = (PowerManager) mServiceContext.getSystemService( - Context.POWER_SERVICE); - PowerManager.WakeLock wakeLock = - powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); - - mHandlerThread = new HandlerThread("HandlerThread"); - final NetworkStatsService.Dependencies deps = makeDependencies(); - mService = new NetworkStatsService(mServiceContext, mNetManager, mAlarmManager, wakeLock, - mClock, mSettings, mStatsFactory, new NetworkStatsObservers(), mStatsDir, - getBaseDir(mStatsDir), deps); - - mElapsedRealtime = 0L; - - expectDefaultSettings(); - expectNetworkStatsUidDetail(buildEmptyStats()); - expectSystemReady(); - mService.systemReady(); - // Verify that system ready fetches realtime stats - verify(mStatsFactory).readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL); - // Wait for posting onChange() event to handler thread and verify that when system ready, - // start monitoring data usage per RAT type because the settings value is mock as false - // by default in expectSettings(). - waitForIdle(); - verify(mNetworkStatsSubscriptionsMonitor).start(); - reset(mNetworkStatsSubscriptionsMonitor); - - doReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS).when(mTelephonyManager) - .checkCarrierPrivilegesForPackageAnyPhone(anyString()); - - mSession = mService.openSession(); - assertNotNull("openSession() failed", mSession); - - // catch INetworkManagementEventObserver during systemReady() - ArgumentCaptor<INetworkManagementEventObserver> networkObserver = - ArgumentCaptor.forClass(INetworkManagementEventObserver.class); - verify(mNetManager).registerObserver(networkObserver.capture()); - mNetworkObserver = networkObserver.getValue(); - } - - @NonNull - private NetworkStatsService.Dependencies makeDependencies() { - return new NetworkStatsService.Dependencies() { - @Override - public HandlerThread makeHandlerThread() { - return mHandlerThread; - } - - @Override - public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor( - @NonNull Context context, @NonNull Looper looper, @NonNull Executor executor, - @NonNull NetworkStatsService service) { - - return mNetworkStatsSubscriptionsMonitor; - } - - @Override - public ContentObserver makeContentObserver(Handler handler, - NetworkStatsSettings settings, NetworkStatsSubscriptionsMonitor monitor) { - mHandler = handler; - return mContentObserver = super.makeContentObserver(handler, settings, monitor); - } - - }; - } - - @After - public void tearDown() throws Exception { - IoUtils.deleteContents(mStatsDir); - - mServiceContext = null; - mStatsDir = null; - - mNetManager = null; - mSettings = null; - - mSession.close(); - mService = null; - - mHandlerThread.quitSafely(); - } - - @Test - public void testNetworkStatsWifi() throws Exception { - // pretend that wifi network comes online; service should ask about full - // network state, and poll any existing interfaces before updating. - expectDefaultSettings(); - NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // verify service has empty history for wifi - assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); - - // modify some number on wifi, and trigger poll event - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, 1024L, 1L, 2048L, 2L)); - expectNetworkStatsUidDetail(buildEmptyStats()); - forcePollAndWaitForIdle(); - - // verify service recorded history - assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0); - - - // and bump forward again, with counters going higher. this is - // important, since polling should correctly subtract last snapshot. - incrementCurrentTime(DAY_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, 4096L, 4L, 8192L, 8L)); - expectNetworkStatsUidDetail(buildEmptyStats()); - forcePollAndWaitForIdle(); - - // verify service recorded history - assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0); - - } - - @Test - public void testStatsRebootPersist() throws Exception { - assertStatsFilesExist(false); - - // pretend that wifi network comes online; service should ask about full - // network state, and poll any existing interfaces before updating. - expectDefaultSettings(); - NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // verify service has empty history for wifi - assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); - - - // modify some number on wifi, and trigger poll event - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, 1024L, 8L, 2048L, 16L)); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L) - .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L)); - mService.setUidForeground(UID_RED, false); - mService.incrementOperationCount(UID_RED, 0xFAAD, 4); - mService.setUidForeground(UID_RED, true); - mService.incrementOperationCount(UID_RED, 0xFAAD, 6); - - forcePollAndWaitForIdle(); - - // verify service recorded history - assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0); - assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10); - assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 512L, 4L, 256L, 2L, 4); - assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 512L, 4L, 256L, 2L, 6); - assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0); - - - // graceful shutdown system, which should trigger persist of stats, and - // clear any values in memory. - expectDefaultSettings(); - mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN)); - assertStatsFilesExist(true); - - // boot through serviceReady() again - expectDefaultSettings(); - expectNetworkStatsUidDetail(buildEmptyStats()); - expectSystemReady(); - - mService.systemReady(); - - // after systemReady(), we should have historical stats loaded again - assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0); - assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10); - assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 512L, 4L, 256L, 2L, 4); - assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 512L, 4L, 256L, 2L, 6); - assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0); - - } - - // TODO: simulate reboot to test bucket resize - @Test - @Ignore - public void testStatsBucketResize() throws Exception { - NetworkStatsHistory history = null; - - assertStatsFilesExist(false); - - // pretend that wifi network comes online; service should ask about full - // network state, and poll any existing interfaces before updating. - expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS); - NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // modify some number on wifi, and trigger poll event - incrementCurrentTime(2 * HOUR_IN_MILLIS); - expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS); - expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, 512L, 4L, 512L, 4L)); - expectNetworkStatsUidDetail(buildEmptyStats()); - forcePollAndWaitForIdle(); - - // verify service recorded history - history = mSession.getHistoryForNetwork(sTemplateWifi, FIELD_ALL); - assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0); - assertEquals(HOUR_IN_MILLIS, history.getBucketDuration()); - assertEquals(2, history.size()); - - - // now change bucket duration setting and trigger another poll with - // exact same values, which should resize existing buckets. - expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS); - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - forcePollAndWaitForIdle(); - - // verify identical stats, but spread across 4 buckets now - history = mSession.getHistoryForNetwork(sTemplateWifi, FIELD_ALL); - assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0); - assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration()); - assertEquals(4, history.size()); - - } - - @Test - public void testUidStatsAcrossNetworks() throws Exception { - // pretend first mobile network comes online - expectDefaultSettings(); - NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildMobile3gState(IMSI_1)}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // create some traffic on first network - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L)); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) - .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L)); - mService.incrementOperationCount(UID_RED, 0xF00D, 10); - - forcePollAndWaitForIdle(); - - // verify service recorded history - assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0); - assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); - assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10); - assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0); - - - // now switch networks; this also tests that we're okay with interfaces - // disappearing, to verify we don't count backwards. - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - states = new NetworkStateSnapshot[] {buildMobile3gState(IMSI_2)}; - expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L)); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) - .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L)); - - mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - forcePollAndWaitForIdle(); - - - // create traffic on second network - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, 2176L, 17L, 1536L, 12L)); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) - .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L) - .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L)); - mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10); - - forcePollAndWaitForIdle(); - - // verify original history still intact - assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0); - assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10); - assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0); - - // and verify new history also recorded under different template, which - // verifies that we didn't cross the streams. - assertNetworkTotal(sTemplateImsi2, 128L, 1L, 1024L, 8L, 0); - assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); - assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1L, 1024L, 8L, 10); - - } - - @Test - public void testUidRemovedIsMoved() throws Exception { - // pretend that network comes online - expectDefaultSettings(); - NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // create some traffic - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L)); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L) - .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, - 4096L, 258L, 512L, 32L, 0L) - .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)); - mService.incrementOperationCount(UID_RED, 0xFAAD, 10); - - forcePollAndWaitForIdle(); - - // verify service recorded history - assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0); - assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 10); - assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0); - assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0); - - - // now pretend two UIDs are uninstalled, which should migrate stats to - // special "removed" bucket. - expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L)); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L) - .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, - 4096L, 258L, 512L, 32L, 0L) - .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)); - final Intent intent = new Intent(ACTION_UID_REMOVED); - intent.putExtra(EXTRA_UID, UID_BLUE); - mServiceContext.sendBroadcast(intent); - intent.putExtra(EXTRA_UID, UID_RED); - mServiceContext.sendBroadcast(intent); - - // existing uid and total should remain unchanged; but removed UID - // should be gone completely. - assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0); - assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0); - assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L, 0L, 0L, 0); - assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0); - assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 259L, 528L, 33L, 10); - - } - - @Test - public void testMobileStatsByRatType() throws Exception { - final NetworkTemplate template3g = - buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UMTS); - final NetworkTemplate template4g = - buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_LTE); - final NetworkTemplate template5g = - buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_NR); - final NetworkStateSnapshot[] states = - new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)}; - - // 3G network comes online. - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS); - mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // Create some traffic. - incrementCurrentTime(MINUTE_IN_MILLIS); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, - 12L, 18L, 14L, 1L, 0L))); - forcePollAndWaitForIdle(); - - // Verify 3g templates gets stats. - assertUidTotal(sTemplateImsi1, UID_RED, 12L, 18L, 14L, 1L, 0); - assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0); - assertUidTotal(template4g, UID_RED, 0L, 0L, 0L, 0L, 0); - assertUidTotal(template5g, UID_RED, 0L, 0L, 0L, 0L, 0); - - // 4G network comes online. - incrementCurrentTime(MINUTE_IN_MILLIS); - setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_LTE); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - // Append more traffic on existing 3g stats entry. - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, - 16L, 22L, 17L, 2L, 0L)) - // Add entry that is new on 4g. - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, - 33L, 27L, 8L, 10L, 1L))); - forcePollAndWaitForIdle(); - - // Verify ALL_MOBILE template gets all. 3g template counters do not increase. - assertUidTotal(sTemplateImsi1, UID_RED, 49L, 49L, 25L, 12L, 1); - assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0); - // Verify 4g template counts appended stats on existing entry and newly created entry. - assertUidTotal(template4g, UID_RED, 4L + 33L, 4L + 27L, 3L + 8L, 1L + 10L, 1); - // Verify 5g template doesn't get anything since no traffic is generated on 5g. - assertUidTotal(template5g, UID_RED, 0L, 0L, 0L, 0L, 0); - - // 5g network comes online. - incrementCurrentTime(MINUTE_IN_MILLIS); - setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_NR); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - // Existing stats remains. - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, - 16L, 22L, 17L, 2L, 0L)) - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, - 33L, 27L, 8L, 10L, 1L)) - // Add some traffic on 5g. - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, - 5L, 13L, 31L, 9L, 2L))); - forcePollAndWaitForIdle(); - - // Verify ALL_MOBILE template gets all. - assertUidTotal(sTemplateImsi1, UID_RED, 54L, 62L, 56L, 21L, 3); - // 3g/4g template counters do not increase. - assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0); - assertUidTotal(template4g, UID_RED, 4L + 33L, 4L + 27L, 3L + 8L, 1L + 10L, 1); - // Verify 5g template gets the 5g count. - assertUidTotal(template5g, UID_RED, 5L, 13L, 31L, 9L, 2); - } - - @Test - public void testMobileStatsOemManaged() throws Exception { - final NetworkTemplate templateOemPaid = new NetworkTemplate(MATCH_MOBILE_WILDCARD, - /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, - METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PAID, - SUBSCRIBER_ID_MATCH_RULE_EXACT); - - final NetworkTemplate templateOemPrivate = new NetworkTemplate(MATCH_MOBILE_WILDCARD, - /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, - METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PRIVATE, - SUBSCRIBER_ID_MATCH_RULE_EXACT); - - final NetworkTemplate templateOemAll = new NetworkTemplate(MATCH_MOBILE_WILDCARD, - /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, - METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, - OEM_PAID | OEM_PRIVATE, SUBSCRIBER_ID_MATCH_RULE_EXACT); - - final NetworkTemplate templateOemYes = new NetworkTemplate(MATCH_MOBILE_WILDCARD, - /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, - METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES, - SUBSCRIBER_ID_MATCH_RULE_EXACT); - - final NetworkTemplate templateOemNone = new NetworkTemplate(MATCH_MOBILE_WILDCARD, - /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, - METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO, - SUBSCRIBER_ID_MATCH_RULE_EXACT); - - // OEM_PAID network comes online. - NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{ - buildOemManagedMobileState(IMSI_1, false, - new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PAID})}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // Create some traffic. - incrementCurrentTime(MINUTE_IN_MILLIS); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, - 36L, 41L, 24L, 96L, 0L))); - forcePollAndWaitForIdle(); - - // OEM_PRIVATE network comes online. - states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false, - new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE})}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // Create some traffic. - incrementCurrentTime(MINUTE_IN_MILLIS); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, - 49L, 71L, 72L, 48L, 0L))); - forcePollAndWaitForIdle(); - - // OEM_PAID + OEM_PRIVATE network comes online. - states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false, - new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, - NetworkCapabilities.NET_CAPABILITY_OEM_PAID})}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // Create some traffic. - incrementCurrentTime(MINUTE_IN_MILLIS); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, - 57L, 86L, 83L, 93L, 0L))); - forcePollAndWaitForIdle(); - - // OEM_NONE network comes online. - states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false, new int[]{})}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // Create some traffic. - incrementCurrentTime(MINUTE_IN_MILLIS); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, - 29L, 73L, 34L, 31L, 0L))); - forcePollAndWaitForIdle(); - - // Verify OEM_PAID template gets only relevant stats. - assertUidTotal(templateOemPaid, UID_RED, 36L, 41L, 24L, 96L, 0); - - // Verify OEM_PRIVATE template gets only relevant stats. - assertUidTotal(templateOemPrivate, UID_RED, 49L, 71L, 72L, 48L, 0); - - // Verify OEM_PAID + OEM_PRIVATE template gets only relevant stats. - assertUidTotal(templateOemAll, UID_RED, 57L, 86L, 83L, 93L, 0); - - // Verify OEM_NONE sees only non-OEM managed stats. - assertUidTotal(templateOemNone, UID_RED, 29L, 73L, 34L, 31L, 0); - - // Verify OEM_MANAGED_YES sees all OEM managed stats. - assertUidTotal(templateOemYes, UID_RED, - 36L + 49L + 57L, - 41L + 71L + 86L, - 24L + 72L + 83L, - 96L + 48L + 93L, 0); - - // Verify ALL_MOBILE template gets both OEM managed and non-OEM managed stats. - assertUidTotal(sTemplateImsi1, UID_RED, - 36L + 49L + 57L + 29L, - 41L + 71L + 86L + 73L, - 24L + 72L + 83L + 34L, - 96L + 48L + 93L + 31L, 0); - } - - // TODO: support per IMSI state - private void setMobileRatTypeAndWaitForIdle(int ratType) { - when(mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(anyString())) - .thenReturn(ratType); - mService.handleOnCollapsedRatTypeChanged(); - HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT); - } - - @Test - public void testSummaryForAllUid() throws Exception { - // pretend that network comes online - expectDefaultSettings(); - NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // create some traffic for two apps - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L) - .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L)); - mService.incrementOperationCount(UID_RED, 0xF00D, 1); - - forcePollAndWaitForIdle(); - - // verify service recorded history - assertUidTotal(sTemplateWifi, UID_RED, 50L, 5L, 50L, 5L, 1); - assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 8L, 512L, 4L, 0); - - - // now create more traffic in next hour, but only for one app - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L) - .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, - 2048L, 16L, 1024L, 8L, 0L)); - forcePollAndWaitForIdle(); - - // first verify entire history present - NetworkStats stats = mSession.getSummaryForAllUid( - sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true); - assertEquals(3, stats.size()); - assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 50L, 5L, 50L, 5L, 1); - assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 10L, 1L, 10L, 1L, 1); - assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 2048L, 16L, 1024L, 8L, 0); - - // now verify that recent history only contains one uid - final long currentTime = currentTimeMillis(); - stats = mSession.getSummaryForAllUid( - sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true); - assertEquals(1, stats.size()); - assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 1024L, 8L, 512L, 4L, 0); - } - - @Test - public void testDetailedUidStats() throws Exception { - // pretend that network comes online - expectDefaultSettings(); - NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - NetworkStats.Entry entry1 = new NetworkStats.Entry( - TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L); - NetworkStats.Entry entry2 = new NetworkStats.Entry( - TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 50L, 5L, 50L, 5L, 0L); - NetworkStats.Entry entry3 = new NetworkStats.Entry( - TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xBEEF, 1024L, 8L, 512L, 4L, 0L); - - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3) - .insertEntry(entry1) - .insertEntry(entry2) - .insertEntry(entry3)); - mService.incrementOperationCount(UID_RED, 0xF00D, 1); - - NetworkStats stats = mService.getDetailedUidStats(INTERFACES_ALL); - - assertEquals(3, stats.size()); - entry1.operations = 1; - assertEquals(entry1, stats.getValues(0, null)); - entry2.operations = 1; - assertEquals(entry2, stats.getValues(1, null)); - assertEquals(entry3, stats.getValues(2, null)); - } - - @Test - public void testDetailedUidStats_Filtered() throws Exception { - // pretend that network comes online - expectDefaultSettings(); - - final String stackedIface = "stacked-test0"; - final LinkProperties stackedProp = new LinkProperties(); - stackedProp.setInterfaceName(stackedIface); - final NetworkStateSnapshot wifiState = buildWifiState(); - wifiState.getLinkProperties().addStackedLink(stackedProp); - NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {wifiState}; - - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - NetworkStats.Entry uidStats = new NetworkStats.Entry( - TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xF00D, 1024L, 8L, 512L, 4L, 0L); - // Stacked on matching interface - NetworkStats.Entry tetheredStats1 = new NetworkStats.Entry( - stackedIface, UID_BLUE, SET_DEFAULT, 0xF00D, 1024L, 8L, 512L, 4L, 0L); - // Different interface - NetworkStats.Entry tetheredStats2 = new NetworkStats.Entry( - "otherif", UID_BLUE, SET_DEFAULT, 0xF00D, 1024L, 8L, 512L, 4L, 0L); - - final String[] ifaceFilter = new String[] { TEST_IFACE }; - final String[] augmentedIfaceFilter = new String[] { stackedIface, TEST_IFACE }; - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats()); - when(mStatsFactory.augmentWithStackedInterfaces(eq(ifaceFilter))) - .thenReturn(augmentedIfaceFilter); - when(mStatsFactory.readNetworkStatsDetail(eq(UID_ALL), any(), eq(TAG_ALL))) - .thenReturn(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(uidStats)); - when(mNetManager.getNetworkStatsTethering(STATS_PER_UID)) - .thenReturn(new NetworkStats(getElapsedRealtime(), 2) - .insertEntry(tetheredStats1) - .insertEntry(tetheredStats2)); - - NetworkStats stats = mService.getDetailedUidStats(ifaceFilter); - - // mStatsFactory#readNetworkStatsDetail() has the following invocations: - // 1) NetworkStatsService#systemReady from #setUp. - // 2) mService#forceUpdateIfaces in the test above. - // - // Additionally, we should have one call from the above call to mService#getDetailedUidStats - // with the augmented ifaceFilter. - verify(mStatsFactory, times(2)).readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL); - verify(mStatsFactory, times(1)).readNetworkStatsDetail( - eq(UID_ALL), - eq(augmentedIfaceFilter), - eq(TAG_ALL)); - assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), TEST_IFACE)); - assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), stackedIface)); - assertEquals(2, stats.size()); - assertEquals(uidStats, stats.getValues(0, null)); - assertEquals(tetheredStats1, stats.getValues(1, null)); - } - - @Test - public void testForegroundBackground() throws Exception { - // pretend that network comes online - expectDefaultSettings(); - NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // create some initial traffic - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)); - mService.incrementOperationCount(UID_RED, 0xF00D, 1); - - forcePollAndWaitForIdle(); - - // verify service recorded history - assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1); - - - // now switch to foreground - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L)); - mService.setUidForeground(UID_RED, true); - mService.incrementOperationCount(UID_RED, 0xFAAD, 1); - - forcePollAndWaitForIdle(); - - // test that we combined correctly - assertUidTotal(sTemplateWifi, UID_RED, 160L, 4L, 160L, 4L, 2); - - // verify entire history present - final NetworkStats stats = mSession.getSummaryForAllUid( - sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true); - assertEquals(4, stats.size()); - assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1); - assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1); - assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 32L, 2L, 32L, 2L, 1); - assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 1L, 1L, 1L, 1L, 1); - } - - @Test - public void testMetered() throws Exception { - // pretend that network comes online - expectDefaultSettings(); - NetworkStateSnapshot[] states = - new NetworkStateSnapshot[] {buildWifiState(true /* isMetered */, TEST_IFACE)}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // create some initial traffic - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats()); - // Note that all traffic from NetworkManagementService is tagged as METERED_NO, ROAMING_NO - // and DEFAULT_NETWORK_YES, because these three properties aren't tracked at that layer. - // We layer them on top by inspecting the iface properties. - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L)); - mService.incrementOperationCount(UID_RED, 0xF00D, 1); - - forcePollAndWaitForIdle(); - - // verify service recorded history - assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1); - // verify entire history present - final NetworkStats stats = mSession.getSummaryForAllUid( - sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true); - assertEquals(2, stats.size()); - assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1); - assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1); - } - - @Test - public void testRoaming() throws Exception { - // pretend that network comes online - expectDefaultSettings(); - NetworkStateSnapshot[] states = - new NetworkStateSnapshot[] {buildMobile3gState(IMSI_1, true /* isRoaming */)}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // Create some traffic - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats()); - // Note that all traffic from NetworkManagementService is tagged as METERED_NO and - // ROAMING_NO, because metered and roaming isn't tracked at that layer. We layer it - // on top by inspecting the iface properties. - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO, - DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO, - DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L)); - forcePollAndWaitForIdle(); - - // verify service recorded history - assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0); - - // verify entire history present - final NetworkStats stats = mSession.getSummaryForAllUid( - sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true); - assertEquals(2, stats.size()); - assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_YES, - DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0); - assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_YES, - DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0); - } - - @Test - public void testTethering() throws Exception { - // pretend first mobile network comes online - expectDefaultSettings(); - final NetworkStateSnapshot[] states = - new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // create some tethering traffic - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - - // Register custom provider and retrieve callback. - final TestableNetworkStatsProviderBinder provider = - new TestableNetworkStatsProviderBinder(); - final INetworkStatsProviderCallback cb = - mService.registerNetworkStatsProvider("TEST-TETHERING-OFFLOAD", provider); - assertNotNull(cb); - final long now = getElapsedRealtime(); - - // Traffic seen by kernel counters (includes software tethering). - final NetworkStats swIfaceStats = new NetworkStats(now, 1) - .insertEntry(TEST_IFACE, 1536L, 12L, 384L, 3L); - // Hardware tethering traffic, not seen by kernel counters. - final NetworkStats tetherHwIfaceStats = new NetworkStats(now, 1) - .insertEntry(new NetworkStats.Entry(TEST_IFACE, UID_ALL, SET_DEFAULT, - TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, - 512L, 4L, 128L, 1L, 0L)); - final NetworkStats tetherHwUidStats = new NetworkStats(now, 1) - .insertEntry(new NetworkStats.Entry(TEST_IFACE, UID_TETHERING, SET_DEFAULT, - TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, - 512L, 4L, 128L, 1L, 0L)); - cb.notifyStatsUpdated(0 /* unused */, tetherHwIfaceStats, tetherHwUidStats); - - // Fake some traffic done by apps on the device (as opposed to tethering), and record it - // into UID stats (as opposed to iface stats). - final NetworkStats localUidStats = new NetworkStats(now, 1) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L); - // Software per-uid tethering traffic. - final NetworkStats tetherSwUidStats = new NetworkStats(now, 1) - .insertEntry(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1408L, 10L, 256L, 1L, - 0L); - - expectNetworkStatsSummary(swIfaceStats); - expectNetworkStatsUidDetail(localUidStats, tetherSwUidStats); - forcePollAndWaitForIdle(); - - // verify service recorded history - assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0); - assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0); - assertUidTotal(sTemplateImsi1, UID_TETHERING, 1920L, 14L, 384L, 2L, 0); - } - - @Test - public void testRegisterUsageCallback() throws Exception { - // pretend that wifi network comes online; service should ask about full - // network state, and poll any existing interfaces before updating. - expectDefaultSettings(); - NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // verify service has empty history for wifi - assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); - long thresholdInBytes = 1L; // very small; should be overriden by framework - DataUsageRequest inputRequest = new DataUsageRequest( - DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, thresholdInBytes); - - // Create a messenger that waits for callback activity - ConditionVariable cv = new ConditionVariable(false); - LatchedHandler latchedHandler = new LatchedHandler(Looper.getMainLooper(), cv); - Messenger messenger = new Messenger(latchedHandler); - - // Force poll - expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - // Register and verify request and that binder was called - DataUsageRequest request = - mService.registerUsageCallback(mServiceContext.getOpPackageName(), inputRequest, - messenger, mBinder); - assertTrue(request.requestId > 0); - assertTrue(Objects.equals(sTemplateWifi, request.template)); - long minThresholdInBytes = 2 * 1024 * 1024; // 2 MB - assertEquals(minThresholdInBytes, request.thresholdInBytes); - - HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT); - - // Make sure that the caller binder gets connected - verify(mBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt()); - - // modify some number on wifi, and trigger poll event - // not enough traffic to call data usage callback - incrementCurrentTime(HOUR_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, 1024L, 1L, 2048L, 2L)); - expectNetworkStatsUidDetail(buildEmptyStats()); - forcePollAndWaitForIdle(); - - // verify service recorded history - assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0); - - // make sure callback has not being called - assertEquals(INVALID_TYPE, latchedHandler.lastMessageType); - - // and bump forward again, with counters going higher. this is - // important, since it will trigger the data usage callback - incrementCurrentTime(DAY_IN_MILLIS); - expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .insertEntry(TEST_IFACE, 4096000L, 4L, 8192000L, 8L)); - expectNetworkStatsUidDetail(buildEmptyStats()); - forcePollAndWaitForIdle(); - - // verify service recorded history - assertNetworkTotal(sTemplateWifi, 4096000L, 4L, 8192000L, 8L, 0); - - - // Wait for the caller to ack receipt of CALLBACK_LIMIT_REACHED - assertTrue(cv.block(WAIT_TIMEOUT)); - assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, latchedHandler.lastMessageType); - cv.close(); - - // Allow binder to disconnect - when(mBinder.unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt())).thenReturn(true); - - // Unregister request - mService.unregisterUsageRequest(request); - - // Wait for the caller to ack receipt of CALLBACK_RELEASED - assertTrue(cv.block(WAIT_TIMEOUT)); - assertEquals(NetworkStatsManager.CALLBACK_RELEASED, latchedHandler.lastMessageType); - - // Make sure that the caller binder gets disconnected - verify(mBinder).unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt()); - } - - @Test - public void testUnregisterUsageCallback_unknown_noop() throws Exception { - String callingPackage = "the.calling.package"; - long thresholdInBytes = 10 * 1024 * 1024; // 10 MB - DataUsageRequest unknownRequest = new DataUsageRequest( - 2 /* requestId */, sTemplateImsi1, thresholdInBytes); - - mService.unregisterUsageRequest(unknownRequest); - } - - @Test - public void testStatsProviderUpdateStats() throws Exception { - // Pretend that network comes online. - expectDefaultSettings(); - final NetworkStateSnapshot[] states = - new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - // Register custom provider and retrieve callback. - final TestableNetworkStatsProviderBinder provider = - new TestableNetworkStatsProviderBinder(); - final INetworkStatsProviderCallback cb = - mService.registerNetworkStatsProvider("TEST", provider); - assertNotNull(cb); - - mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // Verifies that one requestStatsUpdate will be called during iface update. - provider.expectOnRequestStatsUpdate(0 /* unused */); - - // Create some initial traffic and report to the service. - incrementCurrentTime(HOUR_IN_MILLIS); - final NetworkStats expectedStats = new NetworkStats(0L, 1) - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, - TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, - 128L, 2L, 128L, 2L, 1L)) - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, - 0xF00D, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, - 64L, 1L, 64L, 1L, 1L)); - cb.notifyStatsUpdated(0 /* unused */, expectedStats, expectedStats); - - // Make another empty mutable stats object. This is necessary since the new NetworkStats - // object will be used to compare with the old one in NetworkStatsRecoder, two of them - // cannot be the same object. - expectNetworkStatsUidDetail(buildEmptyStats()); - - forcePollAndWaitForIdle(); - - // Verifies that one requestStatsUpdate and setAlert will be called during polling. - provider.expectOnRequestStatsUpdate(0 /* unused */); - provider.expectOnSetAlert(MB_IN_BYTES); - - // Verifies that service recorded history, does not verify uid tag part. - assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1); - - // Verifies that onStatsUpdated updates the stats accordingly. - final NetworkStats stats = mSession.getSummaryForAllUid( - sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true); - assertEquals(2, stats.size()); - assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1L); - assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1L); - - // Verifies that unregister the callback will remove the provider from service. - cb.unregister(); - forcePollAndWaitForIdle(); - provider.assertNoCallback(); - } - - @Test - public void testDualVilteProviderStats() throws Exception { - // Pretend that network comes online. - expectDefaultSettings(); - final int subId1 = 1; - final int subId2 = 2; - final NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{ - buildImsState(IMSI_1, subId1, TEST_IFACE), - buildImsState(IMSI_2, subId2, TEST_IFACE2)}; - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - // Register custom provider and retrieve callback. - final TestableNetworkStatsProviderBinder provider = - new TestableNetworkStatsProviderBinder(); - final INetworkStatsProviderCallback cb = - mService.registerNetworkStatsProvider("TEST", provider); - assertNotNull(cb); - - mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // Verifies that one requestStatsUpdate will be called during iface update. - provider.expectOnRequestStatsUpdate(0 /* unused */); - - // Create some initial traffic and report to the service. - incrementCurrentTime(HOUR_IN_MILLIS); - final String vtIface1 = NetworkStats.IFACE_VT + subId1; - final String vtIface2 = NetworkStats.IFACE_VT + subId2; - final NetworkStats expectedStats = new NetworkStats(0L, 1) - .addEntry(new NetworkStats.Entry(vtIface1, UID_RED, SET_DEFAULT, - TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, - 128L, 2L, 128L, 2L, 1L)) - .addEntry(new NetworkStats.Entry(vtIface2, UID_RED, SET_DEFAULT, - TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, - 64L, 1L, 64L, 1L, 1L)); - cb.notifyStatsUpdated(0 /* unused */, expectedStats, expectedStats); - - // Make another empty mutable stats object. This is necessary since the new NetworkStats - // object will be used to compare with the old one in NetworkStatsRecoder, two of them - // cannot be the same object. - expectNetworkStatsUidDetail(buildEmptyStats()); - - forcePollAndWaitForIdle(); - - // Verifies that one requestStatsUpdate and setAlert will be called during polling. - provider.expectOnRequestStatsUpdate(0 /* unused */); - provider.expectOnSetAlert(MB_IN_BYTES); - - // Verifies that service recorded history, does not verify uid tag part. - assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 1); - - // Verifies that onStatsUpdated updates the stats accordingly. - NetworkStats stats = mSession.getSummaryForAllUid( - sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true); - assertEquals(1, stats.size()); - assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1L); - - stats = mSession.getSummaryForAllUid( - sTemplateImsi2, Long.MIN_VALUE, Long.MAX_VALUE, true); - assertEquals(1, stats.size()); - assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, - DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1L); - - // Verifies that unregister the callback will remove the provider from service. - cb.unregister(); - forcePollAndWaitForIdle(); - provider.assertNoCallback(); - } - - @Test - public void testStatsProviderSetAlert() throws Exception { - // Pretend that network comes online. - expectDefaultSettings(); - NetworkStateSnapshot[] states = - new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)}; - mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // Register custom provider and retrieve callback. - final TestableNetworkStatsProviderBinder provider = - new TestableNetworkStatsProviderBinder(); - final INetworkStatsProviderCallback cb = - mService.registerNetworkStatsProvider("TEST", provider); - assertNotNull(cb); - - // Simulates alert quota of the provider has been reached. - cb.notifyAlertReached(); - HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT); - - // Verifies that polling is triggered by alert reached. - provider.expectOnRequestStatsUpdate(0 /* unused */); - // Verifies that global alert will be re-armed. - provider.expectOnSetAlert(MB_IN_BYTES); - } - - private void setCombineSubtypeEnabled(boolean enable) { - when(mSettings.getCombineSubtypeEnabled()).thenReturn(enable); - mHandler.post(() -> mContentObserver.onChange(false, Settings.Global - .getUriFor(Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED))); - waitForIdle(); - if (enable) { - verify(mNetworkStatsSubscriptionsMonitor).stop(); - } else { - verify(mNetworkStatsSubscriptionsMonitor).start(); - } - } - - @Test - public void testDynamicWatchForNetworkRatTypeChanges() throws Exception { - // Build 3G template, type unknown template to get stats while network type is unknown - // and type all template to get the sum of all network type stats. - final NetworkTemplate template3g = - buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UMTS); - final NetworkTemplate templateUnknown = - buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UNKNOWN); - final NetworkTemplate templateAll = - buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL); - final NetworkStateSnapshot[] states = - new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)}; - - expectNetworkStatsSummary(buildEmptyStats()); - expectNetworkStatsUidDetail(buildEmptyStats()); - - // 3G network comes online. - setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS); - mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // Create some traffic. - incrementCurrentTime(MINUTE_IN_MILLIS); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, - 12L, 18L, 14L, 1L, 0L))); - forcePollAndWaitForIdle(); - - // Since CombineSubtypeEnabled is false by default in unit test, the generated traffic - // will be split by RAT type. Verify 3G templates gets stats, while template with unknown - // RAT type gets nothing, and template with NETWORK_TYPE_ALL gets all stats. - assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0); - assertUidTotal(templateUnknown, UID_RED, 0L, 0L, 0L, 0L, 0); - assertUidTotal(templateAll, UID_RED, 12L, 18L, 14L, 1L, 0); - - // Stop monitoring data usage per RAT type changes NetworkStatsService records data - // to {@link TelephonyManager#NETWORK_TYPE_UNKNOWN}. - setCombineSubtypeEnabled(true); - - // Call handleOnCollapsedRatTypeChanged manually to simulate the callback fired - // when stopping monitor, this is needed by NetworkStatsService to trigger updateIfaces. - mService.handleOnCollapsedRatTypeChanged(); - HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT); - // Create some traffic. - incrementCurrentTime(MINUTE_IN_MILLIS); - // Append more traffic on existing snapshot. - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, - 12L + 4L, 18L + 4L, 14L + 3L, 1L + 1L, 0L)) - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, - 35L, 29L, 7L, 11L, 1L))); - forcePollAndWaitForIdle(); - - // Verify 3G counters do not increase, while template with unknown RAT type gets new - // traffic and template with NETWORK_TYPE_ALL gets all stats. - assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0); - assertUidTotal(templateUnknown, UID_RED, 4L + 35L, 4L + 29L, 3L + 7L, 1L + 11L, 1); - assertUidTotal(templateAll, UID_RED, 16L + 35L, 22L + 29L, 17L + 7L, 2L + 11L, 1); - - // Start monitoring data usage per RAT type changes and NetworkStatsService records data - // by a granular subtype representative of the actual subtype - setCombineSubtypeEnabled(false); - - mService.handleOnCollapsedRatTypeChanged(); - HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT); - // Create some traffic. - incrementCurrentTime(MINUTE_IN_MILLIS); - // Append more traffic on existing snapshot. - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, - 22L, 26L, 19L, 5L, 0L)) - .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, - 35L, 29L, 7L, 11L, 1L))); - forcePollAndWaitForIdle(); - - // Verify traffic is split by RAT type, no increase on template with unknown RAT type - // and template with NETWORK_TYPE_ALL gets all stats. - assertUidTotal(template3g, UID_RED, 6L + 12L , 4L + 18L, 2L + 14L, 3L + 1L, 0); - assertUidTotal(templateUnknown, UID_RED, 4L + 35L, 4L + 29L, 3L + 7L, 1L + 11L, 1); - assertUidTotal(templateAll, UID_RED, 22L + 35L, 26L + 29L, 19L + 7L, 5L + 11L, 1); - } - - @Test - public void testOperationCount_nonDefault_traffic() throws Exception { - // Pretend mobile network comes online, but wifi is the default network. - expectDefaultSettings(); - NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{ - buildWifiState(true /*isMetered*/, TEST_IFACE2), buildMobile3gState(IMSI_1)}; - expectNetworkStatsUidDetail(buildEmptyStats()); - mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), - new UnderlyingNetworkInfo[0]); - - // Create some traffic on mobile network. - incrementCurrentTime(HOUR_IN_MILLIS); - expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 2L, 1L, 3L, 4L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_YES, 1L, 3L, 2L, 1L, 0L) - .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 5L, 4L, 1L, 4L, 0L)); - // Increment operation count, which must have a specific tag. - mService.incrementOperationCount(UID_RED, 0xF00D, 2); - forcePollAndWaitForIdle(); - - // Verify mobile summary is not changed by the operation count. - final NetworkTemplate templateMobile = - buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL); - final NetworkStats statsMobile = mSession.getSummaryForAllUid( - templateMobile, Long.MIN_VALUE, Long.MAX_VALUE, true); - assertValues(statsMobile, IFACE_ALL, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL, 3L, 4L, 5L, 5L, 0); - assertValues(statsMobile, IFACE_ALL, UID_RED, SET_ALL, 0xF00D, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL, 5L, 4L, 1L, 4L, 0); - - // Verify the operation count is blamed onto the default network. - // TODO: Blame onto the default network is not very reasonable. Consider blame onto the - // network that generates the traffic. - final NetworkTemplate templateWifi = buildTemplateWifiWildcard(); - final NetworkStats statsWifi = mSession.getSummaryForAllUid( - templateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true); - assertValues(statsWifi, IFACE_ALL, UID_RED, SET_ALL, 0xF00D, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL, 0L, 0L, 0L, 0L, 2); - } - - private static File getBaseDir(File statsDir) { - File baseDir = new File(statsDir, "netstats"); - baseDir.mkdirs(); - return baseDir; - } - - private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long rxPackets, - long txBytes, long txPackets, int operations) throws Exception { - assertNetworkTotal(template, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes, - txPackets, operations); - } - - private void assertNetworkTotal(NetworkTemplate template, long start, long end, long rxBytes, - long rxPackets, long txBytes, long txPackets, int operations) throws Exception { - // verify history API - final NetworkStatsHistory history = mSession.getHistoryForNetwork(template, FIELD_ALL); - assertValues(history, start, end, rxBytes, rxPackets, txBytes, txPackets, operations); - - // verify summary API - final NetworkStats stats = mSession.getSummaryForNetwork(template, start, end); - assertValues(stats, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL, rxBytes, rxPackets, txBytes, txPackets, operations); - } - - private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets, - long txBytes, long txPackets, int operations) throws Exception { - assertUidTotal(template, uid, SET_ALL, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, - rxBytes, rxPackets, txBytes, txPackets, operations); - } - - private void assertUidTotal(NetworkTemplate template, int uid, int set, int metered, - int roaming, int defaultNetwork, long rxBytes, long rxPackets, long txBytes, - long txPackets, int operations) throws Exception { - // verify history API - final NetworkStatsHistory history = mSession.getHistoryForUid( - template, uid, set, TAG_NONE, FIELD_ALL); - assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes, - txPackets, operations); - - // verify summary API - final NetworkStats stats = mSession.getSummaryForAllUid( - template, Long.MIN_VALUE, Long.MAX_VALUE, false); - assertValues(stats, IFACE_ALL, uid, set, TAG_NONE, metered, roaming, defaultNetwork, - rxBytes, rxPackets, txBytes, txPackets, operations); - } - - private void expectSystemReady() throws Exception { - expectNetworkStatsSummary(buildEmptyStats()); - } - - private String getActiveIface(NetworkStateSnapshot... states) throws Exception { - if (states == null || states.length == 0 || states[0].getLinkProperties() == null) { - return null; - } - return states[0].getLinkProperties().getInterfaceName(); - } - - private void expectNetworkStatsSummary(NetworkStats summary) throws Exception { - expectNetworkStatsSummaryDev(summary.clone()); - expectNetworkStatsSummaryXt(summary.clone()); - } - - private void expectNetworkStatsSummaryDev(NetworkStats summary) throws Exception { - when(mStatsFactory.readNetworkStatsSummaryDev()).thenReturn(summary); - } - - private void expectNetworkStatsSummaryXt(NetworkStats summary) throws Exception { - when(mStatsFactory.readNetworkStatsSummaryXt()).thenReturn(summary); - } - - private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception { - expectNetworkStatsUidDetail(detail, new NetworkStats(0L, 0)); - } - - private void expectNetworkStatsUidDetail(NetworkStats detail, NetworkStats tetherStats) - throws Exception { - when(mStatsFactory.readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL)) - .thenReturn(detail); - - // also include tethering details, since they are folded into UID - when(mNetManager.getNetworkStatsTethering(STATS_PER_UID)).thenReturn(tetherStats); - } - - private void expectDefaultSettings() throws Exception { - expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS); - } - - private void expectSettings(long persistBytes, long bucketDuration, long deleteAge) - throws Exception { - when(mSettings.getPollInterval()).thenReturn(HOUR_IN_MILLIS); - when(mSettings.getPollDelay()).thenReturn(0L); - when(mSettings.getSampleEnabled()).thenReturn(true); - when(mSettings.getCombineSubtypeEnabled()).thenReturn(false); - - final Config config = new Config(bucketDuration, deleteAge, deleteAge); - when(mSettings.getDevConfig()).thenReturn(config); - when(mSettings.getXtConfig()).thenReturn(config); - when(mSettings.getUidConfig()).thenReturn(config); - when(mSettings.getUidTagConfig()).thenReturn(config); - - when(mSettings.getGlobalAlertBytes(anyLong())).thenReturn(MB_IN_BYTES); - when(mSettings.getDevPersistBytes(anyLong())).thenReturn(MB_IN_BYTES); - when(mSettings.getXtPersistBytes(anyLong())).thenReturn(MB_IN_BYTES); - when(mSettings.getUidPersistBytes(anyLong())).thenReturn(MB_IN_BYTES); - when(mSettings.getUidTagPersistBytes(anyLong())).thenReturn(MB_IN_BYTES); - } - - private void assertStatsFilesExist(boolean exist) { - final File basePath = new File(mStatsDir, "netstats"); - if (exist) { - assertTrue(basePath.list().length > 0); - } else { - assertTrue(basePath.list().length == 0); - } - } - - private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes, - long rxPackets, long txBytes, long txPackets, int operations) { - final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null); - assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); - assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets); - assertEquals("unexpected txBytes", txBytes, entry.txBytes); - assertEquals("unexpected txPackets", txPackets, entry.txPackets); - assertEquals("unexpected operations", operations, entry.operations); - } - - private static NetworkStateSnapshot buildWifiState() { - return buildWifiState(false, TEST_IFACE); - } - - private static NetworkStateSnapshot buildWifiState(boolean isMetered, @NonNull String iface) { - final LinkProperties prop = new LinkProperties(); - prop.setInterfaceName(iface); - final NetworkCapabilities capabilities = new NetworkCapabilities(); - capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !isMetered); - capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true); - capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); - capabilities.setSSID(TEST_SSID); - return new NetworkStateSnapshot(WIFI_NETWORK, capabilities, prop, null, TYPE_WIFI); - } - - private static NetworkStateSnapshot buildMobile3gState(String subscriberId) { - return buildMobile3gState(subscriberId, false /* isRoaming */); - } - - private static NetworkStateSnapshot buildMobile3gState(String subscriberId, boolean isRoaming) { - final LinkProperties prop = new LinkProperties(); - prop.setInterfaceName(TEST_IFACE); - final NetworkCapabilities capabilities = new NetworkCapabilities(); - capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false); - capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming); - capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); - return new NetworkStateSnapshot( - MOBILE_NETWORK, capabilities, prop, subscriberId, TYPE_MOBILE); - } - - private NetworkStats buildEmptyStats() { - return new NetworkStats(getElapsedRealtime(), 0); - } - - private static NetworkStateSnapshot buildOemManagedMobileState( - String subscriberId, boolean isRoaming, int[] oemNetCapabilities) { - final LinkProperties prop = new LinkProperties(); - prop.setInterfaceName(TEST_IFACE); - final NetworkCapabilities capabilities = new NetworkCapabilities(); - capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false); - capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming); - for (int nc : oemNetCapabilities) { - capabilities.setCapability(nc, true); - } - capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); - return new NetworkStateSnapshot(MOBILE_NETWORK, capabilities, prop, subscriberId, - TYPE_MOBILE); - } - - private static NetworkStateSnapshot buildImsState( - String subscriberId, int subId, String ifaceName) { - final LinkProperties prop = new LinkProperties(); - prop.setInterfaceName(ifaceName); - final NetworkCapabilities capabilities = new NetworkCapabilities(); - capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, true); - capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true); - capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_IMS, true); - capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); - capabilities.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId)); - return new NetworkStateSnapshot( - MOBILE_NETWORK, capabilities, prop, subscriberId, TYPE_MOBILE); - } - - private long getElapsedRealtime() { - return mElapsedRealtime; - } - - private long startTimeMillis() { - return TEST_START; - } - - private long currentTimeMillis() { - return startTimeMillis() + mElapsedRealtime; - } - - private void incrementCurrentTime(long duration) { - mElapsedRealtime += duration; - } - - private void forcePollAndWaitForIdle() { - mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); - waitForIdle(); - } - - private void waitForIdle() { - HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT); - } - - static class LatchedHandler extends Handler { - private final ConditionVariable mCv; - int lastMessageType = INVALID_TYPE; - - LatchedHandler(Looper looper, ConditionVariable cv) { - super(looper); - mCv = cv; - } - - @Override - public void handleMessage(Message msg) { - lastMessageType = msg.what; - mCv.open(); - super.handleMessage(msg); - } - } -} diff --git a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java b/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java deleted file mode 100644 index 6d2c7dc39ffd..000000000000 --- a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.net; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.clearInvocations; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.Context; -import android.net.NetworkTemplate; -import android.os.test.TestLooper; -import android.telephony.NetworkRegistrationInfo; -import android.telephony.PhoneStateListener; -import android.telephony.ServiceState; -import android.telephony.SubscriptionManager; -import android.telephony.TelephonyManager; - -import com.android.internal.util.CollectionUtils; -import com.android.server.net.NetworkStatsSubscriptionsMonitor.RatTypeListener; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; - -@RunWith(JUnit4.class) -public final class NetworkStatsSubscriptionsMonitorTest { - private static final int TEST_SUBID1 = 3; - private static final int TEST_SUBID2 = 5; - private static final String TEST_IMSI1 = "466921234567890"; - private static final String TEST_IMSI2 = "466920987654321"; - private static final String TEST_IMSI3 = "466929999999999"; - - @Mock private Context mContext; - @Mock private SubscriptionManager mSubscriptionManager; - @Mock private TelephonyManager mTelephonyManager; - @Mock private NetworkStatsSubscriptionsMonitor.Delegate mDelegate; - private final List<Integer> mTestSubList = new ArrayList<>(); - - private final Executor mExecutor = Executors.newSingleThreadExecutor(); - private NetworkStatsSubscriptionsMonitor mMonitor; - private TestLooper mTestLooper = new TestLooper(); - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); - - when(mContext.getSystemService(eq(Context.TELEPHONY_SUBSCRIPTION_SERVICE))) - .thenReturn(mSubscriptionManager); - when(mContext.getSystemService(eq(Context.TELEPHONY_SERVICE))) - .thenReturn(mTelephonyManager); - - mMonitor = new NetworkStatsSubscriptionsMonitor(mContext, mTestLooper.getLooper(), - mExecutor, mDelegate); - } - - @Test - public void testStartStop() { - // Verify that addOnSubscriptionsChangedListener() is never called before start(). - verify(mSubscriptionManager, never()) - .addOnSubscriptionsChangedListener(mExecutor, mMonitor); - mMonitor.start(); - verify(mSubscriptionManager).addOnSubscriptionsChangedListener(mExecutor, mMonitor); - - // Verify that removeOnSubscriptionsChangedListener() is never called before stop() - verify(mSubscriptionManager, never()).removeOnSubscriptionsChangedListener(mMonitor); - mMonitor.stop(); - verify(mSubscriptionManager).removeOnSubscriptionsChangedListener(mMonitor); - } - - @NonNull - private static int[] convertArrayListToIntArray(@NonNull List<Integer> arrayList) { - final int[] list = new int[arrayList.size()]; - for (int i = 0; i < arrayList.size(); i++) { - list[i] = arrayList.get(i); - } - return list; - } - - private void setRatTypeForSub(List<RatTypeListener> listeners, - int subId, int type) { - final ServiceState serviceState = mock(ServiceState.class); - when(serviceState.getDataNetworkType()).thenReturn(type); - final RatTypeListener match = CollectionUtils - .find(listeners, it -> it.getSubId() == subId); - if (match == null) { - fail("Could not find listener with subId: " + subId); - } - match.onServiceStateChanged(serviceState); - } - - private void addTestSub(int subId, String subscriberId) { - // add SubId to TestSubList. - if (mTestSubList.contains(subId)) fail("The subscriber list already contains this ID"); - - mTestSubList.add(subId); - - final int[] subList = convertArrayListToIntArray(mTestSubList); - when(mSubscriptionManager.getCompleteActiveSubscriptionIdList()).thenReturn(subList); - when(mTelephonyManager.getSubscriberId(subId)).thenReturn(subscriberId); - mMonitor.onSubscriptionsChanged(); - } - - private void updateSubscriberIdForTestSub(int subId, @Nullable final String subscriberId) { - when(mTelephonyManager.getSubscriberId(subId)).thenReturn(subscriberId); - mMonitor.onSubscriptionsChanged(); - } - - private void removeTestSub(int subId) { - // Remove subId from TestSubList. - mTestSubList.removeIf(it -> it == subId); - final int[] subList = convertArrayListToIntArray(mTestSubList); - when(mSubscriptionManager.getCompleteActiveSubscriptionIdList()).thenReturn(subList); - mMonitor.onSubscriptionsChanged(); - } - - private void assertRatTypeChangedForSub(String subscriberId, int ratType) { - assertEquals(ratType, mMonitor.getRatTypeForSubscriberId(subscriberId)); - final ArgumentCaptor<Integer> typeCaptor = ArgumentCaptor.forClass(Integer.class); - // Verify callback with the subscriberId and the RAT type should be as expected. - // It will fail if get a callback with an unexpected RAT type. - verify(mDelegate).onCollapsedRatTypeChanged(eq(subscriberId), typeCaptor.capture()); - final int type = typeCaptor.getValue(); - assertEquals(ratType, type); - } - - private void assertRatTypeNotChangedForSub(String subscriberId, int ratType) { - assertEquals(mMonitor.getRatTypeForSubscriberId(subscriberId), ratType); - // Should never get callback with any RAT type. - verify(mDelegate, never()).onCollapsedRatTypeChanged(eq(subscriberId), anyInt()); - } - - @Test - public void testSubChangedAndRatTypeChanged() { - final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor = - ArgumentCaptor.forClass(RatTypeListener.class); - - mMonitor.start(); - // Insert sim1, verify RAT type is NETWORK_TYPE_UNKNOWN, and never get any callback - // before changing RAT type. - addTestSub(TEST_SUBID1, TEST_IMSI1); - assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); - - // Insert sim2. - addTestSub(TEST_SUBID2, TEST_IMSI2); - assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); - verify(mTelephonyManager, times(2)).listen(ratTypeListenerCaptor.capture(), - eq(PhoneStateListener.LISTEN_SERVICE_STATE)); - reset(mDelegate); - - // Set RAT type of sim1 to UMTS. - // Verify RAT type of sim1 after subscription gets onCollapsedRatTypeChanged() callback - // and others remain untouched. - setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, - TelephonyManager.NETWORK_TYPE_UMTS); - assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); - assertRatTypeNotChangedForSub(TEST_IMSI2, TelephonyManager.NETWORK_TYPE_UNKNOWN); - assertRatTypeNotChangedForSub(TEST_IMSI3, TelephonyManager.NETWORK_TYPE_UNKNOWN); - reset(mDelegate); - - // Set RAT type of sim2 to LTE. - // Verify RAT type of sim2 after subscription gets onCollapsedRatTypeChanged() callback - // and others remain untouched. - setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID2, - TelephonyManager.NETWORK_TYPE_LTE); - assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); - assertRatTypeChangedForSub(TEST_IMSI2, TelephonyManager.NETWORK_TYPE_LTE); - assertRatTypeNotChangedForSub(TEST_IMSI3, TelephonyManager.NETWORK_TYPE_UNKNOWN); - reset(mDelegate); - - // Remove sim2 and verify that callbacks are fired and RAT type is correct for sim2. - // while the other two remain untouched. - removeTestSub(TEST_SUBID2); - verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_NONE)); - assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); - assertRatTypeChangedForSub(TEST_IMSI2, TelephonyManager.NETWORK_TYPE_UNKNOWN); - assertRatTypeNotChangedForSub(TEST_IMSI3, TelephonyManager.NETWORK_TYPE_UNKNOWN); - reset(mDelegate); - - // Set RAT type of sim1 to UNKNOWN. Then stop monitoring subscription changes - // and verify that the listener for sim1 is removed. - setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, - TelephonyManager.NETWORK_TYPE_UNKNOWN); - assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); - reset(mDelegate); - - mMonitor.stop(); - verify(mTelephonyManager, times(2)).listen(any(), eq(PhoneStateListener.LISTEN_NONE)); - assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); - } - - - @Test - public void test5g() { - mMonitor.start(); - // Insert sim1, verify RAT type is NETWORK_TYPE_UNKNOWN, and never get any callback - // before changing RAT type. Also capture listener for later use. - addTestSub(TEST_SUBID1, TEST_IMSI1); - assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); - final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor = - ArgumentCaptor.forClass(RatTypeListener.class); - verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor.capture(), - eq(PhoneStateListener.LISTEN_SERVICE_STATE)); - final RatTypeListener listener = CollectionUtils - .find(ratTypeListenerCaptor.getAllValues(), it -> it.getSubId() == TEST_SUBID1); - assertNotNull(listener); - - // Set RAT type to 5G NSA (non-standalone) mode, verify the monitor outputs - // NETWORK_TYPE_5G_NSA. - final ServiceState serviceState = mock(ServiceState.class); - when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE); - when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED); - listener.onServiceStateChanged(serviceState); - assertRatTypeChangedForSub(TEST_IMSI1, NetworkTemplate.NETWORK_TYPE_5G_NSA); - reset(mDelegate); - - // Set RAT type to LTE without NR connected, the RAT type should be downgraded to LTE. - when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_NONE); - listener.onServiceStateChanged(serviceState); - assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_LTE); - reset(mDelegate); - - // Verify NR connected with other RAT type does not take effect. - when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_UMTS); - when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED); - listener.onServiceStateChanged(serviceState); - assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); - reset(mDelegate); - - // Set RAT type to 5G standalone mode, the RAT type should be NR. - setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, - TelephonyManager.NETWORK_TYPE_NR); - assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR); - reset(mDelegate); - - // Set NR state to none in standalone mode does not change anything. - when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_NR); - when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_NONE); - listener.onServiceStateChanged(serviceState); - assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR); - } - - @Test - public void testSubscriberIdUnavailable() { - final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor = - ArgumentCaptor.forClass(RatTypeListener.class); - - mMonitor.start(); - // Insert sim1, set subscriberId to null which is normal in SIM PIN locked case. - // Verify RAT type is NETWORK_TYPE_UNKNOWN and service will not perform listener - // registration. - addTestSub(TEST_SUBID1, null); - verify(mTelephonyManager, never()).listen(any(), anyInt()); - assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); - - // Set IMSI for sim1, verify the listener will be registered. - updateSubscriberIdForTestSub(TEST_SUBID1, TEST_IMSI1); - verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor.capture(), - eq(PhoneStateListener.LISTEN_SERVICE_STATE)); - reset(mTelephonyManager); - when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); - - // Set RAT type of sim1 to UMTS. Verify RAT type of sim1 is changed. - setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, - TelephonyManager.NETWORK_TYPE_UMTS); - assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); - reset(mDelegate); - - // Set IMSI to null again to simulate somehow IMSI is not available, such as - // modem crash. Verify service should unregister listener. - updateSubscriberIdForTestSub(TEST_SUBID1, null); - verify(mTelephonyManager, times(1)).listen(eq(ratTypeListenerCaptor.getValue()), - eq(PhoneStateListener.LISTEN_NONE)); - assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); - reset(mDelegate); - clearInvocations(mTelephonyManager); - - // Simulate somehow IMSI is back. Verify service will register with - // another listener and fire callback accordingly. - final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor2 = - ArgumentCaptor.forClass(RatTypeListener.class); - updateSubscriberIdForTestSub(TEST_SUBID1, TEST_IMSI1); - verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor2.capture(), - eq(PhoneStateListener.LISTEN_SERVICE_STATE)); - assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); - reset(mDelegate); - clearInvocations(mTelephonyManager); - - // Set RAT type of sim1 to LTE. Verify RAT type of sim1 still works. - setRatTypeForSub(ratTypeListenerCaptor2.getAllValues(), TEST_SUBID1, - TelephonyManager.NETWORK_TYPE_LTE); - assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_LTE); - reset(mDelegate); - - mMonitor.stop(); - verify(mTelephonyManager, times(1)).listen(eq(ratTypeListenerCaptor2.getValue()), - eq(PhoneStateListener.LISTEN_NONE)); - assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); - } - - /** - * Verify that when IMSI suddenly changed for a given subId, the service will register a new - * listener and unregister the old one, and report changes on updated IMSI. This is for modem - * feature that may be enabled for certain carrier, which changes to use a different IMSI while - * roaming on certain networks for multi-IMSI SIM cards, but the subId stays the same. - */ - @Test - public void testSubscriberIdChanged() { - mMonitor.start(); - // Insert sim1, verify RAT type is NETWORK_TYPE_UNKNOWN, and never get any callback - // before changing RAT type. - addTestSub(TEST_SUBID1, TEST_IMSI1); - final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor = - ArgumentCaptor.forClass(RatTypeListener.class); - verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor.capture(), - eq(PhoneStateListener.LISTEN_SERVICE_STATE)); - assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); - - // Set RAT type of sim1 to UMTS. - // Verify RAT type of sim1 changes accordingly. - setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, - TelephonyManager.NETWORK_TYPE_UMTS); - assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); - reset(mDelegate); - clearInvocations(mTelephonyManager); - - // Simulate IMSI of sim1 changed to IMSI2. Verify the service will register with - // another listener and remove the old one. The RAT type of new IMSI stays at - // NETWORK_TYPE_UNKNOWN until received initial callback from telephony. - final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor2 = - ArgumentCaptor.forClass(RatTypeListener.class); - updateSubscriberIdForTestSub(TEST_SUBID1, TEST_IMSI2); - verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor2.capture(), - eq(PhoneStateListener.LISTEN_SERVICE_STATE)); - verify(mTelephonyManager, times(1)).listen(eq(ratTypeListenerCaptor.getValue()), - eq(PhoneStateListener.LISTEN_NONE)); - assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); - assertRatTypeNotChangedForSub(TEST_IMSI2, TelephonyManager.NETWORK_TYPE_UNKNOWN); - reset(mDelegate); - - // Set RAT type of sim1 to UMTS for new listener to simulate the initial callback received - // from telephony after registration. Verify RAT type of sim1 changes with IMSI2 - // accordingly. - setRatTypeForSub(ratTypeListenerCaptor2.getAllValues(), TEST_SUBID1, - TelephonyManager.NETWORK_TYPE_UMTS); - assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); - assertRatTypeChangedForSub(TEST_IMSI2, TelephonyManager.NETWORK_TYPE_UMTS); - reset(mDelegate); - } -} diff --git a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java b/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java deleted file mode 100644 index ebbc0ef62548..000000000000 --- a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.net.ipmemorystore; - -import static org.junit.Assert.assertEquals; - -import android.net.ipmemorystore.NetworkAttributes; -import android.net.networkstack.aidl.quirks.IPv6ProvisioningLossQuirk; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.lang.reflect.Field; -import java.net.Inet4Address; -import java.net.UnknownHostException; -import java.util.Arrays; - -/** Unit tests for {@link NetworkAttributes}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class NetworkAttributesTest { - private static final String WEIGHT_FIELD_NAME_PREFIX = "WEIGHT_"; - private static final float EPSILON = 0.0001f; - - // This is running two tests to make sure the total weight is the sum of all weights. To be - // sure this is not fireproof, but you'd kind of need to do it on purpose to pass. - @Test - public void testTotalWeight() throws IllegalAccessException, UnknownHostException { - // Make sure that TOTAL_WEIGHT is equal to the sum of the fields starting with WEIGHT_ - float sum = 0f; - final Field[] fieldList = NetworkAttributes.class.getDeclaredFields(); - for (final Field field : fieldList) { - if (!field.getName().startsWith(WEIGHT_FIELD_NAME_PREFIX)) continue; - field.setAccessible(true); - sum += (float) field.get(null); - } - assertEquals(sum, NetworkAttributes.TOTAL_WEIGHT, EPSILON); - - final IPv6ProvisioningLossQuirk ipv6ProvisioningLossQuirk = - new IPv6ProvisioningLossQuirk(3, System.currentTimeMillis() + 7_200_000); - // Use directly the constructor with all attributes, and make sure that when compared - // to itself the score is a clean 1.0f. - final NetworkAttributes na = - new NetworkAttributes( - (Inet4Address) Inet4Address.getByAddress(new byte[] {1, 2, 3, 4}), - System.currentTimeMillis() + 7_200_000, - "some hint", - Arrays.asList(Inet4Address.getByAddress(new byte[] {5, 6, 7, 8}), - Inet4Address.getByAddress(new byte[] {9, 0, 1, 2})), - 98, ipv6ProvisioningLossQuirk); - assertEquals(1.0f, na.getNetworkGroupSamenessConfidence(na), EPSILON); - } -} diff --git a/tests/net/jni/Android.bp b/tests/net/jni/Android.bp deleted file mode 100644 index 22a04f5c0945..000000000000 --- a/tests/net/jni/Android.bp +++ /dev/null @@ -1,32 +0,0 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -cc_library_shared { - name: "libnetworkstatsfactorytestjni", - - cflags: [ - "-Wall", - "-Werror", - "-Wno-unused-parameter", - "-Wthread-safety", - ], - - srcs: [ - ":lib_networkStatsFactory_native", - "test_onload.cpp", - ], - - shared_libs: [ - "libbpf_android", - "liblog", - "libnativehelper", - "libnetdbpf", - "libnetdutils", - ], -} diff --git a/tests/net/jni/test_onload.cpp b/tests/net/jni/test_onload.cpp deleted file mode 100644 index 5194ddb0d882..000000000000 --- a/tests/net/jni/test_onload.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * this is a mini native libaray for NetworkStatsFactoryTest to run properly. It - * load all the native method related to NetworkStatsFactory when test run - */ -#include <nativehelper/JNIHelp.h> -#include "jni.h" -#include "utils/Log.h" -#include "utils/misc.h" - -namespace android { -int register_android_server_net_NetworkStatsFactory(JNIEnv* env); -}; - -using namespace android; - -extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) -{ - JNIEnv* env = NULL; - jint result = -1; - - if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { - ALOGE("GetEnv failed!"); - return result; - } - ALOG_ASSERT(env, "Could not retrieve the env!"); - register_android_server_net_NetworkStatsFactory(env); - return JNI_VERSION_1_4; -} diff --git a/tests/net/res/raw/history_v1 b/tests/net/res/raw/history_v1 Binary files differdeleted file mode 100644 index de79491c032e..000000000000 --- a/tests/net/res/raw/history_v1 +++ /dev/null diff --git a/tests/net/res/raw/net_dev_typical b/tests/net/res/raw/net_dev_typical deleted file mode 100644 index 290bf03eb9b4..000000000000 --- a/tests/net/res/raw/net_dev_typical +++ /dev/null @@ -1,8 +0,0 @@ -Inter-| Receive | Transmit - face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed - lo: 8308 116 0 0 0 0 0 0 8308 116 0 0 0 0 0 0 -rmnet0: 1507570 2205 0 0 0 0 0 0 489339 2237 0 0 0 0 0 0 - ifb0: 52454 151 0 151 0 0 0 0 0 0 0 0 0 0 0 0 - ifb1: 52454 151 0 151 0 0 0 0 0 0 0 0 0 0 0 0 - sit0: 0 0 0 0 0 0 0 0 0 0 148 0 0 0 0 0 -ip6tnl0: 0 0 0 0 0 0 0 0 0 0 151 151 0 0 0 0 diff --git a/tests/net/res/raw/netstats_uid_v4 b/tests/net/res/raw/netstats_uid_v4 Binary files differdeleted file mode 100644 index e75fc1ca5c2e..000000000000 --- a/tests/net/res/raw/netstats_uid_v4 +++ /dev/null diff --git a/tests/net/res/raw/netstats_v1 b/tests/net/res/raw/netstats_v1 Binary files differdeleted file mode 100644 index e80860a6b959..000000000000 --- a/tests/net/res/raw/netstats_v1 +++ /dev/null diff --git a/tests/net/res/raw/xt_qtaguid_iface_fmt_typical b/tests/net/res/raw/xt_qtaguid_iface_fmt_typical deleted file mode 100644 index 656d5bb82da4..000000000000 --- a/tests/net/res/raw/xt_qtaguid_iface_fmt_typical +++ /dev/null @@ -1,4 +0,0 @@ -ifname total_skb_rx_bytes total_skb_rx_packets total_skb_tx_bytes total_skb_tx_packets -rmnet2 4968 35 3081 39 -rmnet1 11153922 8051 190226 2468 -rmnet0 6824 16 5692 10 diff --git a/tests/net/res/raw/xt_qtaguid_iface_typical b/tests/net/res/raw/xt_qtaguid_iface_typical deleted file mode 100644 index 610723aef2f2..000000000000 --- a/tests/net/res/raw/xt_qtaguid_iface_typical +++ /dev/null @@ -1,6 +0,0 @@ -rmnet3 1 0 0 0 0 20822 501 1149991 815 -rmnet2 1 0 0 0 0 1594 15 1313 15 -rmnet1 1 0 0 0 0 207398 458 166918 565 -rmnet0 1 0 0 0 0 2112 24 700 10 -test1 1 1 2 3 4 5 6 7 8 -test2 0 1 2 3 4 5 6 7 8 diff --git a/tests/net/res/raw/xt_qtaguid_typical b/tests/net/res/raw/xt_qtaguid_typical deleted file mode 100644 index c1b0d259955c..000000000000 --- a/tests/net/res/raw/xt_qtaguid_typical +++ /dev/null @@ -1,71 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 wlan0 0x0 0 0 18621 96 2898 44 312 6 15897 58 2412 32 312 6 1010 16 1576 22 -3 wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 wlan0 0x0 1000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -5 wlan0 0x0 1000 1 1949 13 1078 14 0 0 1600 10 349 3 0 0 600 10 478 4 -6 wlan0 0x0 10005 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -7 wlan0 0x0 10005 1 32081 38 5315 50 32081 38 0 0 0 0 5315 50 0 0 0 0 -8 wlan0 0x0 10011 0 35777 53 5718 57 0 0 0 0 35777 53 0 0 0 0 5718 57 -9 wlan0 0x0 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -10 wlan0 0x0 10014 0 0 0 1098 13 0 0 0 0 0 0 0 0 0 0 1098 13 -11 wlan0 0x0 10014 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -12 wlan0 0x0 10021 0 562386 573 49228 549 0 0 0 0 562386 573 0 0 0 0 49228 549 -13 wlan0 0x0 10021 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -14 wlan0 0x0 10031 0 3425 5 586 6 0 0 0 0 3425 5 0 0 0 0 586 6 -15 wlan0 0x0 10031 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -16 wlan0 0x7fffff0100000000 10021 0 562386 573 49228 549 0 0 0 0 562386 573 0 0 0 0 49228 549 -17 wlan0 0x7fffff0100000000 10021 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -18 wlan0 0x7fffff0100000000 10031 0 3425 5 586 6 0 0 0 0 3425 5 0 0 0 0 586 6 -19 wlan0 0x7fffff0100000000 10031 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -20 rmnet2 0x0 0 0 547 5 118 2 40 1 243 1 264 3 0 0 62 1 56 1 -21 rmnet2 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -22 rmnet2 0x0 10001 0 1125899906842624 5 984 11 632 5 0 0 0 0 984 11 0 0 0 0 -23 rmnet2 0x0 10001 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -24 rmnet1 0x0 0 0 26736 174 7098 130 7210 97 18382 64 1144 13 2932 64 4054 64 112 2 -25 rmnet1 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -26 rmnet1 0x0 1000 0 75774 77 18038 78 75335 72 439 5 0 0 17668 73 370 5 0 0 -27 rmnet1 0x0 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -28 rmnet1 0x0 10007 0 269945 578 111632 586 269945 578 0 0 0 0 111632 586 0 0 0 0 -29 rmnet1 0x0 10007 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -30 rmnet1 0x0 10011 0 1741256 6918 769778 7019 1741256 6918 0 0 0 0 769778 7019 0 0 0 0 -31 rmnet1 0x0 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -32 rmnet1 0x0 10014 0 0 0 786 12 0 0 0 0 0 0 786 12 0 0 0 0 -33 rmnet1 0x0 10014 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -34 rmnet1 0x0 10021 0 433533 1454 393420 1604 433533 1454 0 0 0 0 393420 1604 0 0 0 0 -35 rmnet1 0x0 10021 1 21215 33 10278 33 21215 33 0 0 0 0 10278 33 0 0 0 0 -36 rmnet1 0x0 10036 0 6310 25 3284 29 6310 25 0 0 0 0 3284 29 0 0 0 0 -37 rmnet1 0x0 10036 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -38 rmnet1 0x0 10047 0 34264 47 3936 34 34264 47 0 0 0 0 3936 34 0 0 0 0 -39 rmnet1 0x0 10047 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -40 rmnet1 0x4e7700000000 10011 0 9187 27 4248 33 9187 27 0 0 0 0 4248 33 0 0 0 0 -41 rmnet1 0x4e7700000000 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -42 rmnet1 0x1000000000000000 10007 0 2109 4 791 4 2109 4 0 0 0 0 791 4 0 0 0 0 -43 rmnet1 0x1000000000000000 10007 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -44 rmnet1 0x1000000400000000 10007 0 9811 22 6286 22 9811 22 0 0 0 0 6286 22 0 0 0 0 -45 rmnet1 0x1000000400000000 10007 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -46 rmnet1 0x1010000000000000 10021 0 164833 426 135392 527 164833 426 0 0 0 0 135392 527 0 0 0 0 -47 rmnet1 0x1010000000000000 10021 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -48 rmnet1 0x1144000400000000 10011 0 10112 18 3334 17 10112 18 0 0 0 0 3334 17 0 0 0 0 -49 rmnet1 0x1144000400000000 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -50 rmnet1 0x1244000400000000 10011 0 1300 3 848 2 1300 3 0 0 0 0 848 2 0 0 0 0 -51 rmnet1 0x1244000400000000 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -52 rmnet1 0x3000000000000000 10007 0 10389 14 1521 12 10389 14 0 0 0 0 1521 12 0 0 0 0 -53 rmnet1 0x3000000000000000 10007 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -54 rmnet1 0x3000000400000000 10007 0 238070 380 93938 404 238070 380 0 0 0 0 93938 404 0 0 0 0 -55 rmnet1 0x3000000400000000 10007 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -56 rmnet1 0x3010000000000000 10021 0 219110 578 227423 676 219110 578 0 0 0 0 227423 676 0 0 0 0 -57 rmnet1 0x3010000000000000 10021 1 742 3 1265 3 742 3 0 0 0 0 1265 3 0 0 0 0 -58 rmnet1 0x3020000000000000 10021 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -59 rmnet1 0x3020000000000000 10021 1 20473 30 9013 30 20473 30 0 0 0 0 9013 30 0 0 0 0 -60 rmnet1 0x3144000400000000 10011 0 43963 92 34414 116 43963 92 0 0 0 0 34414 116 0 0 0 0 -61 rmnet1 0x3144000400000000 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -62 rmnet1 0x3244000400000000 10011 0 3486 8 1520 9 3486 8 0 0 0 0 1520 9 0 0 0 0 -63 rmnet1 0x3244000400000000 10011 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -64 rmnet1 0x7fffff0100000000 10021 0 29102 56 8865 60 29102 56 0 0 0 0 8865 60 0 0 0 0 -65 rmnet1 0x7fffff0100000000 10021 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -66 rmnet1 0x7fffff0300000000 1000 0 995 13 14145 14 995 13 0 0 0 0 14145 14 0 0 0 0 -67 rmnet1 0x7fffff0300000000 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -68 rmnet0 0x0 0 0 4312 49 1288 23 0 0 0 0 4312 49 0 0 0 0 1288 23 -69 rmnet0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -70 rmnet0 0x0 10080 0 22266 30 20976 30 0 0 0 0 22266 30 0 0 0 0 20976 30 -71 rmnet0 0x0 10080 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/tests/net/res/raw/xt_qtaguid_vpn_incorrect_iface b/tests/net/res/raw/xt_qtaguid_vpn_incorrect_iface deleted file mode 100644 index fc92715253ed..000000000000 --- a/tests/net/res/raw/xt_qtaguid_vpn_incorrect_iface +++ /dev/null @@ -1,3 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 test_nss_tun0 0x0 1001 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0 -3 test1 0x0 1004 0 1100 100 1100 100 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying deleted file mode 100644 index 1ef18894b669..000000000000 --- a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying +++ /dev/null @@ -1,5 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0 -3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0 -4 test0 0x0 1004 0 3300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -5 test0 0x0 1004 1 0 0 1650 150 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_compression b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_compression deleted file mode 100644 index 6d6bf550bbfa..000000000000 --- a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_compression +++ /dev/null @@ -1,4 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 test_nss_tun0 0x0 1001 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0 -3 test_nss_tun0 0x0 1002 0 3000 300 3000 300 0 0 0 0 0 0 0 0 0 0 0 0 -4 test0 0x0 1004 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_own_traffic b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_own_traffic deleted file mode 100644 index 2c2e5d2555f6..000000000000 --- a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_own_traffic +++ /dev/null @@ -1,6 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0 -3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0 -4 test_nss_tun0 0x0 1004 0 5000 500 6000 600 0 0 0 0 0 0 0 0 0 0 0 0 -5 test0 0x0 1004 0 8800 800 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -6 test0 0x0 1004 1 0 0 8250 750 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn deleted file mode 100644 index eb0513b10049..000000000000 --- a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn +++ /dev/null @@ -1,9 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0 -3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0 -4 test_nss_tun1 0x0 1001 0 3000 300 700 70 0 0 0 0 0 0 0 0 0 0 0 0 -5 test_nss_tun1 0x0 1002 0 500 50 250 25 0 0 0 0 0 0 0 0 0 0 0 0 -6 test0 0x0 1004 0 3300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -7 test0 0x0 1004 1 0 0 1650 150 0 0 0 0 0 0 0 0 0 0 0 0 -8 test1 0x0 1004 0 3850 350 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -9 test1 0x0 1004 1 0 0 1045 95 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file diff --git a/tests/net/res/raw/xt_qtaguid_vpn_rewrite_through_self b/tests/net/res/raw/xt_qtaguid_vpn_rewrite_through_self deleted file mode 100644 index afcdd7199026..000000000000 --- a/tests/net/res/raw/xt_qtaguid_vpn_rewrite_through_self +++ /dev/null @@ -1,6 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0 -3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0 -4 test_nss_tun0 0x0 1004 0 0 0 1600 160 0 0 0 0 0 0 0 0 0 0 0 0 -5 test0 0x0 1004 1 0 0 1760 176 0 0 0 0 0 0 0 0 0 0 0 0 -6 test0 0x0 1004 0 3300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file diff --git a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_duplication b/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_duplication deleted file mode 100644 index d7c7eb9f4ae8..000000000000 --- a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_duplication +++ /dev/null @@ -1,5 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 test_nss_tun0 0x0 1001 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0 -3 test_nss_tun0 0x0 1002 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0 -4 test0 0x0 1004 0 2200 200 2200 200 0 0 0 0 0 0 0 0 0 0 0 0 -5 test1 0x0 1004 0 2200 200 2200 200 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file diff --git a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split b/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split deleted file mode 100644 index 38a3dce4a834..000000000000 --- a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split +++ /dev/null @@ -1,4 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 test_nss_tun0 0x0 1001 0 500 50 1000 100 0 0 0 0 0 0 0 0 0 0 0 0 -3 test0 0x0 1004 0 330 30 660 60 0 0 0 0 0 0 0 0 0 0 0 0 -4 test1 0x0 1004 0 220 20 440 40 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file diff --git a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split_compression b/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split_compression deleted file mode 100644 index d35244b3b4f2..000000000000 --- a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split_compression +++ /dev/null @@ -1,4 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 test_nss_tun0 0x0 1001 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0 -3 test0 0x0 1004 0 600 60 600 60 0 0 0 0 0 0 0 0 0 0 0 0 -4 test1 0x0 1004 0 200 20 200 20 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file diff --git a/tests/net/res/raw/xt_qtaguid_vpn_with_clat b/tests/net/res/raw/xt_qtaguid_vpn_with_clat deleted file mode 100644 index 0d893d515ca2..000000000000 --- a/tests/net/res/raw/xt_qtaguid_vpn_with_clat +++ /dev/null @@ -1,8 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0 -3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0 -4 v4-test0 0x0 1004 0 3300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -5 v4-test0 0x0 1004 1 0 0 1650 150 0 0 0 0 0 0 0 0 0 0 0 0 -6 test0 0x0 0 0 9300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -7 test0 0x0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -8 test0 0x0 1029 0 0 0 4650 150 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file diff --git a/tests/net/res/raw/xt_qtaguid_with_clat b/tests/net/res/raw/xt_qtaguid_with_clat deleted file mode 100644 index f04b32f08332..000000000000 --- a/tests/net/res/raw/xt_qtaguid_with_clat +++ /dev/null @@ -1,43 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 v4-wlan0 0x0 0 0 256 5 196 4 256 5 0 0 0 0 196 4 0 0 0 0 -3 v4-wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 v4-wlan0 0x0 1000 0 30312 25 1770 27 30236 24 76 1 0 0 1694 26 76 1 0 0 -5 v4-wlan0 0x0 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -6 v4-wlan0 0x0 10060 0 9398432 6717 169412 4235 9398432 6717 0 0 0 0 169412 4235 0 0 0 0 -7 v4-wlan0 0x0 10060 1 1448660 1041 31192 753 1448660 1041 0 0 0 0 31192 753 0 0 0 0 -8 v4-wlan0 0x0 10102 0 9702 16 2870 23 9702 16 0 0 0 0 2870 23 0 0 0 0 -9 v4-wlan0 0x0 10102 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -10 wlan0 0x0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -11 wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -12 wlan0 0x0 1000 0 6126 13 2013 16 5934 11 192 2 0 0 1821 14 192 2 0 0 -13 wlan0 0x0 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -14 wlan0 0x0 10013 0 0 0 144 2 0 0 0 0 0 0 144 2 0 0 0 0 -15 wlan0 0x0 10013 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -16 wlan0 0x0 10018 0 5980263 4715 167667 1922 5972583 4709 0 0 7680 6 167667 1922 0 0 0 0 -17 wlan0 0x0 10018 1 43995 37 2766 27 43995 37 0 0 0 0 2766 27 0 0 0 0 -18 wlan0 0x0 10060 0 134356 133 8705 74 134356 133 0 0 0 0 8705 74 0 0 0 0 -19 wlan0 0x0 10060 1 294709 326 26448 256 294709 326 0 0 0 0 26448 256 0 0 0 0 -20 wlan0 0x0 10079 0 10926 13 1507 13 10926 13 0 0 0 0 1507 13 0 0 0 0 -21 wlan0 0x0 10079 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -22 wlan0 0x0 10102 0 25038 42 8245 57 25038 42 0 0 0 0 8245 57 0 0 0 0 -23 wlan0 0x0 10102 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -24 wlan0 0x0 10103 0 0 0 192 2 0 0 0 0 0 0 0 0 192 2 0 0 -25 wlan0 0x0 10103 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -26 wlan0 0x1000040700000000 10018 0 831 6 655 5 831 6 0 0 0 0 655 5 0 0 0 0 -27 wlan0 0x1000040700000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -28 wlan0 0x1000040b00000000 10018 0 1714 8 1561 7 1714 8 0 0 0 0 1561 7 0 0 0 0 -29 wlan0 0x1000040b00000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -30 wlan0 0x1000120300000000 10018 0 8243 11 2234 12 8243 11 0 0 0 0 2234 12 0 0 0 0 -31 wlan0 0x1000120300000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -32 wlan0 0x1000180300000000 10018 0 56368 49 4790 39 56368 49 0 0 0 0 4790 39 0 0 0 0 -33 wlan0 0x1000180300000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -34 wlan0 0x1000300000000000 10018 0 9488 17 18813 25 1808 11 0 0 7680 6 18813 25 0 0 0 0 -35 wlan0 0x1000300000000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -36 wlan0 0x3000180400000000 10018 0 131262 103 7416 103 131262 103 0 0 0 0 7416 103 0 0 0 0 -37 wlan0 0x3000180400000000 10018 1 43995 37 2766 27 43995 37 0 0 0 0 2766 27 0 0 0 0 -38 wlan0 0xffffff0100000000 10018 0 5771986 4518 131190 1725 5771986 4518 0 0 0 0 131190 1725 0 0 0 0 -39 wlan0 0xffffff0100000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -40 dummy0 0x0 0 0 0 0 168 3 0 0 0 0 0 0 0 0 0 0 168 3 -41 dummy0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -42 lo 0x0 0 0 1288 16 1288 16 0 0 532 8 756 8 0 0 532 8 756 8 -43 lo 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_after b/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_after deleted file mode 100644 index 12d98ca29f57..000000000000 --- a/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_after +++ /dev/null @@ -1,189 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 r_rmnet_data0 0x0 0 0 0 0 392 6 0 0 0 0 0 0 0 0 0 0 392 6 -3 r_rmnet_data0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 v4-wlan0 0x0 0 0 58952 2072 2888 65 264 6 0 0 58688 2066 132 3 0 0 2756 62 -5 v4-wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -6 v4-wlan0 0x0 10034 0 6192 11 1445 11 6192 11 0 0 0 0 1445 11 0 0 0 0 -7 v4-wlan0 0x0 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -8 v4-wlan0 0x0 10057 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -9 v4-wlan0 0x0 10057 1 728 7 392 7 0 0 728 7 0 0 0 0 392 7 0 0 -10 v4-wlan0 0x0 10106 0 2232 18 2232 18 0 0 2232 18 0 0 0 0 2232 18 0 0 -11 v4-wlan0 0x0 10106 1 432952718 314238 5442288 121260 432950238 314218 2480 20 0 0 5433900 121029 8388 231 0 0 -12 wlan0 0x0 0 0 330187296 250652 0 0 329106990 236273 226202 1255 854104 13124 0 0 0 0 0 0 -13 wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -14 wlan0 0x0 1000 0 77113 272 56151 575 77113 272 0 0 0 0 19191 190 36960 385 0 0 -15 wlan0 0x0 1000 1 20227 80 8356 72 18539 74 1688 6 0 0 7562 66 794 6 0 0 -16 wlan0 0x0 10006 0 80755 92 9122 99 80755 92 0 0 0 0 9122 99 0 0 0 0 -17 wlan0 0x0 10006 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -18 wlan0 0x0 10015 0 4390 7 14824 252 4390 7 0 0 0 0 14824 252 0 0 0 0 -19 wlan0 0x0 10015 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -20 wlan0 0x0 10018 0 4928 11 1741 14 4928 11 0 0 0 0 1741 14 0 0 0 0 -21 wlan0 0x0 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -22 wlan0 0x0 10020 0 21163552 34395 2351650 15326 21162947 34390 605 5 0 0 2351045 15321 605 5 0 0 -23 wlan0 0x0 10020 1 13835740 12938 1548795 6365 13833754 12920 1986 18 0 0 1546809 6347 1986 18 0 0 -24 wlan0 0x0 10023 0 13405 40 5042 44 13405 40 0 0 0 0 5042 44 0 0 0 0 -25 wlan0 0x0 10023 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -26 wlan0 0x0 10034 0 436394741 342648 6237981 80442 436394741 342648 0 0 0 0 6237981 80442 0 0 0 0 -27 wlan0 0x0 10034 1 64860872 51297 1335539 15546 64860872 51297 0 0 0 0 1335539 15546 0 0 0 0 -28 wlan0 0x0 10044 0 17614444 14774 521004 5694 17329882 14432 284562 342 0 0 419974 5408 101030 286 0 0 -29 wlan0 0x0 10044 1 17701 33 3100 28 17701 33 0 0 0 0 3100 28 0 0 0 0 -30 wlan0 0x0 10057 0 12312074 9339 436098 5450 12248060 9263 64014 76 0 0 414224 5388 21874 62 0 0 -31 wlan0 0x0 10057 1 1332953195 954797 31849632 457698 1331933207 953569 1019988 1228 0 0 31702284 456899 147348 799 0 0 -32 wlan0 0x0 10060 0 32972 200 433705 380 32972 200 0 0 0 0 433705 380 0 0 0 0 -33 wlan0 0x0 10060 1 32106 66 37789 87 32106 66 0 0 0 0 37789 87 0 0 0 0 -34 wlan0 0x0 10061 0 7675 23 2509 22 7675 23 0 0 0 0 2509 22 0 0 0 0 -35 wlan0 0x0 10061 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -36 wlan0 0x0 10074 0 38355 82 10447 97 38355 82 0 0 0 0 10447 97 0 0 0 0 -37 wlan0 0x0 10074 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -38 wlan0 0x0 10078 0 49013 79 7167 69 49013 79 0 0 0 0 7167 69 0 0 0 0 -39 wlan0 0x0 10078 1 5872 8 1236 10 5872 8 0 0 0 0 1236 10 0 0 0 0 -40 wlan0 0x0 10082 0 8301 13 1981 15 8301 13 0 0 0 0 1981 15 0 0 0 0 -41 wlan0 0x0 10082 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -42 wlan0 0x0 10086 0 7001 14 1579 15 7001 14 0 0 0 0 1579 15 0 0 0 0 -43 wlan0 0x0 10086 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -44 wlan0 0x0 10090 0 24327795 20224 920502 14661 24327795 20224 0 0 0 0 920502 14661 0 0 0 0 -45 wlan0 0x0 10090 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -46 wlan0 0x0 10092 0 36849 78 12449 81 36849 78 0 0 0 0 12449 81 0 0 0 0 -47 wlan0 0x0 10092 1 60 1 103 1 60 1 0 0 0 0 103 1 0 0 0 0 -48 wlan0 0x0 10095 0 131962 223 37069 241 131962 223 0 0 0 0 37069 241 0 0 0 0 -49 wlan0 0x0 10095 1 12949 21 3930 21 12949 21 0 0 0 0 3930 21 0 0 0 0 -50 wlan0 0x0 10106 0 30899554 22679 632476 12296 30895334 22645 4220 34 0 0 628256 12262 4220 34 0 0 -51 wlan0 0x0 10106 1 88923475 64963 1606962 35612 88917201 64886 3586 29 2688 48 1602032 35535 4930 77 0 0 -52 wlan0 0x40700000000 10020 0 705732 10589 404428 5504 705732 10589 0 0 0 0 404428 5504 0 0 0 0 -53 wlan0 0x40700000000 10020 1 2376 36 1296 18 2376 36 0 0 0 0 1296 18 0 0 0 0 -54 wlan0 0x40800000000 10020 0 34624 146 122525 160 34624 146 0 0 0 0 122525 160 0 0 0 0 -55 wlan0 0x40800000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -56 wlan0 0x40b00000000 10020 0 22411 85 7364 57 22411 85 0 0 0 0 7364 57 0 0 0 0 -57 wlan0 0x40b00000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -58 wlan0 0x120300000000 10020 0 76641 241 32783 169 76641 241 0 0 0 0 32783 169 0 0 0 0 -59 wlan0 0x120300000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -60 wlan0 0x130100000000 10020 0 73101 287 23236 203 73101 287 0 0 0 0 23236 203 0 0 0 0 -61 wlan0 0x130100000000 10020 1 264 4 144 2 264 4 0 0 0 0 144 2 0 0 0 0 -62 wlan0 0x180300000000 10020 0 330648 399 24736 232 330648 399 0 0 0 0 24736 232 0 0 0 0 -63 wlan0 0x180300000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -64 wlan0 0x180400000000 10020 0 21865 59 5022 42 21865 59 0 0 0 0 5022 42 0 0 0 0 -65 wlan0 0x180400000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -66 wlan0 0x300000000000 10020 0 15984 65 26927 57 15984 65 0 0 0 0 26927 57 0 0 0 0 -67 wlan0 0x300000000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -68 wlan0 0x1065fff00000000 10020 0 131871 599 93783 445 131871 599 0 0 0 0 93783 445 0 0 0 0 -69 wlan0 0x1065fff00000000 10020 1 264 4 144 2 264 4 0 0 0 0 144 2 0 0 0 0 -70 wlan0 0x1b24f4600000000 10034 0 15445 42 23329 45 15445 42 0 0 0 0 23329 45 0 0 0 0 -71 wlan0 0x1b24f4600000000 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -72 wlan0 0x1000010000000000 10020 0 5542 9 1364 10 5542 9 0 0 0 0 1364 10 0 0 0 0 -73 wlan0 0x1000010000000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -74 wlan0 0x1000040100000000 10020 0 47196 184 213319 257 47196 184 0 0 0 0 213319 257 0 0 0 0 -75 wlan0 0x1000040100000000 10020 1 60 1 103 1 60 1 0 0 0 0 103 1 0 0 0 0 -76 wlan0 0x1000040700000000 10020 0 11599 50 10786 47 11599 50 0 0 0 0 10786 47 0 0 0 0 -77 wlan0 0x1000040700000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -78 wlan0 0x1000040800000000 10020 0 21902 145 174139 166 21902 145 0 0 0 0 174139 166 0 0 0 0 -79 wlan0 0x1000040800000000 10020 1 8568 88 105743 90 8568 88 0 0 0 0 105743 90 0 0 0 0 -80 wlan0 0x1000100300000000 10020 0 55213 118 194551 199 55213 118 0 0 0 0 194551 199 0 0 0 0 -81 wlan0 0x1000100300000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -82 wlan0 0x1000120300000000 10020 0 50826 74 21153 70 50826 74 0 0 0 0 21153 70 0 0 0 0 -83 wlan0 0x1000120300000000 10020 1 72 1 175 2 72 1 0 0 0 0 175 2 0 0 0 0 -84 wlan0 0x1000180300000000 10020 0 744198 657 65437 592 744198 657 0 0 0 0 65437 592 0 0 0 0 -85 wlan0 0x1000180300000000 10020 1 144719 132 10989 108 144719 132 0 0 0 0 10989 108 0 0 0 0 -86 wlan0 0x1000180600000000 10020 0 4599 8 1928 10 4599 8 0 0 0 0 1928 10 0 0 0 0 -87 wlan0 0x1000180600000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -88 wlan0 0x1000250000000000 10020 0 57740 98 13076 88 57740 98 0 0 0 0 13076 88 0 0 0 0 -89 wlan0 0x1000250000000000 10020 1 328 3 414 4 207 2 121 1 0 0 293 3 121 1 0 0 -90 wlan0 0x1000300000000000 10020 0 7675 30 31331 32 7675 30 0 0 0 0 31331 32 0 0 0 0 -91 wlan0 0x1000300000000000 10020 1 30173 97 101335 100 30173 97 0 0 0 0 101335 100 0 0 0 0 -92 wlan0 0x1000310200000000 10020 0 1681 9 2194 9 1681 9 0 0 0 0 2194 9 0 0 0 0 -93 wlan0 0x1000310200000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -94 wlan0 0x1000360000000000 10020 0 5606 20 2831 20 5606 20 0 0 0 0 2831 20 0 0 0 0 -95 wlan0 0x1000360000000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -96 wlan0 0x11065fff00000000 10020 0 18363 91 83367 104 18363 91 0 0 0 0 83367 104 0 0 0 0 -97 wlan0 0x11065fff00000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -98 wlan0 0x3000009600000000 10020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -99 wlan0 0x3000009600000000 10020 1 6163 18 2424 18 6163 18 0 0 0 0 2424 18 0 0 0 0 -100 wlan0 0x3000009800000000 10020 0 23337 46 8723 39 23337 46 0 0 0 0 8723 39 0 0 0 0 -101 wlan0 0x3000009800000000 10020 1 33744 93 72437 89 33744 93 0 0 0 0 72437 89 0 0 0 0 -102 wlan0 0x3000020000000000 10020 0 4124 11 8969 19 4124 11 0 0 0 0 8969 19 0 0 0 0 -103 wlan0 0x3000020000000000 10020 1 5993 11 3815 14 5993 11 0 0 0 0 3815 14 0 0 0 0 -104 wlan0 0x3000040100000000 10020 0 113809 342 135666 308 113809 342 0 0 0 0 135666 308 0 0 0 0 -105 wlan0 0x3000040100000000 10020 1 142508 642 500579 637 142508 642 0 0 0 0 500579 637 0 0 0 0 -106 wlan0 0x3000040700000000 10020 0 365815 5119 213340 2733 365815 5119 0 0 0 0 213340 2733 0 0 0 0 -107 wlan0 0x3000040700000000 10020 1 30747 130 18408 100 30747 130 0 0 0 0 18408 100 0 0 0 0 -108 wlan0 0x3000040800000000 10020 0 34672 112 68623 92 34672 112 0 0 0 0 68623 92 0 0 0 0 -109 wlan0 0x3000040800000000 10020 1 78443 199 140944 192 78443 199 0 0 0 0 140944 192 0 0 0 0 -110 wlan0 0x3000040b00000000 10020 0 14949 33 4017 26 14949 33 0 0 0 0 4017 26 0 0 0 0 -111 wlan0 0x3000040b00000000 10020 1 996 15 576 8 996 15 0 0 0 0 576 8 0 0 0 0 -112 wlan0 0x3000090000000000 10020 0 11826 67 7309 52 11826 67 0 0 0 0 7309 52 0 0 0 0 -113 wlan0 0x3000090000000000 10020 1 24805 41 4785 41 24805 41 0 0 0 0 4785 41 0 0 0 0 -114 wlan0 0x3000100300000000 10020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -115 wlan0 0x3000100300000000 10020 1 3112 10 1628 10 3112 10 0 0 0 0 1628 10 0 0 0 0 -116 wlan0 0x3000120300000000 10020 0 38249 107 20374 85 38249 107 0 0 0 0 20374 85 0 0 0 0 -117 wlan0 0x3000120300000000 10020 1 122581 174 36792 143 122581 174 0 0 0 0 36792 143 0 0 0 0 -118 wlan0 0x3000130100000000 10020 0 2700 41 1524 21 2700 41 0 0 0 0 1524 21 0 0 0 0 -119 wlan0 0x3000130100000000 10020 1 22515 59 8366 52 22515 59 0 0 0 0 8366 52 0 0 0 0 -120 wlan0 0x3000180200000000 10020 0 6411 18 14511 20 6411 18 0 0 0 0 14511 20 0 0 0 0 -121 wlan0 0x3000180200000000 10020 1 336 5 319 4 336 5 0 0 0 0 319 4 0 0 0 0 -122 wlan0 0x3000180300000000 10020 0 129301 136 17622 97 129301 136 0 0 0 0 17622 97 0 0 0 0 -123 wlan0 0x3000180300000000 10020 1 464787 429 41703 336 464787 429 0 0 0 0 41703 336 0 0 0 0 -124 wlan0 0x3000180400000000 10020 0 11014 39 2787 25 11014 39 0 0 0 0 2787 25 0 0 0 0 -125 wlan0 0x3000180400000000 10020 1 144040 139 7540 80 144040 139 0 0 0 0 7540 80 0 0 0 0 -126 wlan0 0x3000210100000000 10020 0 10278 44 4579 33 10278 44 0 0 0 0 4579 33 0 0 0 0 -127 wlan0 0x3000210100000000 10020 1 31151 73 14159 47 31151 73 0 0 0 0 14159 47 0 0 0 0 -128 wlan0 0x3000250000000000 10020 0 132 2 72 1 132 2 0 0 0 0 72 1 0 0 0 0 -129 wlan0 0x3000250000000000 10020 1 76614 143 17711 130 76080 137 534 6 0 0 17177 124 534 6 0 0 -130 wlan0 0x3000260100000000 10020 0 9426 26 3535 20 9426 26 0 0 0 0 3535 20 0 0 0 0 -131 wlan0 0x3000260100000000 10020 1 468 7 288 4 468 7 0 0 0 0 288 4 0 0 0 0 -132 wlan0 0x3000300000000000 10020 0 7241 29 12055 26 7241 29 0 0 0 0 12055 26 0 0 0 0 -133 wlan0 0x3000300000000000 10020 1 3273 23 11232 21 3273 23 0 0 0 0 11232 21 0 0 0 0 -134 wlan0 0x3000310000000000 10020 0 132 2 72 1 132 2 0 0 0 0 72 1 0 0 0 0 -135 wlan0 0x3000310000000000 10020 1 53425 64 8721 62 53425 64 0 0 0 0 8721 62 0 0 0 0 -136 wlan0 0x3000310500000000 10020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -137 wlan0 0x3000310500000000 10020 1 9929 16 3879 18 9929 16 0 0 0 0 3879 18 0 0 0 0 -138 wlan0 0x3000320100000000 10020 0 6844 14 3745 13 6844 14 0 0 0 0 3745 13 0 0 0 0 -139 wlan0 0x3000320100000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -140 wlan0 0x3000360000000000 10020 0 8855 43 4749 31 8855 43 0 0 0 0 4749 31 0 0 0 0 -141 wlan0 0x3000360000000000 10020 1 5597 19 2456 19 5597 19 0 0 0 0 2456 19 0 0 0 0 -142 wlan0 0x3010000000000000 10090 0 605140 527 38435 429 605140 527 0 0 0 0 38435 429 0 0 0 0 -143 wlan0 0x3010000000000000 10090 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -144 wlan0 0x31065fff00000000 10020 0 22011 67 29665 64 22011 67 0 0 0 0 29665 64 0 0 0 0 -145 wlan0 0x31065fff00000000 10020 1 10695 34 18347 35 10695 34 0 0 0 0 18347 35 0 0 0 0 -146 wlan0 0x32e544f900000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -147 wlan0 0x32e544f900000000 10034 1 40143 54 7299 61 40143 54 0 0 0 0 7299 61 0 0 0 0 -148 wlan0 0x58872a4400000000 10018 0 4928 11 1669 13 4928 11 0 0 0 0 1669 13 0 0 0 0 -149 wlan0 0x58872a4400000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -150 wlan0 0x5caeaa7b00000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -151 wlan0 0x5caeaa7b00000000 10034 1 74971 73 7103 75 74971 73 0 0 0 0 7103 75 0 0 0 0 -152 wlan0 0x9e00923800000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -153 wlan0 0x9e00923800000000 10034 1 72385 98 13072 110 72385 98 0 0 0 0 13072 110 0 0 0 0 -154 wlan0 0xb972bdd400000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -155 wlan0 0xb972bdd400000000 10034 1 15282 24 3034 27 15282 24 0 0 0 0 3034 27 0 0 0 0 -156 wlan0 0xc7c9f7ba00000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -157 wlan0 0xc7c9f7ba00000000 10034 1 194915 185 13316 138 194915 185 0 0 0 0 13316 138 0 0 0 0 -158 wlan0 0xc9395b2600000000 10034 0 6991 13 6215 14 6991 13 0 0 0 0 6215 14 0 0 0 0 -159 wlan0 0xc9395b2600000000 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -160 wlan0 0xdaddf21100000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -161 wlan0 0xdaddf21100000000 10034 1 928676 849 81570 799 928676 849 0 0 0 0 81570 799 0 0 0 0 -162 wlan0 0xe8d195d100000000 10020 0 516 8 288 4 516 8 0 0 0 0 288 4 0 0 0 0 -163 wlan0 0xe8d195d100000000 10020 1 5905 15 2622 15 5905 15 0 0 0 0 2622 15 0 0 0 0 -164 wlan0 0xe8d195d100000000 10034 0 236640 524 312523 555 236640 524 0 0 0 0 312523 555 0 0 0 0 -165 wlan0 0xe8d195d100000000 10034 1 319028 539 188776 553 319028 539 0 0 0 0 188776 553 0 0 0 0 -166 wlan0 0xffffff0100000000 10006 0 80755 92 9122 99 80755 92 0 0 0 0 9122 99 0 0 0 0 -167 wlan0 0xffffff0100000000 10006 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -168 wlan0 0xffffff0100000000 10020 0 17874405 14068 223987 3065 17874405 14068 0 0 0 0 223987 3065 0 0 0 0 -169 wlan0 0xffffff0100000000 10020 1 11011258 8672 177693 2407 11011258 8672 0 0 0 0 177693 2407 0 0 0 0 -170 wlan0 0xffffff0100000000 10034 0 436062595 341880 5843990 79630 436062595 341880 0 0 0 0 5843990 79630 0 0 0 0 -171 wlan0 0xffffff0100000000 10034 1 63201220 49447 1005882 13713 63201220 49447 0 0 0 0 1005882 13713 0 0 0 0 -172 wlan0 0xffffff0100000000 10044 0 17159287 13702 356212 4778 17159287 13702 0 0 0 0 356212 4778 0 0 0 0 -173 wlan0 0xffffff0100000000 10044 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -174 wlan0 0xffffff0100000000 10078 0 10439 17 1665 15 10439 17 0 0 0 0 1665 15 0 0 0 0 -175 wlan0 0xffffff0100000000 10078 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -176 wlan0 0xffffff0100000000 10090 0 23722655 19697 881995 14231 23722655 19697 0 0 0 0 881995 14231 0 0 0 0 -177 wlan0 0xffffff0100000000 10090 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -178 wlan0 0xffffff0500000000 1000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -179 wlan0 0xffffff0500000000 1000 1 1592 5 314 1 0 0 1592 5 0 0 0 0 314 1 0 0 -180 wlan0 0xffffff0600000000 1000 0 0 0 36960 385 0 0 0 0 0 0 0 0 36960 385 0 0 -181 wlan0 0xffffff0600000000 1000 1 96 1 480 5 0 0 96 1 0 0 0 0 480 5 0 0 -182 wlan0 0xffffff0700000000 1000 0 38732 229 16567 163 38732 229 0 0 0 0 16567 163 0 0 0 0 -183 wlan0 0xffffff0700000000 1000 1 18539 74 7562 66 18539 74 0 0 0 0 7562 66 0 0 0 0 -184 wlan0 0xffffff0900000000 1000 0 38381 43 2624 27 38381 43 0 0 0 0 2624 27 0 0 0 0 -185 wlan0 0xffffff0900000000 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -186 dummy0 0x0 0 0 0 0 168 3 0 0 0 0 0 0 0 0 0 0 168 3 -187 dummy0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -188 wlan0 0x0 1029 0 0 0 8524052 130894 0 0 0 0 0 0 7871216 121284 108568 1325 544268 8285 -189 wlan0 0x0 1029 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_before b/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_before deleted file mode 100644 index ce4bcc3a3b43..000000000000 --- a/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_before +++ /dev/null @@ -1,187 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 r_rmnet_data0 0x0 0 0 0 0 392 6 0 0 0 0 0 0 0 0 0 0 392 6 -3 r_rmnet_data0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 v4-wlan0 0x0 0 0 58848 2070 2836 64 160 4 0 0 58688 2066 80 2 0 0 2756 62 -5 v4-wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -6 v4-wlan0 0x0 10034 0 6192 11 1445 11 6192 11 0 0 0 0 1445 11 0 0 0 0 -7 v4-wlan0 0x0 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -8 v4-wlan0 0x0 10057 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -9 v4-wlan0 0x0 10057 1 728 7 392 7 0 0 728 7 0 0 0 0 392 7 0 0 -10 v4-wlan0 0x0 10106 0 1488 12 1488 12 0 0 1488 12 0 0 0 0 1488 12 0 0 -11 v4-wlan0 0x0 10106 1 323981189 235142 3509032 84542 323979453 235128 1736 14 0 0 3502676 84363 6356 179 0 0 -12 wlan0 0x0 0 0 330187296 250652 0 0 329106990 236273 226202 1255 854104 13124 0 0 0 0 0 0 -13 wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -14 wlan0 0x0 1000 0 77113 272 56151 575 77113 272 0 0 0 0 19191 190 36960 385 0 0 -15 wlan0 0x0 1000 1 20227 80 8356 72 18539 74 1688 6 0 0 7562 66 794 6 0 0 -16 wlan0 0x0 10006 0 80755 92 9122 99 80755 92 0 0 0 0 9122 99 0 0 0 0 -17 wlan0 0x0 10006 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -18 wlan0 0x0 10015 0 4390 7 14824 252 4390 7 0 0 0 0 14824 252 0 0 0 0 -19 wlan0 0x0 10015 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -20 wlan0 0x0 10018 0 4928 11 1741 14 4928 11 0 0 0 0 1741 14 0 0 0 0 -21 wlan0 0x0 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -22 wlan0 0x0 10020 0 21141412 34316 2329881 15262 21140807 34311 605 5 0 0 2329276 15257 605 5 0 0 -23 wlan0 0x0 10020 1 13835740 12938 1548555 6362 13833754 12920 1986 18 0 0 1546569 6344 1986 18 0 0 -24 wlan0 0x0 10023 0 13405 40 5042 44 13405 40 0 0 0 0 5042 44 0 0 0 0 -25 wlan0 0x0 10023 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -26 wlan0 0x0 10034 0 436394741 342648 6237981 80442 436394741 342648 0 0 0 0 6237981 80442 0 0 0 0 -27 wlan0 0x0 10034 1 64860872 51297 1335539 15546 64860872 51297 0 0 0 0 1335539 15546 0 0 0 0 -28 wlan0 0x0 10044 0 17614444 14774 521004 5694 17329882 14432 284562 342 0 0 419974 5408 101030 286 0 0 -29 wlan0 0x0 10044 1 17701 33 3100 28 17701 33 0 0 0 0 3100 28 0 0 0 0 -30 wlan0 0x0 10057 0 12311735 9335 435954 5448 12247721 9259 64014 76 0 0 414080 5386 21874 62 0 0 -31 wlan0 0x0 10057 1 1332953195 954797 31849632 457698 1331933207 953569 1019988 1228 0 0 31702284 456899 147348 799 0 0 -32 wlan0 0x0 10060 0 32972 200 433705 380 32972 200 0 0 0 0 433705 380 0 0 0 0 -33 wlan0 0x0 10060 1 32106 66 37789 87 32106 66 0 0 0 0 37789 87 0 0 0 0 -34 wlan0 0x0 10061 0 7675 23 2509 22 7675 23 0 0 0 0 2509 22 0 0 0 0 -35 wlan0 0x0 10061 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -36 wlan0 0x0 10074 0 38355 82 10447 97 38355 82 0 0 0 0 10447 97 0 0 0 0 -37 wlan0 0x0 10074 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -38 wlan0 0x0 10078 0 49013 79 7167 69 49013 79 0 0 0 0 7167 69 0 0 0 0 -39 wlan0 0x0 10078 1 5872 8 1236 10 5872 8 0 0 0 0 1236 10 0 0 0 0 -40 wlan0 0x0 10082 0 8301 13 1981 15 8301 13 0 0 0 0 1981 15 0 0 0 0 -41 wlan0 0x0 10082 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -42 wlan0 0x0 10086 0 7001 14 1579 15 7001 14 0 0 0 0 1579 15 0 0 0 0 -43 wlan0 0x0 10086 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -44 wlan0 0x0 10090 0 24327795 20224 920502 14661 24327795 20224 0 0 0 0 920502 14661 0 0 0 0 -45 wlan0 0x0 10090 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -46 wlan0 0x0 10092 0 36849 78 12449 81 36849 78 0 0 0 0 12449 81 0 0 0 0 -47 wlan0 0x0 10092 1 60 1 103 1 60 1 0 0 0 0 103 1 0 0 0 0 -48 wlan0 0x0 10095 0 131962 223 37069 241 131962 223 0 0 0 0 37069 241 0 0 0 0 -49 wlan0 0x0 10095 1 12949 21 3930 21 12949 21 0 0 0 0 3930 21 0 0 0 0 -50 wlan0 0x0 10106 0 30899554 22679 632476 12296 30895334 22645 4220 34 0 0 628256 12262 4220 34 0 0 -51 wlan0 0x0 10106 1 88922349 64952 1605126 35599 88916075 64875 3586 29 2688 48 1600196 35522 4930 77 0 0 -52 wlan0 0x40700000000 10020 0 705732 10589 404428 5504 705732 10589 0 0 0 0 404428 5504 0 0 0 0 -53 wlan0 0x40700000000 10020 1 2376 36 1296 18 2376 36 0 0 0 0 1296 18 0 0 0 0 -54 wlan0 0x40800000000 10020 0 34624 146 122525 160 34624 146 0 0 0 0 122525 160 0 0 0 0 -55 wlan0 0x40800000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -56 wlan0 0x40b00000000 10020 0 22411 85 7364 57 22411 85 0 0 0 0 7364 57 0 0 0 0 -57 wlan0 0x40b00000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -58 wlan0 0x120300000000 10020 0 76641 241 32783 169 76641 241 0 0 0 0 32783 169 0 0 0 0 -59 wlan0 0x120300000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -60 wlan0 0x130100000000 10020 0 73101 287 23236 203 73101 287 0 0 0 0 23236 203 0 0 0 0 -61 wlan0 0x130100000000 10020 1 264 4 144 2 264 4 0 0 0 0 144 2 0 0 0 0 -62 wlan0 0x180300000000 10020 0 330648 399 24736 232 330648 399 0 0 0 0 24736 232 0 0 0 0 -63 wlan0 0x180300000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -64 wlan0 0x180400000000 10020 0 21865 59 5022 42 21865 59 0 0 0 0 5022 42 0 0 0 0 -65 wlan0 0x180400000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -66 wlan0 0x300000000000 10020 0 15984 65 26927 57 15984 65 0 0 0 0 26927 57 0 0 0 0 -67 wlan0 0x300000000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -68 wlan0 0x1065fff00000000 10020 0 131871 599 93783 445 131871 599 0 0 0 0 93783 445 0 0 0 0 -69 wlan0 0x1065fff00000000 10020 1 264 4 144 2 264 4 0 0 0 0 144 2 0 0 0 0 -70 wlan0 0x1b24f4600000000 10034 0 15445 42 23329 45 15445 42 0 0 0 0 23329 45 0 0 0 0 -71 wlan0 0x1b24f4600000000 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -72 wlan0 0x1000010000000000 10020 0 5542 9 1364 10 5542 9 0 0 0 0 1364 10 0 0 0 0 -73 wlan0 0x1000010000000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -74 wlan0 0x1000040100000000 10020 0 47196 184 213319 257 47196 184 0 0 0 0 213319 257 0 0 0 0 -75 wlan0 0x1000040100000000 10020 1 60 1 103 1 60 1 0 0 0 0 103 1 0 0 0 0 -76 wlan0 0x1000040700000000 10020 0 11599 50 10786 47 11599 50 0 0 0 0 10786 47 0 0 0 0 -77 wlan0 0x1000040700000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -78 wlan0 0x1000040800000000 10020 0 21902 145 174139 166 21902 145 0 0 0 0 174139 166 0 0 0 0 -79 wlan0 0x1000040800000000 10020 1 8568 88 105743 90 8568 88 0 0 0 0 105743 90 0 0 0 0 -80 wlan0 0x1000100300000000 10020 0 55213 118 194551 199 55213 118 0 0 0 0 194551 199 0 0 0 0 -81 wlan0 0x1000100300000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -82 wlan0 0x1000120300000000 10020 0 50826 74 21153 70 50826 74 0 0 0 0 21153 70 0 0 0 0 -83 wlan0 0x1000120300000000 10020 1 72 1 175 2 72 1 0 0 0 0 175 2 0 0 0 0 -84 wlan0 0x1000180300000000 10020 0 744198 657 65437 592 744198 657 0 0 0 0 65437 592 0 0 0 0 -85 wlan0 0x1000180300000000 10020 1 144719 132 10989 108 144719 132 0 0 0 0 10989 108 0 0 0 0 -86 wlan0 0x1000180600000000 10020 0 4599 8 1928 10 4599 8 0 0 0 0 1928 10 0 0 0 0 -87 wlan0 0x1000180600000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -88 wlan0 0x1000250000000000 10020 0 57740 98 13076 88 57740 98 0 0 0 0 13076 88 0 0 0 0 -89 wlan0 0x1000250000000000 10020 1 328 3 414 4 207 2 121 1 0 0 293 3 121 1 0 0 -90 wlan0 0x1000300000000000 10020 0 7675 30 31331 32 7675 30 0 0 0 0 31331 32 0 0 0 0 -91 wlan0 0x1000300000000000 10020 1 30173 97 101335 100 30173 97 0 0 0 0 101335 100 0 0 0 0 -92 wlan0 0x1000310200000000 10020 0 1681 9 2194 9 1681 9 0 0 0 0 2194 9 0 0 0 0 -93 wlan0 0x1000310200000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -94 wlan0 0x1000360000000000 10020 0 5606 20 2831 20 5606 20 0 0 0 0 2831 20 0 0 0 0 -95 wlan0 0x1000360000000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -96 wlan0 0x11065fff00000000 10020 0 18363 91 83367 104 18363 91 0 0 0 0 83367 104 0 0 0 0 -97 wlan0 0x11065fff00000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -98 wlan0 0x3000009600000000 10020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -99 wlan0 0x3000009600000000 10020 1 6163 18 2424 18 6163 18 0 0 0 0 2424 18 0 0 0 0 -100 wlan0 0x3000009800000000 10020 0 23337 46 8723 39 23337 46 0 0 0 0 8723 39 0 0 0 0 -101 wlan0 0x3000009800000000 10020 1 33744 93 72437 89 33744 93 0 0 0 0 72437 89 0 0 0 0 -102 wlan0 0x3000020000000000 10020 0 4124 11 8969 19 4124 11 0 0 0 0 8969 19 0 0 0 0 -103 wlan0 0x3000020000000000 10020 1 5993 11 3815 14 5993 11 0 0 0 0 3815 14 0 0 0 0 -104 wlan0 0x3000040100000000 10020 0 106718 322 121557 287 106718 322 0 0 0 0 121557 287 0 0 0 0 -105 wlan0 0x3000040100000000 10020 1 142508 642 500579 637 142508 642 0 0 0 0 500579 637 0 0 0 0 -106 wlan0 0x3000040700000000 10020 0 365419 5113 213124 2730 365419 5113 0 0 0 0 213124 2730 0 0 0 0 -107 wlan0 0x3000040700000000 10020 1 30747 130 18408 100 30747 130 0 0 0 0 18408 100 0 0 0 0 -108 wlan0 0x3000040800000000 10020 0 34672 112 68623 92 34672 112 0 0 0 0 68623 92 0 0 0 0 -109 wlan0 0x3000040800000000 10020 1 78443 199 140944 192 78443 199 0 0 0 0 140944 192 0 0 0 0 -110 wlan0 0x3000040b00000000 10020 0 14949 33 4017 26 14949 33 0 0 0 0 4017 26 0 0 0 0 -111 wlan0 0x3000040b00000000 10020 1 996 15 576 8 996 15 0 0 0 0 576 8 0 0 0 0 -112 wlan0 0x3000090000000000 10020 0 4017 28 3610 25 4017 28 0 0 0 0 3610 25 0 0 0 0 -113 wlan0 0x3000090000000000 10020 1 24805 41 4545 38 24805 41 0 0 0 0 4545 38 0 0 0 0 -114 wlan0 0x3000100300000000 10020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -115 wlan0 0x3000100300000000 10020 1 3112 10 1628 10 3112 10 0 0 0 0 1628 10 0 0 0 0 -116 wlan0 0x3000120300000000 10020 0 38249 107 20374 85 38249 107 0 0 0 0 20374 85 0 0 0 0 -117 wlan0 0x3000120300000000 10020 1 122581 174 36792 143 122581 174 0 0 0 0 36792 143 0 0 0 0 -118 wlan0 0x3000130100000000 10020 0 2700 41 1524 21 2700 41 0 0 0 0 1524 21 0 0 0 0 -119 wlan0 0x3000130100000000 10020 1 22515 59 8366 52 22515 59 0 0 0 0 8366 52 0 0 0 0 -120 wlan0 0x3000180200000000 10020 0 6411 18 14511 20 6411 18 0 0 0 0 14511 20 0 0 0 0 -121 wlan0 0x3000180200000000 10020 1 336 5 319 4 336 5 0 0 0 0 319 4 0 0 0 0 -122 wlan0 0x3000180300000000 10020 0 129301 136 17622 97 129301 136 0 0 0 0 17622 97 0 0 0 0 -123 wlan0 0x3000180300000000 10020 1 464787 429 41703 336 464787 429 0 0 0 0 41703 336 0 0 0 0 -124 wlan0 0x3000180400000000 10020 0 11014 39 2787 25 11014 39 0 0 0 0 2787 25 0 0 0 0 -125 wlan0 0x3000180400000000 10020 1 144040 139 7540 80 144040 139 0 0 0 0 7540 80 0 0 0 0 -126 wlan0 0x3000210100000000 10020 0 10278 44 4579 33 10278 44 0 0 0 0 4579 33 0 0 0 0 -127 wlan0 0x3000210100000000 10020 1 31151 73 14159 47 31151 73 0 0 0 0 14159 47 0 0 0 0 -128 wlan0 0x3000250000000000 10020 0 132 2 72 1 132 2 0 0 0 0 72 1 0 0 0 0 -129 wlan0 0x3000250000000000 10020 1 76614 143 17711 130 76080 137 534 6 0 0 17177 124 534 6 0 0 -130 wlan0 0x3000260100000000 10020 0 9426 26 3535 20 9426 26 0 0 0 0 3535 20 0 0 0 0 -131 wlan0 0x3000260100000000 10020 1 468 7 288 4 468 7 0 0 0 0 288 4 0 0 0 0 -132 wlan0 0x3000300000000000 10020 0 7241 29 12055 26 7241 29 0 0 0 0 12055 26 0 0 0 0 -133 wlan0 0x3000300000000000 10020 1 3273 23 11232 21 3273 23 0 0 0 0 11232 21 0 0 0 0 -134 wlan0 0x3000310000000000 10020 0 132 2 72 1 132 2 0 0 0 0 72 1 0 0 0 0 -135 wlan0 0x3000310000000000 10020 1 53425 64 8721 62 53425 64 0 0 0 0 8721 62 0 0 0 0 -136 wlan0 0x3000310500000000 10020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -137 wlan0 0x3000310500000000 10020 1 9929 16 3879 18 9929 16 0 0 0 0 3879 18 0 0 0 0 -138 wlan0 0x3000360000000000 10020 0 8855 43 4749 31 8855 43 0 0 0 0 4749 31 0 0 0 0 -139 wlan0 0x3000360000000000 10020 1 5597 19 2456 19 5597 19 0 0 0 0 2456 19 0 0 0 0 -140 wlan0 0x3010000000000000 10090 0 605140 527 38435 429 605140 527 0 0 0 0 38435 429 0 0 0 0 -141 wlan0 0x3010000000000000 10090 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -142 wlan0 0x31065fff00000000 10020 0 22011 67 29665 64 22011 67 0 0 0 0 29665 64 0 0 0 0 -143 wlan0 0x31065fff00000000 10020 1 10695 34 18347 35 10695 34 0 0 0 0 18347 35 0 0 0 0 -144 wlan0 0x32e544f900000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -145 wlan0 0x32e544f900000000 10034 1 40143 54 7299 61 40143 54 0 0 0 0 7299 61 0 0 0 0 -146 wlan0 0x58872a4400000000 10018 0 4928 11 1669 13 4928 11 0 0 0 0 1669 13 0 0 0 0 -147 wlan0 0x58872a4400000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -148 wlan0 0x5caeaa7b00000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -149 wlan0 0x5caeaa7b00000000 10034 1 74971 73 7103 75 74971 73 0 0 0 0 7103 75 0 0 0 0 -150 wlan0 0x9e00923800000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -151 wlan0 0x9e00923800000000 10034 1 72385 98 13072 110 72385 98 0 0 0 0 13072 110 0 0 0 0 -152 wlan0 0xb972bdd400000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -153 wlan0 0xb972bdd400000000 10034 1 15282 24 3034 27 15282 24 0 0 0 0 3034 27 0 0 0 0 -154 wlan0 0xc7c9f7ba00000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -155 wlan0 0xc7c9f7ba00000000 10034 1 194915 185 13316 138 194915 185 0 0 0 0 13316 138 0 0 0 0 -156 wlan0 0xc9395b2600000000 10034 0 6991 13 6215 14 6991 13 0 0 0 0 6215 14 0 0 0 0 -157 wlan0 0xc9395b2600000000 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -158 wlan0 0xdaddf21100000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -159 wlan0 0xdaddf21100000000 10034 1 928676 849 81570 799 928676 849 0 0 0 0 81570 799 0 0 0 0 -160 wlan0 0xe8d195d100000000 10020 0 516 8 288 4 516 8 0 0 0 0 288 4 0 0 0 0 -161 wlan0 0xe8d195d100000000 10020 1 5905 15 2622 15 5905 15 0 0 0 0 2622 15 0 0 0 0 -162 wlan0 0xe8d195d100000000 10034 0 236640 524 312523 555 236640 524 0 0 0 0 312523 555 0 0 0 0 -163 wlan0 0xe8d195d100000000 10034 1 319028 539 188776 553 319028 539 0 0 0 0 188776 553 0 0 0 0 -164 wlan0 0xffffff0100000000 10006 0 80755 92 9122 99 80755 92 0 0 0 0 9122 99 0 0 0 0 -165 wlan0 0xffffff0100000000 10006 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -166 wlan0 0xffffff0100000000 10020 0 17874405 14068 223987 3065 17874405 14068 0 0 0 0 223987 3065 0 0 0 0 -167 wlan0 0xffffff0100000000 10020 1 11011258 8672 177693 2407 11011258 8672 0 0 0 0 177693 2407 0 0 0 0 -168 wlan0 0xffffff0100000000 10034 0 436062595 341880 5843990 79630 436062595 341880 0 0 0 0 5843990 79630 0 0 0 0 -169 wlan0 0xffffff0100000000 10034 1 63201220 49447 1005882 13713 63201220 49447 0 0 0 0 1005882 13713 0 0 0 0 -170 wlan0 0xffffff0100000000 10044 0 17159287 13702 356212 4778 17159287 13702 0 0 0 0 356212 4778 0 0 0 0 -171 wlan0 0xffffff0100000000 10044 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -172 wlan0 0xffffff0100000000 10078 0 10439 17 1665 15 10439 17 0 0 0 0 1665 15 0 0 0 0 -173 wlan0 0xffffff0100000000 10078 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -174 wlan0 0xffffff0100000000 10090 0 23722655 19697 881995 14231 23722655 19697 0 0 0 0 881995 14231 0 0 0 0 -175 wlan0 0xffffff0100000000 10090 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -176 wlan0 0xffffff0500000000 1000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -177 wlan0 0xffffff0500000000 1000 1 1592 5 314 1 0 0 1592 5 0 0 0 0 314 1 0 0 -178 wlan0 0xffffff0600000000 1000 0 0 0 36960 385 0 0 0 0 0 0 0 0 36960 385 0 0 -179 wlan0 0xffffff0600000000 1000 1 96 1 480 5 0 0 96 1 0 0 0 0 480 5 0 0 -180 wlan0 0xffffff0700000000 1000 0 38732 229 16567 163 38732 229 0 0 0 0 16567 163 0 0 0 0 -181 wlan0 0xffffff0700000000 1000 1 18539 74 7562 66 18539 74 0 0 0 0 7562 66 0 0 0 0 -182 wlan0 0xffffff0900000000 1000 0 38381 43 2624 27 38381 43 0 0 0 0 2624 27 0 0 0 0 -183 wlan0 0xffffff0900000000 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -184 dummy0 0x0 0 0 0 0 168 3 0 0 0 0 0 0 0 0 0 0 168 3 -185 dummy0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -186 wlan0 0x0 1029 0 0 0 5855801 94173 0 0 0 0 0 0 5208040 84634 103637 1256 544124 8283 -187 wlan0 0x0 1029 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/tests/net/res/raw/xt_qtaguid_with_clat_simple b/tests/net/res/raw/xt_qtaguid_with_clat_simple deleted file mode 100644 index a1d6d411bad8..000000000000 --- a/tests/net/res/raw/xt_qtaguid_with_clat_simple +++ /dev/null @@ -1,4 +0,0 @@ -idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets -2 v4-wlan0 0x0 10060 0 42600 213 4100 41 42600 213 0 0 0 0 4100 41 0 0 0 0 -3 v4-wlan0 0x0 10060 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 wlan0 0x0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/tests/net/smoketest/Android.bp b/tests/net/smoketest/Android.bp deleted file mode 100644 index 1535f3ddcb38..000000000000 --- a/tests/net/smoketest/Android.bp +++ /dev/null @@ -1,31 +0,0 @@ -// This test exists only because the jni_libs list for these tests is difficult to -// maintain: the test itself only depends on libnetworkstatsfactorytestjni, but the test -// fails to load that library unless *all* the dependencies of that library are explicitly -// listed in jni_libs. This means that whenever any of the dependencies changes the test -// starts failing and breaking presubmits in frameworks/base. We cannot easily put -// FrameworksNetTests into global presubmit because they are at times flaky, but this -// test is effectively empty beyond validating that the libraries load correctly, and -// thus should be stable enough to put in global presubmit. -// -// TODO: remove this hack when there is a better solution for jni_libs that includes -// dependent libraries. -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -android_test { - name: "FrameworksNetSmokeTests", - defaults: ["FrameworksNetTests-jni-defaults"], - srcs: ["java/SmokeTest.java"], - test_suites: ["device-tests"], - static_libs: [ - "androidx.test.rules", - "mockito-target-minus-junit4", - "services.core", - ], -} diff --git a/tests/net/smoketest/AndroidManifest.xml b/tests/net/smoketest/AndroidManifest.xml deleted file mode 100644 index f1b9febb9f57..000000000000 --- a/tests/net/smoketest/AndroidManifest.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.frameworks.tests.net.smoketest"> - <application> - <uses-library android:name="android.test.runner" /> - </application> - - <instrumentation - android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="com.android.frameworks.tests.net.smoketest" - android:label="Frameworks Networking Smoke Tests" /> -</manifest> diff --git a/tests/net/smoketest/AndroidTest.xml b/tests/net/smoketest/AndroidTest.xml deleted file mode 100644 index ac366e4ac544..000000000000 --- a/tests/net/smoketest/AndroidTest.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<configuration description="Runs Frameworks Networking Smoke Tests."> - <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> - <option name="test-file-name" value="FrameworksNetSmokeTests.apk" /> - </target_preparer> - - <option name="test-suite-tag" value="apct" /> - <option name="test-tag" value="FrameworksNetSmokeTests" /> - <test class="com.android.tradefed.testtype.AndroidJUnitTest" > - <option name="package" value="com.android.frameworks.tests.net.smoketest" /> - <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> - <option name="hidden-api-checks" value="false"/> - </test> -</configuration> diff --git a/tests/net/smoketest/java/SmokeTest.java b/tests/net/smoketest/java/SmokeTest.java deleted file mode 100644 index 7d6655fde15e..000000000000 --- a/tests/net/smoketest/java/SmokeTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.net; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -@RunWith(JUnit4.class) -public final class SmokeTest { - - @Test - public void testLoadJni() { - System.loadLibrary("networkstatsfactorytestjni"); - assertEquals(0, 0x00); - } -} |