packages/Connectivity moved to packages/modules/Connectivity
BUG: 186628461
TEST: TH
Change-Id: I2727e13dbe051162f23ef279ca11cd5cca1fc761
diff --git a/Android.bp b/Android.bp
index 214e5b3..16a3946 100644
--- a/Android.bp
+++ b/Android.bp
@@ -284,10 +284,11 @@
generate_get_transaction_name: true,
local_include_dirs: [
"media/aidl",
- // TODO: move to include_dirs when migrated to packages/modules
- "packages/Connectivity/framework/aidl-export",
],
- include_dirs: ["frameworks/av/aidl"],
+ include_dirs: [
+ "frameworks/av/aidl",
+ "packages/modules/Connectivity/framework/aidl-export",
+ ],
},
dxflags: [
"--core-library",
@@ -526,12 +527,12 @@
local_include_dirs: [
"apex/media/aidl/stable",
"media/aidl",
- // TODO: move to include-dirs for packages/modules/Connectivity when this moves out of
- // frameworks/base
- "packages/Connectivity/framework/aidl-export",
"telephony/java",
],
- include_dirs: ["frameworks/av/aidl"],
+ include_dirs: [
+ "frameworks/av/aidl",
+ "packages/modules/Connectivity/framework/aidl-export",
+ ],
},
// These are libs from framework-internal-utils that are required (i.e. being referenced)
// from framework-non-updatable-sources. Add more here when there's a need.
diff --git a/packages/Connectivity/OWNERS b/packages/Connectivity/OWNERS
deleted file mode 100644
index 4f1e3e5..0000000
--- a/packages/Connectivity/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Placing an OWNERS block to perform migration
-# detailed in b/186628461
-baligh@google.com
diff --git a/packages/Connectivity/TEST_MAPPING b/packages/Connectivity/TEST_MAPPING
deleted file mode 100644
index 94f9232..0000000
--- a/packages/Connectivity/TEST_MAPPING
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "imports": [
- {
- "path": "frameworks/base/core/java/android/net"
- },
- {
- "path": "packages/modules/NetworkStack"
- },
- {
- "path": "packages/modules/CaptivePortalLogin"
- },
- {
- "path": "packages/modules/Connectivity"
- },
- {
- "path": "packages/modules/Connectivity/Tethering"
- }
- ]
-}
\ No newline at end of file
diff --git a/packages/Connectivity/framework/Android.bp b/packages/Connectivity/framework/Android.bp
deleted file mode 100644
index 6eb8348..0000000
--- a/packages/Connectivity/framework/Android.bp
+++ /dev/null
@@ -1,165 +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 {
- // 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"],
-}
-
-filegroup {
- name: "framework-connectivity-internal-sources",
- srcs: [
- "src/**/*.java",
- "src/**/*.aidl",
- ],
- path: "src",
- visibility: [
- "//visibility:private",
- ],
-}
-
-filegroup {
- name: "framework-connectivity-aidl-export-sources",
- srcs: [
- "aidl-export/**/*.aidl",
- ],
- path: "aidl-export",
- visibility: [
- "//visibility:private",
- ],
-}
-
-// TODO: use a java_library in the bootclasspath instead
-filegroup {
- name: "framework-connectivity-sources",
- srcs: [
- ":framework-connectivity-internal-sources",
- ":framework-connectivity-aidl-export-sources",
- ],
- visibility: [
- "//frameworks/base",
- "//packages/modules/Connectivity:__subpackages__",
- ],
-}
-
-java_library {
- name: "framework-connectivity-annotations",
- sdk_version: "module_current",
- srcs: [
- "src/android/net/ConnectivityAnnotations.java",
- ],
- libs: [
- "framework-annotations-lib",
- "framework-connectivity",
- ],
- visibility: [
- "//frameworks/base:__subpackages__",
- "//packages/modules/Connectivity:__subpackages__",
- ],
-}
-
-java_sdk_library {
- name: "framework-connectivity",
- sdk_version: "module_current",
- min_sdk_version: "30",
- defaults: ["framework-module-defaults"],
- installable: true,
- srcs: [
- ":framework-connectivity-sources",
- ":net-utils-framework-common-srcs",
- ],
- aidl: {
- include_dirs: [
- // Include directories for parcelables that are part of the stable API, and need a
- // one-line "parcelable X" .aidl declaration to be used in AIDL interfaces.
- // TODO(b/180293679): remove these dependencies as they should not be necessary once
- // the module builds against API (the parcelable declarations exist in framework.aidl)
- "frameworks/base/core/java", // For framework parcelables
- "frameworks/native/aidl/binder", // For PersistableBundle.aidl
- ],
- },
- impl_only_libs: [
- // TODO (b/183097033) remove once module_current includes core_platform
- "stable.core.platform.api.stubs",
- "framework-tethering.stubs.module_lib",
- "framework-wifi.stubs.module_lib",
- "net-utils-device-common",
- ],
- libs: [
- "unsupportedappusage",
- ],
- jarjar_rules: "jarjar-rules.txt",
- permitted_packages: ["android.net"],
- impl_library_visibility: [
- "//packages/modules/Connectivity/Tethering/apex",
- // In preparation for future move
- "//packages/modules/Connectivity/apex",
- "//packages/modules/Connectivity/service",
- "//frameworks/base/packages/Connectivity/service",
- "//frameworks/base",
-
- // Tests using hidden APIs
- "//cts/tests/netlegacy22.api",
- "//external/sl4a:__subpackages__",
- "//frameworks/base/packages/Connectivity/tests:__subpackages__",
- "//frameworks/libs/net/common/testutils",
- "//frameworks/libs/net/common/tests:__subpackages__",
- "//frameworks/opt/telephony/tests/telephonytests",
- "//packages/modules/CaptivePortalLogin/tests",
- "//packages/modules/Connectivity/Tethering/tests:__subpackages__",
- "//packages/modules/Connectivity/tests:__subpackages__",
- "//packages/modules/NetworkStack/tests:__subpackages__",
- "//packages/modules/Wifi/service/tests/wifitests",
- ],
- apex_available: [
- "com.android.tethering",
- ],
-}
-
-cc_library_shared {
- name: "libframework-connectivity-jni",
- min_sdk_version: "30",
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- // Don't warn about S API usage even with
- // min_sdk 30: the library is only loaded
- // on S+ devices
- "-Wno-unguarded-availability",
- "-Wthread-safety",
- ],
- srcs: [
- "jni/android_net_NetworkUtils.cpp",
- "jni/onload.cpp",
- ],
- shared_libs: [
- "libandroid",
- "liblog",
- "libnativehelper",
- ],
- header_libs: [
- "dnsproxyd_protocol_headers",
- ],
- stl: "none",
- apex_available: [
- "com.android.tethering",
- ],
-}
diff --git a/packages/Connectivity/framework/aidl-export/android/net/CaptivePortalData.aidl b/packages/Connectivity/framework/aidl-export/android/net/CaptivePortalData.aidl
deleted file mode 100644
index 1d57ee7..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/CaptivePortalData.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 android.net;
-
-@JavaOnlyStableParcelable parcelable CaptivePortalData;
diff --git a/packages/Connectivity/framework/aidl-export/android/net/ConnectivityDiagnosticsManager.aidl b/packages/Connectivity/framework/aidl-export/android/net/ConnectivityDiagnosticsManager.aidl
deleted file mode 100644
index 82ba0ca..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/ConnectivityDiagnosticsManager.aidl
+++ /dev/null
@@ -1,21 +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;
-
-parcelable ConnectivityDiagnosticsManager.ConnectivityReport;
-parcelable ConnectivityDiagnosticsManager.DataStallReport;
\ No newline at end of file
diff --git a/packages/Connectivity/framework/aidl-export/android/net/DhcpInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/DhcpInfo.aidl
deleted file mode 100644
index 29cd21f..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/DhcpInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2008, 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;
-
-parcelable DhcpInfo;
diff --git a/packages/Connectivity/framework/aidl-export/android/net/IpConfiguration.aidl b/packages/Connectivity/framework/aidl-export/android/net/IpConfiguration.aidl
deleted file mode 100644
index 7a30f0e..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/IpConfiguration.aidl
+++ /dev/null
@@ -1,19 +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;
-
-parcelable IpConfiguration;
diff --git a/packages/Connectivity/framework/aidl-export/android/net/IpPrefix.aidl b/packages/Connectivity/framework/aidl-export/android/net/IpPrefix.aidl
deleted file mode 100644
index 3495efc..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/IpPrefix.aidl
+++ /dev/null
@@ -1,22 +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;
-
-// @JavaOnlyStableParcelable only affects the parcelable when built as stable aidl (aidl_interface
-// build rule).
-@JavaOnlyStableParcelable parcelable IpPrefix;
diff --git a/packages/Connectivity/framework/aidl-export/android/net/KeepalivePacketData.aidl b/packages/Connectivity/framework/aidl-export/android/net/KeepalivePacketData.aidl
deleted file mode 100644
index d456b53..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/KeepalivePacketData.aidl
+++ /dev/null
@@ -1,19 +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;
-
-parcelable KeepalivePacketData;
diff --git a/packages/Connectivity/framework/aidl-export/android/net/LinkAddress.aidl b/packages/Connectivity/framework/aidl-export/android/net/LinkAddress.aidl
deleted file mode 100644
index 9c804db..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/LinkAddress.aidl
+++ /dev/null
@@ -1,21 +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;
-
-@JavaOnlyStableParcelable parcelable LinkAddress;
-
diff --git a/packages/Connectivity/framework/aidl-export/android/net/LinkProperties.aidl b/packages/Connectivity/framework/aidl-export/android/net/LinkProperties.aidl
deleted file mode 100644
index a8b3c7b..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/LinkProperties.aidl
+++ /dev/null
@@ -1,20 +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;
-
-@JavaOnlyStableParcelable parcelable LinkProperties;
diff --git a/packages/Connectivity/framework/aidl-export/android/net/MacAddress.aidl b/packages/Connectivity/framework/aidl-export/android/net/MacAddress.aidl
deleted file mode 100644
index 48a18a7..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/MacAddress.aidl
+++ /dev/null
@@ -1,20 +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;
-
-@JavaOnlyStableParcelable parcelable MacAddress;
diff --git a/packages/Connectivity/framework/aidl-export/android/net/Network.aidl b/packages/Connectivity/framework/aidl-export/android/net/Network.aidl
deleted file mode 100644
index 05622025b..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/Network.aidl
+++ /dev/null
@@ -1,20 +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;
-
-@JavaOnlyStableParcelable parcelable Network;
diff --git a/packages/Connectivity/framework/aidl-export/android/net/NetworkAgentConfig.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkAgentConfig.aidl
deleted file mode 100644
index cb70bdd..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/NetworkAgentConfig.aidl
+++ /dev/null
@@ -1,19 +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;
-
-parcelable NetworkAgentConfig;
diff --git a/packages/Connectivity/framework/aidl-export/android/net/NetworkCapabilities.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkCapabilities.aidl
deleted file mode 100644
index 01d3286..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/NetworkCapabilities.aidl
+++ /dev/null
@@ -1,21 +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;
-
-@JavaOnlyStableParcelable parcelable NetworkCapabilities;
-
diff --git a/packages/Connectivity/framework/aidl-export/android/net/NetworkInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkInfo.aidl
deleted file mode 100644
index f501873..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/NetworkInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2007, 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;
-
-parcelable NetworkInfo;
diff --git a/packages/Connectivity/framework/aidl-export/android/net/NetworkRequest.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkRequest.aidl
deleted file mode 100644
index 508defc..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/NetworkRequest.aidl
+++ /dev/null
@@ -1,20 +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;
-
-parcelable NetworkRequest;
-
diff --git a/packages/Connectivity/framework/aidl-export/android/net/NetworkScore.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkScore.aidl
deleted file mode 100644
index af12dcf..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/NetworkScore.aidl
+++ /dev/null
@@ -1,20 +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;
-
-parcelable NetworkScore;
-
diff --git a/packages/Connectivity/framework/aidl-export/android/net/OemNetworkPreferences.aidl b/packages/Connectivity/framework/aidl-export/android/net/OemNetworkPreferences.aidl
deleted file mode 100644
index 2b6a4ce..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/OemNetworkPreferences.aidl
+++ /dev/null
@@ -1,19 +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;
-
-parcelable OemNetworkPreferences;
diff --git a/packages/Connectivity/framework/aidl-export/android/net/ProxyInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/ProxyInfo.aidl
deleted file mode 100644
index a5d0c12..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/ProxyInfo.aidl
+++ /dev/null
@@ -1,21 +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;
-
-@JavaOnlyStableParcelable parcelable ProxyInfo;
-
diff --git a/packages/Connectivity/framework/aidl-export/android/net/QosFilterParcelable.aidl b/packages/Connectivity/framework/aidl-export/android/net/QosFilterParcelable.aidl
deleted file mode 100644
index 312d635..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/QosFilterParcelable.aidl
+++ /dev/null
@@ -1,21 +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;
-
-parcelable QosFilterParcelable;
-
diff --git a/packages/Connectivity/framework/aidl-export/android/net/QosSession.aidl b/packages/Connectivity/framework/aidl-export/android/net/QosSession.aidl
deleted file mode 100644
index c2cf366..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/QosSession.aidl
+++ /dev/null
@@ -1,21 +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;
-
-parcelable QosSession;
-
diff --git a/packages/Connectivity/framework/aidl-export/android/net/QosSocketInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/QosSocketInfo.aidl
deleted file mode 100644
index 476c090..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/QosSocketInfo.aidl
+++ /dev/null
@@ -1,21 +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;
-
-parcelable QosSocketInfo;
-
diff --git a/packages/Connectivity/framework/aidl-export/android/net/RouteInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/RouteInfo.aidl
deleted file mode 100644
index 7af9fda..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/RouteInfo.aidl
+++ /dev/null
@@ -1,19 +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;
-
-@JavaOnlyStableParcelable parcelable RouteInfo;
diff --git a/packages/Connectivity/framework/aidl-export/android/net/StaticIpConfiguration.aidl b/packages/Connectivity/framework/aidl-export/android/net/StaticIpConfiguration.aidl
deleted file mode 100644
index 8aac701..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/StaticIpConfiguration.aidl
+++ /dev/null
@@ -1,20 +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;
-
-@JavaOnlyStableParcelable parcelable StaticIpConfiguration;
\ No newline at end of file
diff --git a/packages/Connectivity/framework/aidl-export/android/net/TestNetworkInterface.aidl b/packages/Connectivity/framework/aidl-export/android/net/TestNetworkInterface.aidl
deleted file mode 100644
index e1f4f9f..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/TestNetworkInterface.aidl
+++ /dev/null
@@ -1,20 +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;
-
-/** @hide */
-parcelable TestNetworkInterface;
diff --git a/packages/Connectivity/framework/aidl-export/android/net/apf/ApfCapabilities.aidl b/packages/Connectivity/framework/aidl-export/android/net/apf/ApfCapabilities.aidl
deleted file mode 100644
index 7c4d4c2..0000000
--- a/packages/Connectivity/framework/aidl-export/android/net/apf/ApfCapabilities.aidl
+++ /dev/null
@@ -1,20 +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;
-
-@JavaOnlyStableParcelable parcelable ApfCapabilities;
\ No newline at end of file
diff --git a/packages/Connectivity/framework/api/current.txt b/packages/Connectivity/framework/api/current.txt
deleted file mode 100644
index 33f4d14..0000000
--- a/packages/Connectivity/framework/api/current.txt
+++ /dev/null
@@ -1,476 +0,0 @@
-// Signature format: 2.0
-package android.net {
-
- public class CaptivePortal implements android.os.Parcelable {
- method public int describeContents();
- method public void ignoreNetwork();
- method public void reportCaptivePortalDismissed();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.CaptivePortal> CREATOR;
- }
-
- public class ConnectivityDiagnosticsManager {
- method public void registerConnectivityDiagnosticsCallback(@NonNull android.net.NetworkRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback);
- method public void unregisterConnectivityDiagnosticsCallback(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback);
- }
-
- public abstract static class ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback {
- ctor public ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback();
- method public void onConnectivityReportAvailable(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityReport);
- method public void onDataStallSuspected(@NonNull android.net.ConnectivityDiagnosticsManager.DataStallReport);
- method public void onNetworkConnectivityReported(@NonNull android.net.Network, boolean);
- }
-
- public static final class ConnectivityDiagnosticsManager.ConnectivityReport implements android.os.Parcelable {
- ctor public ConnectivityDiagnosticsManager.ConnectivityReport(@NonNull android.net.Network, long, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkCapabilities, @NonNull android.os.PersistableBundle);
- method public int describeContents();
- method @NonNull public android.os.PersistableBundle getAdditionalInfo();
- method @NonNull public android.net.LinkProperties getLinkProperties();
- method @NonNull public android.net.Network getNetwork();
- method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
- method public long getReportTimestamp();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.ConnectivityDiagnosticsManager.ConnectivityReport> CREATOR;
- field public static final String KEY_NETWORK_PROBES_ATTEMPTED_BITMASK = "networkProbesAttempted";
- field public static final String KEY_NETWORK_PROBES_SUCCEEDED_BITMASK = "networkProbesSucceeded";
- field public static final String KEY_NETWORK_VALIDATION_RESULT = "networkValidationResult";
- field public static final int NETWORK_PROBE_DNS = 4; // 0x4
- field public static final int NETWORK_PROBE_FALLBACK = 32; // 0x20
- field public static final int NETWORK_PROBE_HTTP = 8; // 0x8
- field public static final int NETWORK_PROBE_HTTPS = 16; // 0x10
- field public static final int NETWORK_PROBE_PRIVATE_DNS = 64; // 0x40
- field public static final int NETWORK_VALIDATION_RESULT_INVALID = 0; // 0x0
- field public static final int NETWORK_VALIDATION_RESULT_PARTIALLY_VALID = 2; // 0x2
- field public static final int NETWORK_VALIDATION_RESULT_SKIPPED = 3; // 0x3
- field public static final int NETWORK_VALIDATION_RESULT_VALID = 1; // 0x1
- }
-
- public static final class ConnectivityDiagnosticsManager.DataStallReport implements android.os.Parcelable {
- ctor public ConnectivityDiagnosticsManager.DataStallReport(@NonNull android.net.Network, long, int, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkCapabilities, @NonNull android.os.PersistableBundle);
- method public int describeContents();
- method public int getDetectionMethod();
- method @NonNull public android.net.LinkProperties getLinkProperties();
- method @NonNull public android.net.Network getNetwork();
- method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
- method public long getReportTimestamp();
- method @NonNull public android.os.PersistableBundle getStallDetails();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.ConnectivityDiagnosticsManager.DataStallReport> CREATOR;
- field public static final int DETECTION_METHOD_DNS_EVENTS = 1; // 0x1
- field public static final int DETECTION_METHOD_TCP_METRICS = 2; // 0x2
- field public static final String KEY_DNS_CONSECUTIVE_TIMEOUTS = "dnsConsecutiveTimeouts";
- field public static final String KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS = "tcpMetricsCollectionPeriodMillis";
- field public static final String KEY_TCP_PACKET_FAIL_RATE = "tcpPacketFailRate";
- }
-
- public class ConnectivityManager {
- method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
- method public boolean bindProcessToNetwork(@Nullable android.net.Network);
- method @NonNull public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull android.net.IpSecManager.UdpEncapsulationSocket, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
- method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network getActiveNetwork();
- method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getActiveNetworkInfo();
- method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo[] getAllNetworkInfo();
- method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network[] getAllNetworks();
- method @Deprecated public boolean getBackgroundDataSetting();
- method @Nullable public android.net.Network getBoundNetworkForProcess();
- method public int getConnectionOwnerUid(int, @NonNull java.net.InetSocketAddress, @NonNull java.net.InetSocketAddress);
- method @Nullable public android.net.ProxyInfo getDefaultProxy();
- method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.LinkProperties getLinkProperties(@Nullable android.net.Network);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public int getMultipathPreference(@Nullable android.net.Network);
- method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkCapabilities getNetworkCapabilities(@Nullable android.net.Network);
- method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getNetworkInfo(int);
- method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getNetworkInfo(@Nullable android.net.Network);
- method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public int getNetworkPreference();
- method @Nullable public byte[] getNetworkWatchlistConfigHash();
- method @Deprecated @Nullable public static android.net.Network getProcessDefaultNetwork();
- method public int getRestrictBackgroundStatus();
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public boolean isActiveNetworkMetered();
- method public boolean isDefaultNetworkActive();
- method @Deprecated public static boolean isNetworkTypeValid(int);
- method public void registerBestMatchingNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.app.PendingIntent);
- method public void releaseNetworkRequest(@NonNull android.app.PendingIntent);
- method public void removeDefaultNetworkActiveListener(@NonNull android.net.ConnectivityManager.OnNetworkActiveListener);
- method @Deprecated public void reportBadNetwork(@Nullable android.net.Network);
- method public void reportNetworkConnectivity(@Nullable android.net.Network, boolean);
- method public boolean requestBandwidthUpdate(@NonNull android.net.Network);
- method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback);
- method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, int);
- method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler, int);
- method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.app.PendingIntent);
- method @Deprecated public void setNetworkPreference(int);
- method @Deprecated public static boolean setProcessDefaultNetwork(@Nullable android.net.Network);
- method public void unregisterNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback);
- method public void unregisterNetworkCallback(@NonNull android.app.PendingIntent);
- field @Deprecated public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
- field public static final String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL";
- field public static final String ACTION_RESTRICT_BACKGROUND_CHANGED = "android.net.conn.RESTRICT_BACKGROUND_CHANGED";
- field @Deprecated public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
- field @Deprecated public static final int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
- field public static final String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL";
- field public static final String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL";
- field @Deprecated public static final String EXTRA_EXTRA_INFO = "extraInfo";
- field @Deprecated public static final String EXTRA_IS_FAILOVER = "isFailover";
- field public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
- field @Deprecated public static final String EXTRA_NETWORK_INFO = "networkInfo";
- field public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
- field @Deprecated public static final String EXTRA_NETWORK_TYPE = "networkType";
- field public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
- field @Deprecated public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
- field public static final String EXTRA_REASON = "reason";
- field public static final int MULTIPATH_PREFERENCE_HANDOVER = 1; // 0x1
- field public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 4; // 0x4
- field public static final int MULTIPATH_PREFERENCE_RELIABILITY = 2; // 0x2
- field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
- field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
- field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
- field @Deprecated public static final int TYPE_BLUETOOTH = 7; // 0x7
- field @Deprecated public static final int TYPE_DUMMY = 8; // 0x8
- field @Deprecated public static final int TYPE_ETHERNET = 9; // 0x9
- field @Deprecated public static final int TYPE_MOBILE = 0; // 0x0
- field @Deprecated public static final int TYPE_MOBILE_DUN = 4; // 0x4
- field @Deprecated public static final int TYPE_MOBILE_HIPRI = 5; // 0x5
- field @Deprecated public static final int TYPE_MOBILE_MMS = 2; // 0x2
- field @Deprecated public static final int TYPE_MOBILE_SUPL = 3; // 0x3
- field @Deprecated public static final int TYPE_VPN = 17; // 0x11
- field @Deprecated public static final int TYPE_WIFI = 1; // 0x1
- field @Deprecated public static final int TYPE_WIMAX = 6; // 0x6
- }
-
- public static class ConnectivityManager.NetworkCallback {
- ctor public ConnectivityManager.NetworkCallback();
- ctor public ConnectivityManager.NetworkCallback(int);
- method public void onAvailable(@NonNull android.net.Network);
- method public void onBlockedStatusChanged(@NonNull android.net.Network, boolean);
- method public void onCapabilitiesChanged(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities);
- method public void onLinkPropertiesChanged(@NonNull android.net.Network, @NonNull android.net.LinkProperties);
- method public void onLosing(@NonNull android.net.Network, int);
- method public void onLost(@NonNull android.net.Network);
- method public void onUnavailable();
- field public static final int FLAG_INCLUDE_LOCATION_INFO = 1; // 0x1
- }
-
- public static interface ConnectivityManager.OnNetworkActiveListener {
- method public void onNetworkActive();
- }
-
- public class DhcpInfo implements android.os.Parcelable {
- ctor public DhcpInfo();
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.DhcpInfo> CREATOR;
- field public int dns1;
- field public int dns2;
- field public int gateway;
- field public int ipAddress;
- field public int leaseDuration;
- field public int netmask;
- field public int serverAddress;
- }
-
- public final class DnsResolver {
- method @NonNull public static android.net.DnsResolver getInstance();
- method public void query(@Nullable android.net.Network, @NonNull String, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super java.util.List<java.net.InetAddress>>);
- method public void query(@Nullable android.net.Network, @NonNull String, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super java.util.List<java.net.InetAddress>>);
- method public void rawQuery(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super byte[]>);
- method public void rawQuery(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super byte[]>);
- field public static final int CLASS_IN = 1; // 0x1
- field public static final int ERROR_PARSE = 0; // 0x0
- field public static final int ERROR_SYSTEM = 1; // 0x1
- field public static final int FLAG_EMPTY = 0; // 0x0
- field public static final int FLAG_NO_CACHE_LOOKUP = 4; // 0x4
- field public static final int FLAG_NO_CACHE_STORE = 2; // 0x2
- field public static final int FLAG_NO_RETRY = 1; // 0x1
- field public static final int TYPE_A = 1; // 0x1
- field public static final int TYPE_AAAA = 28; // 0x1c
- }
-
- public static interface DnsResolver.Callback<T> {
- method public void onAnswer(@NonNull T, int);
- method public void onError(@NonNull android.net.DnsResolver.DnsException);
- }
-
- public static class DnsResolver.DnsException extends java.lang.Exception {
- field public final int code;
- }
-
- public class InetAddresses {
- method public static boolean isNumericAddress(@NonNull String);
- method @NonNull public static java.net.InetAddress parseNumericAddress(@NonNull String);
- }
-
- public final class IpPrefix implements android.os.Parcelable {
- method public boolean contains(@NonNull java.net.InetAddress);
- method public int describeContents();
- method @NonNull public java.net.InetAddress getAddress();
- method @IntRange(from=0, to=128) public int getPrefixLength();
- method @NonNull public byte[] getRawAddress();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
- }
-
- public class LinkAddress implements android.os.Parcelable {
- method public int describeContents();
- method public java.net.InetAddress getAddress();
- method public int getFlags();
- method @IntRange(from=0, to=128) public int getPrefixLength();
- method public int getScope();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.LinkAddress> CREATOR;
- }
-
- public final class LinkProperties implements android.os.Parcelable {
- ctor public LinkProperties();
- method public boolean addRoute(@NonNull android.net.RouteInfo);
- method public void clear();
- method public int describeContents();
- method @Nullable public java.net.Inet4Address getDhcpServerAddress();
- method @NonNull public java.util.List<java.net.InetAddress> getDnsServers();
- method @Nullable public String getDomains();
- method @Nullable public android.net.ProxyInfo getHttpProxy();
- method @Nullable public String getInterfaceName();
- method @NonNull public java.util.List<android.net.LinkAddress> getLinkAddresses();
- method public int getMtu();
- method @Nullable public android.net.IpPrefix getNat64Prefix();
- method @Nullable public String getPrivateDnsServerName();
- method @NonNull public java.util.List<android.net.RouteInfo> getRoutes();
- method public boolean isPrivateDnsActive();
- method public boolean isWakeOnLanSupported();
- method public void setDhcpServerAddress(@Nullable java.net.Inet4Address);
- method public void setDnsServers(@NonNull java.util.Collection<java.net.InetAddress>);
- method public void setDomains(@Nullable String);
- method public void setHttpProxy(@Nullable android.net.ProxyInfo);
- method public void setInterfaceName(@Nullable String);
- method public void setLinkAddresses(@NonNull java.util.Collection<android.net.LinkAddress>);
- method public void setMtu(int);
- method public void setNat64Prefix(@Nullable android.net.IpPrefix);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.LinkProperties> CREATOR;
- }
-
- public final class MacAddress implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public static android.net.MacAddress fromBytes(@NonNull byte[]);
- method @NonNull public static android.net.MacAddress fromString(@NonNull String);
- method public int getAddressType();
- method @Nullable public java.net.Inet6Address getLinkLocalIpv6FromEui48Mac();
- method public boolean isLocallyAssigned();
- method public boolean matches(@NonNull android.net.MacAddress, @NonNull android.net.MacAddress);
- method @NonNull public byte[] toByteArray();
- method @NonNull public String toOuiString();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.net.MacAddress BROADCAST_ADDRESS;
- field @NonNull public static final android.os.Parcelable.Creator<android.net.MacAddress> CREATOR;
- field public static final int TYPE_BROADCAST = 3; // 0x3
- field public static final int TYPE_MULTICAST = 2; // 0x2
- field public static final int TYPE_UNICAST = 1; // 0x1
- }
-
- public class Network implements android.os.Parcelable {
- method public void bindSocket(java.net.DatagramSocket) throws java.io.IOException;
- method public void bindSocket(java.net.Socket) throws java.io.IOException;
- method public void bindSocket(java.io.FileDescriptor) throws java.io.IOException;
- method public int describeContents();
- method public static android.net.Network fromNetworkHandle(long);
- method public java.net.InetAddress[] getAllByName(String) throws java.net.UnknownHostException;
- method public java.net.InetAddress getByName(String) throws java.net.UnknownHostException;
- method public long getNetworkHandle();
- method public javax.net.SocketFactory getSocketFactory();
- method public java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException;
- method public java.net.URLConnection openConnection(java.net.URL, java.net.Proxy) throws java.io.IOException;
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.Network> CREATOR;
- }
-
- public final class NetworkCapabilities implements android.os.Parcelable {
- ctor public NetworkCapabilities();
- ctor public NetworkCapabilities(android.net.NetworkCapabilities);
- method public int describeContents();
- method @NonNull public int[] getCapabilities();
- method public int getLinkDownstreamBandwidthKbps();
- method public int getLinkUpstreamBandwidthKbps();
- method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
- method public int getOwnerUid();
- method public int getSignalStrength();
- method @Nullable public android.net.TransportInfo getTransportInfo();
- method public boolean hasCapability(int);
- method public boolean hasTransport(int);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkCapabilities> CREATOR;
- field public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; // 0x11
- field public static final int NET_CAPABILITY_CBS = 5; // 0x5
- field public static final int NET_CAPABILITY_DUN = 2; // 0x2
- field public static final int NET_CAPABILITY_EIMS = 10; // 0xa
- field public static final int NET_CAPABILITY_ENTERPRISE = 29; // 0x1d
- field public static final int NET_CAPABILITY_FOREGROUND = 19; // 0x13
- field public static final int NET_CAPABILITY_FOTA = 3; // 0x3
- field public static final int NET_CAPABILITY_HEAD_UNIT = 32; // 0x20
- field public static final int NET_CAPABILITY_IA = 7; // 0x7
- field public static final int NET_CAPABILITY_IMS = 4; // 0x4
- field public static final int NET_CAPABILITY_INTERNET = 12; // 0xc
- field public static final int NET_CAPABILITY_MCX = 23; // 0x17
- field public static final int NET_CAPABILITY_MMS = 0; // 0x0
- field public static final int NET_CAPABILITY_NOT_CONGESTED = 20; // 0x14
- field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb
- field public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; // 0xd
- field public static final int NET_CAPABILITY_NOT_ROAMING = 18; // 0x12
- field public static final int NET_CAPABILITY_NOT_SUSPENDED = 21; // 0x15
- field public static final int NET_CAPABILITY_NOT_VPN = 15; // 0xf
- field public static final int NET_CAPABILITY_RCS = 8; // 0x8
- field public static final int NET_CAPABILITY_SUPL = 1; // 0x1
- field public static final int NET_CAPABILITY_TEMPORARILY_NOT_METERED = 25; // 0x19
- field public static final int NET_CAPABILITY_TRUSTED = 14; // 0xe
- field public static final int NET_CAPABILITY_VALIDATED = 16; // 0x10
- field public static final int NET_CAPABILITY_WIFI_P2P = 6; // 0x6
- field public static final int NET_CAPABILITY_XCAP = 9; // 0x9
- field public static final int SIGNAL_STRENGTH_UNSPECIFIED = -2147483648; // 0x80000000
- field public static final int TRANSPORT_BLUETOOTH = 2; // 0x2
- field public static final int TRANSPORT_CELLULAR = 0; // 0x0
- field public static final int TRANSPORT_ETHERNET = 3; // 0x3
- field public static final int TRANSPORT_LOWPAN = 6; // 0x6
- field public static final int TRANSPORT_USB = 8; // 0x8
- field public static final int TRANSPORT_VPN = 4; // 0x4
- field public static final int TRANSPORT_WIFI = 1; // 0x1
- field public static final int TRANSPORT_WIFI_AWARE = 5; // 0x5
- }
-
- @Deprecated public class NetworkInfo implements android.os.Parcelable {
- ctor @Deprecated public NetworkInfo(int, int, @Nullable String, @Nullable String);
- method @Deprecated public int describeContents();
- method @Deprecated @NonNull public android.net.NetworkInfo.DetailedState getDetailedState();
- method @Deprecated public String getExtraInfo();
- method @Deprecated public String getReason();
- method @Deprecated public android.net.NetworkInfo.State getState();
- method @Deprecated public int getSubtype();
- method @Deprecated public String getSubtypeName();
- method @Deprecated public int getType();
- method @Deprecated public String getTypeName();
- method @Deprecated public boolean isAvailable();
- method @Deprecated public boolean isConnected();
- method @Deprecated public boolean isConnectedOrConnecting();
- method @Deprecated public boolean isFailover();
- method @Deprecated public boolean isRoaming();
- method @Deprecated public void setDetailedState(@NonNull android.net.NetworkInfo.DetailedState, @Nullable String, @Nullable String);
- method @Deprecated public void writeToParcel(android.os.Parcel, int);
- field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
- }
-
- @Deprecated public enum NetworkInfo.DetailedState {
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState AUTHENTICATING;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState BLOCKED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState CAPTIVE_PORTAL_CHECK;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState CONNECTED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState CONNECTING;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState DISCONNECTED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState DISCONNECTING;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState FAILED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState IDLE;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState OBTAINING_IPADDR;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState SCANNING;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState SUSPENDED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState VERIFYING_POOR_LINK;
- }
-
- @Deprecated public enum NetworkInfo.State {
- enum_constant @Deprecated public static final android.net.NetworkInfo.State CONNECTED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.State CONNECTING;
- enum_constant @Deprecated public static final android.net.NetworkInfo.State DISCONNECTED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.State DISCONNECTING;
- enum_constant @Deprecated public static final android.net.NetworkInfo.State SUSPENDED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.State UNKNOWN;
- }
-
- public class NetworkRequest implements android.os.Parcelable {
- method public boolean canBeSatisfiedBy(@Nullable android.net.NetworkCapabilities);
- method public int describeContents();
- method @NonNull public int[] getCapabilities();
- method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
- method @NonNull public int[] getTransportTypes();
- method public boolean hasCapability(int);
- method public boolean hasTransport(int);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkRequest> CREATOR;
- }
-
- public static class NetworkRequest.Builder {
- ctor public NetworkRequest.Builder();
- ctor public NetworkRequest.Builder(@NonNull android.net.NetworkRequest);
- method public android.net.NetworkRequest.Builder addCapability(int);
- method public android.net.NetworkRequest.Builder addTransportType(int);
- method public android.net.NetworkRequest build();
- method @NonNull public android.net.NetworkRequest.Builder clearCapabilities();
- method public android.net.NetworkRequest.Builder removeCapability(int);
- method public android.net.NetworkRequest.Builder removeTransportType(int);
- method @NonNull public android.net.NetworkRequest.Builder setIncludeOtherUidNetworks(boolean);
- method @Deprecated public android.net.NetworkRequest.Builder setNetworkSpecifier(String);
- method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier);
- }
-
- public class ParseException extends java.lang.RuntimeException {
- ctor public ParseException(@NonNull String);
- ctor public ParseException(@NonNull String, @NonNull Throwable);
- field public String response;
- }
-
- public class ProxyInfo implements android.os.Parcelable {
- ctor public ProxyInfo(@Nullable android.net.ProxyInfo);
- method public static android.net.ProxyInfo buildDirectProxy(String, int);
- method public static android.net.ProxyInfo buildDirectProxy(String, int, java.util.List<java.lang.String>);
- method public static android.net.ProxyInfo buildPacProxy(android.net.Uri);
- method @NonNull public static android.net.ProxyInfo buildPacProxy(@NonNull android.net.Uri, int);
- method public int describeContents();
- method public String[] getExclusionList();
- method public String getHost();
- method public android.net.Uri getPacFileUrl();
- method public int getPort();
- method public boolean isValid();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.ProxyInfo> CREATOR;
- }
-
- public final class RouteInfo implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.net.IpPrefix getDestination();
- method @Nullable public java.net.InetAddress getGateway();
- method @Nullable public String getInterface();
- method public boolean hasGateway();
- method public boolean isDefaultRoute();
- method public boolean matches(java.net.InetAddress);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.RouteInfo> CREATOR;
- }
-
- public abstract class SocketKeepalive implements java.lang.AutoCloseable {
- method public final void close();
- method public final void start(@IntRange(from=0xa, to=0xe10) int);
- method public final void stop();
- field public static final int ERROR_HARDWARE_ERROR = -31; // 0xffffffe1
- field public static final int ERROR_INSUFFICIENT_RESOURCES = -32; // 0xffffffe0
- field public static final int ERROR_INVALID_INTERVAL = -24; // 0xffffffe8
- field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb
- field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9
- field public static final int ERROR_INVALID_NETWORK = -20; // 0xffffffec
- field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea
- field public static final int ERROR_INVALID_SOCKET = -25; // 0xffffffe7
- field public static final int ERROR_SOCKET_NOT_IDLE = -26; // 0xffffffe6
- field public static final int ERROR_UNSUPPORTED = -30; // 0xffffffe2
- }
-
- public static class SocketKeepalive.Callback {
- ctor public SocketKeepalive.Callback();
- method public void onDataReceived();
- method public void onError(int);
- method public void onStarted();
- method public void onStopped();
- }
-
- public interface TransportInfo {
- }
-
-}
-
diff --git a/packages/Connectivity/framework/api/lint-baseline.txt b/packages/Connectivity/framework/api/lint-baseline.txt
deleted file mode 100644
index 2f4004a..0000000
--- a/packages/Connectivity/framework/api/lint-baseline.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-// Baseline format: 1.0
-VisiblySynchronized: android.net.NetworkInfo#toString():
- Internal locks must not be exposed (synchronizing on this or class is still
- externally observable): method android.net.NetworkInfo.toString()
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
deleted file mode 100644
index 6c454bc..0000000
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ /dev/null
@@ -1,179 +0,0 @@
-// Signature format: 2.0
-package android.net {
-
- public final class ConnectivityFrameworkInitializer {
- method public static void registerServiceWrappers();
- }
-
- public class ConnectivityManager {
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void factoryReset();
- method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshots();
- method @Nullable public android.net.ProxyInfo getGlobalProxy();
- method @NonNull public static android.util.Range<java.lang.Integer> getIpSecNetIdRange();
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackForUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @Deprecated public boolean requestRouteToHostAddress(int, java.net.InetAddress);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAcceptPartialConnectivity(@NonNull android.net.Network, boolean, boolean);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAcceptUnvalidated(@NonNull android.net.Network, boolean, boolean);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAvoidUnvalidated(@NonNull android.net.Network);
- method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setGlobalProxy(@Nullable android.net.ProxyInfo);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setLegacyLockdownVpnEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreference(@NonNull android.os.UserHandle, int, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setRequireVpnForUids(boolean, @NonNull java.util.Collection<android.util.Range<java.lang.Integer>>);
- method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void startCaptivePortalApp(@NonNull android.net.Network);
- method public void systemReady();
- field public static final String ACTION_CLEAR_DNS_CACHE = "android.net.action.CLEAR_DNS_CACHE";
- field public static final String ACTION_PROMPT_LOST_VALIDATION = "android.net.action.PROMPT_LOST_VALIDATION";
- field public static final String ACTION_PROMPT_PARTIAL_CONNECTIVITY = "android.net.action.PROMPT_PARTIAL_CONNECTIVITY";
- field public static final String ACTION_PROMPT_UNVALIDATED = "android.net.action.PROMPT_UNVALIDATED";
- field public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 262144; // 0x40000
- field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000
- field public static final int BLOCKED_METERED_REASON_MASK = -65536; // 0xffff0000
- field public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 131072; // 0x20000
- field public static final int BLOCKED_REASON_APP_STANDBY = 4; // 0x4
- field public static final int BLOCKED_REASON_BATTERY_SAVER = 1; // 0x1
- field public static final int BLOCKED_REASON_DOZE = 2; // 0x2
- field public static final int BLOCKED_REASON_LOCKDOWN_VPN = 16; // 0x10
- field public static final int BLOCKED_REASON_NONE = 0; // 0x0
- field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8
- field public static final int PROFILE_NETWORK_PREFERENCE_DEFAULT = 0; // 0x0
- field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE = 1; // 0x1
- }
-
- public static class ConnectivityManager.NetworkCallback {
- method public void onBlockedStatusChanged(@NonNull android.net.Network, int);
- }
-
- public class ConnectivitySettingsManager {
- method public static void clearGlobalProxy(@NonNull android.content.Context);
- method @NonNull public static java.util.Set<java.lang.String> getAppsAllowedOnRestrictedNetworks(@NonNull android.content.Context);
- method @Nullable public static String getCaptivePortalHttpUrl(@NonNull android.content.Context);
- method public static int getCaptivePortalMode(@NonNull android.content.Context, int);
- method @NonNull public static java.time.Duration getConnectivityKeepPendingIntentDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
- method @NonNull public static android.util.Range<java.lang.Integer> getDnsResolverSampleRanges(@NonNull android.content.Context);
- method @NonNull public static java.time.Duration getDnsResolverSampleValidityDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static int getDnsResolverSuccessThresholdPercent(@NonNull android.content.Context, int);
- method @Nullable public static android.net.ProxyInfo getGlobalProxy(@NonNull android.content.Context);
- method @NonNull public static java.time.Duration getMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static boolean getMobileDataAlwaysOn(@NonNull android.content.Context, boolean);
- method @NonNull public static java.util.Set<java.lang.Integer> getMobileDataPreferredUids(@NonNull android.content.Context);
- method public static int getNetworkAvoidBadWifi(@NonNull android.content.Context);
- method @Nullable public static String getNetworkMeteredMultipathPreference(@NonNull android.content.Context);
- method public static int getNetworkSwitchNotificationMaximumDailyCount(@NonNull android.content.Context, int);
- method @NonNull public static java.time.Duration getNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
- method @NonNull public static String getPrivateDnsDefaultMode(@NonNull android.content.Context);
- method @Nullable public static String getPrivateDnsHostname(@NonNull android.content.Context);
- method public static int getPrivateDnsMode(@NonNull android.content.Context);
- method public static boolean getWifiAlwaysRequested(@NonNull android.content.Context, boolean);
- method @NonNull public static java.time.Duration getWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static void setAppsAllowedOnRestrictedNetworks(@NonNull android.content.Context, @NonNull java.util.Set<java.lang.String>);
- method public static void setCaptivePortalHttpUrl(@NonNull android.content.Context, @Nullable String);
- method public static void setCaptivePortalMode(@NonNull android.content.Context, int);
- method public static void setConnectivityKeepPendingIntentDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static void setDnsResolverSampleRanges(@NonNull android.content.Context, @NonNull android.util.Range<java.lang.Integer>);
- method public static void setDnsResolverSampleValidityDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static void setDnsResolverSuccessThresholdPercent(@NonNull android.content.Context, @IntRange(from=0, to=100) int);
- method public static void setGlobalProxy(@NonNull android.content.Context, @NonNull android.net.ProxyInfo);
- method public static void setMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static void setMobileDataAlwaysOn(@NonNull android.content.Context, boolean);
- method public static void setMobileDataPreferredUids(@NonNull android.content.Context, @NonNull java.util.Set<java.lang.Integer>);
- method public static void setNetworkAvoidBadWifi(@NonNull android.content.Context, int);
- method public static void setNetworkMeteredMultipathPreference(@NonNull android.content.Context, @NonNull String);
- method public static void setNetworkSwitchNotificationMaximumDailyCount(@NonNull android.content.Context, @IntRange(from=0) int);
- method public static void setNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static void setPrivateDnsDefaultMode(@NonNull android.content.Context, @NonNull int);
- method public static void setPrivateDnsHostname(@NonNull android.content.Context, @Nullable String);
- method public static void setPrivateDnsMode(@NonNull android.content.Context, int);
- method public static void setWifiAlwaysRequested(@NonNull android.content.Context, boolean);
- method public static void setWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
- field public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; // 0x2
- field public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0; // 0x0
- field public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1; // 0x1
- field public static final int NETWORK_AVOID_BAD_WIFI_AVOID = 2; // 0x2
- field public static final int NETWORK_AVOID_BAD_WIFI_IGNORE = 0; // 0x0
- field public static final int NETWORK_AVOID_BAD_WIFI_PROMPT = 1; // 0x1
- field public static final int PRIVATE_DNS_MODE_OFF = 1; // 0x1
- field public static final int PRIVATE_DNS_MODE_OPPORTUNISTIC = 2; // 0x2
- field public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3; // 0x3
- }
-
- public final class NetworkAgentConfig implements android.os.Parcelable {
- method @Nullable public String getSubscriberId();
- method public boolean isBypassableVpn();
- }
-
- public static final class NetworkAgentConfig.Builder {
- method @NonNull public android.net.NetworkAgentConfig.Builder setBypassableVpn(boolean);
- method @NonNull public android.net.NetworkAgentConfig.Builder setSubscriberId(@Nullable String);
- }
-
- public final class NetworkCapabilities implements android.os.Parcelable {
- method @Nullable public java.util.Set<android.util.Range<java.lang.Integer>> getUids();
- method public boolean hasForbiddenCapability(int);
- field public static final long REDACT_ALL = -1L; // 0xffffffffffffffffL
- field public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1L; // 0x1L
- field public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 2L; // 0x2L
- field public static final long REDACT_FOR_NETWORK_SETTINGS = 4L; // 0x4L
- field public static final long REDACT_NONE = 0L; // 0x0L
- field public static final int TRANSPORT_TEST = 7; // 0x7
- }
-
- public static final class NetworkCapabilities.Builder {
- method @NonNull public android.net.NetworkCapabilities.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
- }
-
- public class NetworkRequest implements android.os.Parcelable {
- method @NonNull public int[] getForbiddenCapabilities();
- method public boolean hasForbiddenCapability(int);
- }
-
- public static class NetworkRequest.Builder {
- method @NonNull public android.net.NetworkRequest.Builder addForbiddenCapability(int);
- method @NonNull public android.net.NetworkRequest.Builder removeForbiddenCapability(int);
- method @NonNull public android.net.NetworkRequest.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
- }
-
- public final class TestNetworkInterface implements android.os.Parcelable {
- ctor public TestNetworkInterface(@NonNull android.os.ParcelFileDescriptor, @NonNull String);
- method public int describeContents();
- method @NonNull public android.os.ParcelFileDescriptor getFileDescriptor();
- method @NonNull public String getInterfaceName();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TestNetworkInterface> CREATOR;
- }
-
- public class TestNetworkManager {
- method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_TEST_NETWORKS) public android.net.TestNetworkInterface createTapInterface();
- method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_TEST_NETWORKS) public android.net.TestNetworkInterface createTunInterface(@NonNull java.util.Collection<android.net.LinkAddress>);
- method @RequiresPermission(android.Manifest.permission.MANAGE_TEST_NETWORKS) public void setupTestNetwork(@NonNull String, @NonNull android.os.IBinder);
- method @RequiresPermission(android.Manifest.permission.MANAGE_TEST_NETWORKS) public void teardownTestNetwork(@NonNull android.net.Network);
- field public static final String TEST_TAP_PREFIX = "testtap";
- }
-
- public final class TestNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
- ctor public TestNetworkSpecifier(@NonNull String);
- method public int describeContents();
- method @Nullable public String getInterfaceName();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TestNetworkSpecifier> CREATOR;
- }
-
- public interface TransportInfo {
- method public default long getApplicableRedactions();
- method @NonNull public default android.net.TransportInfo makeCopy(long);
- }
-
- public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
- ctor public VpnTransportInfo(int, @Nullable String);
- method public int describeContents();
- method @Nullable public String getSessionId();
- method public int getType();
- method @NonNull public android.net.VpnTransportInfo makeCopy(long);
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.VpnTransportInfo> CREATOR;
- }
-
-}
-
diff --git a/packages/Connectivity/framework/api/module-lib-removed.txt b/packages/Connectivity/framework/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/packages/Connectivity/framework/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/packages/Connectivity/framework/api/removed.txt b/packages/Connectivity/framework/api/removed.txt
deleted file mode 100644
index 303a1e61..0000000
--- a/packages/Connectivity/framework/api/removed.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-// Signature format: 2.0
-package android.net {
-
- public class ConnectivityManager {
- method @Deprecated public boolean requestRouteToHost(int, int);
- method @Deprecated public int startUsingNetworkFeature(int, String);
- method @Deprecated public int stopUsingNetworkFeature(int, String);
- }
-
-}
-
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
deleted file mode 100644
index d1d51da..0000000
--- a/packages/Connectivity/framework/api/system-current.txt
+++ /dev/null
@@ -1,505 +0,0 @@
-// Signature format: 2.0
-package android.net {
-
- public class CaptivePortal implements android.os.Parcelable {
- method @Deprecated public void logEvent(int, @NonNull String);
- method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void reevaluateNetwork();
- method public void useNetwork();
- field public static final int APP_REQUEST_REEVALUATION_REQUIRED = 100; // 0x64
- field public static final int APP_RETURN_DISMISSED = 0; // 0x0
- field public static final int APP_RETURN_UNWANTED = 1; // 0x1
- field public static final int APP_RETURN_WANTED_AS_IS = 2; // 0x2
- }
-
- public final class CaptivePortalData implements android.os.Parcelable {
- method public int describeContents();
- method public long getByteLimit();
- method public long getExpiryTimeMillis();
- method public long getRefreshTimeMillis();
- method @Nullable public android.net.Uri getUserPortalUrl();
- method public int getUserPortalUrlSource();
- method @Nullable public CharSequence getVenueFriendlyName();
- method @Nullable public android.net.Uri getVenueInfoUrl();
- method public int getVenueInfoUrlSource();
- method public boolean isCaptive();
- method public boolean isSessionExtendable();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field public static final int CAPTIVE_PORTAL_DATA_SOURCE_OTHER = 0; // 0x0
- field public static final int CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT = 1; // 0x1
- field @NonNull public static final android.os.Parcelable.Creator<android.net.CaptivePortalData> CREATOR;
- }
-
- public static class CaptivePortalData.Builder {
- ctor public CaptivePortalData.Builder();
- ctor public CaptivePortalData.Builder(@Nullable android.net.CaptivePortalData);
- method @NonNull public android.net.CaptivePortalData build();
- method @NonNull public android.net.CaptivePortalData.Builder setBytesRemaining(long);
- method @NonNull public android.net.CaptivePortalData.Builder setCaptive(boolean);
- method @NonNull public android.net.CaptivePortalData.Builder setExpiryTime(long);
- method @NonNull public android.net.CaptivePortalData.Builder setRefreshTime(long);
- method @NonNull public android.net.CaptivePortalData.Builder setSessionExtendable(boolean);
- method @NonNull public android.net.CaptivePortalData.Builder setUserPortalUrl(@Nullable android.net.Uri);
- method @NonNull public android.net.CaptivePortalData.Builder setUserPortalUrl(@Nullable android.net.Uri, int);
- method @NonNull public android.net.CaptivePortalData.Builder setVenueFriendlyName(@Nullable CharSequence);
- method @NonNull public android.net.CaptivePortalData.Builder setVenueInfoUrl(@Nullable android.net.Uri);
- method @NonNull public android.net.CaptivePortalData.Builder setVenueInfoUrl(@Nullable android.net.Uri, int);
- }
-
- public class ConnectivityManager {
- method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createNattKeepalive(@NonNull android.net.Network, @NonNull android.os.ParcelFileDescriptor, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
- method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String getCaptivePortalServerUrl();
- method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener);
- method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public int registerNetworkProvider(@NonNull android.net.NetworkProvider);
- method public void registerQosCallback(@NonNull android.net.QosSocketInfo, @NonNull java.util.concurrent.Executor, @NonNull android.net.QosCallback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
- method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void requestNetwork(@NonNull android.net.NetworkRequest, int, int, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_AIRPLANE_MODE, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean);
- method @RequiresPermission(android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE) public void setOemNetworkPreference(@NonNull android.net.OemNetworkPreferences, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public boolean shouldAvoidBadWifi();
- method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
- method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
- method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public void unregisterNetworkProvider(@NonNull android.net.NetworkProvider);
- method public void unregisterQosCallback(@NonNull android.net.QosCallback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void unregisterTetheringEventCallback(@NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
- field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
- field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
- field public static final int TETHERING_BLUETOOTH = 2; // 0x2
- field public static final int TETHERING_USB = 1; // 0x1
- field public static final int TETHERING_WIFI = 0; // 0x0
- field @Deprecated public static final int TETHER_ERROR_ENTITLEMENT_UNKONWN = 13; // 0xd
- field @Deprecated public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
- field @Deprecated public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb
- field public static final int TYPE_NONE = -1; // 0xffffffff
- field @Deprecated public static final int TYPE_PROXY = 16; // 0x10
- field @Deprecated public static final int TYPE_WIFI_P2P = 13; // 0xd
- }
-
- @Deprecated public abstract static class ConnectivityManager.OnStartTetheringCallback {
- ctor @Deprecated public ConnectivityManager.OnStartTetheringCallback();
- method @Deprecated public void onTetheringFailed();
- method @Deprecated public void onTetheringStarted();
- }
-
- @Deprecated public static interface ConnectivityManager.OnTetheringEntitlementResultListener {
- method @Deprecated public void onTetheringEntitlementResult(int);
- }
-
- @Deprecated public abstract static class ConnectivityManager.OnTetheringEventCallback {
- ctor @Deprecated public ConnectivityManager.OnTetheringEventCallback();
- method @Deprecated public void onUpstreamChanged(@Nullable android.net.Network);
- }
-
- public final class InvalidPacketException extends java.lang.Exception {
- ctor public InvalidPacketException(int);
- method public int getError();
- field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb
- field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9
- field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea
- }
-
- public final class IpConfiguration implements android.os.Parcelable {
- ctor public IpConfiguration();
- ctor public IpConfiguration(@NonNull android.net.IpConfiguration);
- method public int describeContents();
- method @Nullable public android.net.ProxyInfo getHttpProxy();
- method @NonNull public android.net.IpConfiguration.IpAssignment getIpAssignment();
- method @NonNull public android.net.IpConfiguration.ProxySettings getProxySettings();
- method @Nullable public android.net.StaticIpConfiguration getStaticIpConfiguration();
- method public void setHttpProxy(@Nullable android.net.ProxyInfo);
- method public void setIpAssignment(@NonNull android.net.IpConfiguration.IpAssignment);
- method public void setProxySettings(@NonNull android.net.IpConfiguration.ProxySettings);
- method public void setStaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.IpConfiguration> CREATOR;
- }
-
- public enum IpConfiguration.IpAssignment {
- enum_constant public static final android.net.IpConfiguration.IpAssignment DHCP;
- enum_constant public static final android.net.IpConfiguration.IpAssignment STATIC;
- enum_constant public static final android.net.IpConfiguration.IpAssignment UNASSIGNED;
- }
-
- public enum IpConfiguration.ProxySettings {
- enum_constant public static final android.net.IpConfiguration.ProxySettings NONE;
- enum_constant public static final android.net.IpConfiguration.ProxySettings PAC;
- enum_constant public static final android.net.IpConfiguration.ProxySettings STATIC;
- enum_constant public static final android.net.IpConfiguration.ProxySettings UNASSIGNED;
- }
-
- public final class IpPrefix implements android.os.Parcelable {
- ctor public IpPrefix(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
- ctor public IpPrefix(@NonNull String);
- }
-
- public class KeepalivePacketData {
- ctor protected KeepalivePacketData(@NonNull java.net.InetAddress, @IntRange(from=0, to=65535) int, @NonNull java.net.InetAddress, @IntRange(from=0, to=65535) int, @NonNull byte[]) throws android.net.InvalidPacketException;
- method @NonNull public java.net.InetAddress getDstAddress();
- method public int getDstPort();
- method @NonNull public byte[] getPacket();
- method @NonNull public java.net.InetAddress getSrcAddress();
- method public int getSrcPort();
- }
-
- public class LinkAddress implements android.os.Parcelable {
- ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int);
- ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int, long, long);
- ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
- ctor public LinkAddress(@NonNull String);
- ctor public LinkAddress(@NonNull String, int, int);
- method public long getDeprecationTime();
- method public long getExpirationTime();
- method public boolean isGlobalPreferred();
- method public boolean isIpv4();
- method public boolean isIpv6();
- method public boolean isSameAddressAs(@Nullable android.net.LinkAddress);
- field public static final long LIFETIME_PERMANENT = 9223372036854775807L; // 0x7fffffffffffffffL
- field public static final long LIFETIME_UNKNOWN = -1L; // 0xffffffffffffffffL
- }
-
- public final class LinkProperties implements android.os.Parcelable {
- ctor public LinkProperties(@Nullable android.net.LinkProperties);
- ctor public LinkProperties(@Nullable android.net.LinkProperties, boolean);
- method public boolean addDnsServer(@NonNull java.net.InetAddress);
- method public boolean addLinkAddress(@NonNull android.net.LinkAddress);
- method public boolean addPcscfServer(@NonNull java.net.InetAddress);
- method @NonNull public java.util.List<java.net.InetAddress> getAddresses();
- method @NonNull public java.util.List<java.lang.String> getAllInterfaceNames();
- method @NonNull public java.util.List<android.net.LinkAddress> getAllLinkAddresses();
- method @NonNull public java.util.List<android.net.RouteInfo> getAllRoutes();
- method @Nullable public android.net.Uri getCaptivePortalApiUrl();
- method @Nullable public android.net.CaptivePortalData getCaptivePortalData();
- method @NonNull public java.util.List<java.net.InetAddress> getPcscfServers();
- method @Nullable public String getTcpBufferSizes();
- method @NonNull public java.util.List<java.net.InetAddress> getValidatedPrivateDnsServers();
- method public boolean hasGlobalIpv6Address();
- method public boolean hasIpv4Address();
- method public boolean hasIpv4DefaultRoute();
- method public boolean hasIpv4DnsServer();
- method public boolean hasIpv6DefaultRoute();
- method public boolean hasIpv6DnsServer();
- method public boolean isIpv4Provisioned();
- method public boolean isIpv6Provisioned();
- method public boolean isProvisioned();
- method public boolean isReachable(@NonNull java.net.InetAddress);
- method public boolean removeDnsServer(@NonNull java.net.InetAddress);
- method public boolean removeLinkAddress(@NonNull android.net.LinkAddress);
- method public boolean removeRoute(@NonNull android.net.RouteInfo);
- method public void setCaptivePortalApiUrl(@Nullable android.net.Uri);
- method public void setCaptivePortalData(@Nullable android.net.CaptivePortalData);
- method public void setPcscfServers(@NonNull java.util.Collection<java.net.InetAddress>);
- method public void setPrivateDnsServerName(@Nullable String);
- method public void setTcpBufferSizes(@Nullable String);
- method public void setUsePrivateDns(boolean);
- method public void setValidatedPrivateDnsServers(@NonNull java.util.Collection<java.net.InetAddress>);
- }
-
- public final class NattKeepalivePacketData extends android.net.KeepalivePacketData implements android.os.Parcelable {
- ctor public NattKeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[]) throws android.net.InvalidPacketException;
- method public int describeContents();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.NattKeepalivePacketData> CREATOR;
- }
-
- public class Network implements android.os.Parcelable {
- ctor public Network(@NonNull android.net.Network);
- method public int getNetId();
- method @NonNull public android.net.Network getPrivateDnsBypassingCopy();
- }
-
- public abstract class NetworkAgent {
- ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, int, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider);
- ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkScore, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider);
- method @Nullable public android.net.Network getNetwork();
- method public void markConnected();
- method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData);
- method public void onAutomaticReconnectDisabled();
- method public void onBandwidthUpdateRequested();
- method public void onNetworkCreated();
- method public void onNetworkDestroyed();
- method public void onNetworkUnwanted();
- method public void onQosCallbackRegistered(int, @NonNull android.net.QosFilter);
- method public void onQosCallbackUnregistered(int);
- method public void onRemoveKeepalivePacketFilter(int);
- method public void onSaveAcceptUnvalidated(boolean);
- method public void onSignalStrengthThresholdsUpdated(@NonNull int[]);
- method public void onStartSocketKeepalive(int, @NonNull java.time.Duration, @NonNull android.net.KeepalivePacketData);
- method public void onStopSocketKeepalive(int);
- method public void onValidationStatus(int, @Nullable android.net.Uri);
- method @NonNull public android.net.Network register();
- method public final void sendLinkProperties(@NonNull android.net.LinkProperties);
- method public final void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
- method public final void sendNetworkScore(@NonNull android.net.NetworkScore);
- method public final void sendNetworkScore(@IntRange(from=0, to=99) int);
- method public final void sendQosCallbackError(int, int);
- method public final void sendQosSessionAvailable(int, int, @NonNull android.net.QosSessionAttributes);
- method public final void sendQosSessionLost(int, int, int);
- method public final void sendSocketKeepaliveEvent(int, int);
- method @Deprecated public void setLegacySubtype(int, @NonNull String);
- method public void setLingerDuration(@NonNull java.time.Duration);
- method public void setTeardownDelayMillis(@IntRange(from=0, to=0x1388) int);
- method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
- method public void unregister();
- field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
- field public static final int VALIDATION_STATUS_VALID = 1; // 0x1
- }
-
- public final class NetworkAgentConfig implements android.os.Parcelable {
- method public int describeContents();
- method public int getLegacyType();
- method @NonNull public String getLegacyTypeName();
- method public boolean isExplicitlySelected();
- method public boolean isPartialConnectivityAcceptable();
- method public boolean isUnvalidatedConnectivityAcceptable();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkAgentConfig> CREATOR;
- }
-
- public static final class NetworkAgentConfig.Builder {
- ctor public NetworkAgentConfig.Builder();
- method @NonNull public android.net.NetworkAgentConfig build();
- method @NonNull public android.net.NetworkAgentConfig.Builder setExplicitlySelected(boolean);
- method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyExtraInfo(@NonNull String);
- method @NonNull public android.net.NetworkAgentConfig.Builder setLegacySubType(int);
- method @NonNull public android.net.NetworkAgentConfig.Builder setLegacySubTypeName(@NonNull String);
- method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyType(int);
- method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyTypeName(@NonNull String);
- method @NonNull public android.net.NetworkAgentConfig.Builder setNat64DetectionEnabled(boolean);
- method @NonNull public android.net.NetworkAgentConfig.Builder setPartialConnectivityAcceptable(boolean);
- method @NonNull public android.net.NetworkAgentConfig.Builder setProvisioningNotificationEnabled(boolean);
- method @NonNull public android.net.NetworkAgentConfig.Builder setUnvalidatedConnectivityAcceptable(boolean);
- }
-
- public final class NetworkCapabilities implements android.os.Parcelable {
- method @NonNull public int[] getAdministratorUids();
- method @Nullable public static String getCapabilityCarrierName(int);
- method @Nullable public String getSsid();
- method @NonNull public java.util.Set<java.lang.Integer> getSubscriptionIds();
- method @NonNull public int[] getTransportTypes();
- method public boolean isPrivateDnsBroken();
- method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
- field public static final int NET_CAPABILITY_BIP = 31; // 0x1f
- field public static final int NET_CAPABILITY_NOT_VCN_MANAGED = 28; // 0x1c
- field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16
- field public static final int NET_CAPABILITY_OEM_PRIVATE = 26; // 0x1a
- field public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24; // 0x18
- field public static final int NET_CAPABILITY_VEHICLE_INTERNAL = 27; // 0x1b
- field public static final int NET_CAPABILITY_VSIM = 30; // 0x1e
- }
-
- public static final class NetworkCapabilities.Builder {
- ctor public NetworkCapabilities.Builder();
- ctor public NetworkCapabilities.Builder(@NonNull android.net.NetworkCapabilities);
- method @NonNull public android.net.NetworkCapabilities.Builder addCapability(int);
- method @NonNull public android.net.NetworkCapabilities.Builder addTransportType(int);
- method @NonNull public android.net.NetworkCapabilities build();
- method @NonNull public android.net.NetworkCapabilities.Builder removeCapability(int);
- method @NonNull public android.net.NetworkCapabilities.Builder removeTransportType(int);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setAdministratorUids(@NonNull int[]);
- method @NonNull public android.net.NetworkCapabilities.Builder setLinkDownstreamBandwidthKbps(int);
- method @NonNull public android.net.NetworkCapabilities.Builder setLinkUpstreamBandwidthKbps(int);
- method @NonNull public android.net.NetworkCapabilities.Builder setNetworkSpecifier(@Nullable android.net.NetworkSpecifier);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setOwnerUid(int);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorPackageName(@Nullable String);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorUid(int);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkCapabilities.Builder setSignalStrength(int);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setSsid(@Nullable String);
- method @NonNull public android.net.NetworkCapabilities.Builder setSubscriptionIds(@NonNull java.util.Set<java.lang.Integer>);
- method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo);
- method @NonNull public static android.net.NetworkCapabilities.Builder withoutDefaultCapabilities();
- }
-
- public class NetworkProvider {
- ctor public NetworkProvider(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String);
- method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull android.net.NetworkRequest);
- method public int getProviderId();
- method public void onNetworkRequestWithdrawn(@NonNull android.net.NetworkRequest);
- method public void onNetworkRequested(@NonNull android.net.NetworkRequest, @IntRange(from=0, to=99) int, int);
- method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void registerNetworkOffer(@NonNull android.net.NetworkScore, @NonNull android.net.NetworkCapabilities, @NonNull java.util.concurrent.Executor, @NonNull android.net.NetworkProvider.NetworkOfferCallback);
- method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void unregisterNetworkOffer(@NonNull android.net.NetworkProvider.NetworkOfferCallback);
- field public static final int ID_NONE = -1; // 0xffffffff
- }
-
- public static interface NetworkProvider.NetworkOfferCallback {
- method public void onNetworkNeeded(@NonNull android.net.NetworkRequest);
- method public void onNetworkUnneeded(@NonNull android.net.NetworkRequest);
- }
-
- public class NetworkReleasedException extends java.lang.Exception {
- }
-
- public class NetworkRequest implements android.os.Parcelable {
- method @Nullable public String getRequestorPackageName();
- method public int getRequestorUid();
- }
-
- public static class NetworkRequest.Builder {
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int);
- method @NonNull public android.net.NetworkRequest.Builder setSubscriptionIds(@NonNull java.util.Set<java.lang.Integer>);
- }
-
- public final class NetworkScore implements android.os.Parcelable {
- method public int describeContents();
- method public int getKeepConnectedReason();
- method public int getLegacyInt();
- method public boolean isExiting();
- method public boolean isTransportPrimary();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkScore> CREATOR;
- field public static final int KEEP_CONNECTED_FOR_HANDOVER = 1; // 0x1
- field public static final int KEEP_CONNECTED_NONE = 0; // 0x0
- }
-
- public static final class NetworkScore.Builder {
- ctor public NetworkScore.Builder();
- method @NonNull public android.net.NetworkScore build();
- method @NonNull public android.net.NetworkScore.Builder setExiting(boolean);
- method @NonNull public android.net.NetworkScore.Builder setKeepConnectedReason(int);
- method @NonNull public android.net.NetworkScore.Builder setLegacyInt(int);
- method @NonNull public android.net.NetworkScore.Builder setTransportPrimary(boolean);
- }
-
- public final class OemNetworkPreferences implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public java.util.Map<java.lang.String,java.lang.Integer> getNetworkPreferences();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.OemNetworkPreferences> CREATOR;
- field public static final int OEM_NETWORK_PREFERENCE_OEM_PAID = 1; // 0x1
- field public static final int OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK = 2; // 0x2
- field public static final int OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY = 3; // 0x3
- field public static final int OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY = 4; // 0x4
- field public static final int OEM_NETWORK_PREFERENCE_UNINITIALIZED = 0; // 0x0
- }
-
- public static final class OemNetworkPreferences.Builder {
- ctor public OemNetworkPreferences.Builder();
- ctor public OemNetworkPreferences.Builder(@NonNull android.net.OemNetworkPreferences);
- method @NonNull public android.net.OemNetworkPreferences.Builder addNetworkPreference(@NonNull String, int);
- method @NonNull public android.net.OemNetworkPreferences build();
- method @NonNull public android.net.OemNetworkPreferences.Builder clearNetworkPreference(@NonNull String);
- }
-
- public abstract class QosCallback {
- ctor public QosCallback();
- method public void onError(@NonNull android.net.QosCallbackException);
- method public void onQosSessionAvailable(@NonNull android.net.QosSession, @NonNull android.net.QosSessionAttributes);
- method public void onQosSessionLost(@NonNull android.net.QosSession);
- }
-
- public static class QosCallback.QosCallbackRegistrationException extends java.lang.RuntimeException {
- }
-
- public final class QosCallbackException extends java.lang.Exception {
- }
-
- public abstract class QosFilter {
- method @NonNull public abstract android.net.Network getNetwork();
- method public abstract boolean matchesLocalAddress(@NonNull java.net.InetAddress, int, int);
- method public abstract boolean matchesRemoteAddress(@NonNull java.net.InetAddress, int, int);
- }
-
- public final class QosSession implements android.os.Parcelable {
- ctor public QosSession(int, int);
- method public int describeContents();
- method public int getSessionId();
- method public int getSessionType();
- method public long getUniqueId();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSession> CREATOR;
- field public static final int TYPE_EPS_BEARER = 1; // 0x1
- field public static final int TYPE_NR_BEARER = 2; // 0x2
- }
-
- public interface QosSessionAttributes {
- }
-
- public final class QosSocketInfo implements android.os.Parcelable {
- ctor public QosSocketInfo(@NonNull android.net.Network, @NonNull java.net.Socket) throws java.io.IOException;
- method public int describeContents();
- method @NonNull public java.net.InetSocketAddress getLocalSocketAddress();
- method @NonNull public android.net.Network getNetwork();
- method @Nullable public java.net.InetSocketAddress getRemoteSocketAddress();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSocketInfo> CREATOR;
- }
-
- public final class RouteInfo implements android.os.Parcelable {
- ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int);
- ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int, int);
- method public int getMtu();
- method public int getType();
- field public static final int RTN_THROW = 9; // 0x9
- field public static final int RTN_UNICAST = 1; // 0x1
- field public static final int RTN_UNREACHABLE = 7; // 0x7
- }
-
- public abstract class SocketKeepalive implements java.lang.AutoCloseable {
- field public static final int ERROR_NO_SUCH_SLOT = -33; // 0xffffffdf
- field public static final int SUCCESS = 0; // 0x0
- }
-
- public class SocketLocalAddressChangedException extends java.lang.Exception {
- }
-
- public class SocketNotBoundException extends java.lang.Exception {
- }
-
- public final class StaticIpConfiguration implements android.os.Parcelable {
- ctor public StaticIpConfiguration();
- ctor public StaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
- method public void addDnsServer(@NonNull java.net.InetAddress);
- method public void clear();
- method public int describeContents();
- method @NonNull public java.util.List<java.net.InetAddress> getDnsServers();
- method @Nullable public String getDomains();
- method @Nullable public java.net.InetAddress getGateway();
- method @Nullable public android.net.LinkAddress getIpAddress();
- method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(@Nullable String);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.StaticIpConfiguration> CREATOR;
- }
-
- public static final class StaticIpConfiguration.Builder {
- ctor public StaticIpConfiguration.Builder();
- method @NonNull public android.net.StaticIpConfiguration build();
- method @NonNull public android.net.StaticIpConfiguration.Builder setDnsServers(@NonNull Iterable<java.net.InetAddress>);
- method @NonNull public android.net.StaticIpConfiguration.Builder setDomains(@Nullable String);
- method @NonNull public android.net.StaticIpConfiguration.Builder setGateway(@Nullable java.net.InetAddress);
- method @NonNull public android.net.StaticIpConfiguration.Builder setIpAddress(@Nullable android.net.LinkAddress);
- }
-
- public final class TcpKeepalivePacketData extends android.net.KeepalivePacketData implements android.os.Parcelable {
- ctor public TcpKeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[], int, int, int, int, int, int) throws android.net.InvalidPacketException;
- method public int describeContents();
- method public int getIpTos();
- method public int getIpTtl();
- method public int getTcpAck();
- method public int getTcpSeq();
- method public int getTcpWindow();
- method public int getTcpWindowScale();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TcpKeepalivePacketData> CREATOR;
- }
-
-}
-
-package android.net.apf {
-
- public final class ApfCapabilities implements android.os.Parcelable {
- ctor public ApfCapabilities(int, int, int);
- method public int describeContents();
- method public static boolean getApfDrop8023Frames();
- method @NonNull public static int[] getApfEtherTypeBlackList();
- method public boolean hasDataAccess();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.apf.ApfCapabilities> CREATOR;
- field public final int apfPacketFormat;
- field public final int apfVersionSupported;
- field public final int maximumApfProgramSize;
- }
-
-}
-
diff --git a/packages/Connectivity/framework/api/system-lint-baseline.txt b/packages/Connectivity/framework/api/system-lint-baseline.txt
deleted file mode 100644
index 9a97707..0000000
--- a/packages/Connectivity/framework/api/system-lint-baseline.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Baseline format: 1.0
diff --git a/packages/Connectivity/framework/api/system-removed.txt b/packages/Connectivity/framework/api/system-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/packages/Connectivity/framework/api/system-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/packages/Connectivity/framework/jarjar-rules.txt b/packages/Connectivity/framework/jarjar-rules.txt
deleted file mode 100644
index 2e5848c..0000000
--- a/packages/Connectivity/framework/jarjar-rules.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-rule com.android.net.module.util.** android.net.connectivity.framework.util.@1
-rule android.net.NetworkFactory* android.net.connectivity.framework.NetworkFactory@1
diff --git a/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp b/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp
deleted file mode 100644
index 7478b3e..0000000
--- a/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#define LOG_TAG "NetworkUtils"
-
-#include <android/file_descriptor_jni.h>
-#include <android/multinetwork.h>
-#include <linux/filter.h>
-#include <linux/tcp.h>
-#include <netinet/in.h>
-#include <string.h>
-
-#include <DnsProxydProtocol.h> // NETID_USE_LOCAL_NAMESERVERS
-#include <nativehelper/JNIPlatformHelp.h>
-#include <utils/Log.h>
-
-#include "jni.h"
-
-#define NETUTILS_PKG_NAME "android/net/NetworkUtils"
-
-namespace android {
-
-constexpr int MAXPACKETSIZE = 8 * 1024;
-// FrameworkListener limits the size of commands to 4096 bytes.
-constexpr int MAXCMDSIZE = 4096;
-
-static volatile jclass class_Network = 0;
-static volatile jmethodID method_fromNetworkHandle = 0;
-
-static inline jclass FindClassOrDie(JNIEnv* env, const char* class_name) {
- jclass clazz = env->FindClass(class_name);
- LOG_ALWAYS_FATAL_IF(clazz == NULL, "Unable to find class %s", class_name);
- return clazz;
-}
-
-template <typename T>
-static inline T MakeGlobalRefOrDie(JNIEnv* env, T in) {
- jobject res = env->NewGlobalRef(in);
- LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to create global reference.");
- return static_cast<T>(res);
-}
-
-static void android_net_utils_attachDropAllBPFFilter(JNIEnv *env, jobject clazz, jobject javaFd)
-{
- struct sock_filter filter_code[] = {
- // Reject all.
- BPF_STMT(BPF_RET | BPF_K, 0)
- };
- struct sock_fprog filter = {
- sizeof(filter_code) / sizeof(filter_code[0]),
- filter_code,
- };
-
- int fd = AFileDescriptor_getFd(env, javaFd);
- if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
- }
-}
-
-static void android_net_utils_detachBPFFilter(JNIEnv *env, jobject clazz, jobject javaFd)
-{
- int optval_ignored = 0;
- int fd = AFileDescriptor_getFd(env, javaFd);
- if (setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, &optval_ignored, sizeof(optval_ignored)) !=
- 0) {
- jniThrowExceptionFmt(env, "java/net/SocketException",
- "setsockopt(SO_DETACH_FILTER): %s", strerror(errno));
- }
-}
-
-static jboolean android_net_utils_bindProcessToNetworkHandle(JNIEnv *env, jobject thiz,
- jlong netHandle)
-{
- return (jboolean) !android_setprocnetwork(netHandle);
-}
-
-static jlong android_net_utils_getBoundNetworkHandleForProcess(JNIEnv *env, jobject thiz)
-{
- net_handle_t network;
- if (android_getprocnetwork(&network) != 0) {
- jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
- "android_getprocnetwork(): %s", strerror(errno));
- return NETWORK_UNSPECIFIED;
- }
- return (jlong) network;
-}
-
-static jboolean android_net_utils_bindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz,
- jint netId, jlong netHandle)
-{
- return (jboolean) !android_setprocdns(netHandle);
-}
-
-static jint android_net_utils_bindSocketToNetworkHandle(JNIEnv *env, jobject thiz, jobject javaFd,
- jlong netHandle) {
- return android_setsocknetwork(netHandle, AFileDescriptor_getFd(env, javaFd));
-}
-
-static bool checkLenAndCopy(JNIEnv* env, const jbyteArray& addr, int len, void* dst)
-{
- if (env->GetArrayLength(addr) != len) {
- return false;
- }
- env->GetByteArrayRegion(addr, 0, len, reinterpret_cast<jbyte*>(dst));
- return true;
-}
-
-static jobject android_net_utils_resNetworkQuery(JNIEnv *env, jobject thiz, jlong netHandle,
- jstring dname, jint ns_class, jint ns_type, jint flags) {
- const jsize javaCharsCount = env->GetStringLength(dname);
- const jsize byteCountUTF8 = env->GetStringUTFLength(dname);
-
- // Only allow dname which could be simply formatted to UTF8.
- // In native layer, res_mkquery would re-format the input char array to packet.
- char queryname[byteCountUTF8 + 1];
- memset(queryname, 0, (byteCountUTF8 + 1) * sizeof(char));
-
- env->GetStringUTFRegion(dname, 0, javaCharsCount, queryname);
- int fd = android_res_nquery(netHandle, queryname, ns_class, ns_type, flags);
-
- if (fd < 0) {
- jniThrowErrnoException(env, "resNetworkQuery", -fd);
- return nullptr;
- }
-
- return jniCreateFileDescriptor(env, fd);
-}
-
-static jobject android_net_utils_resNetworkSend(JNIEnv *env, jobject thiz, jlong netHandle,
- jbyteArray msg, jint msgLen, jint flags) {
- uint8_t data[MAXCMDSIZE];
-
- checkLenAndCopy(env, msg, msgLen, data);
- int fd = android_res_nsend(netHandle, data, msgLen, flags);
-
- if (fd < 0) {
- jniThrowErrnoException(env, "resNetworkSend", -fd);
- return nullptr;
- }
-
- return jniCreateFileDescriptor(env, fd);
-}
-
-static jobject android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz, jobject javaFd) {
- int fd = AFileDescriptor_getFd(env, javaFd);
- int rcode;
- uint8_t buf[MAXPACKETSIZE] = {0};
-
- int res = android_res_nresult(fd, &rcode, buf, MAXPACKETSIZE);
- jniSetFileDescriptorOfFD(env, javaFd, -1);
- if (res < 0) {
- jniThrowErrnoException(env, "resNetworkResult", -res);
- return nullptr;
- }
-
- jbyteArray answer = env->NewByteArray(res);
- if (answer == nullptr) {
- jniThrowErrnoException(env, "resNetworkResult", ENOMEM);
- return nullptr;
- } else {
- env->SetByteArrayRegion(answer, 0, res, reinterpret_cast<jbyte*>(buf));
- }
-
- jclass class_DnsResponse = env->FindClass("android/net/DnsResolver$DnsResponse");
- jmethodID ctor = env->GetMethodID(class_DnsResponse, "<init>", "([BI)V");
-
- return env->NewObject(class_DnsResponse, ctor, answer, rcode);
-}
-
-static void android_net_utils_resNetworkCancel(JNIEnv *env, jobject thiz, jobject javaFd) {
- int fd = AFileDescriptor_getFd(env, javaFd);
- android_res_cancel(fd);
- jniSetFileDescriptorOfFD(env, javaFd, -1);
-}
-
-static jobject android_net_utils_getDnsNetwork(JNIEnv *env, jobject thiz) {
- net_handle_t dnsNetHandle = NETWORK_UNSPECIFIED;
- if (int res = android_getprocdns(&dnsNetHandle) < 0) {
- jniThrowErrnoException(env, "getDnsNetwork", -res);
- return nullptr;
- }
-
- if (method_fromNetworkHandle == 0) {
- // This may be called multiple times concurrently but that is fine
- class_Network = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/net/Network"));
- method_fromNetworkHandle = env->GetStaticMethodID(class_Network, "fromNetworkHandle",
- "(J)Landroid/net/Network;");
- }
- return env->CallStaticObjectMethod(class_Network, method_fromNetworkHandle,
- static_cast<jlong>(dnsNetHandle));
-}
-
-static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) {
- if (javaFd == NULL) {
- jniThrowNullPointerException(env, NULL);
- return NULL;
- }
-
- int fd = AFileDescriptor_getFd(env, javaFd);
- struct tcp_repair_window trw = {};
- socklen_t size = sizeof(trw);
-
- // Obtain the parameters of the TCP repair window.
- int rc = getsockopt(fd, IPPROTO_TCP, TCP_REPAIR_WINDOW, &trw, &size);
- if (rc == -1) {
- jniThrowErrnoException(env, "getsockopt : TCP_REPAIR_WINDOW", errno);
- return NULL;
- }
-
- struct tcp_info tcpinfo = {};
- socklen_t tcpinfo_size = sizeof(tcp_info);
-
- // Obtain the window scale from the tcp info structure. This contains a scale factor that
- // should be applied to the window size.
- rc = getsockopt(fd, IPPROTO_TCP, TCP_INFO, &tcpinfo, &tcpinfo_size);
- if (rc == -1) {
- jniThrowErrnoException(env, "getsockopt : TCP_INFO", errno);
- return NULL;
- }
-
- jclass class_TcpRepairWindow = env->FindClass("android/net/TcpRepairWindow");
- jmethodID ctor = env->GetMethodID(class_TcpRepairWindow, "<init>", "(IIIIII)V");
-
- return env->NewObject(class_TcpRepairWindow, ctor, trw.snd_wl1, trw.snd_wnd, trw.max_window,
- trw.rcv_wnd, trw.rcv_wup, tcpinfo.tcpi_rcv_wscale);
-}
-
-// ----------------------------------------------------------------------------
-
-/*
- * JNI registration.
- */
-// clang-format off
-static const JNINativeMethod gNetworkUtilMethods[] = {
- /* name, signature, funcPtr */
- { "bindProcessToNetworkHandle", "(J)Z", (void*) android_net_utils_bindProcessToNetworkHandle },
- { "getBoundNetworkHandleForProcess", "()J", (void*) android_net_utils_getBoundNetworkHandleForProcess },
- { "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
- { "bindSocketToNetworkHandle", "(Ljava/io/FileDescriptor;J)I", (void*) android_net_utils_bindSocketToNetworkHandle },
- { "attachDropAllBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDropAllBPFFilter },
- { "detachBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_detachBPFFilter },
- { "getTcpRepairWindow", "(Ljava/io/FileDescriptor;)Landroid/net/TcpRepairWindow;", (void*) android_net_utils_getTcpRepairWindow },
- { "resNetworkSend", "(J[BII)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkSend },
- { "resNetworkQuery", "(JLjava/lang/String;III)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkQuery },
- { "resNetworkResult", "(Ljava/io/FileDescriptor;)Landroid/net/DnsResolver$DnsResponse;", (void*) android_net_utils_resNetworkResult },
- { "resNetworkCancel", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_resNetworkCancel },
- { "getDnsNetwork", "()Landroid/net/Network;", (void*) android_net_utils_getDnsNetwork },
-};
-// clang-format on
-
-int register_android_net_NetworkUtils(JNIEnv* env)
-{
- return jniRegisterNativeMethods(env, NETUTILS_PKG_NAME, gNetworkUtilMethods,
- NELEM(gNetworkUtilMethods));
-}
-
-}; // namespace android
diff --git a/packages/Connectivity/framework/jni/onload.cpp b/packages/Connectivity/framework/jni/onload.cpp
deleted file mode 100644
index 435f434..0000000
--- a/packages/Connectivity/framework/jni/onload.cpp
+++ /dev/null
@@ -1,38 +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.
- */
-
-#include <nativehelper/JNIHelp.h>
-#include <log/log.h>
-
-namespace android {
-
-int register_android_net_NetworkUtils(JNIEnv* env);
-
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
- JNIEnv *env;
- if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
- ALOGE("GetEnv failed");
- return JNI_ERR;
- }
-
- if (register_android_net_NetworkUtils(env) < 0) {
- return JNI_ERR;
- }
-
- return JNI_VERSION_1_6;
-}
-
-};
\ No newline at end of file
diff --git a/packages/Connectivity/framework/lint-baseline.xml b/packages/Connectivity/framework/lint-baseline.xml
deleted file mode 100644
index df37ae8..0000000
--- a/packages/Connectivity/framework/lint-baseline.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 30): `new android.net.ParseException`"
- errorLine1=" ParseException pe = new ParseException(e.reason, e.getCause());"
- errorLine2=" ~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/Connectivity/framework/src/android/net/DnsResolver.java"
- line="301"
- column="37"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Class requires API level 31 (current min is 30): `android.telephony.TelephonyCallback`"
- errorLine1=" protected class ActiveDataSubscriptionIdListener extends TelephonyCallback"
- errorLine2=" ~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java"
- line="96"
- column="62"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Class requires API level 31 (current min is 30): `android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener`"
- errorLine1=" implements TelephonyCallback.ActiveDataSubscriptionIdListener {"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java"
- line="97"
- column="24"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 30): `android.telephony.TelephonyManager#registerTelephonyCallback`"
- errorLine1=" ctx.getSystemService(TelephonyManager.class).registerTelephonyCallback("
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java"
- line="126"
- column="54"/>
- </issue>
-
-</issues>
diff --git a/packages/Connectivity/framework/src/android/net/CaptivePortal.java b/packages/Connectivity/framework/src/android/net/CaptivePortal.java
deleted file mode 100644
index 4a7b601..0000000
--- a/packages/Connectivity/framework/src/android/net/CaptivePortal.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed urnder 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.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-
-/**
- * A class allowing apps handling the {@link ConnectivityManager#ACTION_CAPTIVE_PORTAL_SIGN_IN}
- * activity to indicate to the system different outcomes of captive portal sign in. This class is
- * passed as an extra named {@link ConnectivityManager#EXTRA_CAPTIVE_PORTAL} with the
- * {@code ACTION_CAPTIVE_PORTAL_SIGN_IN} activity.
- */
-public class CaptivePortal implements Parcelable {
- /**
- * Response code from the captive portal application, indicating that the portal was dismissed
- * and the network should be re-validated.
- * @see ICaptivePortal#appResponse(int)
- * @see android.net.INetworkMonitor#notifyCaptivePortalAppFinished(int)
- * @hide
- */
- @SystemApi
- public static final int APP_RETURN_DISMISSED = 0;
- /**
- * Response code from the captive portal application, indicating that the user did not login and
- * does not want to use the captive portal network.
- * @see ICaptivePortal#appResponse(int)
- * @see android.net.INetworkMonitor#notifyCaptivePortalAppFinished(int)
- * @hide
- */
- @SystemApi
- public static final int APP_RETURN_UNWANTED = 1;
- /**
- * Response code from the captive portal application, indicating that the user does not wish to
- * login but wants to use the captive portal network as-is.
- * @see ICaptivePortal#appResponse(int)
- * @see android.net.INetworkMonitor#notifyCaptivePortalAppFinished(int)
- * @hide
- */
- @SystemApi
- public static final int APP_RETURN_WANTED_AS_IS = 2;
- /** Event offset of request codes from captive portal application. */
- private static final int APP_REQUEST_BASE = 100;
- /**
- * Request code from the captive portal application, indicating that the network condition may
- * have changed and the network should be re-validated.
- * @see ICaptivePortal#appRequest(int)
- * @see android.net.INetworkMonitor#forceReevaluation(int)
- * @hide
- */
- @SystemApi
- public static final int APP_REQUEST_REEVALUATION_REQUIRED = APP_REQUEST_BASE + 0;
-
- private final IBinder mBinder;
-
- /** @hide */
- public CaptivePortal(@NonNull IBinder binder) {
- mBinder = binder;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeStrongBinder(mBinder);
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<CaptivePortal> CREATOR
- = new Parcelable.Creator<CaptivePortal>() {
- @Override
- public CaptivePortal createFromParcel(Parcel in) {
- return new CaptivePortal(in.readStrongBinder());
- }
-
- @Override
- public CaptivePortal[] newArray(int size) {
- return new CaptivePortal[size];
- }
- };
-
- /**
- * Indicate to the system that the captive portal has been
- * dismissed. In response the framework will re-evaluate the network's
- * connectivity and might take further action thereafter.
- */
- public void reportCaptivePortalDismissed() {
- try {
- ICaptivePortal.Stub.asInterface(mBinder).appResponse(APP_RETURN_DISMISSED);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Indicate to the system that the user does not want to pursue signing in to the
- * captive portal and the system should continue to prefer other networks
- * without captive portals for use as the default active data network. The
- * system will not retest the network for a captive portal so as to avoid
- * disturbing the user with further sign in to network notifications.
- */
- public void ignoreNetwork() {
- try {
- ICaptivePortal.Stub.asInterface(mBinder).appResponse(APP_RETURN_UNWANTED);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Indicate to the system the user wants to use this network as is, even though
- * the captive portal is still in place. The system will treat the network
- * as if it did not have a captive portal when selecting the network to use
- * as the default active data network. This may result in this network
- * becoming the default active data network, which could disrupt network
- * connectivity for apps because the captive portal is still in place.
- * @hide
- */
- @SystemApi
- public void useNetwork() {
- try {
- ICaptivePortal.Stub.asInterface(mBinder).appResponse(APP_RETURN_WANTED_AS_IS);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Request that the system reevaluates the captive portal status.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
- public void reevaluateNetwork() {
- try {
- ICaptivePortal.Stub.asInterface(mBinder).appRequest(APP_REQUEST_REEVALUATION_REQUIRED);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Log a captive portal login event.
- * @param eventId one of the CAPTIVE_PORTAL_LOGIN_* constants in metrics_constants.proto.
- * @param packageName captive portal application package name.
- * @hide
- * @deprecated The event will not be logged in Android S and above. The
- * caller is migrating to statsd.
- */
- @Deprecated
- @SystemApi
- public void logEvent(int eventId, @NonNull String packageName) {
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/CaptivePortalData.java b/packages/Connectivity/framework/src/android/net/CaptivePortalData.java
deleted file mode 100644
index 53aa1b9..0000000
--- a/packages/Connectivity/framework/src/android/net/CaptivePortalData.java
+++ /dev/null
@@ -1,379 +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.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Metadata sent by captive portals, see https://www.ietf.org/id/draft-ietf-capport-api-03.txt.
- * @hide
- */
-@SystemApi
-public final class CaptivePortalData implements Parcelable {
- private final long mRefreshTimeMillis;
- @Nullable
- private final Uri mUserPortalUrl;
- @Nullable
- private final Uri mVenueInfoUrl;
- private final boolean mIsSessionExtendable;
- private final long mByteLimit;
- private final long mExpiryTimeMillis;
- private final boolean mCaptive;
- private final String mVenueFriendlyName;
- private final int mVenueInfoUrlSource;
- private final int mUserPortalUrlSource;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"CAPTIVE_PORTAL_DATA_SOURCE_"}, value = {
- CAPTIVE_PORTAL_DATA_SOURCE_OTHER,
- CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT})
- public @interface CaptivePortalDataSource {}
-
- /**
- * Source of information: Other (default)
- */
- public static final int CAPTIVE_PORTAL_DATA_SOURCE_OTHER = 0;
-
- /**
- * Source of information: Wi-Fi Passpoint
- */
- public static final int CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT = 1;
-
- private CaptivePortalData(long refreshTimeMillis, Uri userPortalUrl, Uri venueInfoUrl,
- boolean isSessionExtendable, long byteLimit, long expiryTimeMillis, boolean captive,
- CharSequence venueFriendlyName, int venueInfoUrlSource, int userPortalUrlSource) {
- mRefreshTimeMillis = refreshTimeMillis;
- mUserPortalUrl = userPortalUrl;
- mVenueInfoUrl = venueInfoUrl;
- mIsSessionExtendable = isSessionExtendable;
- mByteLimit = byteLimit;
- mExpiryTimeMillis = expiryTimeMillis;
- mCaptive = captive;
- mVenueFriendlyName = venueFriendlyName == null ? null : venueFriendlyName.toString();
- mVenueInfoUrlSource = venueInfoUrlSource;
- mUserPortalUrlSource = userPortalUrlSource;
- }
-
- private CaptivePortalData(Parcel p) {
- this(p.readLong(), p.readParcelable(null), p.readParcelable(null), p.readBoolean(),
- p.readLong(), p.readLong(), p.readBoolean(), p.readString(), p.readInt(),
- p.readInt());
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeLong(mRefreshTimeMillis);
- dest.writeParcelable(mUserPortalUrl, 0);
- dest.writeParcelable(mVenueInfoUrl, 0);
- dest.writeBoolean(mIsSessionExtendable);
- dest.writeLong(mByteLimit);
- dest.writeLong(mExpiryTimeMillis);
- dest.writeBoolean(mCaptive);
- dest.writeString(mVenueFriendlyName);
- dest.writeInt(mVenueInfoUrlSource);
- dest.writeInt(mUserPortalUrlSource);
- }
-
- /**
- * A builder to create new {@link CaptivePortalData}.
- */
- public static class Builder {
- private long mRefreshTime;
- private Uri mUserPortalUrl;
- private Uri mVenueInfoUrl;
- private boolean mIsSessionExtendable;
- private long mBytesRemaining = -1;
- private long mExpiryTime = -1;
- private boolean mCaptive;
- private CharSequence mVenueFriendlyName;
- private @CaptivePortalDataSource int mVenueInfoUrlSource = CAPTIVE_PORTAL_DATA_SOURCE_OTHER;
- private @CaptivePortalDataSource int mUserPortalUrlSource =
- CAPTIVE_PORTAL_DATA_SOURCE_OTHER;
-
- /**
- * Create an empty builder.
- */
- public Builder() {}
-
- /**
- * Create a builder copying all data from existing {@link CaptivePortalData}.
- */
- public Builder(@Nullable CaptivePortalData data) {
- if (data == null) return;
- setRefreshTime(data.mRefreshTimeMillis)
- .setUserPortalUrl(data.mUserPortalUrl, data.mUserPortalUrlSource)
- .setVenueInfoUrl(data.mVenueInfoUrl, data.mVenueInfoUrlSource)
- .setSessionExtendable(data.mIsSessionExtendable)
- .setBytesRemaining(data.mByteLimit)
- .setExpiryTime(data.mExpiryTimeMillis)
- .setCaptive(data.mCaptive)
- .setVenueFriendlyName(data.mVenueFriendlyName);
- }
-
- /**
- * Set the time at which data was last refreshed, as per {@link System#currentTimeMillis()}.
- */
- @NonNull
- public Builder setRefreshTime(long refreshTime) {
- mRefreshTime = refreshTime;
- return this;
- }
-
- /**
- * Set the URL to be used for users to login to the portal, if captive.
- */
- @NonNull
- public Builder setUserPortalUrl(@Nullable Uri userPortalUrl) {
- return setUserPortalUrl(userPortalUrl, CAPTIVE_PORTAL_DATA_SOURCE_OTHER);
- }
-
- /**
- * Set the URL to be used for users to login to the portal, if captive, and the source of
- * the data, see {@link CaptivePortalDataSource}
- */
- @NonNull
- public Builder setUserPortalUrl(@Nullable Uri userPortalUrl,
- @CaptivePortalDataSource int source) {
- mUserPortalUrl = userPortalUrl;
- mUserPortalUrlSource = source;
- return this;
- }
-
- /**
- * Set the URL that can be used by users to view information about the network venue.
- */
- @NonNull
- public Builder setVenueInfoUrl(@Nullable Uri venueInfoUrl) {
- return setVenueInfoUrl(venueInfoUrl, CAPTIVE_PORTAL_DATA_SOURCE_OTHER);
- }
-
- /**
- * Set the URL that can be used by users to view information about the network venue, and
- * the source of the data, see {@link CaptivePortalDataSource}
- */
- @NonNull
- public Builder setVenueInfoUrl(@Nullable Uri venueInfoUrl,
- @CaptivePortalDataSource int source) {
- mVenueInfoUrl = venueInfoUrl;
- mVenueInfoUrlSource = source;
- return this;
- }
-
- /**
- * Set whether the portal supports extending a user session on the portal URL page.
- */
- @NonNull
- public Builder setSessionExtendable(boolean sessionExtendable) {
- mIsSessionExtendable = sessionExtendable;
- return this;
- }
-
- /**
- * Set the number of bytes remaining on the network before the portal closes.
- */
- @NonNull
- public Builder setBytesRemaining(long bytesRemaining) {
- mBytesRemaining = bytesRemaining;
- return this;
- }
-
- /**
- * Set the time at the session will expire, as per {@link System#currentTimeMillis()}.
- */
- @NonNull
- public Builder setExpiryTime(long expiryTime) {
- mExpiryTime = expiryTime;
- return this;
- }
-
- /**
- * Set whether the network is captive (portal closed).
- */
- @NonNull
- public Builder setCaptive(boolean captive) {
- mCaptive = captive;
- return this;
- }
-
- /**
- * Set the venue friendly name.
- */
- @NonNull
- public Builder setVenueFriendlyName(@Nullable CharSequence venueFriendlyName) {
- mVenueFriendlyName = venueFriendlyName;
- return this;
- }
-
- /**
- * Create a new {@link CaptivePortalData}.
- */
- @NonNull
- public CaptivePortalData build() {
- return new CaptivePortalData(mRefreshTime, mUserPortalUrl, mVenueInfoUrl,
- mIsSessionExtendable, mBytesRemaining, mExpiryTime, mCaptive,
- mVenueFriendlyName, mVenueInfoUrlSource,
- mUserPortalUrlSource);
- }
- }
-
- /**
- * Get the time at which data was last refreshed, as per {@link System#currentTimeMillis()}.
- */
- public long getRefreshTimeMillis() {
- return mRefreshTimeMillis;
- }
-
- /**
- * Get the URL to be used for users to login to the portal, or extend their session if
- * {@link #isSessionExtendable()} is true.
- */
- @Nullable
- public Uri getUserPortalUrl() {
- return mUserPortalUrl;
- }
-
- /**
- * Get the URL that can be used by users to view information about the network venue.
- */
- @Nullable
- public Uri getVenueInfoUrl() {
- return mVenueInfoUrl;
- }
-
- /**
- * Indicates whether the user portal URL can be used to extend sessions, when the user is logged
- * in and the session has a time or byte limit.
- */
- public boolean isSessionExtendable() {
- return mIsSessionExtendable;
- }
-
- /**
- * Get the remaining bytes on the captive portal session, at the time {@link CaptivePortalData}
- * was refreshed. This may be different from the limit currently enforced by the portal.
- * @return The byte limit, or -1 if not set.
- */
- public long getByteLimit() {
- return mByteLimit;
- }
-
- /**
- * Get the time at the session will expire, as per {@link System#currentTimeMillis()}.
- * @return The expiry time, or -1 if unset.
- */
- public long getExpiryTimeMillis() {
- return mExpiryTimeMillis;
- }
-
- /**
- * Get whether the network is captive (portal closed).
- */
- public boolean isCaptive() {
- return mCaptive;
- }
-
- /**
- * Get the information source of the Venue URL
- * @return The source that the Venue URL was obtained from
- */
- public @CaptivePortalDataSource int getVenueInfoUrlSource() {
- return mVenueInfoUrlSource;
- }
-
- /**
- * Get the information source of the user portal URL
- * @return The source that the user portal URL was obtained from
- */
- public @CaptivePortalDataSource int getUserPortalUrlSource() {
- return mUserPortalUrlSource;
- }
-
- /**
- * Get the venue friendly name
- */
- @Nullable
- public CharSequence getVenueFriendlyName() {
- return mVenueFriendlyName;
- }
-
- @NonNull
- public static final Creator<CaptivePortalData> CREATOR = new Creator<CaptivePortalData>() {
- @Override
- public CaptivePortalData createFromParcel(Parcel source) {
- return new CaptivePortalData(source);
- }
-
- @Override
- public CaptivePortalData[] newArray(int size) {
- return new CaptivePortalData[size];
- }
- };
-
- @Override
- public int hashCode() {
- return Objects.hash(mRefreshTimeMillis, mUserPortalUrl, mVenueInfoUrl,
- mIsSessionExtendable, mByteLimit, mExpiryTimeMillis, mCaptive, mVenueFriendlyName,
- mVenueInfoUrlSource, mUserPortalUrlSource);
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (!(obj instanceof CaptivePortalData)) return false;
- final CaptivePortalData other = (CaptivePortalData) obj;
- return mRefreshTimeMillis == other.mRefreshTimeMillis
- && Objects.equals(mUserPortalUrl, other.mUserPortalUrl)
- && Objects.equals(mVenueInfoUrl, other.mVenueInfoUrl)
- && mIsSessionExtendable == other.mIsSessionExtendable
- && mByteLimit == other.mByteLimit
- && mExpiryTimeMillis == other.mExpiryTimeMillis
- && mCaptive == other.mCaptive
- && Objects.equals(mVenueFriendlyName, other.mVenueFriendlyName)
- && mVenueInfoUrlSource == other.mVenueInfoUrlSource
- && mUserPortalUrlSource == other.mUserPortalUrlSource;
- }
-
- @Override
- public String toString() {
- return "CaptivePortalData {"
- + "refreshTime: " + mRefreshTimeMillis
- + ", userPortalUrl: " + mUserPortalUrl
- + ", venueInfoUrl: " + mVenueInfoUrl
- + ", isSessionExtendable: " + mIsSessionExtendable
- + ", byteLimit: " + mByteLimit
- + ", expiryTime: " + mExpiryTimeMillis
- + ", captive: " + mCaptive
- + ", venueFriendlyName: " + mVenueFriendlyName
- + ", venueInfoUrlSource: " + mVenueInfoUrlSource
- + ", userPortalUrlSource: " + mUserPortalUrlSource
- + "}";
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/ConnectionInfo.aidl b/packages/Connectivity/framework/src/android/net/ConnectionInfo.aidl
deleted file mode 100644
index 07faf8b..0000000
--- a/packages/Connectivity/framework/src/android/net/ConnectionInfo.aidl
+++ /dev/null
@@ -1,20 +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;
-
-parcelable ConnectionInfo;
diff --git a/packages/Connectivity/framework/src/android/net/ConnectionInfo.java b/packages/Connectivity/framework/src/android/net/ConnectionInfo.java
deleted file mode 100644
index 4514a84..0000000
--- a/packages/Connectivity/framework/src/android/net/ConnectionInfo.java
+++ /dev/null
@@ -1,83 +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 android.os.Parcel;
-import android.os.Parcelable;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-
-/**
- * Describe a network connection including local and remote address/port of a connection and the
- * transport protocol.
- *
- * @hide
- */
-public final class ConnectionInfo implements Parcelable {
- public final int protocol;
- public final InetSocketAddress local;
- public final InetSocketAddress remote;
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public ConnectionInfo(int protocol, InetSocketAddress local, InetSocketAddress remote) {
- this.protocol = protocol;
- this.local = local;
- this.remote = remote;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(protocol);
- out.writeByteArray(local.getAddress().getAddress());
- out.writeInt(local.getPort());
- out.writeByteArray(remote.getAddress().getAddress());
- out.writeInt(remote.getPort());
- }
-
- public static final @android.annotation.NonNull Creator<ConnectionInfo> CREATOR = new Creator<ConnectionInfo>() {
- public ConnectionInfo createFromParcel(Parcel in) {
- int protocol = in.readInt();
- InetAddress localAddress;
- try {
- localAddress = InetAddress.getByAddress(in.createByteArray());
- } catch (UnknownHostException e) {
- throw new IllegalArgumentException("Invalid InetAddress");
- }
- int localPort = in.readInt();
- InetAddress remoteAddress;
- try {
- remoteAddress = InetAddress.getByAddress(in.createByteArray());
- } catch (UnknownHostException e) {
- throw new IllegalArgumentException("Invalid InetAddress");
- }
- int remotePort = in.readInt();
- InetSocketAddress local = new InetSocketAddress(localAddress, localPort);
- InetSocketAddress remote = new InetSocketAddress(remoteAddress, remotePort);
- return new ConnectionInfo(protocol, local, remote);
- }
-
- public ConnectionInfo[] newArray(int size) {
- return new ConnectionInfo[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.java
deleted file mode 100644
index dcc8a5e..0000000
--- a/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.java
+++ /dev/null
@@ -1,778 +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.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.StringDef;
-import android.content.Context;
-import android.os.Binder;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-import android.os.RemoteException;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
-
-/**
- * Class that provides utilities for collecting network connectivity diagnostics information.
- * Connectivity information is made available through triggerable diagnostics tools and by listening
- * to System validations. Some diagnostics information may be permissions-restricted.
- *
- * <p>ConnectivityDiagnosticsManager is intended for use by applications offering network
- * connectivity on a user device. These tools will provide several mechanisms for these applications
- * to be alerted to network conditions as well as diagnose potential network issues themselves.
- *
- * <p>The primary responsibilities of this class are to:
- *
- * <ul>
- * <li>Allow permissioned applications to register and unregister callbacks for network event
- * notifications
- * <li>Invoke callbacks for network event notifications, including:
- * <ul>
- * <li>Network validations
- * <li>Data stalls
- * <li>Connectivity reports from applications
- * </ul>
- * </ul>
- */
-public class ConnectivityDiagnosticsManager {
- /** @hide */
- @VisibleForTesting
- public static final Map<ConnectivityDiagnosticsCallback, ConnectivityDiagnosticsBinder>
- sCallbacks = new ConcurrentHashMap<>();
-
- private final Context mContext;
- private final IConnectivityManager mService;
-
- /** @hide */
- public ConnectivityDiagnosticsManager(Context context, IConnectivityManager service) {
- mContext = Objects.requireNonNull(context, "missing context");
- mService = Objects.requireNonNull(service, "missing IConnectivityManager");
- }
-
- /** @hide */
- @VisibleForTesting
- public static boolean persistableBundleEquals(
- @Nullable PersistableBundle a, @Nullable PersistableBundle b) {
- if (a == b) return true;
- if (a == null || b == null) return false;
- if (!Objects.equals(a.keySet(), b.keySet())) return false;
- for (String key : a.keySet()) {
- if (!Objects.equals(a.get(key), b.get(key))) return false;
- }
- return true;
- }
-
- /** Class that includes connectivity information for a specific Network at a specific time. */
- public static final class ConnectivityReport implements Parcelable {
- /**
- * The overall status of the network is that it is invalid; it neither provides
- * connectivity nor has been exempted from validation.
- */
- public static final int NETWORK_VALIDATION_RESULT_INVALID = 0;
-
- /**
- * The overall status of the network is that it is valid, this may be because it provides
- * full Internet access (all probes succeeded), or because other properties of the network
- * caused probes not to be run.
- */
- // TODO: link to INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID
- public static final int NETWORK_VALIDATION_RESULT_VALID = 1;
-
- /**
- * The overall status of the network is that it provides partial connectivity; some
- * probed services succeeded but others failed.
- */
- // TODO: link to INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
- public static final int NETWORK_VALIDATION_RESULT_PARTIALLY_VALID = 2;
-
- /**
- * Due to the properties of the network, validation was not performed.
- */
- public static final int NETWORK_VALIDATION_RESULT_SKIPPED = 3;
-
- /** @hide */
- @IntDef(
- prefix = {"NETWORK_VALIDATION_RESULT_"},
- value = {
- NETWORK_VALIDATION_RESULT_INVALID,
- NETWORK_VALIDATION_RESULT_VALID,
- NETWORK_VALIDATION_RESULT_PARTIALLY_VALID,
- NETWORK_VALIDATION_RESULT_SKIPPED
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface NetworkValidationResult {}
-
- /**
- * The overall validation result for the Network being reported on.
- *
- * <p>The possible values for this key are:
- * {@link #NETWORK_VALIDATION_RESULT_INVALID},
- * {@link #NETWORK_VALIDATION_RESULT_VALID},
- * {@link #NETWORK_VALIDATION_RESULT_PARTIALLY_VALID},
- * {@link #NETWORK_VALIDATION_RESULT_SKIPPED}.
- *
- * @see android.net.NetworkCapabilities#NET_CAPABILITY_VALIDATED
- */
- @NetworkValidationResult
- public static final String KEY_NETWORK_VALIDATION_RESULT = "networkValidationResult";
-
- /** DNS probe. */
- // TODO: link to INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS
- public static final int NETWORK_PROBE_DNS = 0x04;
-
- /** HTTP probe. */
- // TODO: link to INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP
- public static final int NETWORK_PROBE_HTTP = 0x08;
-
- /** HTTPS probe. */
- // TODO: link to INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS;
- public static final int NETWORK_PROBE_HTTPS = 0x10;
-
- /** Captive portal fallback probe. */
- // TODO: link to INetworkMonitor.NETWORK_VALIDATION_FALLBACK
- public static final int NETWORK_PROBE_FALLBACK = 0x20;
-
- /** Private DNS (DNS over TLS) probd. */
- // TODO: link to INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS
- public static final int NETWORK_PROBE_PRIVATE_DNS = 0x40;
-
- /** @hide */
- @IntDef(
- prefix = {"NETWORK_PROBE_"},
- value = {
- NETWORK_PROBE_DNS,
- NETWORK_PROBE_HTTP,
- NETWORK_PROBE_HTTPS,
- NETWORK_PROBE_FALLBACK,
- NETWORK_PROBE_PRIVATE_DNS
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface NetworkProbe {}
-
- /**
- * A bitmask of network validation probes that succeeded.
- *
- * <p>The possible bits values reported by this key are:
- * {@link #NETWORK_PROBE_DNS},
- * {@link #NETWORK_PROBE_HTTP},
- * {@link #NETWORK_PROBE_HTTPS},
- * {@link #NETWORK_PROBE_FALLBACK},
- * {@link #NETWORK_PROBE_PRIVATE_DNS}.
- */
- @NetworkProbe
- public static final String KEY_NETWORK_PROBES_SUCCEEDED_BITMASK =
- "networkProbesSucceeded";
-
- /**
- * A bitmask of network validation probes that were attempted.
- *
- * <p>These probes may have failed or may be incomplete at the time of this report.
- *
- * <p>The possible bits values reported by this key are:
- * {@link #NETWORK_PROBE_DNS},
- * {@link #NETWORK_PROBE_HTTP},
- * {@link #NETWORK_PROBE_HTTPS},
- * {@link #NETWORK_PROBE_FALLBACK},
- * {@link #NETWORK_PROBE_PRIVATE_DNS}.
- */
- @NetworkProbe
- public static final String KEY_NETWORK_PROBES_ATTEMPTED_BITMASK =
- "networkProbesAttempted";
-
- /** @hide */
- @StringDef(prefix = {"KEY_"}, value = {
- KEY_NETWORK_VALIDATION_RESULT, KEY_NETWORK_PROBES_SUCCEEDED_BITMASK,
- KEY_NETWORK_PROBES_ATTEMPTED_BITMASK})
- @Retention(RetentionPolicy.SOURCE)
- public @interface ConnectivityReportBundleKeys {}
-
- /** The Network for which this ConnectivityReport applied */
- @NonNull private final Network mNetwork;
-
- /**
- * The timestamp for the report. The timestamp is taken from {@link
- * System#currentTimeMillis}.
- */
- private final long mReportTimestamp;
-
- /** LinkProperties available on the Network at the reported timestamp */
- @NonNull private final LinkProperties mLinkProperties;
-
- /** NetworkCapabilities available on the Network at the reported timestamp */
- @NonNull private final NetworkCapabilities mNetworkCapabilities;
-
- /** PersistableBundle that may contain additional info about the report */
- @NonNull private final PersistableBundle mAdditionalInfo;
-
- /**
- * Constructor for ConnectivityReport.
- *
- * <p>Apps should obtain instances through {@link
- * ConnectivityDiagnosticsCallback#onConnectivityReportAvailable} instead of instantiating
- * their own instances (unless for testing purposes).
- *
- * @param network The Network for which this ConnectivityReport applies
- * @param reportTimestamp The timestamp for the report
- * @param linkProperties The LinkProperties available on network at reportTimestamp
- * @param networkCapabilities The NetworkCapabilities available on network at
- * reportTimestamp
- * @param additionalInfo A PersistableBundle that may contain additional info about the
- * report
- */
- public ConnectivityReport(
- @NonNull Network network,
- long reportTimestamp,
- @NonNull LinkProperties linkProperties,
- @NonNull NetworkCapabilities networkCapabilities,
- @NonNull PersistableBundle additionalInfo) {
- mNetwork = network;
- mReportTimestamp = reportTimestamp;
- mLinkProperties = new LinkProperties(linkProperties);
- mNetworkCapabilities = new NetworkCapabilities(networkCapabilities);
- mAdditionalInfo = additionalInfo;
- }
-
- /**
- * Returns the Network for this ConnectivityReport.
- *
- * @return The Network for which this ConnectivityReport applied
- */
- @NonNull
- public Network getNetwork() {
- return mNetwork;
- }
-
- /**
- * Returns the epoch timestamp (milliseconds) for when this report was taken.
- *
- * @return The timestamp for the report. Taken from {@link System#currentTimeMillis}.
- */
- public long getReportTimestamp() {
- return mReportTimestamp;
- }
-
- /**
- * Returns the LinkProperties available when this report was taken.
- *
- * @return LinkProperties available on the Network at the reported timestamp
- */
- @NonNull
- public LinkProperties getLinkProperties() {
- return new LinkProperties(mLinkProperties);
- }
-
- /**
- * Returns the NetworkCapabilities when this report was taken.
- *
- * @return NetworkCapabilities available on the Network at the reported timestamp
- */
- @NonNull
- public NetworkCapabilities getNetworkCapabilities() {
- return new NetworkCapabilities(mNetworkCapabilities);
- }
-
- /**
- * Returns a PersistableBundle with additional info for this report.
- *
- * @return PersistableBundle that may contain additional info about the report
- */
- @NonNull
- public PersistableBundle getAdditionalInfo() {
- return new PersistableBundle(mAdditionalInfo);
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) return true;
- if (!(o instanceof ConnectivityReport)) return false;
- final ConnectivityReport that = (ConnectivityReport) o;
-
- // PersistableBundle is optimized to avoid unparcelling data unless fields are
- // referenced. Because of this, use {@link ConnectivityDiagnosticsManager#equals} over
- // {@link PersistableBundle#kindofEquals}.
- return mReportTimestamp == that.mReportTimestamp
- && mNetwork.equals(that.mNetwork)
- && mLinkProperties.equals(that.mLinkProperties)
- && mNetworkCapabilities.equals(that.mNetworkCapabilities)
- && persistableBundleEquals(mAdditionalInfo, that.mAdditionalInfo);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(
- mNetwork,
- mReportTimestamp,
- mLinkProperties,
- mNetworkCapabilities,
- mAdditionalInfo);
- }
-
- /** {@inheritDoc} */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** {@inheritDoc} */
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeParcelable(mNetwork, flags);
- dest.writeLong(mReportTimestamp);
- dest.writeParcelable(mLinkProperties, flags);
- dest.writeParcelable(mNetworkCapabilities, flags);
- dest.writeParcelable(mAdditionalInfo, flags);
- }
-
- /** Implement the Parcelable interface */
- public static final @NonNull Creator<ConnectivityReport> CREATOR =
- new Creator<ConnectivityReport>() {
- public ConnectivityReport createFromParcel(Parcel in) {
- return new ConnectivityReport(
- in.readParcelable(null),
- in.readLong(),
- in.readParcelable(null),
- in.readParcelable(null),
- in.readParcelable(null));
- }
-
- public ConnectivityReport[] newArray(int size) {
- return new ConnectivityReport[size];
- }
- };
- }
-
- /** Class that includes information for a suspected data stall on a specific Network */
- public static final class DataStallReport implements Parcelable {
- /**
- * Indicates that the Data Stall was detected using DNS events.
- */
- public static final int DETECTION_METHOD_DNS_EVENTS = 1;
-
- /**
- * Indicates that the Data Stall was detected using TCP metrics.
- */
- public static final int DETECTION_METHOD_TCP_METRICS = 2;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(
- prefix = {"DETECTION_METHOD_"},
- value = {DETECTION_METHOD_DNS_EVENTS, DETECTION_METHOD_TCP_METRICS})
- public @interface DetectionMethod {}
-
- /**
- * This key represents the period in milliseconds over which other included TCP metrics
- * were measured.
- *
- * <p>This key will be included if the data stall detection method is
- * {@link #DETECTION_METHOD_TCP_METRICS}.
- *
- * <p>This value is an int.
- */
- public static final String KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS =
- "tcpMetricsCollectionPeriodMillis";
-
- /**
- * This key represents the fail rate of TCP packets when the suspected data stall was
- * detected.
- *
- * <p>This key will be included if the data stall detection method is
- * {@link #DETECTION_METHOD_TCP_METRICS}.
- *
- * <p>This value is an int percentage between 0 and 100.
- */
- public static final String KEY_TCP_PACKET_FAIL_RATE = "tcpPacketFailRate";
-
- /**
- * This key represents the consecutive number of DNS timeouts that have occurred.
- *
- * <p>The consecutive count will be reset any time a DNS response is received.
- *
- * <p>This key will be included if the data stall detection method is
- * {@link #DETECTION_METHOD_DNS_EVENTS}.
- *
- * <p>This value is an int.
- */
- public static final String KEY_DNS_CONSECUTIVE_TIMEOUTS = "dnsConsecutiveTimeouts";
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @StringDef(prefix = {"KEY_"}, value = {
- KEY_TCP_PACKET_FAIL_RATE,
- KEY_DNS_CONSECUTIVE_TIMEOUTS
- })
- public @interface DataStallReportBundleKeys {}
-
- /** The Network for which this DataStallReport applied */
- @NonNull private final Network mNetwork;
-
- /**
- * The timestamp for the report. The timestamp is taken from {@link
- * System#currentTimeMillis}.
- */
- private long mReportTimestamp;
-
- /** A bitmask of the detection methods used to identify the suspected data stall */
- @DetectionMethod private final int mDetectionMethod;
-
- /** LinkProperties available on the Network at the reported timestamp */
- @NonNull private final LinkProperties mLinkProperties;
-
- /** NetworkCapabilities available on the Network at the reported timestamp */
- @NonNull private final NetworkCapabilities mNetworkCapabilities;
-
- /** PersistableBundle that may contain additional information on the suspected data stall */
- @NonNull private final PersistableBundle mStallDetails;
-
- /**
- * Constructor for DataStallReport.
- *
- * <p>Apps should obtain instances through {@link
- * ConnectivityDiagnosticsCallback#onDataStallSuspected} instead of instantiating their own
- * instances (unless for testing purposes).
- *
- * @param network The Network for which this DataStallReport applies
- * @param reportTimestamp The timestamp for the report
- * @param detectionMethod The detection method used to identify this data stall
- * @param linkProperties The LinkProperties available on network at reportTimestamp
- * @param networkCapabilities The NetworkCapabilities available on network at
- * reportTimestamp
- * @param stallDetails A PersistableBundle that may contain additional info about the report
- */
- public DataStallReport(
- @NonNull Network network,
- long reportTimestamp,
- @DetectionMethod int detectionMethod,
- @NonNull LinkProperties linkProperties,
- @NonNull NetworkCapabilities networkCapabilities,
- @NonNull PersistableBundle stallDetails) {
- mNetwork = network;
- mReportTimestamp = reportTimestamp;
- mDetectionMethod = detectionMethod;
- mLinkProperties = new LinkProperties(linkProperties);
- mNetworkCapabilities = new NetworkCapabilities(networkCapabilities);
- mStallDetails = stallDetails;
- }
-
- /**
- * Returns the Network for this DataStallReport.
- *
- * @return The Network for which this DataStallReport applied
- */
- @NonNull
- public Network getNetwork() {
- return mNetwork;
- }
-
- /**
- * Returns the epoch timestamp (milliseconds) for when this report was taken.
- *
- * @return The timestamp for the report. Taken from {@link System#currentTimeMillis}.
- */
- public long getReportTimestamp() {
- return mReportTimestamp;
- }
-
- /**
- * Returns the bitmask of detection methods used to identify this suspected data stall.
- *
- * @return The bitmask of detection methods used to identify the suspected data stall
- */
- public int getDetectionMethod() {
- return mDetectionMethod;
- }
-
- /**
- * Returns the LinkProperties available when this report was taken.
- *
- * @return LinkProperties available on the Network at the reported timestamp
- */
- @NonNull
- public LinkProperties getLinkProperties() {
- return new LinkProperties(mLinkProperties);
- }
-
- /**
- * Returns the NetworkCapabilities when this report was taken.
- *
- * @return NetworkCapabilities available on the Network at the reported timestamp
- */
- @NonNull
- public NetworkCapabilities getNetworkCapabilities() {
- return new NetworkCapabilities(mNetworkCapabilities);
- }
-
- /**
- * Returns a PersistableBundle with additional info for this report.
- *
- * <p>Gets a bundle with details about the suspected data stall including information
- * specific to the monitoring method that detected the data stall.
- *
- * @return PersistableBundle that may contain additional information on the suspected data
- * stall
- */
- @NonNull
- public PersistableBundle getStallDetails() {
- return new PersistableBundle(mStallDetails);
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) return true;
- if (!(o instanceof DataStallReport)) return false;
- final DataStallReport that = (DataStallReport) o;
-
- // PersistableBundle is optimized to avoid unparcelling data unless fields are
- // referenced. Because of this, use {@link ConnectivityDiagnosticsManager#equals} over
- // {@link PersistableBundle#kindofEquals}.
- return mReportTimestamp == that.mReportTimestamp
- && mDetectionMethod == that.mDetectionMethod
- && mNetwork.equals(that.mNetwork)
- && mLinkProperties.equals(that.mLinkProperties)
- && mNetworkCapabilities.equals(that.mNetworkCapabilities)
- && persistableBundleEquals(mStallDetails, that.mStallDetails);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(
- mNetwork,
- mReportTimestamp,
- mDetectionMethod,
- mLinkProperties,
- mNetworkCapabilities,
- mStallDetails);
- }
-
- /** {@inheritDoc} */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** {@inheritDoc} */
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeParcelable(mNetwork, flags);
- dest.writeLong(mReportTimestamp);
- dest.writeInt(mDetectionMethod);
- dest.writeParcelable(mLinkProperties, flags);
- dest.writeParcelable(mNetworkCapabilities, flags);
- dest.writeParcelable(mStallDetails, flags);
- }
-
- /** Implement the Parcelable interface */
- public static final @NonNull Creator<DataStallReport> CREATOR =
- new Creator<DataStallReport>() {
- public DataStallReport createFromParcel(Parcel in) {
- return new DataStallReport(
- in.readParcelable(null),
- in.readLong(),
- in.readInt(),
- in.readParcelable(null),
- in.readParcelable(null),
- in.readParcelable(null));
- }
-
- public DataStallReport[] newArray(int size) {
- return new DataStallReport[size];
- }
- };
- }
-
- /** @hide */
- @VisibleForTesting
- public static class ConnectivityDiagnosticsBinder
- extends IConnectivityDiagnosticsCallback.Stub {
- @NonNull private final ConnectivityDiagnosticsCallback mCb;
- @NonNull private final Executor mExecutor;
-
- /** @hide */
- @VisibleForTesting
- public ConnectivityDiagnosticsBinder(
- @NonNull ConnectivityDiagnosticsCallback cb, @NonNull Executor executor) {
- this.mCb = cb;
- this.mExecutor = executor;
- }
-
- /** @hide */
- @VisibleForTesting
- public void onConnectivityReportAvailable(@NonNull ConnectivityReport report) {
- final long token = Binder.clearCallingIdentity();
- try {
- mExecutor.execute(() -> {
- mCb.onConnectivityReportAvailable(report);
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /** @hide */
- @VisibleForTesting
- public void onDataStallSuspected(@NonNull DataStallReport report) {
- final long token = Binder.clearCallingIdentity();
- try {
- mExecutor.execute(() -> {
- mCb.onDataStallSuspected(report);
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /** @hide */
- @VisibleForTesting
- public void onNetworkConnectivityReported(
- @NonNull Network network, boolean hasConnectivity) {
- final long token = Binder.clearCallingIdentity();
- try {
- mExecutor.execute(() -> {
- mCb.onNetworkConnectivityReported(network, hasConnectivity);
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- }
-
- /**
- * Abstract base class for Connectivity Diagnostics callbacks. Used for notifications about
- * network connectivity events. Must be extended by applications wanting notifications.
- */
- public abstract static class ConnectivityDiagnosticsCallback {
- /**
- * Called when the platform completes a data connectivity check. This will also be invoked
- * immediately upon registration for each network matching the request with the latest
- * report, if a report has already been generated for that network.
- *
- * <p>The Network specified in the ConnectivityReport may not be active any more when this
- * method is invoked.
- *
- * @param report The ConnectivityReport containing information about a connectivity check
- */
- public void onConnectivityReportAvailable(@NonNull ConnectivityReport report) {}
-
- /**
- * Called when the platform suspects a data stall on some Network.
- *
- * <p>The Network specified in the DataStallReport may not be active any more when this
- * method is invoked.
- *
- * @param report The DataStallReport containing information about the suspected data stall
- */
- public void onDataStallSuspected(@NonNull DataStallReport report) {}
-
- /**
- * Called when any app reports connectivity to the System.
- *
- * @param network The Network for which connectivity has been reported
- * @param hasConnectivity The connectivity reported to the System
- */
- public void onNetworkConnectivityReported(
- @NonNull Network network, boolean hasConnectivity) {}
- }
-
- /**
- * Registers a ConnectivityDiagnosticsCallback with the System.
- *
- * <p>Only apps that offer network connectivity to the user should be registering callbacks.
- * These are the only apps whose callbacks will be invoked by the system. Apps considered to
- * meet these conditions include:
- *
- * <ul>
- * <li>Carrier apps with active subscriptions
- * <li>Active VPNs
- * <li>WiFi Suggesters
- * </ul>
- *
- * <p>Callbacks registered by apps not meeting the above criteria will not be invoked.
- *
- * <p>If a registering app loses its relevant permissions, any callbacks it registered will
- * silently stop receiving callbacks. Note that registering apps must also have location
- * permissions to receive callbacks as some Networks may be location-bound (such as WiFi
- * networks).
- *
- * <p>Each register() call <b>MUST</b> use a ConnectivityDiagnosticsCallback instance that is
- * not currently registered. If a ConnectivityDiagnosticsCallback instance is registered with
- * multiple NetworkRequests, an IllegalArgumentException will be thrown.
- *
- * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
- * number of outstanding requests to 100 per app (identified by their UID), shared with
- * callbacks in {@link ConnectivityManager}. Registering a callback with this method will count
- * toward this limit. If this limit is exceeded, an exception will be thrown. To avoid hitting
- * this issue and to conserve resources, make sure to unregister the callbacks with
- * {@link #unregisterConnectivityDiagnosticsCallback}.
- *
- * @param request The NetworkRequest that will be used to match with Networks for which
- * callbacks will be fired
- * @param e The Executor to be used for running the callback method invocations
- * @param callback The ConnectivityDiagnosticsCallback that the caller wants registered with the
- * System
- * @throws IllegalArgumentException if the same callback instance is registered with multiple
- * NetworkRequests
- * @throws RuntimeException if the app already has too many callbacks registered.
- */
- public void registerConnectivityDiagnosticsCallback(
- @NonNull NetworkRequest request,
- @NonNull Executor e,
- @NonNull ConnectivityDiagnosticsCallback callback) {
- final ConnectivityDiagnosticsBinder binder = new ConnectivityDiagnosticsBinder(callback, e);
- if (sCallbacks.putIfAbsent(callback, binder) != null) {
- throw new IllegalArgumentException("Callback is currently registered");
- }
-
- try {
- mService.registerConnectivityDiagnosticsCallback(
- binder, request, mContext.getOpPackageName());
- } catch (RemoteException exception) {
- exception.rethrowFromSystemServer();
- }
- }
-
- /**
- * Unregisters a ConnectivityDiagnosticsCallback with the System.
- *
- * <p>If the given callback is not currently registered with the System, this operation will be
- * a no-op.
- *
- * @param callback The ConnectivityDiagnosticsCallback to be unregistered from the System.
- */
- public void unregisterConnectivityDiagnosticsCallback(
- @NonNull ConnectivityDiagnosticsCallback callback) {
- // unconditionally removing from sCallbacks prevents race conditions here, since remove() is
- // atomic.
- final ConnectivityDiagnosticsBinder binder = sCallbacks.remove(callback);
- if (binder == null) return;
-
- try {
- mService.unregisterConnectivityDiagnosticsCallback(binder);
- } catch (RemoteException exception) {
- exception.rethrowFromSystemServer();
- }
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java b/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java
deleted file mode 100644
index a2e218d..0000000
--- a/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java
+++ /dev/null
@@ -1,78 +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.annotation.SystemApi;
-import android.app.SystemServiceRegistry;
-import android.content.Context;
-
-/**
- * Class for performing registration for all core connectivity services.
- *
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public final class ConnectivityFrameworkInitializer {
- private ConnectivityFrameworkInitializer() {}
-
- /**
- * Called by {@link SystemServiceRegistry}'s static initializer and registers all core
- * connectivity services to {@link Context}, so that {@link Context#getSystemService} can
- * return them.
- *
- * @throws IllegalStateException if this is called anywhere besides
- * {@link SystemServiceRegistry}.
- */
- public static void registerServiceWrappers() {
- // registerContextAwareService will throw if this is called outside of SystemServiceRegistry
- // initialization.
- SystemServiceRegistry.registerContextAwareService(
- Context.CONNECTIVITY_SERVICE,
- ConnectivityManager.class,
- (context, serviceBinder) -> {
- IConnectivityManager icm = IConnectivityManager.Stub.asInterface(serviceBinder);
- return new ConnectivityManager(context, icm);
- }
- );
-
- SystemServiceRegistry.registerContextAwareService(
- Context.CONNECTIVITY_DIAGNOSTICS_SERVICE,
- ConnectivityDiagnosticsManager.class,
- (context) -> {
- final ConnectivityManager cm = context.getSystemService(
- ConnectivityManager.class);
- return cm.createDiagnosticsManager();
- }
- );
-
- SystemServiceRegistry.registerContextAwareService(
- Context.TEST_NETWORK_SERVICE,
- TestNetworkManager.class,
- context -> {
- final ConnectivityManager cm = context.getSystemService(
- ConnectivityManager.class);
- return cm.startOrGetTestNetworkManager();
- }
- );
-
- SystemServiceRegistry.registerContextAwareService(
- DnsResolverServiceManager.DNS_RESOLVER_SERVICE,
- DnsResolverServiceManager.class,
- (context, serviceBinder) -> new DnsResolverServiceManager(serviceBinder)
- );
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
deleted file mode 100644
index 93455bc..0000000
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ /dev/null
@@ -1,5459 +0,0 @@
-/*
- * Copyright (C) 2008 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.annotation.SystemApi.Client.MODULE_LIBRARIES;
-import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST;
-import static android.net.NetworkRequest.Type.LISTEN;
-import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
-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 android.net.QosCallback.QosCallbackRegistrationException;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.app.PendingIntent;
-import android.app.admin.DevicePolicyManager;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.net.ConnectivityAnnotations.MultipathPreference;
-import android.net.ConnectivityAnnotations.RestrictBackgroundStatus;
-import android.net.ConnectivityDiagnosticsManager.DataStallReport.DetectionMethod;
-import android.net.IpSecManager.UdpEncapsulationSocket;
-import android.net.SocketKeepalive.Callback;
-import android.net.TetheringManager.StartTetheringCallback;
-import android.net.TetheringManager.TetheringEventCallback;
-import android.net.TetheringManager.TetheringRequest;
-import android.net.wifi.WifiNetworkSuggestion;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Build.VERSION_CODES;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.ParcelFileDescriptor;
-import android.os.PersistableBundle;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.os.ServiceSpecificException;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Range;
-import android.util.SparseIntArray;
-
-import com.android.internal.annotations.GuardedBy;
-
-import libcore.net.event.NetworkEventDispatcher;
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.RejectedExecutionException;
-
-/**
- * Class that answers queries about the state of network connectivity. It also
- * notifies applications when network connectivity changes.
- * <p>
- * The primary responsibilities of this class are to:
- * <ol>
- * <li>Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)</li>
- * <li>Send broadcast intents when network connectivity changes</li>
- * <li>Attempt to "fail over" to another network when connectivity to a network
- * is lost</li>
- * <li>Provide an API that allows applications to query the coarse-grained or fine-grained
- * state of the available networks</li>
- * <li>Provide an API that allows applications to request and select networks for their data
- * traffic</li>
- * </ol>
- */
-@SystemService(Context.CONNECTIVITY_SERVICE)
-public class ConnectivityManager {
- private static final String TAG = "ConnectivityManager";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- /**
- * A change in network connectivity has occurred. A default connection has either
- * been established or lost. The NetworkInfo for the affected network is
- * sent as an extra; it should be consulted to see what kind of
- * connectivity event occurred.
- * <p/>
- * Apps targeting Android 7.0 (API level 24) and higher do not receive this
- * broadcast if they declare the broadcast receiver in their manifest. Apps
- * will still receive broadcasts if they register their
- * {@link android.content.BroadcastReceiver} with
- * {@link android.content.Context#registerReceiver Context.registerReceiver()}
- * and that context is still valid.
- * <p/>
- * If this is a connection that was the result of failing over from a
- * disconnected network, then the FAILOVER_CONNECTION boolean extra is
- * set to true.
- * <p/>
- * For a loss of connectivity, if the connectivity manager is attempting
- * to connect (or has already connected) to another network, the
- * NetworkInfo for the new network is also passed as an extra. This lets
- * any receivers of the broadcast know that they should not necessarily
- * tell the user that no data traffic will be possible. Instead, the
- * receiver should expect another broadcast soon, indicating either that
- * the failover attempt succeeded (and so there is still overall data
- * connectivity), or that the failover attempt failed, meaning that all
- * connectivity has been lost.
- * <p/>
- * For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY
- * is set to {@code true} if there are no connected networks at all.
- *
- * @deprecated apps should use the more versatile {@link #requestNetwork},
- * {@link #registerNetworkCallback} or {@link #registerDefaultNetworkCallback}
- * functions instead for faster and more detailed updates about the network
- * changes they care about.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- @Deprecated
- public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
-
- /**
- * The device has connected to a network that has presented a captive
- * portal, which is blocking Internet connectivity. The user was presented
- * with a notification that network sign in is required,
- * and the user invoked the notification's action indicating they
- * desire to sign in to the network. Apps handling this activity should
- * facilitate signing in to the network. This action includes a
- * {@link Network} typed extra called {@link #EXTRA_NETWORK} that represents
- * the network presenting the captive portal; all communication with the
- * captive portal must be done using this {@code Network} object.
- * <p/>
- * This activity includes a {@link CaptivePortal} extra named
- * {@link #EXTRA_CAPTIVE_PORTAL} that can be used to indicate different
- * outcomes of the captive portal sign in to the system:
- * <ul>
- * <li> When the app handling this action believes the user has signed in to
- * the network and the captive portal has been dismissed, the app should
- * call {@link CaptivePortal#reportCaptivePortalDismissed} so the system can
- * reevaluate the network. If reevaluation finds the network no longer
- * subject to a captive portal, the network may become the default active
- * data network.</li>
- * <li> When the app handling this action believes the user explicitly wants
- * to ignore the captive portal and the network, the app should call
- * {@link CaptivePortal#ignoreNetwork}. </li>
- * </ul>
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL";
-
- /**
- * The lookup key for a {@link NetworkInfo} object. Retrieve with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- *
- * @deprecated The {@link NetworkInfo} object is deprecated, as many of its properties
- * can't accurately represent modern network characteristics.
- * Please obtain information about networks from the {@link NetworkCapabilities}
- * or {@link LinkProperties} objects instead.
- */
- @Deprecated
- public static final String EXTRA_NETWORK_INFO = "networkInfo";
-
- /**
- * Network type which triggered a {@link #CONNECTIVITY_ACTION} broadcast.
- *
- * @see android.content.Intent#getIntExtra(String, int)
- * @deprecated The network type is not rich enough to represent the characteristics
- * of modern networks. Please use {@link NetworkCapabilities} instead,
- * in particular the transports.
- */
- @Deprecated
- public static final String EXTRA_NETWORK_TYPE = "networkType";
-
- /**
- * The lookup key for a boolean that indicates whether a connect event
- * is for a network to which the connectivity manager was failing over
- * following a disconnect on another network.
- * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
- *
- * @deprecated See {@link NetworkInfo}.
- */
- @Deprecated
- public static final String EXTRA_IS_FAILOVER = "isFailover";
- /**
- * The lookup key for a {@link NetworkInfo} object. This is supplied when
- * there is another network that it may be possible to connect to. Retrieve with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- *
- * @deprecated See {@link NetworkInfo}.
- */
- @Deprecated
- public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
- /**
- * The lookup key for a boolean that indicates whether there is a
- * complete lack of connectivity, i.e., no network is available.
- * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
- */
- public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
- /**
- * The lookup key for a string that indicates why an attempt to connect
- * to a network failed. The string has no particular structure. It is
- * intended to be used in notifications presented to users. Retrieve
- * it with {@link android.content.Intent#getStringExtra(String)}.
- */
- public static final String EXTRA_REASON = "reason";
- /**
- * The lookup key for a string that provides optionally supplied
- * extra information about the network state. The information
- * may be passed up from the lower networking layers, and its
- * meaning may be specific to a particular network type. Retrieve
- * it with {@link android.content.Intent#getStringExtra(String)}.
- *
- * @deprecated See {@link NetworkInfo#getExtraInfo()}.
- */
- @Deprecated
- public static final String EXTRA_EXTRA_INFO = "extraInfo";
- /**
- * The lookup key for an int that provides information about
- * our connection to the internet at large. 0 indicates no connection,
- * 100 indicates a great connection. Retrieve it with
- * {@link android.content.Intent#getIntExtra(String, int)}.
- * {@hide}
- */
- public static final String EXTRA_INET_CONDITION = "inetCondition";
- /**
- * The lookup key for a {@link CaptivePortal} object included with the
- * {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN} intent. The {@code CaptivePortal}
- * object can be used to either indicate to the system that the captive
- * portal has been dismissed or that the user does not want to pursue
- * signing in to captive portal. Retrieve it with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- */
- public static final String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL";
-
- /**
- * Key for passing a URL to the captive portal login activity.
- */
- public static final String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL";
-
- /**
- * Key for passing a {@link android.net.captiveportal.CaptivePortalProbeSpec} to the captive
- * portal login activity.
- * {@hide}
- */
- @SystemApi
- public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC =
- "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
-
- /**
- * Key for passing a user agent string to the captive portal login activity.
- * {@hide}
- */
- @SystemApi
- public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT =
- "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
-
- /**
- * Broadcast action to indicate the change of data activity status
- * (idle or active) on a network in a recent period.
- * The network becomes active when data transmission is started, or
- * idle if there is no data transmission for a period of time.
- * {@hide}
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_DATA_ACTIVITY_CHANGE =
- "android.net.conn.DATA_ACTIVITY_CHANGE";
- /**
- * The lookup key for an enum that indicates the network device type on which this data activity
- * change happens.
- * {@hide}
- */
- public static final String EXTRA_DEVICE_TYPE = "deviceType";
- /**
- * The lookup key for a boolean that indicates the device is active or not. {@code true} means
- * it is actively sending or receiving data and {@code false} means it is idle.
- * {@hide}
- */
- public static final String EXTRA_IS_ACTIVE = "isActive";
- /**
- * The lookup key for a long that contains the timestamp (nanos) of the radio state change.
- * {@hide}
- */
- public static final String EXTRA_REALTIME_NS = "tsNanos";
-
- /**
- * Broadcast Action: The setting for background data usage has changed
- * values. Use {@link #getBackgroundDataSetting()} to get the current value.
- * <p>
- * If an application uses the network in the background, it should listen
- * for this broadcast and stop using the background data if the value is
- * {@code false}.
- * <p>
- *
- * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability
- * of background data depends on several combined factors, and
- * this broadcast is no longer sent. Instead, when background
- * data is unavailable, {@link #getActiveNetworkInfo()} will now
- * appear disconnected. During first boot after a platform
- * upgrade, this broadcast will be sent once if
- * {@link #getBackgroundDataSetting()} was {@code false} before
- * the upgrade.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- @Deprecated
- public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED =
- "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
-
- /**
- * Broadcast Action: The network connection may not be good
- * uses {@code ConnectivityManager.EXTRA_INET_CONDITION} and
- * {@code ConnectivityManager.EXTRA_NETWORK_INFO} to specify
- * the network and it's condition.
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- @UnsupportedAppUsage
- public static final String INET_CONDITION_ACTION =
- "android.net.conn.INET_CONDITION_ACTION";
-
- /**
- * Broadcast Action: A tetherable connection has come or gone.
- * Uses {@code ConnectivityManager.EXTRA_AVAILABLE_TETHER},
- * {@code ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY},
- * {@code ConnectivityManager.EXTRA_ACTIVE_TETHER}, and
- * {@code ConnectivityManager.EXTRA_ERRORED_TETHER} to indicate
- * the current state of tethering. Each include a list of
- * interface names in that state (may be empty).
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final String ACTION_TETHER_STATE_CHANGED =
- TetheringManager.ACTION_TETHER_STATE_CHANGED;
-
- /**
- * @hide
- * gives a String[] listing all the interfaces configured for
- * tethering and currently available for tethering.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final String EXTRA_AVAILABLE_TETHER = TetheringManager.EXTRA_AVAILABLE_TETHER;
-
- /**
- * @hide
- * gives a String[] listing all the interfaces currently in local-only
- * mode (ie, has DHCPv4+IPv6-ULA support and no packet forwarding)
- */
- public static final String EXTRA_ACTIVE_LOCAL_ONLY = TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY;
-
- /**
- * @hide
- * gives a String[] listing all the interfaces currently tethered
- * (ie, has DHCPv4 support and packets potentially forwarded/NATed)
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final String EXTRA_ACTIVE_TETHER = TetheringManager.EXTRA_ACTIVE_TETHER;
-
- /**
- * @hide
- * gives a String[] listing all the interfaces we tried to tether and
- * failed. Use {@link #getLastTetherError} to find the error code
- * for any interfaces listed here.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final String EXTRA_ERRORED_TETHER = TetheringManager.EXTRA_ERRORED_TETHER;
-
- /**
- * Broadcast Action: The captive portal tracker has finished its test.
- * Sent only while running Setup Wizard, in lieu of showing a user
- * notification.
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_CAPTIVE_PORTAL_TEST_COMPLETED =
- "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED";
- /**
- * The lookup key for a boolean that indicates whether a captive portal was detected.
- * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
- * @hide
- */
- public static final String EXTRA_IS_CAPTIVE_PORTAL = "captivePortal";
-
- /**
- * Action used to display a dialog that asks the user whether to connect to a network that is
- * not validated. This intent is used to start the dialog in settings via startActivity.
- *
- * This action includes a {@link Network} typed extra which is called
- * {@link ConnectivityManager#EXTRA_NETWORK} that represents the network which is unvalidated.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final String ACTION_PROMPT_UNVALIDATED = "android.net.action.PROMPT_UNVALIDATED";
-
- /**
- * Action used to display a dialog that asks the user whether to avoid a network that is no
- * longer validated. This intent is used to start the dialog in settings via startActivity.
- *
- * This action includes a {@link Network} typed extra which is called
- * {@link ConnectivityManager#EXTRA_NETWORK} that represents the network which is no longer
- * validated.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final String ACTION_PROMPT_LOST_VALIDATION =
- "android.net.action.PROMPT_LOST_VALIDATION";
-
- /**
- * Action used to display a dialog that asks the user whether to stay connected to a network
- * that has not validated. This intent is used to start the dialog in settings via
- * startActivity.
- *
- * This action includes a {@link Network} typed extra which is called
- * {@link ConnectivityManager#EXTRA_NETWORK} that represents the network which has partial
- * connectivity.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final String ACTION_PROMPT_PARTIAL_CONNECTIVITY =
- "android.net.action.PROMPT_PARTIAL_CONNECTIVITY";
-
- /**
- * Clear DNS Cache Action: This is broadcast when networks have changed and old
- * DNS entries should be cleared.
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final String ACTION_CLEAR_DNS_CACHE = "android.net.action.CLEAR_DNS_CACHE";
-
- /**
- * Invalid tethering type.
- * @see #startTethering(int, boolean, OnStartTetheringCallback)
- * @hide
- */
- public static final int TETHERING_INVALID = TetheringManager.TETHERING_INVALID;
-
- /**
- * Wifi tethering type.
- * @see #startTethering(int, boolean, OnStartTetheringCallback)
- * @hide
- */
- @SystemApi
- public static final int TETHERING_WIFI = 0;
-
- /**
- * USB tethering type.
- * @see #startTethering(int, boolean, OnStartTetheringCallback)
- * @hide
- */
- @SystemApi
- public static final int TETHERING_USB = 1;
-
- /**
- * Bluetooth tethering type.
- * @see #startTethering(int, boolean, OnStartTetheringCallback)
- * @hide
- */
- @SystemApi
- public static final int TETHERING_BLUETOOTH = 2;
-
- /**
- * Wifi P2p tethering type.
- * Wifi P2p tethering is set through events automatically, and don't
- * need to start from #startTethering(int, boolean, OnStartTetheringCallback).
- * @hide
- */
- public static final int TETHERING_WIFI_P2P = TetheringManager.TETHERING_WIFI_P2P;
-
- /**
- * Extra used for communicating with the TetherService. Includes the type of tethering to
- * enable if any.
- * @hide
- */
- public static final String EXTRA_ADD_TETHER_TYPE = TetheringConstants.EXTRA_ADD_TETHER_TYPE;
-
- /**
- * Extra used for communicating with the TetherService. Includes the type of tethering for
- * which to cancel provisioning.
- * @hide
- */
- public static final String EXTRA_REM_TETHER_TYPE = TetheringConstants.EXTRA_REM_TETHER_TYPE;
-
- /**
- * Extra used for communicating with the TetherService. True to schedule a recheck of tether
- * provisioning.
- * @hide
- */
- public static final String EXTRA_SET_ALARM = TetheringConstants.EXTRA_SET_ALARM;
-
- /**
- * Tells the TetherService to run a provision check now.
- * @hide
- */
- public static final String EXTRA_RUN_PROVISION = TetheringConstants.EXTRA_RUN_PROVISION;
-
- /**
- * Extra used for communicating with the TetherService. Contains the {@link ResultReceiver}
- * which will receive provisioning results. Can be left empty.
- * @hide
- */
- public static final String EXTRA_PROVISION_CALLBACK =
- TetheringConstants.EXTRA_PROVISION_CALLBACK;
-
- /**
- * The absence of a connection type.
- * @hide
- */
- @SystemApi
- public static final int TYPE_NONE = -1;
-
- /**
- * A Mobile data connection. Devices may support more than one.
- *
- * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an
- * appropriate network. {@see NetworkCapabilities} for supported transports.
- */
- @Deprecated
- public static final int TYPE_MOBILE = 0;
-
- /**
- * A WIFI data connection. Devices may support more than one.
- *
- * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an
- * appropriate network. {@see NetworkCapabilities} for supported transports.
- */
- @Deprecated
- public static final int TYPE_WIFI = 1;
-
- /**
- * An MMS-specific Mobile data connection. This network type may use the
- * same network interface as {@link #TYPE_MOBILE} or it may use a different
- * one. This is used by applications needing to talk to the carrier's
- * Multimedia Messaging Service servers.
- *
- * @deprecated Applications should instead use {@link NetworkCapabilities#hasCapability} or
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that
- * provides the {@link NetworkCapabilities#NET_CAPABILITY_MMS} capability.
- */
- @Deprecated
- public static final int TYPE_MOBILE_MMS = 2;
-
- /**
- * A SUPL-specific Mobile data connection. This network type may use the
- * same network interface as {@link #TYPE_MOBILE} or it may use a different
- * one. This is used by applications needing to talk to the carrier's
- * Secure User Plane Location servers for help locating the device.
- *
- * @deprecated Applications should instead use {@link NetworkCapabilities#hasCapability} or
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that
- * provides the {@link NetworkCapabilities#NET_CAPABILITY_SUPL} capability.
- */
- @Deprecated
- public static final int TYPE_MOBILE_SUPL = 3;
-
- /**
- * A DUN-specific Mobile data connection. This network type may use the
- * same network interface as {@link #TYPE_MOBILE} or it may use a different
- * one. This is sometimes by the system when setting up an upstream connection
- * for tethering so that the carrier is aware of DUN traffic.
- *
- * @deprecated Applications should instead use {@link NetworkCapabilities#hasCapability} or
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that
- * provides the {@link NetworkCapabilities#NET_CAPABILITY_DUN} capability.
- */
- @Deprecated
- public static final int TYPE_MOBILE_DUN = 4;
-
- /**
- * A High Priority Mobile data connection. This network type uses the
- * same network interface as {@link #TYPE_MOBILE} but the routing setup
- * is different.
- *
- * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an
- * appropriate network. {@see NetworkCapabilities} for supported transports.
- */
- @Deprecated
- public static final int TYPE_MOBILE_HIPRI = 5;
-
- /**
- * A WiMAX data connection.
- *
- * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an
- * appropriate network. {@see NetworkCapabilities} for supported transports.
- */
- @Deprecated
- public static final int TYPE_WIMAX = 6;
-
- /**
- * A Bluetooth data connection.
- *
- * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an
- * appropriate network. {@see NetworkCapabilities} for supported transports.
- */
- @Deprecated
- public static final int TYPE_BLUETOOTH = 7;
-
- /**
- * Fake data connection. This should not be used on shipping devices.
- * @deprecated This is not used any more.
- */
- @Deprecated
- public static final int TYPE_DUMMY = 8;
-
- /**
- * An Ethernet data connection.
- *
- * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an
- * appropriate network. {@see NetworkCapabilities} for supported transports.
- */
- @Deprecated
- public static final int TYPE_ETHERNET = 9;
-
- /**
- * Over the air Administration.
- * @deprecated Use {@link NetworkCapabilities} instead.
- * {@hide}
- */
- @Deprecated
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
- public static final int TYPE_MOBILE_FOTA = 10;
-
- /**
- * IP Multimedia Subsystem.
- * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_IMS} instead.
- * {@hide}
- */
- @Deprecated
- @UnsupportedAppUsage
- public static final int TYPE_MOBILE_IMS = 11;
-
- /**
- * Carrier Branded Services.
- * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_CBS} instead.
- * {@hide}
- */
- @Deprecated
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
- public static final int TYPE_MOBILE_CBS = 12;
-
- /**
- * A Wi-Fi p2p connection. Only requesting processes will have access to
- * the peers connected.
- * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_WIFI_P2P} instead.
- * {@hide}
- */
- @Deprecated
- @SystemApi
- public static final int TYPE_WIFI_P2P = 13;
-
- /**
- * The network to use for initially attaching to the network
- * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_IA} instead.
- * {@hide}
- */
- @Deprecated
- @UnsupportedAppUsage
- public static final int TYPE_MOBILE_IA = 14;
-
- /**
- * Emergency PDN connection for emergency services. This
- * may include IMS and MMS in emergency situations.
- * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_EIMS} instead.
- * {@hide}
- */
- @Deprecated
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
- public static final int TYPE_MOBILE_EMERGENCY = 15;
-
- /**
- * The network that uses proxy to achieve connectivity.
- * @deprecated Use {@link NetworkCapabilities} instead.
- * {@hide}
- */
- @Deprecated
- @SystemApi
- public static final int TYPE_PROXY = 16;
-
- /**
- * A virtual network using one or more native bearers.
- * It may or may not be providing security services.
- * @deprecated Applications should use {@link NetworkCapabilities#TRANSPORT_VPN} instead.
- */
- @Deprecated
- public static final int TYPE_VPN = 17;
-
- /**
- * A network that is exclusively meant to be used for testing
- *
- * @deprecated Use {@link NetworkCapabilities} instead.
- * @hide
- */
- @Deprecated
- public static final int TYPE_TEST = 18; // TODO: Remove this once NetworkTypes are unused.
-
- /**
- * @deprecated Use {@link NetworkCapabilities} instead.
- * @hide
- */
- @Deprecated
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "TYPE_" }, value = {
- TYPE_NONE,
- TYPE_MOBILE,
- TYPE_WIFI,
- TYPE_MOBILE_MMS,
- TYPE_MOBILE_SUPL,
- TYPE_MOBILE_DUN,
- TYPE_MOBILE_HIPRI,
- TYPE_WIMAX,
- TYPE_BLUETOOTH,
- TYPE_DUMMY,
- TYPE_ETHERNET,
- TYPE_MOBILE_FOTA,
- TYPE_MOBILE_IMS,
- TYPE_MOBILE_CBS,
- TYPE_WIFI_P2P,
- TYPE_MOBILE_IA,
- TYPE_MOBILE_EMERGENCY,
- TYPE_PROXY,
- TYPE_VPN,
- TYPE_TEST
- })
- public @interface LegacyNetworkType {}
-
- // Deprecated constants for return values of startUsingNetworkFeature. They used to live
- // in com.android.internal.telephony.PhoneConstants until they were made inaccessible.
- private static final int DEPRECATED_PHONE_CONSTANT_APN_ALREADY_ACTIVE = 0;
- private static final int DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED = 1;
- private static final int DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED = 3;
-
- /** {@hide} */
- public static final int MAX_RADIO_TYPE = TYPE_TEST;
-
- /** {@hide} */
- public static final int MAX_NETWORK_TYPE = TYPE_TEST;
-
- private static final int MIN_NETWORK_TYPE = TYPE_MOBILE;
-
- /**
- * If you want to set the default network preference,you can directly
- * change the networkAttributes array in framework's config.xml.
- *
- * @deprecated Since we support so many more networks now, the single
- * network default network preference can't really express
- * the hierarchy. Instead, the default is defined by the
- * networkAttributes in config.xml. You can determine
- * the current value by calling {@link #getNetworkPreference()}
- * from an App.
- */
- @Deprecated
- public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
-
- /**
- * @hide
- */
- public static final int REQUEST_ID_UNSET = 0;
-
- /**
- * Static unique request used as a tombstone for NetworkCallbacks that have been unregistered.
- * This allows to distinguish when unregistering NetworkCallbacks those that were never
- * registered from those that were already unregistered.
- * @hide
- */
- private static final NetworkRequest ALREADY_UNREGISTERED =
- new NetworkRequest.Builder().clearCapabilities().build();
-
- /**
- * A NetID indicating no Network is selected.
- * Keep in sync with bionic/libc/dns/include/resolv_netid.h
- * @hide
- */
- public static final int NETID_UNSET = 0;
-
- /**
- * Flag to indicate that an app is not subject to any restrictions that could result in its
- * network access blocked.
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final int BLOCKED_REASON_NONE = 0;
-
- /**
- * Flag to indicate that an app is subject to Battery saver restrictions that would
- * result in its network access being blocked.
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final int BLOCKED_REASON_BATTERY_SAVER = 1 << 0;
-
- /**
- * Flag to indicate that an app is subject to Doze restrictions that would
- * result in its network access being blocked.
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final int BLOCKED_REASON_DOZE = 1 << 1;
-
- /**
- * Flag to indicate that an app is subject to App Standby restrictions that would
- * result in its network access being blocked.
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final int BLOCKED_REASON_APP_STANDBY = 1 << 2;
-
- /**
- * Flag to indicate that an app is subject to Restricted mode restrictions that would
- * result in its network access being blocked.
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final int BLOCKED_REASON_RESTRICTED_MODE = 1 << 3;
-
- /**
- * Flag to indicate that an app is blocked because it is subject to an always-on VPN but the VPN
- * is not currently connected.
- *
- * @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean)
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final int BLOCKED_REASON_LOCKDOWN_VPN = 1 << 4;
-
- /**
- * Flag to indicate that an app is subject to Data saver restrictions that would
- * result in its metered network access being blocked.
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final int BLOCKED_METERED_REASON_DATA_SAVER = 1 << 16;
-
- /**
- * Flag to indicate that an app is subject to user restrictions that would
- * result in its metered network access being blocked.
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 1 << 17;
-
- /**
- * Flag to indicate that an app is subject to Device admin restrictions that would
- * result in its metered network access being blocked.
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 1 << 18;
-
- /**
- * @hide
- */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, prefix = {"BLOCKED_"}, value = {
- BLOCKED_REASON_NONE,
- BLOCKED_REASON_BATTERY_SAVER,
- BLOCKED_REASON_DOZE,
- BLOCKED_REASON_APP_STANDBY,
- BLOCKED_REASON_RESTRICTED_MODE,
- BLOCKED_REASON_LOCKDOWN_VPN,
- BLOCKED_METERED_REASON_DATA_SAVER,
- BLOCKED_METERED_REASON_USER_RESTRICTED,
- BLOCKED_METERED_REASON_ADMIN_DISABLED,
- })
- public @interface BlockedReason {}
-
- /**
- * Set of blocked reasons that are only applicable on metered networks.
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final int BLOCKED_METERED_REASON_MASK = 0xffff0000;
-
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
- private final IConnectivityManager mService;
-
- /**
- * A kludge to facilitate static access where a Context pointer isn't available, like in the
- * case of the static set/getProcessDefaultNetwork methods and from the Network class.
- * TODO: Remove this after deprecating the static methods in favor of non-static methods or
- * methods that take a Context argument.
- */
- private static ConnectivityManager sInstance;
-
- private final Context mContext;
-
- private final TetheringManager mTetheringManager;
-
- /**
- * Tests if a given integer represents a valid network type.
- * @param networkType the type to be tested
- * @return a boolean. {@code true} if the type is valid, else {@code false}
- * @deprecated All APIs accepting a network type are deprecated. There should be no need to
- * validate a network type.
- */
- @Deprecated
- public static boolean isNetworkTypeValid(int networkType) {
- return MIN_NETWORK_TYPE <= networkType && networkType <= MAX_NETWORK_TYPE;
- }
-
- /**
- * Returns a non-localized string representing a given network type.
- * ONLY used for debugging output.
- * @param type the type needing naming
- * @return a String for the given type, or a string version of the type ("87")
- * if no name is known.
- * @deprecated Types are deprecated. Use {@link NetworkCapabilities} instead.
- * {@hide}
- */
- @Deprecated
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static String getNetworkTypeName(int type) {
- switch (type) {
- case TYPE_NONE:
- return "NONE";
- case TYPE_MOBILE:
- return "MOBILE";
- case TYPE_WIFI:
- return "WIFI";
- case TYPE_MOBILE_MMS:
- return "MOBILE_MMS";
- case TYPE_MOBILE_SUPL:
- return "MOBILE_SUPL";
- case TYPE_MOBILE_DUN:
- return "MOBILE_DUN";
- case TYPE_MOBILE_HIPRI:
- return "MOBILE_HIPRI";
- case TYPE_WIMAX:
- return "WIMAX";
- case TYPE_BLUETOOTH:
- return "BLUETOOTH";
- case TYPE_DUMMY:
- return "DUMMY";
- case TYPE_ETHERNET:
- return "ETHERNET";
- case TYPE_MOBILE_FOTA:
- return "MOBILE_FOTA";
- case TYPE_MOBILE_IMS:
- return "MOBILE_IMS";
- case TYPE_MOBILE_CBS:
- return "MOBILE_CBS";
- case TYPE_WIFI_P2P:
- return "WIFI_P2P";
- case TYPE_MOBILE_IA:
- return "MOBILE_IA";
- case TYPE_MOBILE_EMERGENCY:
- return "MOBILE_EMERGENCY";
- case TYPE_PROXY:
- return "PROXY";
- case TYPE_VPN:
- return "VPN";
- default:
- return Integer.toString(type);
- }
- }
-
- /**
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public void systemReady() {
- try {
- mService.systemReady();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Checks if a given type uses the cellular data connection.
- * This should be replaced in the future by a network property.
- * @param networkType the type to check
- * @return a boolean - {@code true} if uses cellular network, else {@code false}
- * @deprecated Types are deprecated. Use {@link NetworkCapabilities} instead.
- * {@hide}
- */
- @Deprecated
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
- public static boolean isNetworkTypeMobile(int networkType) {
- switch (networkType) {
- case TYPE_MOBILE:
- case TYPE_MOBILE_MMS:
- case TYPE_MOBILE_SUPL:
- case TYPE_MOBILE_DUN:
- case TYPE_MOBILE_HIPRI:
- case TYPE_MOBILE_FOTA:
- case TYPE_MOBILE_IMS:
- case TYPE_MOBILE_CBS:
- case TYPE_MOBILE_IA:
- case TYPE_MOBILE_EMERGENCY:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Checks if the given network type is backed by a Wi-Fi radio.
- *
- * @deprecated Types are deprecated. Use {@link NetworkCapabilities} instead.
- * @hide
- */
- @Deprecated
- public static boolean isNetworkTypeWifi(int networkType) {
- switch (networkType) {
- case TYPE_WIFI:
- case TYPE_WIFI_P2P:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Preference for {@link #setNetworkPreferenceForUser(UserHandle, int, Executor, Runnable)}.
- * Specify that the traffic for this user should by follow the default rules.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final int PROFILE_NETWORK_PREFERENCE_DEFAULT = 0;
-
- /**
- * Preference for {@link #setNetworkPreferenceForUser(UserHandle, int, Executor, Runnable)}.
- * Specify that the traffic for this user should by default go on a network with
- * {@link NetworkCapabilities#NET_CAPABILITY_ENTERPRISE}, and on the system default network
- * if no such network is available.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE = 1;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- PROFILE_NETWORK_PREFERENCE_DEFAULT,
- PROFILE_NETWORK_PREFERENCE_ENTERPRISE
- })
- public @interface ProfileNetworkPreference {
- }
-
- /**
- * Specifies the preferred network type. When the device has more
- * than one type available the preferred network type will be used.
- *
- * @param preference the network type to prefer over all others. It is
- * unspecified what happens to the old preferred network in the
- * overall ordering.
- * @deprecated Functionality has been removed as it no longer makes sense,
- * with many more than two networks - we'd need an array to express
- * preference. Instead we use dynamic network properties of
- * the networks to describe their precedence.
- */
- @Deprecated
- public void setNetworkPreference(int preference) {
- }
-
- /**
- * Retrieves the current preferred network type.
- *
- * @return an integer representing the preferred network type
- *
- * @deprecated Functionality has been removed as it no longer makes sense,
- * with many more than two networks - we'd need an array to express
- * preference. Instead we use dynamic network properties of
- * the networks to describe their precedence.
- */
- @Deprecated
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- public int getNetworkPreference() {
- return TYPE_NONE;
- }
-
- /**
- * Returns details about the currently active default data network. When
- * connected, this network is the default route for outgoing connections.
- * You should always check {@link NetworkInfo#isConnected()} before initiating
- * network traffic. This may return {@code null} when there is no default
- * network.
- * Note that if the default network is a VPN, this method will return the
- * NetworkInfo for one of its underlying networks instead, or null if the
- * VPN agent did not specify any. Apps interested in learning about VPNs
- * should use {@link #getNetworkInfo(android.net.Network)} instead.
- *
- * @return a {@link NetworkInfo} object for the current default network
- * or {@code null} if no default network is currently active
- * @deprecated See {@link NetworkInfo}.
- */
- @Deprecated
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @Nullable
- public NetworkInfo getActiveNetworkInfo() {
- try {
- return mService.getActiveNetworkInfo();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns a {@link Network} object corresponding to the currently active
- * default data network. In the event that the current active default data
- * network disconnects, the returned {@code Network} object will no longer
- * be usable. This will return {@code null} when there is no default
- * network.
- *
- * @return a {@link Network} object for the current default network or
- * {@code null} if no default network is currently active
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @Nullable
- public Network getActiveNetwork() {
- try {
- return mService.getActiveNetwork();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns a {@link Network} object corresponding to the currently active
- * default data network for a specific UID. In the event that the default data
- * network disconnects, the returned {@code Network} object will no longer
- * be usable. This will return {@code null} when there is no default
- * network for the UID.
- *
- * @return a {@link Network} object for the current default network for the
- * given UID or {@code null} if no default network is currently active
- *
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
- @Nullable
- public Network getActiveNetworkForUid(int uid) {
- return getActiveNetworkForUid(uid, false);
- }
-
- /** {@hide} */
- public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
- try {
- return mService.getActiveNetworkForUid(uid, ignoreBlocked);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Adds or removes a requirement for given UID ranges to use the VPN.
- *
- * If set to {@code true}, informs the system that the UIDs in the specified ranges must not
- * have any connectivity except if a VPN is connected and applies to the UIDs, or if the UIDs
- * otherwise have permission to bypass the VPN (e.g., because they have the
- * {@link android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS} permission, or when
- * using a socket protected by a method such as {@link VpnService#protect(DatagramSocket)}. If
- * set to {@code false}, a previously-added restriction is removed.
- * <p>
- * Each of the UID ranges specified by this method is added and removed as is, and no processing
- * is performed on the ranges to de-duplicate, merge, split, or intersect them. In order to
- * remove a previously-added range, the exact range must be removed as is.
- * <p>
- * The changes are applied asynchronously and may not have been applied by the time the method
- * returns. Apps will be notified about any changes that apply to them via
- * {@link NetworkCallback#onBlockedStatusChanged} callbacks called after the changes take
- * effect.
- * <p>
- * This method should be called only by the VPN code.
- *
- * @param ranges the UID ranges to restrict
- * @param requireVpn whether the specified UID ranges must use a VPN
- *
- * @hide
- */
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK,
- android.Manifest.permission.NETWORK_SETTINGS})
- @SystemApi(client = MODULE_LIBRARIES)
- public void setRequireVpnForUids(boolean requireVpn,
- @NonNull Collection<Range<Integer>> ranges) {
- Objects.requireNonNull(ranges);
- // The Range class is not parcelable. Convert to UidRange, which is what is used internally.
- // This method is not necessarily expected to be used outside the system server, so
- // parceling may not be necessary, but it could be used out-of-process, e.g., by the network
- // stack process, or by tests.
- UidRange[] rangesArray = new UidRange[ranges.size()];
- int index = 0;
- for (Range<Integer> range : ranges) {
- rangesArray[index++] = new UidRange(range.getLower(), range.getUpper());
- }
- try {
- mService.setRequireVpnForUids(requireVpn, rangesArray);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Informs ConnectivityService of whether the legacy lockdown VPN, as implemented by
- * LockdownVpnTracker, is in use. This is deprecated for new devices starting from Android 12
- * but is still supported for backwards compatibility.
- * <p>
- * This type of VPN is assumed always to use the system default network, and must always declare
- * exactly one underlying network, which is the network that was the default when the VPN
- * connected.
- * <p>
- * Calling this method with {@code true} enables legacy behaviour, specifically:
- * <ul>
- * <li>Any VPN that applies to userId 0 behaves specially with respect to deprecated
- * {@link #CONNECTIVITY_ACTION} broadcasts. Any such broadcasts will have the state in the
- * {@link #EXTRA_NETWORK_INFO} replaced by state of the VPN network. Also, any time the VPN
- * connects, a {@link #CONNECTIVITY_ACTION} broadcast will be sent for the network
- * underlying the VPN.</li>
- * <li>Deprecated APIs that return {@link NetworkInfo} objects will have their state
- * similarly replaced by the VPN network state.</li>
- * <li>Information on current network interfaces passed to NetworkStatsService will not
- * include any VPN interfaces.</li>
- * </ul>
- *
- * @param enabled whether legacy lockdown VPN is enabled or disabled
- *
- * @hide
- */
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK,
- android.Manifest.permission.NETWORK_SETTINGS})
- @SystemApi(client = MODULE_LIBRARIES)
- public void setLegacyLockdownVpnEnabled(boolean enabled) {
- try {
- mService.setLegacyLockdownVpnEnabled(enabled);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns details about the currently active default data network
- * for a given uid. This is for internal use only to avoid spying
- * other apps.
- *
- * @return a {@link NetworkInfo} object for the current default network
- * for the given uid or {@code null} if no default network is
- * available for the specified uid.
- *
- * {@hide}
- */
- @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public NetworkInfo getActiveNetworkInfoForUid(int uid) {
- return getActiveNetworkInfoForUid(uid, false);
- }
-
- /** {@hide} */
- public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
- try {
- return mService.getActiveNetworkInfoForUid(uid, ignoreBlocked);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns connection status information about a particular
- * network type.
- *
- * @param networkType integer specifying which networkType in
- * which you're interested.
- * @return a {@link NetworkInfo} object for the requested
- * network type or {@code null} if the type is not
- * supported by the device. If {@code networkType} is
- * TYPE_VPN and a VPN is active for the calling app,
- * then this method will try to return one of the
- * underlying networks for the VPN or null if the
- * VPN agent didn't specify any.
- *
- * @deprecated This method does not support multiple connected networks
- * of the same type. Use {@link #getAllNetworks} and
- * {@link #getNetworkInfo(android.net.Network)} instead.
- */
- @Deprecated
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @Nullable
- public NetworkInfo getNetworkInfo(int networkType) {
- try {
- return mService.getNetworkInfo(networkType);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns connection status information about a particular
- * Network.
- *
- * @param network {@link Network} specifying which network
- * in which you're interested.
- * @return a {@link NetworkInfo} object for the requested
- * network or {@code null} if the {@code Network}
- * is not valid.
- * @deprecated See {@link NetworkInfo}.
- */
- @Deprecated
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @Nullable
- public NetworkInfo getNetworkInfo(@Nullable Network network) {
- return getNetworkInfoForUid(network, Process.myUid(), false);
- }
-
- /** {@hide} */
- public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
- try {
- return mService.getNetworkInfoForUid(network, uid, ignoreBlocked);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns connection status information about all network
- * types supported by the device.
- *
- * @return an array of {@link NetworkInfo} objects. Check each
- * {@link NetworkInfo#getType} for which type each applies.
- *
- * @deprecated This method does not support multiple connected networks
- * of the same type. Use {@link #getAllNetworks} and
- * {@link #getNetworkInfo(android.net.Network)} instead.
- */
- @Deprecated
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @NonNull
- public NetworkInfo[] getAllNetworkInfo() {
- try {
- return mService.getAllNetworkInfo();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return a list of {@link NetworkStateSnapshot}s, one for each network that is currently
- * connected.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK,
- android.Manifest.permission.NETWORK_SETTINGS})
- @NonNull
- public List<NetworkStateSnapshot> getAllNetworkStateSnapshots() {
- try {
- return mService.getAllNetworkStateSnapshots();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns the {@link Network} object currently serving a given type, or
- * null if the given type is not connected.
- *
- * @hide
- * @deprecated This method does not support multiple connected networks
- * of the same type. Use {@link #getAllNetworks} and
- * {@link #getNetworkInfo(android.net.Network)} instead.
- */
- @Deprecated
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage
- public Network getNetworkForType(int networkType) {
- try {
- return mService.getNetworkForType(networkType);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns an array of all {@link Network} currently tracked by the
- * framework.
- *
- * @deprecated This method does not provide any notification of network state changes, forcing
- * apps to call it repeatedly. This is inefficient and prone to race conditions.
- * Apps should use methods such as
- * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} instead.
- * Apps that desire to obtain information about networks that do not apply to them
- * can use {@link NetworkRequest.Builder#setIncludeOtherUidNetworks}.
- *
- * @return an array of {@link Network} objects.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @NonNull
- @Deprecated
- public Network[] getAllNetworks() {
- try {
- return mService.getAllNetworks();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns an array of {@link NetworkCapabilities} objects, representing
- * the Networks that applications run by the given user will use by default.
- * @hide
- */
- @UnsupportedAppUsage
- public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
- try {
- return mService.getDefaultNetworkCapabilitiesForUser(
- userId, mContext.getOpPackageName(), getAttributionTag());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns the IP information for the current default network.
- *
- * @return a {@link LinkProperties} object describing the IP info
- * for the current default network, or {@code null} if there
- * is no current default network.
- *
- * {@hide}
- * @deprecated please use {@link #getLinkProperties(Network)} on the return
- * value of {@link #getActiveNetwork()} instead. In particular,
- * this method will return non-null LinkProperties even if the
- * app is blocked by policy from using this network.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 109783091)
- public LinkProperties getActiveLinkProperties() {
- try {
- return mService.getActiveLinkProperties();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns the IP information for a given network type.
- *
- * @param networkType the network type of interest.
- * @return a {@link LinkProperties} object describing the IP info
- * for the given networkType, or {@code null} if there is
- * no current default network.
- *
- * {@hide}
- * @deprecated This method does not support multiple connected networks
- * of the same type. Use {@link #getAllNetworks},
- * {@link #getNetworkInfo(android.net.Network)}, and
- * {@link #getLinkProperties(android.net.Network)} instead.
- */
- @Deprecated
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
- public LinkProperties getLinkProperties(int networkType) {
- try {
- return mService.getLinkPropertiesForType(networkType);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Get the {@link LinkProperties} for the given {@link Network}. This
- * will return {@code null} if the network is unknown.
- *
- * @param network The {@link Network} object identifying the network in question.
- * @return The {@link LinkProperties} for the network, or {@code null}.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @Nullable
- public LinkProperties getLinkProperties(@Nullable Network network) {
- try {
- return mService.getLinkProperties(network);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Get the {@link NetworkCapabilities} for the given {@link Network}. This
- * will return {@code null} if the network is unknown or if the |network| argument is null.
- *
- * This will remove any location sensitive data in {@link TransportInfo} embedded in
- * {@link NetworkCapabilities#getTransportInfo()}. Some transport info instances like
- * {@link android.net.wifi.WifiInfo} contain location sensitive information. Retrieving
- * this location sensitive information (subject to app's location permissions) will be
- * noted by system. To include any location sensitive data in {@link TransportInfo},
- * use a {@link NetworkCallback} with
- * {@link NetworkCallback#FLAG_INCLUDE_LOCATION_INFO} flag.
- *
- * @param network The {@link Network} object identifying the network in question.
- * @return The {@link NetworkCapabilities} for the network, or {@code null}.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @Nullable
- public NetworkCapabilities getNetworkCapabilities(@Nullable Network network) {
- try {
- return mService.getNetworkCapabilities(
- network, mContext.getOpPackageName(), getAttributionTag());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Gets a URL that can be used for resolving whether a captive portal is present.
- * 1. This URL should respond with a 204 response to a GET request to indicate no captive
- * portal is present.
- * 2. This URL must be HTTP as redirect responses are used to find captive portal
- * sign-in pages. Captive portals cannot respond to HTTPS requests with redirects.
- *
- * The system network validation may be using different strategies to detect captive portals,
- * so this method does not necessarily return a URL used by the system. It only returns a URL
- * that may be relevant for other components trying to detect captive portals.
- *
- * @hide
- * @deprecated This API returns URL which is not guaranteed to be one of the URLs used by the
- * system.
- */
- @Deprecated
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public String getCaptivePortalServerUrl() {
- try {
- return mService.getCaptivePortalServerUrl();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Tells the underlying networking system that the caller wants to
- * begin using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- *
- * <p>This method requires the caller to hold either the
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
- * or the ability to modify system settings as determined by
- * {@link android.provider.Settings.System#canWrite}.</p>
- *
- * @param networkType specifies which network the request pertains to
- * @param feature the name of the feature to be used
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- *
- * @deprecated Deprecated in favor of the cleaner
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)} API.
- * In {@link VERSION_CODES#M}, and above, this method is unsupported and will
- * throw {@code UnsupportedOperationException} if called.
- * @removed
- */
- @Deprecated
- public int startUsingNetworkFeature(int networkType, String feature) {
- checkLegacyRoutingApiAccess();
- NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
- if (netCap == null) {
- Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " +
- feature);
- return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED;
- }
-
- NetworkRequest request = null;
- synchronized (sLegacyRequests) {
- LegacyRequest l = sLegacyRequests.get(netCap);
- if (l != null) {
- Log.d(TAG, "renewing startUsingNetworkFeature request " + l.networkRequest);
- renewRequestLocked(l);
- if (l.currentNetwork != null) {
- return DEPRECATED_PHONE_CONSTANT_APN_ALREADY_ACTIVE;
- } else {
- return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED;
- }
- }
-
- request = requestNetworkForFeatureLocked(netCap);
- }
- if (request != null) {
- Log.d(TAG, "starting startUsingNetworkFeature for request " + request);
- return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED;
- } else {
- Log.d(TAG, " request Failed");
- return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED;
- }
- }
-
- /**
- * Tells the underlying networking system that the caller is finished
- * using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- *
- * <p>This method requires the caller to hold either the
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
- * or the ability to modify system settings as determined by
- * {@link android.provider.Settings.System#canWrite}.</p>
- *
- * @param networkType specifies which network the request pertains to
- * @param feature the name of the feature that is no longer needed
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- *
- * @deprecated Deprecated in favor of the cleaner
- * {@link #unregisterNetworkCallback(NetworkCallback)} API.
- * In {@link VERSION_CODES#M}, and above, this method is unsupported and will
- * throw {@code UnsupportedOperationException} if called.
- * @removed
- */
- @Deprecated
- public int stopUsingNetworkFeature(int networkType, String feature) {
- checkLegacyRoutingApiAccess();
- NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
- if (netCap == null) {
- Log.d(TAG, "Can't satisfy stopUsingNetworkFeature for " + networkType + ", " +
- feature);
- return -1;
- }
-
- if (removeRequestForFeature(netCap)) {
- Log.d(TAG, "stopUsingNetworkFeature for " + networkType + ", " + feature);
- }
- return 1;
- }
-
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
- if (networkType == TYPE_MOBILE) {
- switch (feature) {
- case "enableCBS":
- return networkCapabilitiesForType(TYPE_MOBILE_CBS);
- case "enableDUN":
- case "enableDUNAlways":
- return networkCapabilitiesForType(TYPE_MOBILE_DUN);
- case "enableFOTA":
- return networkCapabilitiesForType(TYPE_MOBILE_FOTA);
- case "enableHIPRI":
- return networkCapabilitiesForType(TYPE_MOBILE_HIPRI);
- case "enableIMS":
- return networkCapabilitiesForType(TYPE_MOBILE_IMS);
- case "enableMMS":
- return networkCapabilitiesForType(TYPE_MOBILE_MMS);
- case "enableSUPL":
- return networkCapabilitiesForType(TYPE_MOBILE_SUPL);
- default:
- return null;
- }
- } else if (networkType == TYPE_WIFI && "p2p".equals(feature)) {
- return networkCapabilitiesForType(TYPE_WIFI_P2P);
- }
- return null;
- }
-
- private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
- if (netCap == null) return TYPE_NONE;
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
- return TYPE_MOBILE_CBS;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
- return TYPE_MOBILE_IMS;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
- return TYPE_MOBILE_FOTA;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
- return TYPE_MOBILE_DUN;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
- return TYPE_MOBILE_SUPL;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
- return TYPE_MOBILE_MMS;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
- return TYPE_MOBILE_HIPRI;
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) {
- return TYPE_WIFI_P2P;
- }
- return TYPE_NONE;
- }
-
- private static class LegacyRequest {
- NetworkCapabilities networkCapabilities;
- NetworkRequest networkRequest;
- int expireSequenceNumber;
- Network currentNetwork;
- int delay = -1;
-
- private void clearDnsBinding() {
- if (currentNetwork != null) {
- currentNetwork = null;
- setProcessDefaultNetworkForHostResolution(null);
- }
- }
-
- NetworkCallback networkCallback = new NetworkCallback() {
- @Override
- public void onAvailable(Network network) {
- currentNetwork = network;
- Log.d(TAG, "startUsingNetworkFeature got Network:" + network);
- setProcessDefaultNetworkForHostResolution(network);
- }
- @Override
- public void onLost(Network network) {
- if (network.equals(currentNetwork)) clearDnsBinding();
- Log.d(TAG, "startUsingNetworkFeature lost Network:" + network);
- }
- };
- }
-
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private static final HashMap<NetworkCapabilities, LegacyRequest> sLegacyRequests =
- new HashMap<>();
-
- private NetworkRequest findRequestForFeature(NetworkCapabilities netCap) {
- synchronized (sLegacyRequests) {
- LegacyRequest l = sLegacyRequests.get(netCap);
- if (l != null) return l.networkRequest;
- }
- return null;
- }
-
- private void renewRequestLocked(LegacyRequest l) {
- l.expireSequenceNumber++;
- Log.d(TAG, "renewing request to seqNum " + l.expireSequenceNumber);
- sendExpireMsgForFeature(l.networkCapabilities, l.expireSequenceNumber, l.delay);
- }
-
- private void expireRequest(NetworkCapabilities netCap, int sequenceNum) {
- int ourSeqNum = -1;
- synchronized (sLegacyRequests) {
- LegacyRequest l = sLegacyRequests.get(netCap);
- if (l == null) return;
- ourSeqNum = l.expireSequenceNumber;
- if (l.expireSequenceNumber == sequenceNum) removeRequestForFeature(netCap);
- }
- Log.d(TAG, "expireRequest with " + ourSeqNum + ", " + sequenceNum);
- }
-
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) {
- int delay = -1;
- int type = legacyTypeForNetworkCapabilities(netCap);
- try {
- delay = mService.getRestoreDefaultNetworkDelay(type);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- LegacyRequest l = new LegacyRequest();
- l.networkCapabilities = netCap;
- l.delay = delay;
- l.expireSequenceNumber = 0;
- l.networkRequest = sendRequestForNetwork(
- netCap, l.networkCallback, 0, REQUEST, type, getDefaultHandler());
- if (l.networkRequest == null) return null;
- sLegacyRequests.put(netCap, l);
- sendExpireMsgForFeature(netCap, l.expireSequenceNumber, delay);
- return l.networkRequest;
- }
-
- private void sendExpireMsgForFeature(NetworkCapabilities netCap, int seqNum, int delay) {
- if (delay >= 0) {
- Log.d(TAG, "sending expire msg with seqNum " + seqNum + " and delay " + delay);
- CallbackHandler handler = getDefaultHandler();
- Message msg = handler.obtainMessage(EXPIRE_LEGACY_REQUEST, seqNum, 0, netCap);
- handler.sendMessageDelayed(msg, delay);
- }
- }
-
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private boolean removeRequestForFeature(NetworkCapabilities netCap) {
- final LegacyRequest l;
- synchronized (sLegacyRequests) {
- l = sLegacyRequests.remove(netCap);
- }
- if (l == null) return false;
- unregisterNetworkCallback(l.networkCallback);
- l.clearDnsBinding();
- return true;
- }
-
- private static final SparseIntArray sLegacyTypeToTransport = new SparseIntArray();
- static {
- sLegacyTypeToTransport.put(TYPE_MOBILE, NetworkCapabilities.TRANSPORT_CELLULAR);
- sLegacyTypeToTransport.put(TYPE_MOBILE_CBS, NetworkCapabilities.TRANSPORT_CELLULAR);
- sLegacyTypeToTransport.put(TYPE_MOBILE_DUN, NetworkCapabilities.TRANSPORT_CELLULAR);
- sLegacyTypeToTransport.put(TYPE_MOBILE_FOTA, NetworkCapabilities.TRANSPORT_CELLULAR);
- sLegacyTypeToTransport.put(TYPE_MOBILE_HIPRI, NetworkCapabilities.TRANSPORT_CELLULAR);
- sLegacyTypeToTransport.put(TYPE_MOBILE_IMS, NetworkCapabilities.TRANSPORT_CELLULAR);
- sLegacyTypeToTransport.put(TYPE_MOBILE_MMS, NetworkCapabilities.TRANSPORT_CELLULAR);
- sLegacyTypeToTransport.put(TYPE_MOBILE_SUPL, NetworkCapabilities.TRANSPORT_CELLULAR);
- sLegacyTypeToTransport.put(TYPE_WIFI, NetworkCapabilities.TRANSPORT_WIFI);
- sLegacyTypeToTransport.put(TYPE_WIFI_P2P, NetworkCapabilities.TRANSPORT_WIFI);
- sLegacyTypeToTransport.put(TYPE_BLUETOOTH, NetworkCapabilities.TRANSPORT_BLUETOOTH);
- sLegacyTypeToTransport.put(TYPE_ETHERNET, NetworkCapabilities.TRANSPORT_ETHERNET);
- }
-
- private static final SparseIntArray sLegacyTypeToCapability = new SparseIntArray();
- static {
- sLegacyTypeToCapability.put(TYPE_MOBILE_CBS, NetworkCapabilities.NET_CAPABILITY_CBS);
- sLegacyTypeToCapability.put(TYPE_MOBILE_DUN, NetworkCapabilities.NET_CAPABILITY_DUN);
- sLegacyTypeToCapability.put(TYPE_MOBILE_FOTA, NetworkCapabilities.NET_CAPABILITY_FOTA);
- sLegacyTypeToCapability.put(TYPE_MOBILE_IMS, NetworkCapabilities.NET_CAPABILITY_IMS);
- sLegacyTypeToCapability.put(TYPE_MOBILE_MMS, NetworkCapabilities.NET_CAPABILITY_MMS);
- sLegacyTypeToCapability.put(TYPE_MOBILE_SUPL, NetworkCapabilities.NET_CAPABILITY_SUPL);
- sLegacyTypeToCapability.put(TYPE_WIFI_P2P, NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
- }
-
- /**
- * Given a legacy type (TYPE_WIFI, ...) returns a NetworkCapabilities
- * instance suitable for registering a request or callback. Throws an
- * IllegalArgumentException if no mapping from the legacy type to
- * NetworkCapabilities is known.
- *
- * @deprecated Types are deprecated. Use {@link NetworkCallback} or {@link NetworkRequest}
- * to find the network instead.
- * @hide
- */
- public static NetworkCapabilities networkCapabilitiesForType(int type) {
- final NetworkCapabilities nc = new NetworkCapabilities();
-
- // Map from type to transports.
- final int NOT_FOUND = -1;
- final int transport = sLegacyTypeToTransport.get(type, NOT_FOUND);
- if (transport == NOT_FOUND) {
- throw new IllegalArgumentException("unknown legacy type: " + type);
- }
- nc.addTransportType(transport);
-
- // Map from type to capabilities.
- nc.addCapability(sLegacyTypeToCapability.get(
- type, NetworkCapabilities.NET_CAPABILITY_INTERNET));
- nc.maybeMarkCapabilitiesRestricted();
- return nc;
- }
-
- /** @hide */
- public static class PacketKeepaliveCallback {
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public PacketKeepaliveCallback() {
- }
- /** The requested keepalive was successfully started. */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public void onStarted() {}
- /** The keepalive was successfully stopped. */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public void onStopped() {}
- /** An error occurred. */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public void onError(int error) {}
- }
-
- /**
- * Allows applications to request that the system periodically send specific packets on their
- * behalf, using hardware offload to save battery power.
- *
- * To request that the system send keepalives, call one of the methods that return a
- * {@link ConnectivityManager.PacketKeepalive} object, such as {@link #startNattKeepalive},
- * passing in a non-null callback. If the callback is successfully started, the callback's
- * {@code onStarted} method will be called. If an error occurs, {@code onError} will be called,
- * specifying one of the {@code ERROR_*} constants in this class.
- *
- * To stop an existing keepalive, call {@link PacketKeepalive#stop}. The system will call
- * {@link PacketKeepaliveCallback#onStopped} if the operation was successful or
- * {@link PacketKeepaliveCallback#onError} if an error occurred.
- *
- * @deprecated Use {@link SocketKeepalive} instead.
- *
- * @hide
- */
- public class PacketKeepalive {
-
- private static final String TAG = "PacketKeepalive";
-
- /** @hide */
- public static final int SUCCESS = 0;
-
- /** @hide */
- public static final int NO_KEEPALIVE = -1;
-
- /** @hide */
- public static final int BINDER_DIED = -10;
-
- /** The specified {@code Network} is not connected. */
- public static final int ERROR_INVALID_NETWORK = -20;
- /** The specified IP addresses are invalid. For example, the specified source IP address is
- * not configured on the specified {@code Network}. */
- public static final int ERROR_INVALID_IP_ADDRESS = -21;
- /** The requested port is invalid. */
- public static final int ERROR_INVALID_PORT = -22;
- /** The packet length is invalid (e.g., too long). */
- public static final int ERROR_INVALID_LENGTH = -23;
- /** The packet transmission interval is invalid (e.g., too short). */
- public static final int ERROR_INVALID_INTERVAL = -24;
-
- /** The hardware does not support this request. */
- public static final int ERROR_HARDWARE_UNSUPPORTED = -30;
- /** The hardware returned an error. */
- public static final int ERROR_HARDWARE_ERROR = -31;
-
- /** The NAT-T destination port for IPsec */
- public static final int NATT_PORT = 4500;
-
- /** The minimum interval in seconds between keepalive packet transmissions */
- public static final int MIN_INTERVAL = 10;
-
- private final Network mNetwork;
- private final ISocketKeepaliveCallback mCallback;
- private final ExecutorService mExecutor;
-
- private volatile Integer mSlot;
-
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public void stop() {
- try {
- mExecutor.execute(() -> {
- try {
- if (mSlot != null) {
- mService.stopKeepalive(mNetwork, mSlot);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Error stopping packet keepalive: ", e);
- throw e.rethrowFromSystemServer();
- }
- });
- } catch (RejectedExecutionException e) {
- // The internal executor has already stopped due to previous event.
- }
- }
-
- private PacketKeepalive(Network network, PacketKeepaliveCallback callback) {
- Objects.requireNonNull(network, "network cannot be null");
- Objects.requireNonNull(callback, "callback cannot be null");
- mNetwork = network;
- mExecutor = Executors.newSingleThreadExecutor();
- mCallback = new ISocketKeepaliveCallback.Stub() {
- @Override
- public void onStarted(int slot) {
- final long token = Binder.clearCallingIdentity();
- try {
- mExecutor.execute(() -> {
- mSlot = slot;
- callback.onStarted();
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void onStopped() {
- final long token = Binder.clearCallingIdentity();
- try {
- mExecutor.execute(() -> {
- mSlot = null;
- callback.onStopped();
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- mExecutor.shutdown();
- }
-
- @Override
- public void onError(int error) {
- final long token = Binder.clearCallingIdentity();
- try {
- mExecutor.execute(() -> {
- mSlot = null;
- callback.onError(error);
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- mExecutor.shutdown();
- }
-
- @Override
- public void onDataReceived() {
- // PacketKeepalive is only used for Nat-T keepalive and as such does not invoke
- // this callback when data is received.
- }
- };
- }
- }
-
- /**
- * Starts an IPsec NAT-T keepalive packet with the specified parameters.
- *
- * @deprecated Use {@link #createSocketKeepalive} instead.
- *
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public PacketKeepalive startNattKeepalive(
- Network network, int intervalSeconds, PacketKeepaliveCallback callback,
- InetAddress srcAddr, int srcPort, InetAddress dstAddr) {
- final PacketKeepalive k = new PacketKeepalive(network, callback);
- try {
- mService.startNattKeepalive(network, intervalSeconds, k.mCallback,
- srcAddr.getHostAddress(), srcPort, dstAddr.getHostAddress());
- } catch (RemoteException e) {
- Log.e(TAG, "Error starting packet keepalive: ", e);
- throw e.rethrowFromSystemServer();
- }
- return k;
- }
-
- // Construct an invalid fd.
- private ParcelFileDescriptor createInvalidFd() {
- final int invalidFd = -1;
- return ParcelFileDescriptor.adoptFd(invalidFd);
- }
-
- /**
- * Request that keepalives be started on a IPsec NAT-T socket.
- *
- * @param network The {@link Network} the socket is on.
- * @param socket The socket that needs to be kept alive.
- * @param source The source address of the {@link UdpEncapsulationSocket}.
- * @param destination The destination address of the {@link UdpEncapsulationSocket}.
- * @param executor The executor on which callback will be invoked. The provided {@link Executor}
- * must run callback sequentially, otherwise the order of callbacks cannot be
- * guaranteed.
- * @param callback A {@link SocketKeepalive.Callback}. Used for notifications about keepalive
- * changes. Must be extended by applications that use this API.
- *
- * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the
- * given socket.
- **/
- public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network,
- @NonNull UdpEncapsulationSocket socket,
- @NonNull InetAddress source,
- @NonNull InetAddress destination,
- @NonNull @CallbackExecutor Executor executor,
- @NonNull Callback callback) {
- ParcelFileDescriptor dup;
- try {
- // Dup is needed here as the pfd inside the socket is owned by the IpSecService,
- // which cannot be obtained by the app process.
- dup = ParcelFileDescriptor.dup(socket.getFileDescriptor());
- } catch (IOException ignored) {
- // Construct an invalid fd, so that if the user later calls start(), it will fail with
- // ERROR_INVALID_SOCKET.
- dup = createInvalidFd();
- }
- return new NattSocketKeepalive(mService, network, dup, socket.getResourceId(), source,
- destination, executor, callback);
- }
-
- /**
- * Request that keepalives be started on a IPsec NAT-T socket file descriptor. Directly called
- * by system apps which don't use IpSecService to create {@link UdpEncapsulationSocket}.
- *
- * @param network The {@link Network} the socket is on.
- * @param pfd The {@link ParcelFileDescriptor} that needs to be kept alive. The provided
- * {@link ParcelFileDescriptor} must be bound to a port and the keepalives will be sent
- * from that port.
- * @param source The source address of the {@link UdpEncapsulationSocket}.
- * @param destination The destination address of the {@link UdpEncapsulationSocket}. The
- * keepalive packets will always be sent to port 4500 of the given {@code destination}.
- * @param executor The executor on which callback will be invoked. The provided {@link Executor}
- * must run callback sequentially, otherwise the order of callbacks cannot be
- * guaranteed.
- * @param callback A {@link SocketKeepalive.Callback}. Used for notifications about keepalive
- * changes. Must be extended by applications that use this API.
- *
- * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the
- * given socket.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD)
- public @NonNull SocketKeepalive createNattKeepalive(@NonNull Network network,
- @NonNull ParcelFileDescriptor pfd,
- @NonNull InetAddress source,
- @NonNull InetAddress destination,
- @NonNull @CallbackExecutor Executor executor,
- @NonNull Callback callback) {
- ParcelFileDescriptor dup;
- try {
- // TODO: Consider remove unnecessary dup.
- dup = pfd.dup();
- } catch (IOException ignored) {
- // Construct an invalid fd, so that if the user later calls start(), it will fail with
- // ERROR_INVALID_SOCKET.
- dup = createInvalidFd();
- }
- return new NattSocketKeepalive(mService, network, dup,
- -1 /* Unused */, source, destination, executor, callback);
- }
-
- /**
- * Request that keepalives be started on a TCP socket.
- * The socket must be established.
- *
- * @param network The {@link Network} the socket is on.
- * @param socket The socket that needs to be kept alive.
- * @param executor The executor on which callback will be invoked. This implementation assumes
- * the provided {@link Executor} runs the callbacks in sequence with no
- * concurrency. Failing this, no guarantee of correctness can be made. It is
- * the responsibility of the caller to ensure the executor provides this
- * guarantee. A simple way of creating such an executor is with the standard
- * tool {@code Executors.newSingleThreadExecutor}.
- * @param callback A {@link SocketKeepalive.Callback}. Used for notifications about keepalive
- * changes. Must be extended by applications that use this API.
- *
- * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the
- * given socket.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD)
- public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network,
- @NonNull Socket socket,
- @NonNull Executor executor,
- @NonNull Callback callback) {
- ParcelFileDescriptor dup;
- try {
- dup = ParcelFileDescriptor.fromSocket(socket);
- } catch (UncheckedIOException ignored) {
- // Construct an invalid fd, so that if the user later calls start(), it will fail with
- // ERROR_INVALID_SOCKET.
- dup = createInvalidFd();
- }
- return new TcpSocketKeepalive(mService, network, dup, executor, callback);
- }
-
- /**
- * Ensure that a network route exists to deliver traffic to the specified
- * host via the specified network interface. An attempt to add a route that
- * already exists is ignored, but treated as successful.
- *
- * <p>This method requires the caller to hold either the
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
- * or the ability to modify system settings as determined by
- * {@link android.provider.Settings.System#canWrite}.</p>
- *
- * @param networkType the type of the network over which traffic to the specified
- * host is to be routed
- * @param hostAddress the IP address of the host to which the route is desired
- * @return {@code true} on success, {@code false} on failure
- *
- * @deprecated Deprecated in favor of the
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)},
- * {@link #bindProcessToNetwork} and {@link Network#getSocketFactory} API.
- * In {@link VERSION_CODES#M}, and above, this method is unsupported and will
- * throw {@code UnsupportedOperationException} if called.
- * @removed
- */
- @Deprecated
- public boolean requestRouteToHost(int networkType, int hostAddress) {
- return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress));
- }
-
- /**
- * Ensure that a network route exists to deliver traffic to the specified
- * host via the specified network interface. An attempt to add a route that
- * already exists is ignored, but treated as successful.
- *
- * <p>This method requires the caller to hold either the
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
- * or the ability to modify system settings as determined by
- * {@link android.provider.Settings.System#canWrite}.</p>
- *
- * @param networkType the type of the network over which traffic to the specified
- * host is to be routed
- * @param hostAddress the IP address of the host to which the route is desired
- * @return {@code true} on success, {@code false} on failure
- * @hide
- * @deprecated Deprecated in favor of the {@link #requestNetwork} and
- * {@link #bindProcessToNetwork} API.
- */
- @Deprecated
- @UnsupportedAppUsage
- @SystemApi(client = MODULE_LIBRARIES)
- public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
- checkLegacyRoutingApiAccess();
- try {
- return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress(),
- mContext.getOpPackageName(), getAttributionTag());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * @return the context's attribution tag
- */
- // TODO: Remove method and replace with direct call once R code is pushed to AOSP
- private @Nullable String getAttributionTag() {
- return mContext.getAttributionTag();
- }
-
- /**
- * Returns the value of the setting for background data usage. If false,
- * applications should not use the network if the application is not in the
- * foreground. Developers should respect this setting, and check the value
- * of this before performing any background data operations.
- * <p>
- * All applications that have background services that use the network
- * should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}.
- * <p>
- * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability of
- * background data depends on several combined factors, and this method will
- * always return {@code true}. Instead, when background data is unavailable,
- * {@link #getActiveNetworkInfo()} will now appear disconnected.
- *
- * @return Whether background data usage is allowed.
- */
- @Deprecated
- public boolean getBackgroundDataSetting() {
- // assume that background data is allowed; final authority is
- // NetworkInfo which may be blocked.
- return true;
- }
-
- /**
- * Sets the value of the setting for background data usage.
- *
- * @param allowBackgroundData Whether an application should use data while
- * it is in the background.
- *
- * @attr ref android.Manifest.permission#CHANGE_BACKGROUND_DATA_SETTING
- * @see #getBackgroundDataSetting()
- * @hide
- */
- @Deprecated
- @UnsupportedAppUsage
- public void setBackgroundDataSetting(boolean allowBackgroundData) {
- // ignored
- }
-
- /**
- * @hide
- * @deprecated Talk to TelephonyManager directly
- */
- @Deprecated
- @UnsupportedAppUsage
- public boolean getMobileDataEnabled() {
- TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
- if (tm != null) {
- int subId = SubscriptionManager.getDefaultDataSubscriptionId();
- Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
- boolean retVal = tm.createForSubscriptionId(subId).isDataEnabled();
- Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
- + " retVal=" + retVal);
- return retVal;
- }
- Log.d("ConnectivityManager", "getMobileDataEnabled()- remote exception retVal=false");
- return false;
- }
-
- /**
- * Callback for use with {@link ConnectivityManager#addDefaultNetworkActiveListener}
- * to find out when the system default network has gone in to a high power state.
- */
- public interface OnNetworkActiveListener {
- /**
- * Called on the main thread of the process to report that the current data network
- * has become active, and it is now a good time to perform any pending network
- * operations. Note that this listener only tells you when the network becomes
- * active; if at any other time you want to know whether it is active (and thus okay
- * to initiate network traffic), you can retrieve its instantaneous state with
- * {@link ConnectivityManager#isDefaultNetworkActive}.
- */
- void onNetworkActive();
- }
-
- private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
- mNetworkActivityListeners = new ArrayMap<>();
-
- /**
- * Start listening to reports when the system's default data network is active, meaning it is
- * a good time to perform network traffic. Use {@link #isDefaultNetworkActive()}
- * to determine the current state of the system's default network after registering the
- * listener.
- * <p>
- * If the process default network has been set with
- * {@link ConnectivityManager#bindProcessToNetwork} this function will not
- * reflect the process's default, but the system default.
- *
- * @param l The listener to be told when the network is active.
- */
- public void addDefaultNetworkActiveListener(final OnNetworkActiveListener l) {
- INetworkActivityListener rl = new INetworkActivityListener.Stub() {
- @Override
- public void onNetworkActive() throws RemoteException {
- l.onNetworkActive();
- }
- };
-
- try {
- mService.registerNetworkActivityListener(rl);
- mNetworkActivityListeners.put(l, rl);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Remove network active listener previously registered with
- * {@link #addDefaultNetworkActiveListener}.
- *
- * @param l Previously registered listener.
- */
- public void removeDefaultNetworkActiveListener(@NonNull OnNetworkActiveListener l) {
- INetworkActivityListener rl = mNetworkActivityListeners.get(l);
- if (rl == null) {
- throw new IllegalArgumentException("Listener was not registered.");
- }
- try {
- mService.registerNetworkActivityListener(rl);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return whether the data network is currently active. An active network means that
- * it is currently in a high power state for performing data transmission. On some
- * types of networks, it may be expensive to move and stay in such a state, so it is
- * more power efficient to batch network traffic together when the radio is already in
- * this state. This method tells you whether right now is currently a good time to
- * initiate network traffic, as the network is already active.
- */
- public boolean isDefaultNetworkActive() {
- try {
- return mService.isDefaultNetworkActive();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * {@hide}
- */
- public ConnectivityManager(Context context, IConnectivityManager service) {
- mContext = Objects.requireNonNull(context, "missing context");
- mService = Objects.requireNonNull(service, "missing IConnectivityManager");
- mTetheringManager = (TetheringManager) mContext.getSystemService(Context.TETHERING_SERVICE);
- sInstance = this;
- }
-
- /** {@hide} */
- @UnsupportedAppUsage
- public static ConnectivityManager from(Context context) {
- return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- }
-
- /** @hide */
- public NetworkRequest getDefaultRequest() {
- try {
- // This is not racy as the default request is final in ConnectivityService.
- return mService.getDefaultRequest();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Check if the package is a allowed to write settings. This also accounts that such an access
- * happened.
- *
- * @return {@code true} iff the package is allowed to write settings.
- */
- // TODO: Remove method and replace with direct call once R code is pushed to AOSP
- private static boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid,
- @NonNull String callingPackage, @Nullable String callingAttributionTag,
- boolean throwException) {
- return Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPackage,
- callingAttributionTag, throwException);
- }
-
- /**
- * @deprecated - use getSystemService. This is a kludge to support static access in certain
- * situations where a Context pointer is unavailable.
- * @hide
- */
- @Deprecated
- static ConnectivityManager getInstanceOrNull() {
- return sInstance;
- }
-
- /**
- * @deprecated - use getSystemService. This is a kludge to support static access in certain
- * situations where a Context pointer is unavailable.
- * @hide
- */
- @Deprecated
- @UnsupportedAppUsage
- private static ConnectivityManager getInstance() {
- if (getInstanceOrNull() == null) {
- throw new IllegalStateException("No ConnectivityManager yet constructed");
- }
- return getInstanceOrNull();
- }
-
- /**
- * Get the set of tetherable, available interfaces. This list is limited by
- * device configuration and current interface existence.
- *
- * @return an array of 0 or more Strings of tetherable interface names.
- *
- * @deprecated Use {@link TetheringEventCallback#onTetherableInterfacesChanged(List)} instead.
- * {@hide}
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage
- @Deprecated
- public String[] getTetherableIfaces() {
- return mTetheringManager.getTetherableIfaces();
- }
-
- /**
- * Get the set of tethered interfaces.
- *
- * @return an array of 0 or more String of currently tethered interface names.
- *
- * @deprecated Use {@link TetheringEventCallback#onTetherableInterfacesChanged(List)} instead.
- * {@hide}
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage
- @Deprecated
- public String[] getTetheredIfaces() {
- return mTetheringManager.getTetheredIfaces();
- }
-
- /**
- * Get the set of interface names which attempted to tether but
- * failed. Re-attempting to tether may cause them to reset to the Tethered
- * state. Alternatively, causing the interface to be destroyed and recreated
- * may cause them to reset to the available state.
- * {@link ConnectivityManager#getLastTetherError} can be used to get more
- * information on the cause of the errors.
- *
- * @return an array of 0 or more String indicating the interface names
- * which failed to tether.
- *
- * @deprecated Use {@link TetheringEventCallback#onError(String, int)} instead.
- * {@hide}
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage
- @Deprecated
- public String[] getTetheringErroredIfaces() {
- return mTetheringManager.getTetheringErroredIfaces();
- }
-
- /**
- * Get the set of tethered dhcp ranges.
- *
- * @deprecated This method is not supported.
- * TODO: remove this function when all of clients are removed.
- * {@hide}
- */
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- @Deprecated
- public String[] getTetheredDhcpRanges() {
- throw new UnsupportedOperationException("getTetheredDhcpRanges is not supported");
- }
-
- /**
- * Attempt to tether the named interface. This will setup a dhcp server
- * on the interface, forward and NAT IP packets and forward DNS requests
- * to the best active upstream network interface. Note that if no upstream
- * IP network interface is available, dhcp will still run and traffic will be
- * allowed between the tethered devices and this device, though upstream net
- * access will of course fail until an upstream network interface becomes
- * active.
- *
- * <p>This method requires the caller to hold either the
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
- * or the ability to modify system settings as determined by
- * {@link android.provider.Settings.System#canWrite}.</p>
- *
- * <p>WARNING: New clients should not use this function. The only usages should be in PanService
- * and WifiStateMachine which need direct access. All other clients should use
- * {@link #startTethering} and {@link #stopTethering} which encapsulate proper provisioning
- * logic.</p>
- *
- * @param iface the interface name to tether.
- * @return error a {@code TETHER_ERROR} value indicating success or failure type
- * @deprecated Use {@link TetheringManager#startTethering} instead
- *
- * {@hide}
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @Deprecated
- public int tether(String iface) {
- return mTetheringManager.tether(iface);
- }
-
- /**
- * Stop tethering the named interface.
- *
- * <p>This method requires the caller to hold either the
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
- * or the ability to modify system settings as determined by
- * {@link android.provider.Settings.System#canWrite}.</p>
- *
- * <p>WARNING: New clients should not use this function. The only usages should be in PanService
- * and WifiStateMachine which need direct access. All other clients should use
- * {@link #startTethering} and {@link #stopTethering} which encapsulate proper provisioning
- * logic.</p>
- *
- * @param iface the interface name to untether.
- * @return error a {@code TETHER_ERROR} value indicating success or failure type
- *
- * {@hide}
- */
- @UnsupportedAppUsage
- @Deprecated
- public int untether(String iface) {
- return mTetheringManager.untether(iface);
- }
-
- /**
- * Check if the device allows for tethering. It may be disabled via
- * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
- * due to device configuration.
- *
- * <p>If this app does not have permission to use this API, it will always
- * return false rather than throw an exception.</p>
- *
- * <p>If the device has a hotspot provisioning app, the caller is required to hold the
- * {@link android.Manifest.permission.TETHER_PRIVILEGED} permission.</p>
- *
- * <p>Otherwise, this method requires the caller to hold the ability to modify system
- * settings as determined by {@link android.provider.Settings.System#canWrite}.</p>
- *
- * @return a boolean - {@code true} indicating Tethering is supported.
- *
- * @deprecated Use {@link TetheringEventCallback#onTetheringSupported(boolean)} instead.
- * {@hide}
- */
- @SystemApi
- @RequiresPermission(anyOf = {android.Manifest.permission.TETHER_PRIVILEGED,
- android.Manifest.permission.WRITE_SETTINGS})
- public boolean isTetheringSupported() {
- return mTetheringManager.isTetheringSupported();
- }
-
- /**
- * Callback for use with {@link #startTethering} to find out whether tethering succeeded.
- *
- * @deprecated Use {@link TetheringManager.StartTetheringCallback} instead.
- * @hide
- */
- @SystemApi
- @Deprecated
- public static abstract class OnStartTetheringCallback {
- /**
- * Called when tethering has been successfully started.
- */
- public void onTetheringStarted() {}
-
- /**
- * Called when starting tethering failed.
- */
- public void onTetheringFailed() {}
- }
-
- /**
- * Convenient overload for
- * {@link #startTethering(int, boolean, OnStartTetheringCallback, Handler)} which passes a null
- * handler to run on the current thread's {@link Looper}.
- *
- * @deprecated Use {@link TetheringManager#startTethering} instead.
- * @hide
- */
- @SystemApi
- @Deprecated
- @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
- public void startTethering(int type, boolean showProvisioningUi,
- final OnStartTetheringCallback callback) {
- startTethering(type, showProvisioningUi, callback, null);
- }
-
- /**
- * Runs tether provisioning for the given type if needed and then starts tethering if
- * the check succeeds. If no carrier provisioning is required for tethering, tethering is
- * enabled immediately. If provisioning fails, tethering will not be enabled. It also
- * schedules tether provisioning re-checks if appropriate.
- *
- * @param type The type of tethering to start. Must be one of
- * {@link ConnectivityManager.TETHERING_WIFI},
- * {@link ConnectivityManager.TETHERING_USB}, or
- * {@link ConnectivityManager.TETHERING_BLUETOOTH}.
- * @param showProvisioningUi a boolean indicating to show the provisioning app UI if there
- * is one. This should be true the first time this function is called and also any time
- * the user can see this UI. It gives users information from their carrier about the
- * check failing and how they can sign up for tethering if possible.
- * @param callback an {@link OnStartTetheringCallback} which will be called to notify the caller
- * of the result of trying to tether.
- * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- *
- * @deprecated Use {@link TetheringManager#startTethering} instead.
- * @hide
- */
- @SystemApi
- @Deprecated
- @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
- public void startTethering(int type, boolean showProvisioningUi,
- final OnStartTetheringCallback callback, Handler handler) {
- Objects.requireNonNull(callback, "OnStartTetheringCallback cannot be null.");
-
- final Executor executor = new Executor() {
- @Override
- public void execute(Runnable command) {
- if (handler == null) {
- command.run();
- } else {
- handler.post(command);
- }
- }
- };
-
- final StartTetheringCallback tetheringCallback = new StartTetheringCallback() {
- @Override
- public void onTetheringStarted() {
- callback.onTetheringStarted();
- }
-
- @Override
- public void onTetheringFailed(final int error) {
- callback.onTetheringFailed();
- }
- };
-
- final TetheringRequest request = new TetheringRequest.Builder(type)
- .setShouldShowEntitlementUi(showProvisioningUi).build();
-
- mTetheringManager.startTethering(request, executor, tetheringCallback);
- }
-
- /**
- * Stops tethering for the given type. Also cancels any provisioning rechecks for that type if
- * applicable.
- *
- * @param type The type of tethering to stop. Must be one of
- * {@link ConnectivityManager.TETHERING_WIFI},
- * {@link ConnectivityManager.TETHERING_USB}, or
- * {@link ConnectivityManager.TETHERING_BLUETOOTH}.
- *
- * @deprecated Use {@link TetheringManager#stopTethering} instead.
- * @hide
- */
- @SystemApi
- @Deprecated
- @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
- public void stopTethering(int type) {
- mTetheringManager.stopTethering(type);
- }
-
- /**
- * Callback for use with {@link registerTetheringEventCallback} to find out tethering
- * upstream status.
- *
- * @deprecated Use {@link TetheringManager#OnTetheringEventCallback} instead.
- * @hide
- */
- @SystemApi
- @Deprecated
- public abstract static class OnTetheringEventCallback {
-
- /**
- * Called when tethering upstream changed. This can be called multiple times and can be
- * called any time.
- *
- * @param network the {@link Network} of tethering upstream. Null means tethering doesn't
- * have any upstream.
- */
- public void onUpstreamChanged(@Nullable Network network) {}
- }
-
- @GuardedBy("mTetheringEventCallbacks")
- private final ArrayMap<OnTetheringEventCallback, TetheringEventCallback>
- mTetheringEventCallbacks = new ArrayMap<>();
-
- /**
- * Start listening to tethering change events. Any new added callback will receive the last
- * tethering status right away. If callback is registered when tethering has no upstream or
- * disabled, {@link OnTetheringEventCallback#onUpstreamChanged} will immediately be called
- * with a null argument. The same callback object cannot be registered twice.
- *
- * @param executor the executor on which callback will be invoked.
- * @param callback the callback to be called when tethering has change events.
- *
- * @deprecated Use {@link TetheringManager#registerTetheringEventCallback} instead.
- * @hide
- */
- @SystemApi
- @Deprecated
- @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
- public void registerTetheringEventCallback(
- @NonNull @CallbackExecutor Executor executor,
- @NonNull final OnTetheringEventCallback callback) {
- Objects.requireNonNull(callback, "OnTetheringEventCallback cannot be null.");
-
- final TetheringEventCallback tetherCallback =
- new TetheringEventCallback() {
- @Override
- public void onUpstreamChanged(@Nullable Network network) {
- callback.onUpstreamChanged(network);
- }
- };
-
- synchronized (mTetheringEventCallbacks) {
- mTetheringEventCallbacks.put(callback, tetherCallback);
- mTetheringManager.registerTetheringEventCallback(executor, tetherCallback);
- }
- }
-
- /**
- * Remove tethering event callback previously registered with
- * {@link #registerTetheringEventCallback}.
- *
- * @param callback previously registered callback.
- *
- * @deprecated Use {@link TetheringManager#unregisterTetheringEventCallback} instead.
- * @hide
- */
- @SystemApi
- @Deprecated
- @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
- public void unregisterTetheringEventCallback(
- @NonNull final OnTetheringEventCallback callback) {
- Objects.requireNonNull(callback, "The callback must be non-null");
- synchronized (mTetheringEventCallbacks) {
- final TetheringEventCallback tetherCallback =
- mTetheringEventCallbacks.remove(callback);
- mTetheringManager.unregisterTetheringEventCallback(tetherCallback);
- }
- }
-
-
- /**
- * Get the list of regular expressions that define any tetherable
- * USB network interfaces. If USB tethering is not supported by the
- * device, this list should be empty.
- *
- * @return an array of 0 or more regular expression Strings defining
- * what interfaces are considered tetherable usb interfaces.
- *
- * @deprecated Use {@link TetheringEventCallback#onTetherableInterfaceRegexpsChanged} instead.
- * {@hide}
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage
- @Deprecated
- public String[] getTetherableUsbRegexs() {
- return mTetheringManager.getTetherableUsbRegexs();
- }
-
- /**
- * Get the list of regular expressions that define any tetherable
- * Wifi network interfaces. If Wifi tethering is not supported by the
- * device, this list should be empty.
- *
- * @return an array of 0 or more regular expression Strings defining
- * what interfaces are considered tetherable wifi interfaces.
- *
- * @deprecated Use {@link TetheringEventCallback#onTetherableInterfaceRegexpsChanged} instead.
- * {@hide}
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage
- @Deprecated
- public String[] getTetherableWifiRegexs() {
- return mTetheringManager.getTetherableWifiRegexs();
- }
-
- /**
- * Get the list of regular expressions that define any tetherable
- * Bluetooth network interfaces. If Bluetooth tethering is not supported by the
- * device, this list should be empty.
- *
- * @return an array of 0 or more regular expression Strings defining
- * what interfaces are considered tetherable bluetooth interfaces.
- *
- * @deprecated Use {@link TetheringEventCallback#onTetherableInterfaceRegexpsChanged(
- *TetheringManager.TetheringInterfaceRegexps)} instead.
- * {@hide}
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage
- @Deprecated
- public String[] getTetherableBluetoothRegexs() {
- return mTetheringManager.getTetherableBluetoothRegexs();
- }
-
- /**
- * Attempt to both alter the mode of USB and Tethering of USB. A
- * utility method to deal with some of the complexity of USB - will
- * attempt to switch to Rndis and subsequently tether the resulting
- * interface on {@code true} or turn off tethering and switch off
- * Rndis on {@code false}.
- *
- * <p>This method requires the caller to hold either the
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
- * or the ability to modify system settings as determined by
- * {@link android.provider.Settings.System#canWrite}.</p>
- *
- * @param enable a boolean - {@code true} to enable tethering
- * @return error a {@code TETHER_ERROR} value indicating success or failure type
- * @deprecated Use {@link TetheringManager#startTethering} instead
- *
- * {@hide}
- */
- @UnsupportedAppUsage
- @Deprecated
- public int setUsbTethering(boolean enable) {
- return mTetheringManager.setUsbTethering(enable);
- }
-
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_NO_ERROR}.
- * {@hide}
- */
- @SystemApi
- @Deprecated
- public static final int TETHER_ERROR_NO_ERROR = 0;
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_UNKNOWN_IFACE}.
- * {@hide}
- */
- @Deprecated
- public static final int TETHER_ERROR_UNKNOWN_IFACE =
- TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_SERVICE_UNAVAIL}.
- * {@hide}
- */
- @Deprecated
- public static final int TETHER_ERROR_SERVICE_UNAVAIL =
- TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_UNSUPPORTED}.
- * {@hide}
- */
- @Deprecated
- public static final int TETHER_ERROR_UNSUPPORTED = TetheringManager.TETHER_ERROR_UNSUPPORTED;
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_UNAVAIL_IFACE}.
- * {@hide}
- */
- @Deprecated
- public static final int TETHER_ERROR_UNAVAIL_IFACE =
- TetheringManager.TETHER_ERROR_UNAVAIL_IFACE;
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_INTERNAL_ERROR}.
- * {@hide}
- */
- @Deprecated
- public static final int TETHER_ERROR_MASTER_ERROR =
- TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_TETHER_IFACE_ERROR}.
- * {@hide}
- */
- @Deprecated
- public static final int TETHER_ERROR_TETHER_IFACE_ERROR =
- TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR;
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_UNTETHER_IFACE_ERROR}.
- * {@hide}
- */
- @Deprecated
- public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR =
- TetheringManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_ENABLE_FORWARDING_ERROR}.
- * {@hide}
- */
- @Deprecated
- public static final int TETHER_ERROR_ENABLE_NAT_ERROR =
- TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR;
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_DISABLE_FORWARDING_ERROR}.
- * {@hide}
- */
- @Deprecated
- public static final int TETHER_ERROR_DISABLE_NAT_ERROR =
- TetheringManager.TETHER_ERROR_DISABLE_FORWARDING_ERROR;
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_IFACE_CFG_ERROR}.
- * {@hide}
- */
- @Deprecated
- public static final int TETHER_ERROR_IFACE_CFG_ERROR =
- TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_PROVISIONING_FAILED}.
- * {@hide}
- */
- @SystemApi
- @Deprecated
- public static final int TETHER_ERROR_PROVISION_FAILED = 11;
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_DHCPSERVER_ERROR}.
- * {@hide}
- */
- @Deprecated
- public static final int TETHER_ERROR_DHCPSERVER_ERROR =
- TetheringManager.TETHER_ERROR_DHCPSERVER_ERROR;
- /**
- * @deprecated Use {@link TetheringManager#TETHER_ERROR_ENTITLEMENT_UNKNOWN}.
- * {@hide}
- */
- @SystemApi
- @Deprecated
- public static final int TETHER_ERROR_ENTITLEMENT_UNKONWN = 13;
-
- /**
- * Get a more detailed error code after a Tethering or Untethering
- * request asynchronously failed.
- *
- * @param iface The name of the interface of interest
- * @return error The error code of the last error tethering or untethering the named
- * interface
- *
- * @deprecated Use {@link TetheringEventCallback#onError(String, int)} instead.
- * {@hide}
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @Deprecated
- public int getLastTetherError(String iface) {
- int error = mTetheringManager.getLastTetherError(iface);
- if (error == TetheringManager.TETHER_ERROR_UNKNOWN_TYPE) {
- // TETHER_ERROR_UNKNOWN_TYPE was introduced with TetheringManager and has never been
- // returned by ConnectivityManager. Convert it to the legacy TETHER_ERROR_UNKNOWN_IFACE
- // instead.
- error = TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
- }
- return error;
- }
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- TETHER_ERROR_NO_ERROR,
- TETHER_ERROR_PROVISION_FAILED,
- TETHER_ERROR_ENTITLEMENT_UNKONWN,
- })
- public @interface EntitlementResultCode {
- }
-
- /**
- * Callback for use with {@link #getLatestTetheringEntitlementResult} to find out whether
- * entitlement succeeded.
- *
- * @deprecated Use {@link TetheringManager#OnTetheringEntitlementResultListener} instead.
- * @hide
- */
- @SystemApi
- @Deprecated
- public interface OnTetheringEntitlementResultListener {
- /**
- * Called to notify entitlement result.
- *
- * @param resultCode an int value of entitlement result. It may be one of
- * {@link #TETHER_ERROR_NO_ERROR},
- * {@link #TETHER_ERROR_PROVISION_FAILED}, or
- * {@link #TETHER_ERROR_ENTITLEMENT_UNKONWN}.
- */
- void onTetheringEntitlementResult(@EntitlementResultCode int resultCode);
- }
-
- /**
- * Get the last value of the entitlement check on this downstream. If the cached value is
- * {@link #TETHER_ERROR_NO_ERROR} or showEntitlementUi argument is false, it just return the
- * cached value. Otherwise, a UI-based entitlement check would be performed. It is not
- * guaranteed that the UI-based entitlement check will complete in any specific time period
- * and may in fact never complete. Any successful entitlement check the platform performs for
- * any reason will update the cached value.
- *
- * @param type the downstream type of tethering. Must be one of
- * {@link #TETHERING_WIFI},
- * {@link #TETHERING_USB}, or
- * {@link #TETHERING_BLUETOOTH}.
- * @param showEntitlementUi a boolean indicating whether to run UI-based entitlement check.
- * @param executor the executor on which callback will be invoked.
- * @param listener an {@link OnTetheringEntitlementResultListener} which will be called to
- * notify the caller of the result of entitlement check. The listener may be called zero
- * or one time.
- * @deprecated Use {@link TetheringManager#requestLatestTetheringEntitlementResult} instead.
- * {@hide}
- */
- @SystemApi
- @Deprecated
- @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
- public void getLatestTetheringEntitlementResult(int type, boolean showEntitlementUi,
- @NonNull @CallbackExecutor Executor executor,
- @NonNull final OnTetheringEntitlementResultListener listener) {
- Objects.requireNonNull(listener, "TetheringEntitlementResultListener cannot be null.");
- ResultReceiver wrappedListener = new ResultReceiver(null) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- final long token = Binder.clearCallingIdentity();
- try {
- executor.execute(() -> {
- listener.onTetheringEntitlementResult(resultCode);
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- };
-
- mTetheringManager.requestLatestTetheringEntitlementResult(type, wrappedListener,
- showEntitlementUi);
- }
-
- /**
- * Report network connectivity status. This is currently used only
- * to alter status bar UI.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#STATUS_BAR}.
- *
- * @param networkType The type of network you want to report on
- * @param percentage The quality of the connection 0 is bad, 100 is good
- * @deprecated Types are deprecated. Use {@link #reportNetworkConnectivity} instead.
- * {@hide}
- */
- public void reportInetCondition(int networkType, int percentage) {
- printStackTrace();
- try {
- mService.reportInetCondition(networkType, percentage);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Report a problem network to the framework. This provides a hint to the system
- * that there might be connectivity problems on this network and may cause
- * the framework to re-evaluate network connectivity and/or switch to another
- * network.
- *
- * @param network The {@link Network} the application was attempting to use
- * or {@code null} to indicate the current default network.
- * @deprecated Use {@link #reportNetworkConnectivity} which allows reporting both
- * working and non-working connectivity.
- */
- @Deprecated
- public void reportBadNetwork(@Nullable Network network) {
- printStackTrace();
- try {
- // One of these will be ignored because it matches system's current state.
- // The other will trigger the necessary reevaluation.
- mService.reportNetworkConnectivity(network, true);
- mService.reportNetworkConnectivity(network, false);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Report to the framework whether a network has working connectivity.
- * This provides a hint to the system that a particular network is providing
- * working connectivity or not. In response the framework may re-evaluate
- * the network's connectivity and might take further action thereafter.
- *
- * @param network The {@link Network} the application was attempting to use
- * or {@code null} to indicate the current default network.
- * @param hasConnectivity {@code true} if the application was able to successfully access the
- * Internet using {@code network} or {@code false} if not.
- */
- public void reportNetworkConnectivity(@Nullable Network network, boolean hasConnectivity) {
- printStackTrace();
- try {
- mService.reportNetworkConnectivity(network, hasConnectivity);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Set a network-independent global HTTP proxy.
- *
- * This sets an HTTP proxy that applies to all networks and overrides any network-specific
- * proxy. If set, HTTP libraries that are proxy-aware will use this global proxy when
- * accessing any network, regardless of what the settings for that network are.
- *
- * Note that HTTP proxies are by nature typically network-dependent, and setting a global
- * proxy is likely to break networking on multiple networks. This method is only meant
- * for device policy clients looking to do general internal filtering or similar use cases.
- *
- * {@see #getGlobalProxy}
- * {@see LinkProperties#getHttpProxy}
- *
- * @param p A {@link ProxyInfo} object defining the new global HTTP proxy. Calling this
- * method with a {@code null} value will clear the global HTTP proxy.
- * @hide
- */
- // Used by Device Policy Manager to set the global proxy.
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
- public void setGlobalProxy(@Nullable final ProxyInfo p) {
- try {
- mService.setGlobalProxy(p);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Retrieve any network-independent global HTTP proxy.
- *
- * @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
- * if no global HTTP proxy is set.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @Nullable
- public ProxyInfo getGlobalProxy() {
- try {
- return mService.getGlobalProxy();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Retrieve the global HTTP proxy, or if no global HTTP proxy is set, a
- * network-specific HTTP proxy. If {@code network} is null, the
- * network-specific proxy returned is the proxy of the default active
- * network.
- *
- * @return {@link ProxyInfo} for the current global HTTP proxy, or if no
- * global HTTP proxy is set, {@code ProxyInfo} for {@code network},
- * or when {@code network} is {@code null},
- * the {@code ProxyInfo} for the default active network. Returns
- * {@code null} when no proxy applies or the caller doesn't have
- * permission to use {@code network}.
- * @hide
- */
- public ProxyInfo getProxyForNetwork(Network network) {
- try {
- return mService.getProxyForNetwork(network);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Get the current default HTTP proxy settings. If a global proxy is set it will be returned,
- * otherwise if this process is bound to a {@link Network} using
- * {@link #bindProcessToNetwork} then that {@code Network}'s proxy is returned, otherwise
- * the default network's proxy is returned.
- *
- * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no
- * HTTP proxy is active.
- */
- @Nullable
- public ProxyInfo getDefaultProxy() {
- return getProxyForNetwork(getBoundNetworkForProcess());
- }
-
- /**
- * Returns true if the hardware supports the given network type
- * else it returns false. This doesn't indicate we have coverage
- * or are authorized onto a network, just whether or not the
- * hardware supports it. For example a GSM phone without a SIM
- * should still return {@code true} for mobile data, but a wifi only
- * tablet would return {@code false}.
- *
- * @param networkType The network type we'd like to check
- * @return {@code true} if supported, else {@code false}
- * @deprecated Types are deprecated. Use {@link NetworkCapabilities} instead.
- * @hide
- */
- @Deprecated
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
- public boolean isNetworkSupported(int networkType) {
- try {
- return mService.isNetworkSupported(networkType);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns if the currently active data network is metered. A network is
- * classified as metered when the user is sensitive to heavy data usage on
- * that connection due to monetary costs, data limitations or
- * battery/performance issues. You should check this before doing large
- * data transfers, and warn the user or delay the operation until another
- * network is available.
- *
- * @return {@code true} if large transfers should be avoided, otherwise
- * {@code false}.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- public boolean isActiveNetworkMetered() {
- try {
- return mService.isActiveNetworkMetered();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Set sign in error notification to visible or invisible
- *
- * @hide
- * @deprecated Doesn't properly deal with multiple connected networks of the same type.
- */
- @Deprecated
- public void setProvisioningNotificationVisible(boolean visible, int networkType,
- String action) {
- try {
- mService.setProvisioningNotificationVisible(visible, networkType, action);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Set the value for enabling/disabling airplane mode
- *
- * @param enable whether to enable airplane mode or not
- *
- * @hide
- */
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_AIRPLANE_MODE,
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD,
- android.Manifest.permission.NETWORK_STACK})
- @SystemApi
- public void setAirplaneMode(boolean enable) {
- try {
- mService.setAirplaneMode(enable);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Registers the specified {@link NetworkProvider}.
- * Each listener must only be registered once. The listener can be unregistered with
- * {@link #unregisterNetworkProvider}.
- *
- * @param provider the provider to register
- * @return the ID of the provider. This ID must be used by the provider when registering
- * {@link android.net.NetworkAgent}s.
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_FACTORY})
- public int registerNetworkProvider(@NonNull NetworkProvider provider) {
- if (provider.getProviderId() != NetworkProvider.ID_NONE) {
- throw new IllegalStateException("NetworkProviders can only be registered once");
- }
-
- try {
- int providerId = mService.registerNetworkProvider(provider.getMessenger(),
- provider.getName());
- provider.setProviderId(providerId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- return provider.getProviderId();
- }
-
- /**
- * Unregisters the specified NetworkProvider.
- *
- * @param provider the provider to unregister
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_FACTORY})
- public void unregisterNetworkProvider(@NonNull NetworkProvider provider) {
- try {
- mService.unregisterNetworkProvider(provider.getMessenger());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- provider.setProviderId(NetworkProvider.ID_NONE);
- }
-
- /**
- * Register or update a network offer with ConnectivityService.
- *
- * ConnectivityService keeps track of offers made by the various providers and matches
- * them to networking requests made by apps or the system. A callback identifies an offer
- * uniquely, and later calls with the same callback update the offer. The provider supplies a
- * score and the capabilities of the network it might be able to bring up ; these act as
- * filters used by ConnectivityService to only send those requests that can be fulfilled by the
- * provider.
- *
- * The provider is under no obligation to be able to bring up the network it offers at any
- * given time. Instead, this mechanism is meant to limit requests received by providers
- * to those they actually have a chance to fulfill, as providers don't have a way to compare
- * the quality of the network satisfying a given request to their own offer.
- *
- * An offer can be updated by calling this again with the same callback object. This is
- * similar to calling unofferNetwork and offerNetwork again, but will only update the
- * provider with the changes caused by the changes in the offer.
- *
- * @param provider The provider making this offer.
- * @param score The prospective score of the network.
- * @param caps The prospective capabilities of the network.
- * @param callback The callback to call when this offer is needed or unneeded.
- * @hide exposed via the NetworkProvider class.
- */
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_FACTORY})
- public void offerNetwork(@NonNull final int providerId,
- @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps,
- @NonNull final INetworkOfferCallback callback) {
- try {
- mService.offerNetwork(providerId,
- Objects.requireNonNull(score, "null score"),
- Objects.requireNonNull(caps, "null caps"),
- Objects.requireNonNull(callback, "null callback"));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Withdraw a network offer made with {@link #offerNetwork}.
- *
- * @param callback The callback passed at registration time. This must be the same object
- * that was passed to {@link #offerNetwork}
- * @hide exposed via the NetworkProvider class.
- */
- public void unofferNetwork(@NonNull final INetworkOfferCallback callback) {
- try {
- mService.unofferNetwork(Objects.requireNonNull(callback));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- /** @hide exposed via the NetworkProvider class. */
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_FACTORY})
- public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) {
- try {
- mService.declareNetworkRequestUnfulfillable(request);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * @hide
- * Register a NetworkAgent with ConnectivityService.
- * @return Network corresponding to NetworkAgent.
- */
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_FACTORY})
- public Network registerNetworkAgent(INetworkAgent na, NetworkInfo ni, LinkProperties lp,
- NetworkCapabilities nc, @NonNull NetworkScore score, NetworkAgentConfig config,
- int providerId) {
- try {
- return mService.registerNetworkAgent(na, ni, lp, nc, score, config, providerId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Base class for {@code NetworkRequest} callbacks. Used for notifications about network
- * changes. Should be extended by applications wanting notifications.
- *
- * A {@code NetworkCallback} is registered by calling
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)},
- * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)},
- * or {@link #registerDefaultNetworkCallback(NetworkCallback)}. A {@code NetworkCallback} is
- * unregistered by calling {@link #unregisterNetworkCallback(NetworkCallback)}.
- * A {@code NetworkCallback} should be registered at most once at any time.
- * A {@code NetworkCallback} that has been unregistered can be registered again.
- */
- public static class NetworkCallback {
- /**
- * No flags associated with this callback.
- * @hide
- */
- public static final int FLAG_NONE = 0;
- /**
- * Use this flag to include any location sensitive data in {@link NetworkCapabilities} sent
- * via {@link #onCapabilitiesChanged(Network, NetworkCapabilities)}.
- * <p>
- * These include:
- * <li> Some transport info instances (retrieved via
- * {@link NetworkCapabilities#getTransportInfo()}) like {@link android.net.wifi.WifiInfo}
- * contain location sensitive information.
- * <li> OwnerUid (retrieved via {@link NetworkCapabilities#getOwnerUid()} is location
- * sensitive for wifi suggestor apps (i.e using {@link WifiNetworkSuggestion}).</li>
- * </p>
- * <p>
- * Note:
- * <li> Retrieving this location sensitive information (subject to app's location
- * permissions) will be noted by system. </li>
- * <li> Without this flag any {@link NetworkCapabilities} provided via the callback does
- * not include location sensitive info.
- * </p>
- */
- // Note: Some existing fields which are location sensitive may still be included without
- // this flag if the app targets SDK < S (to maintain backwards compatibility).
- public static final int FLAG_INCLUDE_LOCATION_INFO = 1 << 0;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, prefix = "FLAG_", value = {
- FLAG_NONE,
- FLAG_INCLUDE_LOCATION_INFO
- })
- public @interface Flag { }
-
- /**
- * All the valid flags for error checking.
- */
- private static final int VALID_FLAGS = FLAG_INCLUDE_LOCATION_INFO;
-
- public NetworkCallback() {
- this(FLAG_NONE);
- }
-
- public NetworkCallback(@Flag int flags) {
- if ((flags & VALID_FLAGS) != flags) {
- throw new IllegalArgumentException("Invalid flags");
- }
- mFlags = flags;
- }
-
- /**
- * Called when the framework connects to a new network to evaluate whether it satisfies this
- * request. If evaluation succeeds, this callback may be followed by an {@link #onAvailable}
- * callback. There is no guarantee that this new network will satisfy any requests, or that
- * the network will stay connected for longer than the time necessary to evaluate it.
- * <p>
- * Most applications <b>should not</b> act on this callback, and should instead use
- * {@link #onAvailable}. This callback is intended for use by applications that can assist
- * the framework in properly evaluating the network — for example, an application that
- * can automatically log in to a captive portal without user intervention.
- *
- * @param network The {@link Network} of the network that is being evaluated.
- *
- * @hide
- */
- public void onPreCheck(@NonNull Network network) {}
-
- /**
- * Called when the framework connects and has declared a new network ready for use.
- * This callback may be called more than once if the {@link Network} that is
- * satisfying the request changes.
- *
- * @param network The {@link Network} of the satisfying network.
- * @param networkCapabilities The {@link NetworkCapabilities} of the satisfying network.
- * @param linkProperties The {@link LinkProperties} of the satisfying network.
- * @param blocked Whether access to the {@link Network} is blocked due to system policy.
- * @hide
- */
- public final void onAvailable(@NonNull Network network,
- @NonNull NetworkCapabilities networkCapabilities,
- @NonNull LinkProperties linkProperties, @BlockedReason int blocked) {
- // Internally only this method is called when a new network is available, and
- // it calls the callback in the same way and order that older versions used
- // to call so as not to change the behavior.
- onAvailable(network, networkCapabilities, linkProperties, blocked != 0);
- onBlockedStatusChanged(network, blocked);
- }
-
- /**
- * Legacy variant of onAvailable that takes a boolean blocked reason.
- *
- * This method has never been public API, but it's not final, so there may be apps that
- * implemented it and rely on it being called. Do our best not to break them.
- * Note: such apps will also get a second call to onBlockedStatusChanged immediately after
- * this method is called. There does not seem to be a way to avoid this.
- * TODO: add a compat check to move apps off this method, and eventually stop calling it.
- *
- * @hide
- */
- public void onAvailable(@NonNull Network network,
- @NonNull NetworkCapabilities networkCapabilities,
- @NonNull LinkProperties linkProperties, boolean blocked) {
- onAvailable(network);
- if (!networkCapabilities.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)) {
- onNetworkSuspended(network);
- }
- onCapabilitiesChanged(network, networkCapabilities);
- onLinkPropertiesChanged(network, linkProperties);
- // No call to onBlockedStatusChanged here. That is done by the caller.
- }
-
- /**
- * Called when the framework connects and has declared a new network ready for use.
- *
- * <p>For callbacks registered with {@link #registerNetworkCallback}, multiple networks may
- * be available at the same time, and onAvailable will be called for each of these as they
- * appear.
- *
- * <p>For callbacks registered with {@link #requestNetwork} and
- * {@link #registerDefaultNetworkCallback}, this means the network passed as an argument
- * is the new best network for this request and is now tracked by this callback ; this
- * callback will no longer receive method calls about other networks that may have been
- * passed to this method previously. The previously-best network may have disconnected, or
- * it may still be around and the newly-best network may simply be better.
- *
- * <p>Starting with {@link android.os.Build.VERSION_CODES#O}, this will always immediately
- * be followed by a call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)}
- * then by a call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}, and a call
- * to {@link #onBlockedStatusChanged(Network, boolean)}.
- *
- * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or
- * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in
- * this callback as this is prone to race conditions (there is no guarantee the objects
- * returned by these methods will be current). Instead, wait for a call to
- * {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} and
- * {@link #onLinkPropertiesChanged(Network, LinkProperties)} whose arguments are guaranteed
- * to be well-ordered with respect to other callbacks.
- *
- * @param network The {@link Network} of the satisfying network.
- */
- public void onAvailable(@NonNull Network network) {}
-
- /**
- * Called when the network is about to be lost, typically because there are no outstanding
- * requests left for it. This may be paired with a {@link NetworkCallback#onAvailable} call
- * with the new replacement network for graceful handover. This method is not guaranteed
- * to be called before {@link NetworkCallback#onLost} is called, for example in case a
- * network is suddenly disconnected.
- *
- * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or
- * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in
- * this callback as this is prone to race conditions ; calling these methods while in a
- * callback may return an outdated or even a null object.
- *
- * @param network The {@link Network} that is about to be lost.
- * @param maxMsToLive The time in milliseconds the system intends to keep the network
- * connected for graceful handover; note that the network may still
- * suffer a hard loss at any time.
- */
- public void onLosing(@NonNull Network network, int maxMsToLive) {}
-
- /**
- * Called when a network disconnects or otherwise no longer satisfies this request or
- * callback.
- *
- * <p>If the callback was registered with requestNetwork() or
- * registerDefaultNetworkCallback(), it will only be invoked against the last network
- * returned by onAvailable() when that network is lost and no other network satisfies
- * the criteria of the request.
- *
- * <p>If the callback was registered with registerNetworkCallback() it will be called for
- * each network which no longer satisfies the criteria of the callback.
- *
- * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or
- * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in
- * this callback as this is prone to race conditions ; calling these methods while in a
- * callback may return an outdated or even a null object.
- *
- * @param network The {@link Network} lost.
- */
- public void onLost(@NonNull Network network) {}
-
- /**
- * Called if no network is found within the timeout time specified in
- * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)} call or if the
- * requested network request cannot be fulfilled (whether or not a timeout was
- * specified). When this callback is invoked the associated
- * {@link NetworkRequest} will have already been removed and released, as if
- * {@link #unregisterNetworkCallback(NetworkCallback)} had been called.
- */
- public void onUnavailable() {}
-
- /**
- * Called when the network corresponding to this request changes capabilities but still
- * satisfies the requested criteria.
- *
- * <p>Starting with {@link android.os.Build.VERSION_CODES#O} this method is guaranteed
- * to be called immediately after {@link #onAvailable}.
- *
- * <p>Do NOT call {@link #getLinkProperties(Network)} or other synchronous
- * ConnectivityManager methods in this callback as this is prone to race conditions :
- * calling these methods while in a callback may return an outdated or even a null object.
- *
- * @param network The {@link Network} whose capabilities have changed.
- * @param networkCapabilities The new {@link NetworkCapabilities} for this
- * network.
- */
- public void onCapabilitiesChanged(@NonNull Network network,
- @NonNull NetworkCapabilities networkCapabilities) {}
-
- /**
- * Called when the network corresponding to this request changes {@link LinkProperties}.
- *
- * <p>Starting with {@link android.os.Build.VERSION_CODES#O} this method is guaranteed
- * to be called immediately after {@link #onAvailable}.
- *
- * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or other synchronous
- * ConnectivityManager methods in this callback as this is prone to race conditions :
- * calling these methods while in a callback may return an outdated or even a null object.
- *
- * @param network The {@link Network} whose link properties have changed.
- * @param linkProperties The new {@link LinkProperties} for this network.
- */
- public void onLinkPropertiesChanged(@NonNull Network network,
- @NonNull LinkProperties linkProperties) {}
-
- /**
- * Called when the network the framework connected to for this request suspends data
- * transmission temporarily.
- *
- * <p>This generally means that while the TCP connections are still live temporarily
- * network data fails to transfer. To give a specific example, this is used on cellular
- * networks to mask temporary outages when driving through a tunnel, etc. In general this
- * means read operations on sockets on this network will block once the buffers are
- * drained, and write operations will block once the buffers are full.
- *
- * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or
- * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in
- * this callback as this is prone to race conditions (there is no guarantee the objects
- * returned by these methods will be current).
- *
- * @hide
- */
- public void onNetworkSuspended(@NonNull Network network) {}
-
- /**
- * Called when the network the framework connected to for this request
- * returns from a {@link NetworkInfo.State#SUSPENDED} state. This should always be
- * preceded by a matching {@link NetworkCallback#onNetworkSuspended} call.
-
- * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or
- * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in
- * this callback as this is prone to race conditions : calling these methods while in a
- * callback may return an outdated or even a null object.
- *
- * @hide
- */
- public void onNetworkResumed(@NonNull Network network) {}
-
- /**
- * Called when access to the specified network is blocked or unblocked.
- *
- * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or
- * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in
- * this callback as this is prone to race conditions : calling these methods while in a
- * callback may return an outdated or even a null object.
- *
- * @param network The {@link Network} whose blocked status has changed.
- * @param blocked The blocked status of this {@link Network}.
- */
- public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {}
-
- /**
- * Called when access to the specified network is blocked or unblocked, or the reason for
- * access being blocked changes.
- *
- * If a NetworkCallback object implements this method,
- * {@link #onBlockedStatusChanged(Network, boolean)} will not be called.
- *
- * <p>Do NOT call {@link #getNetworkCapabilities(Network)} or
- * {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in
- * this callback as this is prone to race conditions : calling these methods while in a
- * callback may return an outdated or even a null object.
- *
- * @param network The {@link Network} whose blocked status has changed.
- * @param blocked The blocked status of this {@link Network}.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public void onBlockedStatusChanged(@NonNull Network network, @BlockedReason int blocked) {
- onBlockedStatusChanged(network, blocked != 0);
- }
-
- private NetworkRequest networkRequest;
- private final int mFlags;
- }
-
- /**
- * Constant error codes used by ConnectivityService to communicate about failures and errors
- * across a Binder boundary.
- * @hide
- */
- public interface Errors {
- int TOO_MANY_REQUESTS = 1;
- }
-
- /** @hide */
- public static class TooManyRequestsException extends RuntimeException {}
-
- private static RuntimeException convertServiceException(ServiceSpecificException e) {
- switch (e.errorCode) {
- case Errors.TOO_MANY_REQUESTS:
- return new TooManyRequestsException();
- default:
- Log.w(TAG, "Unknown service error code " + e.errorCode);
- return new RuntimeException(e);
- }
- }
-
- /** @hide */
- public static final int CALLBACK_PRECHECK = 1;
- /** @hide */
- public static final int CALLBACK_AVAILABLE = 2;
- /** @hide arg1 = TTL */
- public static final int CALLBACK_LOSING = 3;
- /** @hide */
- public static final int CALLBACK_LOST = 4;
- /** @hide */
- public static final int CALLBACK_UNAVAIL = 5;
- /** @hide */
- public static final int CALLBACK_CAP_CHANGED = 6;
- /** @hide */
- public static final int CALLBACK_IP_CHANGED = 7;
- /** @hide obj = NetworkCapabilities, arg1 = seq number */
- private static final int EXPIRE_LEGACY_REQUEST = 8;
- /** @hide */
- public static final int CALLBACK_SUSPENDED = 9;
- /** @hide */
- public static final int CALLBACK_RESUMED = 10;
- /** @hide */
- public static final int CALLBACK_BLK_CHANGED = 11;
-
- /** @hide */
- public static String getCallbackName(int whichCallback) {
- switch (whichCallback) {
- case CALLBACK_PRECHECK: return "CALLBACK_PRECHECK";
- case CALLBACK_AVAILABLE: return "CALLBACK_AVAILABLE";
- case CALLBACK_LOSING: return "CALLBACK_LOSING";
- case CALLBACK_LOST: return "CALLBACK_LOST";
- case CALLBACK_UNAVAIL: return "CALLBACK_UNAVAIL";
- case CALLBACK_CAP_CHANGED: return "CALLBACK_CAP_CHANGED";
- case CALLBACK_IP_CHANGED: return "CALLBACK_IP_CHANGED";
- case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST";
- case CALLBACK_SUSPENDED: return "CALLBACK_SUSPENDED";
- case CALLBACK_RESUMED: return "CALLBACK_RESUMED";
- case CALLBACK_BLK_CHANGED: return "CALLBACK_BLK_CHANGED";
- default:
- return Integer.toString(whichCallback);
- }
- }
-
- private class CallbackHandler extends Handler {
- private static final String TAG = "ConnectivityManager.CallbackHandler";
- private static final boolean DBG = false;
-
- CallbackHandler(Looper looper) {
- super(looper);
- }
-
- CallbackHandler(Handler handler) {
- this(Objects.requireNonNull(handler, "Handler cannot be null.").getLooper());
- }
-
- @Override
- public void handleMessage(Message message) {
- if (message.what == EXPIRE_LEGACY_REQUEST) {
- expireRequest((NetworkCapabilities) message.obj, message.arg1);
- return;
- }
-
- final NetworkRequest request = getObject(message, NetworkRequest.class);
- final Network network = getObject(message, Network.class);
- final NetworkCallback callback;
- synchronized (sCallbacks) {
- callback = sCallbacks.get(request);
- if (callback == null) {
- Log.w(TAG,
- "callback not found for " + getCallbackName(message.what) + " message");
- return;
- }
- if (message.what == CALLBACK_UNAVAIL) {
- sCallbacks.remove(request);
- callback.networkRequest = ALREADY_UNREGISTERED;
- }
- }
- if (DBG) {
- Log.d(TAG, getCallbackName(message.what) + " for network " + network);
- }
-
- switch (message.what) {
- case CALLBACK_PRECHECK: {
- callback.onPreCheck(network);
- break;
- }
- case CALLBACK_AVAILABLE: {
- NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
- LinkProperties lp = getObject(message, LinkProperties.class);
- callback.onAvailable(network, cap, lp, message.arg1);
- break;
- }
- case CALLBACK_LOSING: {
- callback.onLosing(network, message.arg1);
- break;
- }
- case CALLBACK_LOST: {
- callback.onLost(network);
- break;
- }
- case CALLBACK_UNAVAIL: {
- callback.onUnavailable();
- break;
- }
- case CALLBACK_CAP_CHANGED: {
- NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
- callback.onCapabilitiesChanged(network, cap);
- break;
- }
- case CALLBACK_IP_CHANGED: {
- LinkProperties lp = getObject(message, LinkProperties.class);
- callback.onLinkPropertiesChanged(network, lp);
- break;
- }
- case CALLBACK_SUSPENDED: {
- callback.onNetworkSuspended(network);
- break;
- }
- case CALLBACK_RESUMED: {
- callback.onNetworkResumed(network);
- break;
- }
- case CALLBACK_BLK_CHANGED: {
- callback.onBlockedStatusChanged(network, message.arg1);
- }
- }
- }
-
- private <T> T getObject(Message msg, Class<T> c) {
- return (T) msg.getData().getParcelable(c.getSimpleName());
- }
- }
-
- private CallbackHandler getDefaultHandler() {
- synchronized (sCallbacks) {
- if (sCallbackHandler == null) {
- sCallbackHandler = new CallbackHandler(ConnectivityThread.getInstanceLooper());
- }
- return sCallbackHandler;
- }
- }
-
- private static final HashMap<NetworkRequest, NetworkCallback> sCallbacks = new HashMap<>();
- private static CallbackHandler sCallbackHandler;
-
- private NetworkRequest sendRequestForNetwork(int asUid, NetworkCapabilities need,
- NetworkCallback callback, int timeoutMs, NetworkRequest.Type reqType, int legacyType,
- CallbackHandler handler) {
- printStackTrace();
- checkCallbackNotNull(callback);
- if (reqType != TRACK_DEFAULT && reqType != TRACK_SYSTEM_DEFAULT && need == null) {
- throw new IllegalArgumentException("null NetworkCapabilities");
- }
- final NetworkRequest request;
- final String callingPackageName = mContext.getOpPackageName();
- try {
- synchronized(sCallbacks) {
- if (callback.networkRequest != null
- && callback.networkRequest != ALREADY_UNREGISTERED) {
- // TODO: throw exception instead and enforce 1:1 mapping of callbacks
- // and requests (http://b/20701525).
- Log.e(TAG, "NetworkCallback was already registered");
- }
- Messenger messenger = new Messenger(handler);
- Binder binder = new Binder();
- final int callbackFlags = callback.mFlags;
- if (reqType == LISTEN) {
- request = mService.listenForNetwork(
- need, messenger, binder, callbackFlags, callingPackageName,
- getAttributionTag());
- } else {
- request = mService.requestNetwork(
- asUid, need, reqType.ordinal(), messenger, timeoutMs, binder,
- legacyType, callbackFlags, callingPackageName, getAttributionTag());
- }
- if (request != null) {
- sCallbacks.put(request, callback);
- }
- callback.networkRequest = request;
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- } catch (ServiceSpecificException e) {
- throw convertServiceException(e);
- }
- return request;
- }
-
- private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, NetworkCallback callback,
- int timeoutMs, NetworkRequest.Type reqType, int legacyType, CallbackHandler handler) {
- return sendRequestForNetwork(Process.INVALID_UID, need, callback, timeoutMs, reqType,
- legacyType, handler);
- }
-
- /**
- * Helper function to request a network with a particular legacy type.
- *
- * This API is only for use in internal system code that requests networks with legacy type and
- * relies on CONNECTIVITY_ACTION broadcasts instead of NetworkCallbacks. New caller should use
- * {@link #requestNetwork(NetworkRequest, NetworkCallback, Handler)} instead.
- *
- * @param request {@link NetworkRequest} describing this request.
- * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
- * before {@link NetworkCallback#onUnavailable()} is called. The timeout must
- * be a positive value (i.e. >0).
- * @param legacyType to specify the network type(#TYPE_*).
- * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
- * the callback must not be shared - it uniquely specifies this request.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
- public void requestNetwork(@NonNull NetworkRequest request,
- int timeoutMs, int legacyType, @NonNull Handler handler,
- @NonNull NetworkCallback networkCallback) {
- if (legacyType == TYPE_NONE) {
- throw new IllegalArgumentException("TYPE_NONE is meaningless legacy type");
- }
- CallbackHandler cbHandler = new CallbackHandler(handler);
- NetworkCapabilities nc = request.networkCapabilities;
- sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, legacyType, cbHandler);
- }
-
- /**
- * Request a network to satisfy a set of {@link NetworkCapabilities}.
- *
- * <p>This method will attempt to find the best network that matches the passed
- * {@link NetworkRequest}, and to bring up one that does if none currently satisfies the
- * criteria. The platform will evaluate which network is the best at its own discretion.
- * Throughput, latency, cost per byte, policy, user preference and other considerations
- * may be factored in the decision of what is considered the best network.
- *
- * <p>As long as this request is outstanding, the platform will try to maintain the best network
- * matching this request, while always attempting to match the request to a better network if
- * possible. If a better match is found, the platform will switch this request to the now-best
- * network and inform the app of the newly best network by invoking
- * {@link NetworkCallback#onAvailable(Network)} on the provided callback. Note that the platform
- * will not try to maintain any other network than the best one currently matching the request:
- * a network not matching any network request may be disconnected at any time.
- *
- * <p>For example, an application could use this method to obtain a connected cellular network
- * even if the device currently has a data connection over Ethernet. This may cause the cellular
- * radio to consume additional power. Or, an application could inform the system that it wants
- * a network supporting sending MMSes and have the system let it know about the currently best
- * MMS-supporting network through the provided {@link NetworkCallback}.
- *
- * <p>The status of the request can be followed by listening to the various callbacks described
- * in {@link NetworkCallback}. The {@link Network} object passed to the callback methods can be
- * used to direct traffic to the network (although accessing some networks may be subject to
- * holding specific permissions). Callers will learn about the specific characteristics of the
- * network through
- * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)} and
- * {@link NetworkCallback#onLinkPropertiesChanged(Network, LinkProperties)}. The methods of the
- * provided {@link NetworkCallback} will only be invoked due to changes in the best network
- * matching the request at any given time; therefore when a better network matching the request
- * becomes available, the {@link NetworkCallback#onAvailable(Network)} method is called
- * with the new network after which no further updates are given about the previously-best
- * network, unless it becomes the best again at some later time. All callbacks are invoked
- * in order on the same thread, which by default is a thread created by the framework running
- * in the app.
- * {@see #requestNetwork(NetworkRequest, NetworkCallback, Handler)} to change where the
- * callbacks are invoked.
- *
- * <p>This{@link NetworkRequest} will live until released via
- * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits, at
- * which point the system may let go of the network at any time.
- *
- * <p>A version of this method which takes a timeout is
- * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)}, that an app can use to only
- * wait for a limited amount of time for the network to become unavailable.
- *
- * <p>It is presently unsupported to request a network with mutable
- * {@link NetworkCapabilities} such as
- * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
- * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
- * as these {@code NetworkCapabilities} represent states that a particular
- * network may never attain, and whether a network will attain these states
- * is unknown prior to bringing up the network so the framework does not
- * know how to go about satisfying a request with these capabilities.
- *
- * <p>This method requires the caller to hold either the
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
- * or the ability to modify system settings as determined by
- * {@link android.provider.Settings.System#canWrite}.</p>
- *
- * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
- * number of outstanding requests to 100 per app (identified by their UID), shared with
- * all variants of this method, of {@link #registerNetworkCallback} as well as
- * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}.
- * Requesting a network with this method will count toward this limit. If this limit is
- * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources,
- * make sure to unregister the callbacks with
- * {@link #unregisterNetworkCallback(NetworkCallback)}.
- *
- * @param request {@link NetworkRequest} describing this request.
- * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
- * the callback must not be shared - it uniquely specifies this request.
- * The callback is invoked on the default internal Handler.
- * @throws IllegalArgumentException if {@code request} contains invalid network capabilities.
- * @throws SecurityException if missing the appropriate permissions.
- * @throws RuntimeException if the app already has too many callbacks registered.
- */
- public void requestNetwork(@NonNull NetworkRequest request,
- @NonNull NetworkCallback networkCallback) {
- requestNetwork(request, networkCallback, getDefaultHandler());
- }
-
- /**
- * Request a network to satisfy a set of {@link NetworkCapabilities}.
- *
- * This method behaves identically to {@link #requestNetwork(NetworkRequest, NetworkCallback)}
- * but runs all the callbacks on the passed Handler.
- *
- * <p>This method has the same permission requirements as
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, is subject to the same limitations,
- * and throws the same exceptions in the same conditions.
- *
- * @param request {@link NetworkRequest} describing this request.
- * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
- * the callback must not be shared - it uniquely specifies this request.
- * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- */
- public void requestNetwork(@NonNull NetworkRequest request,
- @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {
- CallbackHandler cbHandler = new CallbackHandler(handler);
- NetworkCapabilities nc = request.networkCapabilities;
- sendRequestForNetwork(nc, networkCallback, 0, REQUEST, TYPE_NONE, cbHandler);
- }
-
- /**
- * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
- * by a timeout.
- *
- * This function behaves identically to the non-timed-out version
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, but if a suitable network
- * is not found within the given time (in milliseconds) the
- * {@link NetworkCallback#onUnavailable()} callback is called. The request can still be
- * released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)} but does
- * not have to be released if timed-out (it is automatically released). Unregistering a
- * request that timed out is not an error.
- *
- * <p>Do not use this method to poll for the existence of specific networks (e.g. with a small
- * timeout) - {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} is provided
- * for that purpose. Calling this method will attempt to bring up the requested network.
- *
- * <p>This method has the same permission requirements as
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, is subject to the same limitations,
- * and throws the same exceptions in the same conditions.
- *
- * @param request {@link NetworkRequest} describing this request.
- * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
- * the callback must not be shared - it uniquely specifies this request.
- * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
- * before {@link NetworkCallback#onUnavailable()} is called. The timeout must
- * be a positive value (i.e. >0).
- */
- public void requestNetwork(@NonNull NetworkRequest request,
- @NonNull NetworkCallback networkCallback, int timeoutMs) {
- checkTimeout(timeoutMs);
- NetworkCapabilities nc = request.networkCapabilities;
- sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, TYPE_NONE,
- getDefaultHandler());
- }
-
- /**
- * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
- * by a timeout.
- *
- * This method behaves identically to
- * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)} but runs all the callbacks
- * on the passed Handler.
- *
- * <p>This method has the same permission requirements as
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, is subject to the same limitations,
- * and throws the same exceptions in the same conditions.
- *
- * @param request {@link NetworkRequest} describing this request.
- * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
- * the callback must not be shared - it uniquely specifies this request.
- * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
- * before {@link NetworkCallback#onUnavailable} is called.
- */
- public void requestNetwork(@NonNull NetworkRequest request,
- @NonNull NetworkCallback networkCallback, @NonNull Handler handler, int timeoutMs) {
- checkTimeout(timeoutMs);
- CallbackHandler cbHandler = new CallbackHandler(handler);
- NetworkCapabilities nc = request.networkCapabilities;
- sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, TYPE_NONE, cbHandler);
- }
-
- /**
- * The lookup key for a {@link Network} object included with the intent after
- * successfully finding a network for the applications request. Retrieve it with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- * <p>
- * Note that if you intend to invoke {@link Network#openConnection(java.net.URL)}
- * then you must get a ConnectivityManager instance before doing so.
- */
- public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
-
- /**
- * The lookup key for a {@link NetworkRequest} object included with the intent after
- * successfully finding a network for the applications request. Retrieve it with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- */
- public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
-
-
- /**
- * Request a network to satisfy a set of {@link NetworkCapabilities}.
- *
- * This function behaves identically to the version that takes a NetworkCallback, but instead
- * of {@link NetworkCallback} a {@link PendingIntent} is used. This means
- * the request may outlive the calling application and get called back when a suitable
- * network is found.
- * <p>
- * The operation is an Intent broadcast that goes to a broadcast receiver that
- * you registered with {@link Context#registerReceiver} or through the
- * <receiver> tag in an AndroidManifest.xml file
- * <p>
- * The operation Intent is delivered with two extras, a {@link Network} typed
- * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest}
- * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing
- * the original requests parameters. It is important to create a new,
- * {@link NetworkCallback} based request before completing the processing of the
- * Intent to reserve the network or it will be released shortly after the Intent
- * is processed.
- * <p>
- * If there is already a request for this Intent registered (with the equality of
- * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
- * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
- * <p>
- * The request may be released normally by calling
- * {@link #releaseNetworkRequest(android.app.PendingIntent)}.
- * <p>It is presently unsupported to request a network with either
- * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
- * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
- * as these {@code NetworkCapabilities} represent states that a particular
- * network may never attain, and whether a network will attain these states
- * is unknown prior to bringing up the network so the framework does not
- * know how to go about satisfying a request with these capabilities.
- *
- * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
- * number of outstanding requests to 100 per app (identified by their UID), shared with
- * all variants of this method, of {@link #registerNetworkCallback} as well as
- * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}.
- * Requesting a network with this method will count toward this limit. If this limit is
- * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources,
- * make sure to unregister the callbacks with {@link #unregisterNetworkCallback(PendingIntent)}
- * or {@link #releaseNetworkRequest(PendingIntent)}.
- *
- * <p>This method requires the caller to hold either the
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
- * or the ability to modify system settings as determined by
- * {@link android.provider.Settings.System#canWrite}.</p>
- *
- * @param request {@link NetworkRequest} describing this request.
- * @param operation Action to perform when the network is available (corresponds
- * to the {@link NetworkCallback#onAvailable} call. Typically
- * comes from {@link PendingIntent#getBroadcast}. Cannot be null.
- * @throws IllegalArgumentException if {@code request} contains invalid network capabilities.
- * @throws SecurityException if missing the appropriate permissions.
- * @throws RuntimeException if the app already has too many callbacks registered.
- */
- public void requestNetwork(@NonNull NetworkRequest request,
- @NonNull PendingIntent operation) {
- printStackTrace();
- checkPendingIntentNotNull(operation);
- try {
- mService.pendingRequestForNetwork(
- request.networkCapabilities, operation, mContext.getOpPackageName(),
- getAttributionTag());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- } catch (ServiceSpecificException e) {
- throw convertServiceException(e);
- }
- }
-
- /**
- * Removes a request made via {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)}
- * <p>
- * This method has the same behavior as
- * {@link #unregisterNetworkCallback(android.app.PendingIntent)} with respect to
- * releasing network resources and disconnecting.
- *
- * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the
- * PendingIntent passed to
- * {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)} with the
- * corresponding NetworkRequest you'd like to remove. Cannot be null.
- */
- public void releaseNetworkRequest(@NonNull PendingIntent operation) {
- printStackTrace();
- checkPendingIntentNotNull(operation);
- try {
- mService.releasePendingNetworkRequest(operation);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- private static void checkPendingIntentNotNull(PendingIntent intent) {
- Objects.requireNonNull(intent, "PendingIntent cannot be null.");
- }
-
- private static void checkCallbackNotNull(NetworkCallback callback) {
- Objects.requireNonNull(callback, "null NetworkCallback");
- }
-
- private static void checkTimeout(int timeoutMs) {
- if (timeoutMs <= 0) {
- throw new IllegalArgumentException("timeoutMs must be strictly positive.");
- }
- }
-
- /**
- * Registers to receive notifications about all networks which satisfy the given
- * {@link NetworkRequest}. The callbacks will continue to be called until
- * either the application exits or {@link #unregisterNetworkCallback(NetworkCallback)} is
- * called.
- *
- * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
- * number of outstanding requests to 100 per app (identified by their UID), shared with
- * all variants of this method, of {@link #requestNetwork} as well as
- * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}.
- * Requesting a network with this method will count toward this limit. If this limit is
- * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources,
- * make sure to unregister the callbacks with
- * {@link #unregisterNetworkCallback(NetworkCallback)}.
- *
- * @param request {@link NetworkRequest} describing this request.
- * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
- * networks change state.
- * The callback is invoked on the default internal Handler.
- * @throws RuntimeException if the app already has too many callbacks registered.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- public void registerNetworkCallback(@NonNull NetworkRequest request,
- @NonNull NetworkCallback networkCallback) {
- registerNetworkCallback(request, networkCallback, getDefaultHandler());
- }
-
- /**
- * Registers to receive notifications about all networks which satisfy the given
- * {@link NetworkRequest}. The callbacks will continue to be called until
- * either the application exits or {@link #unregisterNetworkCallback(NetworkCallback)} is
- * called.
- *
- * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
- * number of outstanding requests to 100 per app (identified by their UID), shared with
- * all variants of this method, of {@link #requestNetwork} as well as
- * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}.
- * Requesting a network with this method will count toward this limit. If this limit is
- * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources,
- * make sure to unregister the callbacks with
- * {@link #unregisterNetworkCallback(NetworkCallback)}.
- *
- *
- * @param request {@link NetworkRequest} describing this request.
- * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
- * networks change state.
- * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- * @throws RuntimeException if the app already has too many callbacks registered.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- public void registerNetworkCallback(@NonNull NetworkRequest request,
- @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {
- CallbackHandler cbHandler = new CallbackHandler(handler);
- NetworkCapabilities nc = request.networkCapabilities;
- sendRequestForNetwork(nc, networkCallback, 0, LISTEN, TYPE_NONE, cbHandler);
- }
-
- /**
- * Registers a PendingIntent to be sent when a network is available which satisfies the given
- * {@link NetworkRequest}.
- *
- * This function behaves identically to the version that takes a NetworkCallback, but instead
- * of {@link NetworkCallback} a {@link PendingIntent} is used. This means
- * the request may outlive the calling application and get called back when a suitable
- * network is found.
- * <p>
- * The operation is an Intent broadcast that goes to a broadcast receiver that
- * you registered with {@link Context#registerReceiver} or through the
- * <receiver> tag in an AndroidManifest.xml file
- * <p>
- * The operation Intent is delivered with two extras, a {@link Network} typed
- * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest}
- * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing
- * the original requests parameters.
- * <p>
- * If there is already a request for this Intent registered (with the equality of
- * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
- * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
- * <p>
- * The request may be released normally by calling
- * {@link #unregisterNetworkCallback(android.app.PendingIntent)}.
- *
- * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
- * number of outstanding requests to 100 per app (identified by their UID), shared with
- * all variants of this method, of {@link #requestNetwork} as well as
- * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}.
- * Requesting a network with this method will count toward this limit. If this limit is
- * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources,
- * make sure to unregister the callbacks with {@link #unregisterNetworkCallback(PendingIntent)}
- * or {@link #releaseNetworkRequest(PendingIntent)}.
- *
- * @param request {@link NetworkRequest} describing this request.
- * @param operation Action to perform when the network is available (corresponds
- * to the {@link NetworkCallback#onAvailable} call. Typically
- * comes from {@link PendingIntent#getBroadcast}. Cannot be null.
- * @throws RuntimeException if the app already has too many callbacks registered.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- public void registerNetworkCallback(@NonNull NetworkRequest request,
- @NonNull PendingIntent operation) {
- printStackTrace();
- checkPendingIntentNotNull(operation);
- try {
- mService.pendingListenForNetwork(
- request.networkCapabilities, operation, mContext.getOpPackageName(),
- getAttributionTag());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- } catch (ServiceSpecificException e) {
- throw convertServiceException(e);
- }
- }
-
- /**
- * Registers to receive notifications about changes in the application's default network. This
- * may be a physical network or a virtual network, such as a VPN that applies to the
- * application. The callbacks will continue to be called until either the application exits or
- * {@link #unregisterNetworkCallback(NetworkCallback)} is called.
- *
- * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
- * number of outstanding requests to 100 per app (identified by their UID), shared with
- * all variants of this method, of {@link #requestNetwork} as well as
- * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}.
- * Requesting a network with this method will count toward this limit. If this limit is
- * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources,
- * make sure to unregister the callbacks with
- * {@link #unregisterNetworkCallback(NetworkCallback)}.
- *
- * @param networkCallback The {@link NetworkCallback} that the system will call as the
- * application's default network changes.
- * The callback is invoked on the default internal Handler.
- * @throws RuntimeException if the app already has too many callbacks registered.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback) {
- registerDefaultNetworkCallback(networkCallback, getDefaultHandler());
- }
-
- /**
- * Registers to receive notifications about changes in the application's default network. This
- * may be a physical network or a virtual network, such as a VPN that applies to the
- * application. The callbacks will continue to be called until either the application exits or
- * {@link #unregisterNetworkCallback(NetworkCallback)} is called.
- *
- * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
- * number of outstanding requests to 100 per app (identified by their UID), shared with
- * all variants of this method, of {@link #requestNetwork} as well as
- * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}.
- * Requesting a network with this method will count toward this limit. If this limit is
- * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources,
- * make sure to unregister the callbacks with
- * {@link #unregisterNetworkCallback(NetworkCallback)}.
- *
- * @param networkCallback The {@link NetworkCallback} that the system will call as the
- * application's default network changes.
- * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- * @throws RuntimeException if the app already has too many callbacks registered.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback,
- @NonNull Handler handler) {
- registerDefaultNetworkCallbackForUid(Process.INVALID_UID, networkCallback, handler);
- }
-
- /**
- * Registers to receive notifications about changes in the default network for the specified
- * UID. This may be a physical network or a virtual network, such as a VPN that applies to the
- * UID. The callbacks will continue to be called until either the application exits or
- * {@link #unregisterNetworkCallback(NetworkCallback)} is called.
- *
- * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
- * number of outstanding requests to 100 per app (identified by their UID), shared with
- * all variants of this method, of {@link #requestNetwork} as well as
- * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}.
- * Requesting a network with this method will count toward this limit. If this limit is
- * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources,
- * make sure to unregister the callbacks with
- * {@link #unregisterNetworkCallback(NetworkCallback)}.
- *
- * @param uid the UID for which to track default network changes.
- * @param networkCallback The {@link NetworkCallback} that the system will call as the
- * UID's default network changes.
- * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- * @throws RuntimeException if the app already has too many callbacks registered.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @SuppressLint({"ExecutorRegistration", "PairedRegistration"})
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_SETTINGS})
- public void registerDefaultNetworkCallbackForUid(int uid,
- @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {
- CallbackHandler cbHandler = new CallbackHandler(handler);
- sendRequestForNetwork(uid, null /* need */, networkCallback, 0 /* timeoutMs */,
- TRACK_DEFAULT, TYPE_NONE, cbHandler);
- }
-
- /**
- * Registers to receive notifications about changes in the system default network. The callbacks
- * will continue to be called until either the application exits or
- * {@link #unregisterNetworkCallback(NetworkCallback)} is called.
- *
- * This method should not be used to determine networking state seen by applications, because in
- * many cases, most or even all application traffic may not use the default network directly,
- * and traffic from different applications may go on different networks by default. As an
- * example, if a VPN is connected, traffic from all applications might be sent through the VPN
- * and not onto the system default network. Applications or system components desiring to do
- * determine network state as seen by applications should use other methods such as
- * {@link #registerDefaultNetworkCallback(NetworkCallback, Handler)}.
- *
- * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
- * number of outstanding requests to 100 per app (identified by their UID), shared with
- * all variants of this method, of {@link #requestNetwork} as well as
- * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}.
- * Requesting a network with this method will count toward this limit. If this limit is
- * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources,
- * make sure to unregister the callbacks with
- * {@link #unregisterNetworkCallback(NetworkCallback)}.
- *
- * @param networkCallback The {@link NetworkCallback} that the system will call as the
- * system default network changes.
- * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- * @throws RuntimeException if the app already has too many callbacks registered.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @SuppressLint({"ExecutorRegistration", "PairedRegistration"})
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_SETTINGS})
- public void registerSystemDefaultNetworkCallback(@NonNull NetworkCallback networkCallback,
- @NonNull Handler handler) {
- CallbackHandler cbHandler = new CallbackHandler(handler);
- sendRequestForNetwork(null /* NetworkCapabilities need */, networkCallback, 0,
- TRACK_SYSTEM_DEFAULT, TYPE_NONE, cbHandler);
- }
-
- /**
- * Registers to receive notifications about the best matching network which satisfy the given
- * {@link NetworkRequest}. The callbacks will continue to be called until
- * either the application exits or {@link #unregisterNetworkCallback(NetworkCallback)} is
- * called.
- *
- * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
- * number of outstanding requests to 100 per app (identified by their UID), shared with
- * {@link #registerNetworkCallback} and its variants and {@link #requestNetwork} as well as
- * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}.
- * Requesting a network with this method will count toward this limit. If this limit is
- * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources,
- * make sure to unregister the callbacks with
- * {@link #unregisterNetworkCallback(NetworkCallback)}.
- *
- *
- * @param request {@link NetworkRequest} describing this request.
- * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
- * networks change state.
- * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- * @throws RuntimeException if the app already has too many callbacks registered.
- */
- @SuppressLint("ExecutorRegistration")
- public void registerBestMatchingNetworkCallback(@NonNull NetworkRequest request,
- @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {
- final NetworkCapabilities nc = request.networkCapabilities;
- final CallbackHandler cbHandler = new CallbackHandler(handler);
- sendRequestForNetwork(nc, networkCallback, 0, LISTEN_FOR_BEST, TYPE_NONE, cbHandler);
- }
-
- /**
- * Requests bandwidth update for a given {@link Network} and returns whether the update request
- * is accepted by ConnectivityService. Once accepted, ConnectivityService will poll underlying
- * network connection for updated bandwidth information. The caller will be notified via
- * {@link ConnectivityManager.NetworkCallback} if there is an update. Notice that this
- * method assumes that the caller has previously called
- * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} to listen for network
- * changes.
- *
- * @param network {@link Network} specifying which network you're interested.
- * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
- */
- public boolean requestBandwidthUpdate(@NonNull Network network) {
- try {
- return mService.requestBandwidthUpdate(network);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Unregisters a {@code NetworkCallback} and possibly releases networks originating from
- * {@link #requestNetwork(NetworkRequest, NetworkCallback)} and
- * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} calls.
- * If the given {@code NetworkCallback} had previously been used with
- * {@code #requestNetwork}, any networks that had been connected to only to satisfy that request
- * will be disconnected.
- *
- * Notifications that would have triggered that {@code NetworkCallback} will immediately stop
- * triggering it as soon as this call returns.
- *
- * @param networkCallback The {@link NetworkCallback} used when making the request.
- */
- public void unregisterNetworkCallback(@NonNull NetworkCallback networkCallback) {
- printStackTrace();
- checkCallbackNotNull(networkCallback);
- final List<NetworkRequest> reqs = new ArrayList<>();
- // Find all requests associated to this callback and stop callback triggers immediately.
- // Callback is reusable immediately. http://b/20701525, http://b/35921499.
- synchronized (sCallbacks) {
- if (networkCallback.networkRequest == null) {
- throw new IllegalArgumentException("NetworkCallback was not registered");
- }
- if (networkCallback.networkRequest == ALREADY_UNREGISTERED) {
- Log.d(TAG, "NetworkCallback was already unregistered");
- return;
- }
- for (Map.Entry<NetworkRequest, NetworkCallback> e : sCallbacks.entrySet()) {
- if (e.getValue() == networkCallback) {
- reqs.add(e.getKey());
- }
- }
- // TODO: throw exception if callback was registered more than once (http://b/20701525).
- for (NetworkRequest r : reqs) {
- try {
- mService.releaseNetworkRequest(r);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- // Only remove mapping if rpc was successful.
- sCallbacks.remove(r);
- }
- networkCallback.networkRequest = ALREADY_UNREGISTERED;
- }
- }
-
- /**
- * Unregisters a callback previously registered via
- * {@link #registerNetworkCallback(NetworkRequest, android.app.PendingIntent)}.
- *
- * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the
- * PendingIntent passed to
- * {@link #registerNetworkCallback(NetworkRequest, android.app.PendingIntent)}.
- * Cannot be null.
- */
- public void unregisterNetworkCallback(@NonNull PendingIntent operation) {
- releaseNetworkRequest(operation);
- }
-
- /**
- * Informs the system whether it should switch to {@code network} regardless of whether it is
- * validated or not. If {@code accept} is true, and the network was explicitly selected by the
- * user (e.g., by selecting a Wi-Fi network in the Settings app), then the network will become
- * the system default network regardless of any other network that's currently connected. If
- * {@code always} is true, then the choice is remembered, so that the next time the user
- * connects to this network, the system will switch to it.
- *
- * @param network The network to accept.
- * @param accept Whether to accept the network even if unvalidated.
- * @param always Whether to remember this choice in the future.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD,
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
- public void setAcceptUnvalidated(@NonNull Network network, boolean accept, boolean always) {
- try {
- mService.setAcceptUnvalidated(network, accept, always);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Informs the system whether it should consider the network as validated even if it only has
- * partial connectivity. If {@code accept} is true, then the network will be considered as
- * validated even if connectivity is only partial. If {@code always} is true, then the choice
- * is remembered, so that the next time the user connects to this network, the system will
- * switch to it.
- *
- * @param network The network to accept.
- * @param accept Whether to consider the network as validated even if it has partial
- * connectivity.
- * @param always Whether to remember this choice in the future.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD,
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
- public void setAcceptPartialConnectivity(@NonNull Network network, boolean accept,
- boolean always) {
- try {
- mService.setAcceptPartialConnectivity(network, accept, always);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Informs the system to penalize {@code network}'s score when it becomes unvalidated. This is
- * only meaningful if the system is configured not to penalize such networks, e.g., if the
- * {@code config_networkAvoidBadWifi} configuration variable is set to 0 and the {@code
- * NETWORK_AVOID_BAD_WIFI setting is unset}.
- *
- * @param network The network to accept.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD,
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
- public void setAvoidUnvalidated(@NonNull Network network) {
- try {
- mService.setAvoidUnvalidated(network);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Requests that the system open the captive portal app on the specified network.
- *
- * <p>This is to be used on networks where a captive portal was detected, as per
- * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}.
- *
- * @param network The network to log into.
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
- })
- public void startCaptivePortalApp(@NonNull Network network) {
- try {
- mService.startCaptivePortalApp(network);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Requests that the system open the captive portal app with the specified extras.
- *
- * <p>This endpoint is exclusively for use by the NetworkStack and is protected by the
- * corresponding permission.
- * @param network Network on which the captive portal was detected.
- * @param appExtras Extras to include in the app start intent.
- * @hide
- */
- @SystemApi
- @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
- public void startCaptivePortalApp(@NonNull Network network, @NonNull Bundle appExtras) {
- try {
- mService.startCaptivePortalAppInternal(network, appExtras);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Determine whether the device is configured to avoid bad wifi.
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK})
- public boolean shouldAvoidBadWifi() {
- try {
- return mService.shouldAvoidBadWifi();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * It is acceptable to briefly use multipath data to provide seamless connectivity for
- * time-sensitive user-facing operations when the system default network is temporarily
- * unresponsive. The amount of data should be limited (less than one megabyte for every call to
- * this method), and the operation should be infrequent to ensure that data usage is limited.
- *
- * An example of such an operation might be a time-sensitive foreground activity, such as a
- * voice command, that the user is performing while walking out of range of a Wi-Fi network.
- */
- public static final int MULTIPATH_PREFERENCE_HANDOVER = 1 << 0;
-
- /**
- * It is acceptable to use small amounts of multipath data on an ongoing basis to provide
- * a backup channel for traffic that is primarily going over another network.
- *
- * An example might be maintaining backup connections to peers or servers for the purpose of
- * fast fallback if the default network is temporarily unresponsive or disconnects. The traffic
- * on backup paths should be negligible compared to the traffic on the main path.
- */
- public static final int MULTIPATH_PREFERENCE_RELIABILITY = 1 << 1;
-
- /**
- * It is acceptable to use metered data to improve network latency and performance.
- */
- public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 1 << 2;
-
- /**
- * Return value to use for unmetered networks. On such networks we currently set all the flags
- * to true.
- * @hide
- */
- public static final int MULTIPATH_PREFERENCE_UNMETERED =
- MULTIPATH_PREFERENCE_HANDOVER |
- MULTIPATH_PREFERENCE_RELIABILITY |
- MULTIPATH_PREFERENCE_PERFORMANCE;
-
- /**
- * Provides a hint to the calling application on whether it is desirable to use the
- * multinetwork APIs (e.g., {@link Network#openConnection}, {@link Network#bindSocket}, etc.)
- * for multipath data transfer on this network when it is not the system default network.
- * Applications desiring to use multipath network protocols should call this method before
- * each such operation.
- *
- * @param network The network on which the application desires to use multipath data.
- * If {@code null}, this method will return the a preference that will generally
- * apply to metered networks.
- * @return a bitwise OR of zero or more of the {@code MULTIPATH_PREFERENCE_*} constants.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- public @MultipathPreference int getMultipathPreference(@Nullable Network network) {
- try {
- return mService.getMultipathPreference(network);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Resets all connectivity manager settings back to factory defaults.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
- public void factoryReset() {
- try {
- mService.factoryReset();
- mTetheringManager.stopAllTethering();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Binds the current process to {@code network}. All Sockets created in the future
- * (and not explicitly bound via a bound SocketFactory from
- * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
- * {@code network}. All host name resolutions will be limited to {@code network} as well.
- * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
- * work and all host name resolutions will fail. This is by design so an application doesn't
- * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
- * To clear binding pass {@code null} for {@code network}. Using individually bound
- * Sockets created by Network.getSocketFactory().createSocket() and
- * performing network-specific host name resolutions via
- * {@link Network#getAllByName Network.getAllByName} is preferred to calling
- * {@code bindProcessToNetwork}.
- *
- * @param network The {@link Network} to bind the current process to, or {@code null} to clear
- * the current binding.
- * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
- */
- public boolean bindProcessToNetwork(@Nullable Network network) {
- // Forcing callers to call through non-static function ensures ConnectivityManager
- // instantiated.
- return setProcessDefaultNetwork(network);
- }
-
- /**
- * Binds the current process to {@code network}. All Sockets created in the future
- * (and not explicitly bound via a bound SocketFactory from
- * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
- * {@code network}. All host name resolutions will be limited to {@code network} as well.
- * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
- * work and all host name resolutions will fail. This is by design so an application doesn't
- * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
- * To clear binding pass {@code null} for {@code network}. Using individually bound
- * Sockets created by Network.getSocketFactory().createSocket() and
- * performing network-specific host name resolutions via
- * {@link Network#getAllByName Network.getAllByName} is preferred to calling
- * {@code setProcessDefaultNetwork}.
- *
- * @param network The {@link Network} to bind the current process to, or {@code null} to clear
- * the current binding.
- * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
- * @deprecated This function can throw {@link IllegalStateException}. Use
- * {@link #bindProcessToNetwork} instead. {@code bindProcessToNetwork}
- * is a direct replacement.
- */
- @Deprecated
- public static boolean setProcessDefaultNetwork(@Nullable Network network) {
- int netId = (network == null) ? NETID_UNSET : network.netId;
- boolean isSameNetId = (netId == NetworkUtils.getBoundNetworkForProcess());
-
- if (netId != NETID_UNSET) {
- netId = network.getNetIdForResolv();
- }
-
- if (!NetworkUtils.bindProcessToNetwork(netId)) {
- return false;
- }
-
- if (!isSameNetId) {
- // Set HTTP proxy system properties to match network.
- // TODO: Deprecate this static method and replace it with a non-static version.
- try {
- Proxy.setHttpProxyConfiguration(getInstance().getDefaultProxy());
- } catch (SecurityException e) {
- // The process doesn't have ACCESS_NETWORK_STATE, so we can't fetch the proxy.
- Log.e(TAG, "Can't set proxy properties", e);
- }
- // Must flush DNS cache as new network may have different DNS resolutions.
- InetAddressCompat.clearDnsCache();
- // Must flush socket pool as idle sockets will be bound to previous network and may
- // cause subsequent fetches to be performed on old network.
- NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
- }
-
- return true;
- }
-
- /**
- * Returns the {@link Network} currently bound to this process via
- * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
- *
- * @return {@code Network} to which this process is bound, or {@code null}.
- */
- @Nullable
- public Network getBoundNetworkForProcess() {
- // Forcing callers to call thru non-static function ensures ConnectivityManager
- // instantiated.
- return getProcessDefaultNetwork();
- }
-
- /**
- * Returns the {@link Network} currently bound to this process via
- * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
- *
- * @return {@code Network} to which this process is bound, or {@code null}.
- * @deprecated Using this function can lead to other functions throwing
- * {@link IllegalStateException}. Use {@link #getBoundNetworkForProcess} instead.
- * {@code getBoundNetworkForProcess} is a direct replacement.
- */
- @Deprecated
- @Nullable
- public static Network getProcessDefaultNetwork() {
- int netId = NetworkUtils.getBoundNetworkForProcess();
- if (netId == NETID_UNSET) return null;
- return new Network(netId);
- }
-
- private void unsupportedStartingFrom(int version) {
- if (Process.myUid() == Process.SYSTEM_UID) {
- // The getApplicationInfo() call we make below is not supported in system context. Let
- // the call through here, and rely on the fact that ConnectivityService will refuse to
- // allow the system to use these APIs anyway.
- return;
- }
-
- if (mContext.getApplicationInfo().targetSdkVersion >= version) {
- throw new UnsupportedOperationException(
- "This method is not supported in target SDK version " + version + " and above");
- }
- }
-
- // Checks whether the calling app can use the legacy routing API (startUsingNetworkFeature,
- // stopUsingNetworkFeature, requestRouteToHost), and if not throw UnsupportedOperationException.
- // TODO: convert the existing system users (Tethering, GnssLocationProvider) to the new APIs and
- // remove these exemptions. Note that this check is not secure, and apps can still access these
- // functions by accessing ConnectivityService directly. However, it should be clear that doing
- // so is unsupported and may break in the future. http://b/22728205
- private void checkLegacyRoutingApiAccess() {
- unsupportedStartingFrom(VERSION_CODES.M);
- }
-
- /**
- * Binds host resolutions performed by this process to {@code network}.
- * {@link #bindProcessToNetwork} takes precedence over this setting.
- *
- * @param network The {@link Network} to bind host resolutions from the current process to, or
- * {@code null} to clear the current binding.
- * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
- * @hide
- * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}.
- */
- @Deprecated
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
- return NetworkUtils.bindProcessToNetworkForHostResolution(
- (network == null) ? NETID_UNSET : network.getNetIdForResolv());
- }
-
- /**
- * Device is not restricting metered network activity while application is running on
- * background.
- */
- public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1;
-
- /**
- * Device is restricting metered network activity while application is running on background,
- * but application is allowed to bypass it.
- * <p>
- * In this state, application should take action to mitigate metered network access.
- * For example, a music streaming application should switch to a low-bandwidth bitrate.
- */
- public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2;
-
- /**
- * Device is restricting metered network activity while application is running on background.
- * <p>
- * In this state, application should not try to use the network while running on background,
- * because it would be denied.
- */
- public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3;
-
- /**
- * A change in the background metered network activity restriction has occurred.
- * <p>
- * Applications should call {@link #getRestrictBackgroundStatus()} to check if the restriction
- * applies to them.
- * <p>
- * This is only sent to registered receivers, not manifest receivers.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_RESTRICT_BACKGROUND_CHANGED =
- "android.net.conn.RESTRICT_BACKGROUND_CHANGED";
-
- /**
- * Determines if the calling application is subject to metered network restrictions while
- * running on background.
- *
- * @return {@link #RESTRICT_BACKGROUND_STATUS_DISABLED},
- * {@link #RESTRICT_BACKGROUND_STATUS_ENABLED},
- * or {@link #RESTRICT_BACKGROUND_STATUS_WHITELISTED}
- */
- public @RestrictBackgroundStatus int getRestrictBackgroundStatus() {
- try {
- return mService.getRestrictBackgroundStatusByCaller();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * The network watchlist is a list of domains and IP addresses that are associated with
- * potentially harmful apps. This method returns the SHA-256 of the watchlist config file
- * currently used by the system for validation purposes.
- *
- * @return Hash of network watchlist config file. Null if config does not exist.
- */
- @Nullable
- public byte[] getNetworkWatchlistConfigHash() {
- try {
- return mService.getNetworkWatchlistConfigHash();
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to get watchlist config hash");
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns the {@code uid} of the owner of a network connection.
- *
- * @param protocol The protocol of the connection. Only {@code IPPROTO_TCP} and {@code
- * IPPROTO_UDP} currently supported.
- * @param local The local {@link InetSocketAddress} of a connection.
- * @param remote The remote {@link InetSocketAddress} of a connection.
- * @return {@code uid} if the connection is found and the app has permission to observe it
- * (e.g., if it is associated with the calling VPN app's VpnService tunnel) or {@link
- * android.os.Process#INVALID_UID} if the connection is not found.
- * @throws {@link SecurityException} if the caller is not the active VpnService for the current
- * user.
- * @throws {@link IllegalArgumentException} if an unsupported protocol is requested.
- */
- public int getConnectionOwnerUid(
- int protocol, @NonNull InetSocketAddress local, @NonNull InetSocketAddress remote) {
- ConnectionInfo connectionInfo = new ConnectionInfo(protocol, local, remote);
- try {
- return mService.getConnectionOwnerUid(connectionInfo);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- private void printStackTrace() {
- if (DEBUG) {
- final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
- final StringBuffer sb = new StringBuffer();
- for (int i = 3; i < callStack.length; i++) {
- final String stackTrace = callStack[i].toString();
- if (stackTrace == null || stackTrace.contains("android.os")) {
- break;
- }
- sb.append(" [").append(stackTrace).append("]");
- }
- Log.d(TAG, "StackLog:" + sb.toString());
- }
- }
-
- /** @hide */
- public TestNetworkManager startOrGetTestNetworkManager() {
- final IBinder tnBinder;
- try {
- tnBinder = mService.startOrGetTestNetworkService();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
- return new TestNetworkManager(ITestNetworkManager.Stub.asInterface(tnBinder));
- }
-
- /** @hide */
- public ConnectivityDiagnosticsManager createDiagnosticsManager() {
- return new ConnectivityDiagnosticsManager(mContext, mService);
- }
-
- /**
- * Simulates a Data Stall for the specified Network.
- *
- * <p>This method should only be used for tests.
- *
- * <p>The caller must be the owner of the specified Network. This simulates a data stall to
- * have the system behave as if it had happened, but does not actually stall connectivity.
- *
- * @param detectionMethod The detection method used to identify the Data Stall.
- * See ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_*.
- * @param timestampMillis The timestamp at which the stall 'occurred', in milliseconds, as per
- * SystemClock.elapsedRealtime.
- * @param network The Network for which a Data Stall is being simluated.
- * @param extras The PersistableBundle of extras included in the Data Stall notification.
- * @throws SecurityException if the caller is not the owner of the given network.
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_TEST_NETWORKS,
- android.Manifest.permission.NETWORK_STACK})
- public void simulateDataStall(@DetectionMethod int detectionMethod, long timestampMillis,
- @NonNull Network network, @NonNull PersistableBundle extras) {
- try {
- mService.simulateDataStall(detectionMethod, timestampMillis, network, extras);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- }
-
- @NonNull
- private final List<QosCallbackConnection> mQosCallbackConnections = new ArrayList<>();
-
- /**
- * Registers a {@link QosSocketInfo} with an associated {@link QosCallback}. The callback will
- * receive available QoS events related to the {@link Network} and local ip + port
- * specified within socketInfo.
- * <p/>
- * The same {@link QosCallback} must be unregistered before being registered a second time,
- * otherwise {@link QosCallbackRegistrationException} is thrown.
- * <p/>
- * This API does not, in itself, require any permission if called with a network that is not
- * restricted. However, the underlying implementation currently only supports the IMS network,
- * which is always restricted. That means non-preinstalled callers can't possibly find this API
- * useful, because they'd never be called back on networks that they would have access to.
- *
- * @throws SecurityException if {@link QosSocketInfo#getNetwork()} is restricted and the app is
- * missing CONNECTIVITY_USE_RESTRICTED_NETWORKS permission.
- * @throws QosCallback.QosCallbackRegistrationException if qosCallback is already registered.
- * @throws RuntimeException if the app already has too many callbacks registered.
- *
- * Exceptions after the time of registration is passed through
- * {@link QosCallback#onError(QosCallbackException)}. see: {@link QosCallbackException}.
- *
- * @param socketInfo the socket information used to match QoS events
- * @param executor The executor on which the callback will be invoked. The provided
- * {@link Executor} must run callback sequentially, otherwise the order of
- * callbacks cannot be guaranteed.onQosCallbackRegistered
- * @param callback receives qos events that satisfy socketInfo
- *
- * @hide
- */
- @SystemApi
- public void registerQosCallback(@NonNull final QosSocketInfo socketInfo,
- @CallbackExecutor @NonNull final Executor executor,
- @NonNull final QosCallback callback) {
- Objects.requireNonNull(socketInfo, "socketInfo must be non-null");
- Objects.requireNonNull(executor, "executor must be non-null");
- Objects.requireNonNull(callback, "callback must be non-null");
-
- try {
- synchronized (mQosCallbackConnections) {
- if (getQosCallbackConnection(callback) == null) {
- final QosCallbackConnection connection =
- new QosCallbackConnection(this, callback, executor);
- mQosCallbackConnections.add(connection);
- mService.registerQosSocketCallback(socketInfo, connection);
- } else {
- Log.e(TAG, "registerQosCallback: Callback already registered");
- throw new QosCallbackRegistrationException();
- }
- }
- } catch (final RemoteException e) {
- Log.e(TAG, "registerQosCallback: Error while registering ", e);
-
- // The same unregister method method is called for consistency even though nothing
- // will be sent to the ConnectivityService since the callback was never successfully
- // registered.
- unregisterQosCallback(callback);
- e.rethrowFromSystemServer();
- } catch (final ServiceSpecificException e) {
- Log.e(TAG, "registerQosCallback: Error while registering ", e);
- unregisterQosCallback(callback);
- throw convertServiceException(e);
- }
- }
-
- /**
- * Unregisters the given {@link QosCallback}. The {@link QosCallback} will no longer receive
- * events once unregistered and can be registered a second time.
- * <p/>
- * If the {@link QosCallback} does not have an active registration, it is a no-op.
- *
- * @param callback the callback being unregistered
- *
- * @hide
- */
- @SystemApi
- public void unregisterQosCallback(@NonNull final QosCallback callback) {
- Objects.requireNonNull(callback, "The callback must be non-null");
- try {
- synchronized (mQosCallbackConnections) {
- final QosCallbackConnection connection = getQosCallbackConnection(callback);
- if (connection != null) {
- connection.stopReceivingMessages();
- mService.unregisterQosCallback(connection);
- mQosCallbackConnections.remove(connection);
- } else {
- Log.d(TAG, "unregisterQosCallback: Callback not registered");
- }
- }
- } catch (final RemoteException e) {
- Log.e(TAG, "unregisterQosCallback: Error while unregistering ", e);
- e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Gets the connection related to the callback.
- *
- * @param callback the callback to look up
- * @return the related connection
- */
- @Nullable
- private QosCallbackConnection getQosCallbackConnection(final QosCallback callback) {
- for (final QosCallbackConnection connection : mQosCallbackConnections) {
- // Checking by reference here is intentional
- if (connection.getCallback() == callback) {
- return connection;
- }
- }
- return null;
- }
-
- /**
- * Request a network to satisfy a set of {@link NetworkCapabilities}, but
- * does not cause any networks to retain the NET_CAPABILITY_FOREGROUND capability. This can
- * be used to request that the system provide a network without causing the network to be
- * in the foreground.
- *
- * <p>This method will attempt to find the best network that matches the passed
- * {@link NetworkRequest}, and to bring up one that does if none currently satisfies the
- * criteria. The platform will evaluate which network is the best at its own discretion.
- * Throughput, latency, cost per byte, policy, user preference and other considerations
- * may be factored in the decision of what is considered the best network.
- *
- * <p>As long as this request is outstanding, the platform will try to maintain the best network
- * matching this request, while always attempting to match the request to a better network if
- * possible. If a better match is found, the platform will switch this request to the now-best
- * network and inform the app of the newly best network by invoking
- * {@link NetworkCallback#onAvailable(Network)} on the provided callback. Note that the platform
- * will not try to maintain any other network than the best one currently matching the request:
- * a network not matching any network request may be disconnected at any time.
- *
- * <p>For example, an application could use this method to obtain a connected cellular network
- * even if the device currently has a data connection over Ethernet. This may cause the cellular
- * radio to consume additional power. Or, an application could inform the system that it wants
- * a network supporting sending MMSes and have the system let it know about the currently best
- * MMS-supporting network through the provided {@link NetworkCallback}.
- *
- * <p>The status of the request can be followed by listening to the various callbacks described
- * in {@link NetworkCallback}. The {@link Network} object passed to the callback methods can be
- * used to direct traffic to the network (although accessing some networks may be subject to
- * holding specific permissions). Callers will learn about the specific characteristics of the
- * network through
- * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)} and
- * {@link NetworkCallback#onLinkPropertiesChanged(Network, LinkProperties)}. The methods of the
- * provided {@link NetworkCallback} will only be invoked due to changes in the best network
- * matching the request at any given time; therefore when a better network matching the request
- * becomes available, the {@link NetworkCallback#onAvailable(Network)} method is called
- * with the new network after which no further updates are given about the previously-best
- * network, unless it becomes the best again at some later time. All callbacks are invoked
- * in order on the same thread, which by default is a thread created by the framework running
- * in the app.
- *
- * <p>This{@link NetworkRequest} will live until released via
- * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits, at
- * which point the system may let go of the network at any time.
- *
- * <p>It is presently unsupported to request a network with mutable
- * {@link NetworkCapabilities} such as
- * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
- * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
- * as these {@code NetworkCapabilities} represent states that a particular
- * network may never attain, and whether a network will attain these states
- * is unknown prior to bringing up the network so the framework does not
- * know how to go about satisfying a request with these capabilities.
- *
- * <p>To avoid performance issues due to apps leaking callbacks, the system will limit the
- * number of outstanding requests to 100 per app (identified by their UID), shared with
- * all variants of this method, of {@link #registerNetworkCallback} as well as
- * {@link ConnectivityDiagnosticsManager#registerConnectivityDiagnosticsCallback}.
- * Requesting a network with this method will count toward this limit. If this limit is
- * exceeded, an exception will be thrown. To avoid hitting this issue and to conserve resources,
- * make sure to unregister the callbacks with
- * {@link #unregisterNetworkCallback(NetworkCallback)}.
- *
- * @param request {@link NetworkRequest} describing this request.
- * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
- * the callback must not be shared - it uniquely specifies this request.
- * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- * If null, the callback is invoked on the default internal Handler.
- * @throws IllegalArgumentException if {@code request} contains invalid network capabilities.
- * @throws SecurityException if missing the appropriate permissions.
- * @throws RuntimeException if the app already has too many callbacks registered.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @SuppressLint("ExecutorRegistration")
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
- })
- public void requestBackgroundNetwork(@NonNull NetworkRequest request,
- @NonNull NetworkCallback networkCallback,
- @SuppressLint("ListenerLast") @NonNull Handler handler) {
- final NetworkCapabilities nc = request.networkCapabilities;
- sendRequestForNetwork(nc, networkCallback, 0, BACKGROUND_REQUEST,
- TYPE_NONE, new CallbackHandler(handler));
- }
-
- /**
- * Used by automotive devices to set the network preferences used to direct traffic at an
- * application level as per the given OemNetworkPreferences. An example use-case would be an
- * automotive OEM wanting to provide connectivity for applications critical to the usage of a
- * vehicle via a particular network.
- *
- * Calling this will overwrite the existing preference.
- *
- * @param preference {@link OemNetworkPreferences} The application network preference to be set.
- * @param executor the executor on which listener will be invoked.
- * @param listener {@link OnSetOemNetworkPreferenceListener} optional listener used to
- * communicate completion of setOemNetworkPreference(). This will only be
- * called once upon successful completion of setOemNetworkPreference().
- * @throws IllegalArgumentException if {@code preference} contains invalid preference values.
- * @throws SecurityException if missing the appropriate permissions.
- * @throws UnsupportedOperationException if called on a non-automotive device.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE)
- public void setOemNetworkPreference(@NonNull final OemNetworkPreferences preference,
- @Nullable @CallbackExecutor final Executor executor,
- @Nullable final Runnable listener) {
- Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
- if (null != listener) {
- Objects.requireNonNull(executor, "Executor must be non-null");
- }
- final IOnCompleteListener listenerInternal = listener == null ? null :
- new IOnCompleteListener.Stub() {
- @Override
- public void onComplete() {
- executor.execute(listener::run);
- }
- };
-
- try {
- mService.setOemNetworkPreference(preference, listenerInternal);
- } catch (RemoteException e) {
- Log.e(TAG, "setOemNetworkPreference() failed for preference: " + preference.toString());
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Request that a user profile is put by default on a network matching a given preference.
- *
- * See the documentation for the individual preferences for a description of the supported
- * behaviors.
- *
- * @param profile the profile concerned.
- * @param preference the preference for this profile.
- * @param executor an executor to execute the listener on. Optional if listener is null.
- * @param listener an optional listener to listen for completion of the operation.
- * @throws IllegalArgumentException if {@code profile} is not a valid user profile.
- * @throws SecurityException if missing the appropriate permissions.
- * @hide
- */
- // This function is for establishing per-profile default networking and can only be called by
- // the device policy manager, running as the system server. It would make no sense to call it
- // on a context for a user because it does not establish a setting on behalf of a user, rather
- // it establishes a setting for a user on behalf of the DPM.
- @SuppressLint({"UserHandle"})
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
- public void setProfileNetworkPreference(@NonNull final UserHandle profile,
- @ProfileNetworkPreference final int preference,
- @Nullable @CallbackExecutor final Executor executor,
- @Nullable final Runnable listener) {
- if (null != listener) {
- Objects.requireNonNull(executor, "Pass a non-null executor, or a null listener");
- }
- final IOnCompleteListener proxy;
- if (null == listener) {
- proxy = null;
- } else {
- proxy = new IOnCompleteListener.Stub() {
- @Override
- public void onComplete() {
- executor.execute(listener::run);
- }
- };
- }
- try {
- mService.setProfileNetworkPreference(profile, preference, proxy);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- // The first network ID of IPSec tunnel interface.
- private static final int TUN_INTF_NETID_START = 0xFC00; // 0xFC00 = 64512
- // The network ID range of IPSec tunnel interface.
- private static final int TUN_INTF_NETID_RANGE = 0x0400; // 0x0400 = 1024
-
- /**
- * Get the network ID range reserved for IPSec tunnel interfaces.
- *
- * @return A Range which indicates the network ID range of IPSec tunnel interface.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @NonNull
- public static Range<Integer> getIpSecNetIdRange() {
- return new Range(TUN_INTF_NETID_START, TUN_INTF_NETID_START + TUN_INTF_NETID_RANGE - 1);
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityResources.java b/packages/Connectivity/framework/src/android/net/ConnectivityResources.java
deleted file mode 100644
index 18f0de0..0000000
--- a/packages/Connectivity/framework/src/android/net/ConnectivityResources.java
+++ /dev/null
@@ -1,108 +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.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.List;
-
-/**
- * Utility to obtain the {@link com.android.server.ConnectivityService} {@link Resources}, in the
- * ServiceConnectivityResources APK.
- * @hide
- */
-public class ConnectivityResources {
- private static final String RESOURCES_APK_INTENT =
- "com.android.server.connectivity.intent.action.SERVICE_CONNECTIVITY_RESOURCES_APK";
- private static final String RES_PKG_DIR = "/apex/com.android.tethering/";
-
- @NonNull
- private final Context mContext;
-
- @Nullable
- private Context mResourcesContext = null;
-
- @Nullable
- private static Context sTestResourcesContext = null;
-
- public ConnectivityResources(Context context) {
- mContext = context;
- }
-
- /**
- * Convenience method to mock all resources for the duration of a test.
- *
- * Call with a null context to reset after the test.
- */
- @VisibleForTesting
- public static void setResourcesContextForTest(@Nullable Context testContext) {
- sTestResourcesContext = testContext;
- }
-
- /**
- * Get the {@link Context} of the resources package.
- */
- public synchronized Context getResourcesContext() {
- if (sTestResourcesContext != null) {
- return sTestResourcesContext;
- }
-
- if (mResourcesContext != null) {
- return mResourcesContext;
- }
-
- final List<ResolveInfo> pkgs = mContext.getPackageManager()
- .queryIntentActivities(new Intent(RESOURCES_APK_INTENT), MATCH_SYSTEM_ONLY);
- pkgs.removeIf(pkg -> !pkg.activityInfo.applicationInfo.sourceDir.startsWith(RES_PKG_DIR));
- if (pkgs.size() > 1) {
- Log.wtf(ConnectivityResources.class.getSimpleName(),
- "More than one package found: " + pkgs);
- }
- if (pkgs.isEmpty()) {
- throw new IllegalStateException("No connectivity resource package found");
- }
-
- final Context pkgContext;
- try {
- pkgContext = mContext.createPackageContext(
- pkgs.get(0).activityInfo.applicationInfo.packageName, 0 /* flags */);
- } catch (PackageManager.NameNotFoundException e) {
- throw new IllegalStateException("Resolved package not found", e);
- }
-
- mResourcesContext = pkgContext;
- return pkgContext;
- }
-
- /**
- * Get the {@link Resources} of the ServiceConnectivityResources APK.
- */
- public Resources get() {
- return getResourcesContext().getResources();
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java b/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java
deleted file mode 100644
index 1a69099..0000000
--- a/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java
+++ /dev/null
@@ -1,1087 +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.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER;
-import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE;
-import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY;
-
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.net.ConnectivityAnnotations.MultipathPreference;
-import android.os.Process;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.Range;
-
-import com.android.net.module.util.ProxyUtils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.time.Duration;
-import java.util.List;
-import java.util.Set;
-import java.util.StringJoiner;
-
-/**
- * A manager class for connectivity module settings.
- *
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public class ConnectivitySettingsManager {
-
- private ConnectivitySettingsManager() {}
-
- /** Data activity timeout settings */
-
- /**
- * Inactivity timeout to track mobile data activity.
- *
- * If set to a positive integer, it indicates the inactivity timeout value in seconds to
- * infer the data activity of mobile network. After a period of no activity on mobile
- * networks with length specified by the timeout, an {@code ACTION_DATA_ACTIVITY_CHANGE}
- * intent is fired to indicate a transition of network status from "active" to "idle". Any
- * subsequent activity on mobile networks triggers the firing of {@code
- * ACTION_DATA_ACTIVITY_CHANGE} intent indicating transition from "idle" to "active".
- *
- * Network activity refers to transmitting or receiving data on the network interfaces.
- *
- * Tracking is disabled if set to zero or negative value.
- *
- * @hide
- */
- public static final String DATA_ACTIVITY_TIMEOUT_MOBILE = "data_activity_timeout_mobile";
-
- /**
- * Timeout to tracking Wifi data activity. Same as {@code DATA_ACTIVITY_TIMEOUT_MOBILE}
- * but for Wifi network.
- *
- * @hide
- */
- public static final String DATA_ACTIVITY_TIMEOUT_WIFI = "data_activity_timeout_wifi";
-
- /** Dns resolver settings */
-
- /**
- * Sample validity in seconds to configure for the system DNS resolver.
- *
- * @hide
- */
- public static final String DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS =
- "dns_resolver_sample_validity_seconds";
-
- /**
- * Success threshold in percent for use with the system DNS resolver.
- *
- * @hide
- */
- public static final String DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT =
- "dns_resolver_success_threshold_percent";
-
- /**
- * Minimum number of samples needed for statistics to be considered meaningful in the
- * system DNS resolver.
- *
- * @hide
- */
- public static final String DNS_RESOLVER_MIN_SAMPLES = "dns_resolver_min_samples";
-
- /**
- * Maximum number taken into account for statistics purposes in the system DNS resolver.
- *
- * @hide
- */
- public static final String DNS_RESOLVER_MAX_SAMPLES = "dns_resolver_max_samples";
-
- private static final int DNS_RESOLVER_DEFAULT_MIN_SAMPLES = 8;
- private static final int DNS_RESOLVER_DEFAULT_MAX_SAMPLES = 64;
-
- /** Network switch notification settings */
-
- /**
- * The maximum number of notifications shown in 24 hours when switching networks.
- *
- * @hide
- */
- public static final String NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT =
- "network_switch_notification_daily_limit";
-
- /**
- * The minimum time in milliseconds between notifications when switching networks.
- *
- * @hide
- */
- public static final String NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS =
- "network_switch_notification_rate_limit_millis";
-
- /** Captive portal settings */
-
- /**
- * The URL used for HTTP captive portal detection upon a new connection.
- * A 204 response code from the server is used for validation.
- *
- * @hide
- */
- public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
-
- /**
- * What to do when connecting a network that presents a captive portal.
- * Must be one of the CAPTIVE_PORTAL_MODE_* constants below.
- *
- * The default for this setting is CAPTIVE_PORTAL_MODE_PROMPT.
- *
- * @hide
- */
- public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
-
- /**
- * Don't attempt to detect captive portals.
- */
- public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0;
-
- /**
- * When detecting a captive portal, display a notification that
- * prompts the user to sign in.
- */
- public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1;
-
- /**
- * When detecting a captive portal, immediately disconnect from the
- * network and do not reconnect to that network in the future.
- */
- public static final int CAPTIVE_PORTAL_MODE_AVOID = 2;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- CAPTIVE_PORTAL_MODE_IGNORE,
- CAPTIVE_PORTAL_MODE_PROMPT,
- CAPTIVE_PORTAL_MODE_AVOID,
- })
- public @interface CaptivePortalMode {}
-
- /** Global http proxy settings */
-
- /**
- * Host name for global http proxy. Set via ConnectivityManager.
- *
- * @hide
- */
- public static final String GLOBAL_HTTP_PROXY_HOST = "global_http_proxy_host";
-
- /**
- * Integer host port for global http proxy. Set via ConnectivityManager.
- *
- * @hide
- */
- public static final String GLOBAL_HTTP_PROXY_PORT = "global_http_proxy_port";
-
- /**
- * Exclusion list for global proxy. This string contains a list of
- * comma-separated domains where the global proxy does not apply.
- * Domains should be listed in a comma- separated list. Example of
- * acceptable formats: ".domain1.com,my.domain2.com" Use
- * ConnectivityManager to set/get.
- *
- * @hide
- */
- public static final String GLOBAL_HTTP_PROXY_EXCLUSION_LIST =
- "global_http_proxy_exclusion_list";
-
- /**
- * The location PAC File for the proxy.
- *
- * @hide
- */
- public static final String GLOBAL_HTTP_PROXY_PAC = "global_proxy_pac_url";
-
- /** Private dns settings */
-
- /**
- * The requested Private DNS mode (string), and an accompanying specifier (string).
- *
- * Currently, the specifier holds the chosen provider name when the mode requests
- * a specific provider. It may be used to store the provider name even when the
- * mode changes so that temporarily disabling and re-enabling the specific
- * provider mode does not necessitate retyping the provider hostname.
- *
- * @hide
- */
- public static final String PRIVATE_DNS_MODE = "private_dns_mode";
-
- /**
- * The specific Private DNS provider name.
- *
- * @hide
- */
- public static final String PRIVATE_DNS_SPECIFIER = "private_dns_specifier";
-
- /**
- * Forced override of the default mode (hardcoded as "automatic", nee "opportunistic").
- * This allows changing the default mode without effectively disabling other modes,
- * all of which require explicit user action to enable/configure. See also b/79719289.
- *
- * Value is a string, suitable for assignment to PRIVATE_DNS_MODE above.
- *
- * @hide
- */
- public static final String PRIVATE_DNS_DEFAULT_MODE = "private_dns_default_mode";
-
- /** Other settings */
-
- /**
- * The number of milliseconds to hold on to a PendingIntent based request. This delay gives
- * the receivers of the PendingIntent an opportunity to make a new network request before
- * the Network satisfying the request is potentially removed.
- *
- * @hide
- */
- public static final String CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS =
- "connectivity_release_pending_intent_delay_ms";
-
- /**
- * Whether the mobile data connection should remain active even when higher
- * priority networks like WiFi are active, to help make network switching faster.
- *
- * See ConnectivityService for more info.
- *
- * (0 = disabled, 1 = enabled)
- *
- * @hide
- */
- public static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
-
- /**
- * Whether the wifi data connection should remain active even when higher
- * priority networks like Ethernet are active, to keep both networks.
- * In the case where higher priority networks are connected, wifi will be
- * unused unless an application explicitly requests to use it.
- *
- * See ConnectivityService for more info.
- *
- * (0 = disabled, 1 = enabled)
- *
- * @hide
- */
- public static final String WIFI_ALWAYS_REQUESTED = "wifi_always_requested";
-
- /**
- * Whether to automatically switch away from wifi networks that lose Internet access.
- * Only meaningful if config_networkAvoidBadWifi is set to 0, otherwise the system always
- * avoids such networks. Valid values are:
- *
- * 0: Don't avoid bad wifi, don't prompt the user. Get stuck on bad wifi like it's 2013.
- * null: Ask the user whether to switch away from bad wifi.
- * 1: Avoid bad wifi.
- *
- * @hide
- */
- public static final String NETWORK_AVOID_BAD_WIFI = "network_avoid_bad_wifi";
-
- /**
- * Don't avoid bad wifi, don't prompt the user. Get stuck on bad wifi like it's 2013.
- */
- public static final int NETWORK_AVOID_BAD_WIFI_IGNORE = 0;
-
- /**
- * Ask the user whether to switch away from bad wifi.
- */
- public static final int NETWORK_AVOID_BAD_WIFI_PROMPT = 1;
-
- /**
- * Avoid bad wifi.
- */
- public static final int NETWORK_AVOID_BAD_WIFI_AVOID = 2;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- NETWORK_AVOID_BAD_WIFI_IGNORE,
- NETWORK_AVOID_BAD_WIFI_PROMPT,
- NETWORK_AVOID_BAD_WIFI_AVOID,
- })
- public @interface NetworkAvoidBadWifi {}
-
- /**
- * User setting for ConnectivityManager.getMeteredMultipathPreference(). This value may be
- * overridden by the system based on device or application state. If null, the value
- * specified by config_networkMeteredMultipathPreference is used.
- *
- * @hide
- */
- public static final String NETWORK_METERED_MULTIPATH_PREFERENCE =
- "network_metered_multipath_preference";
-
- /**
- * A list of uids that should go on cellular networks in preference even when higher-priority
- * networks are connected.
- *
- * @hide
- */
- public static final String MOBILE_DATA_PREFERRED_UIDS = "mobile_data_preferred_uids";
-
- /**
- * One of the private DNS modes that indicates the private DNS mode is off.
- */
- public static final int PRIVATE_DNS_MODE_OFF = 1;
-
- /**
- * One of the private DNS modes that indicates the private DNS mode is automatic, which
- * will try to use the current DNS as private DNS.
- */
- public static final int PRIVATE_DNS_MODE_OPPORTUNISTIC = 2;
-
- /**
- * One of the private DNS modes that indicates the private DNS mode is strict and the
- * {@link #PRIVATE_DNS_SPECIFIER} is required, which will try to use the value of
- * {@link #PRIVATE_DNS_SPECIFIER} as private DNS.
- */
- public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- PRIVATE_DNS_MODE_OFF,
- PRIVATE_DNS_MODE_OPPORTUNISTIC,
- PRIVATE_DNS_MODE_PROVIDER_HOSTNAME,
- })
- public @interface PrivateDnsMode {}
-
- private static final String PRIVATE_DNS_MODE_OFF_STRING = "off";
- private static final String PRIVATE_DNS_MODE_OPPORTUNISTIC_STRING = "opportunistic";
- private static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING = "hostname";
-
- /**
- * A list of apps that is allowed on restricted networks.
- *
- * @hide
- */
- public static final String APPS_ALLOWED_ON_RESTRICTED_NETWORKS =
- "apps_allowed_on_restricted_networks";
-
- /**
- * Get mobile data activity timeout from {@link Settings}.
- *
- * @param context The {@link Context} to query the setting.
- * @param def The default timeout if no setting value.
- * @return The {@link Duration} of timeout to track mobile data activity.
- */
- @NonNull
- public static Duration getMobileDataActivityTimeout(@NonNull Context context,
- @NonNull Duration def) {
- final int timeout = Settings.Global.getInt(
- context.getContentResolver(), DATA_ACTIVITY_TIMEOUT_MOBILE, (int) def.getSeconds());
- return Duration.ofSeconds(timeout);
- }
-
- /**
- * Set mobile data activity timeout to {@link Settings}.
- * Tracking is disabled if set to zero or negative value.
- *
- * Note: Only use the number of seconds in this duration, lower second(nanoseconds) will be
- * ignored.
- *
- * @param context The {@link Context} to set the setting.
- * @param timeout The mobile data activity timeout.
- */
- public static void setMobileDataActivityTimeout(@NonNull Context context,
- @NonNull Duration timeout) {
- Settings.Global.putInt(context.getContentResolver(), DATA_ACTIVITY_TIMEOUT_MOBILE,
- (int) timeout.getSeconds());
- }
-
- /**
- * Get wifi data activity timeout from {@link Settings}.
- *
- * @param context The {@link Context} to query the setting.
- * @param def The default timeout if no setting value.
- * @return The {@link Duration} of timeout to track wifi data activity.
- */
- @NonNull
- public static Duration getWifiDataActivityTimeout(@NonNull Context context,
- @NonNull Duration def) {
- final int timeout = Settings.Global.getInt(
- context.getContentResolver(), DATA_ACTIVITY_TIMEOUT_WIFI, (int) def.getSeconds());
- return Duration.ofSeconds(timeout);
- }
-
- /**
- * Set wifi data activity timeout to {@link Settings}.
- * Tracking is disabled if set to zero or negative value.
- *
- * Note: Only use the number of seconds in this duration, lower second(nanoseconds) will be
- * ignored.
- *
- * @param context The {@link Context} to set the setting.
- * @param timeout The wifi data activity timeout.
- */
- public static void setWifiDataActivityTimeout(@NonNull Context context,
- @NonNull Duration timeout) {
- Settings.Global.putInt(context.getContentResolver(), DATA_ACTIVITY_TIMEOUT_WIFI,
- (int) timeout.getSeconds());
- }
-
- /**
- * Get dns resolver sample validity duration from {@link Settings}.
- *
- * @param context The {@link Context} to query the setting.
- * @param def The default duration if no setting value.
- * @return The {@link Duration} of sample validity duration to configure for the system DNS
- * resolver.
- */
- @NonNull
- public static Duration getDnsResolverSampleValidityDuration(@NonNull Context context,
- @NonNull Duration def) {
- final int duration = Settings.Global.getInt(context.getContentResolver(),
- DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS, (int) def.getSeconds());
- return Duration.ofSeconds(duration);
- }
-
- /**
- * Set dns resolver sample validity duration to {@link Settings}. The duration must be a
- * positive number of seconds.
- *
- * @param context The {@link Context} to set the setting.
- * @param duration The sample validity duration.
- */
- public static void setDnsResolverSampleValidityDuration(@NonNull Context context,
- @NonNull Duration duration) {
- final int time = (int) duration.getSeconds();
- if (time <= 0) {
- throw new IllegalArgumentException("Invalid duration");
- }
- Settings.Global.putInt(
- context.getContentResolver(), DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS, time);
- }
-
- /**
- * Get dns resolver success threshold percent from {@link Settings}.
- *
- * @param context The {@link Context} to query the setting.
- * @param def The default value if no setting value.
- * @return The success threshold in percent for use with the system DNS resolver.
- */
- public static int getDnsResolverSuccessThresholdPercent(@NonNull Context context, int def) {
- return Settings.Global.getInt(
- context.getContentResolver(), DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT, def);
- }
-
- /**
- * Set dns resolver success threshold percent to {@link Settings}. The threshold percent must
- * be 0~100.
- *
- * @param context The {@link Context} to set the setting.
- * @param percent The success threshold percent.
- */
- public static void setDnsResolverSuccessThresholdPercent(@NonNull Context context,
- @IntRange(from = 0, to = 100) int percent) {
- if (percent < 0 || percent > 100) {
- throw new IllegalArgumentException("Percent must be 0~100");
- }
- Settings.Global.putInt(
- context.getContentResolver(), DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT, percent);
- }
-
- /**
- * Get dns resolver samples range from {@link Settings}.
- *
- * @param context The {@link Context} to query the setting.
- * @return The {@link Range<Integer>} of samples needed for statistics to be considered
- * meaningful in the system DNS resolver.
- */
- @NonNull
- public static Range<Integer> getDnsResolverSampleRanges(@NonNull Context context) {
- final int minSamples = Settings.Global.getInt(context.getContentResolver(),
- DNS_RESOLVER_MIN_SAMPLES, DNS_RESOLVER_DEFAULT_MIN_SAMPLES);
- final int maxSamples = Settings.Global.getInt(context.getContentResolver(),
- DNS_RESOLVER_MAX_SAMPLES, DNS_RESOLVER_DEFAULT_MAX_SAMPLES);
- return new Range<>(minSamples, maxSamples);
- }
-
- /**
- * Set dns resolver samples range to {@link Settings}.
- *
- * @param context The {@link Context} to set the setting.
- * @param range The samples range. The minimum number should be more than 0 and the maximum
- * number should be less that 64.
- */
- public static void setDnsResolverSampleRanges(@NonNull Context context,
- @NonNull Range<Integer> range) {
- if (range.getLower() < 0 || range.getUpper() > 64) {
- throw new IllegalArgumentException("Argument must be 0~64");
- }
- Settings.Global.putInt(
- context.getContentResolver(), DNS_RESOLVER_MIN_SAMPLES, range.getLower());
- Settings.Global.putInt(
- context.getContentResolver(), DNS_RESOLVER_MAX_SAMPLES, range.getUpper());
- }
-
- /**
- * Get maximum count (from {@link Settings}) of switching network notifications shown in 24
- * hours.
- *
- * @param context The {@link Context} to query the setting.
- * @param def The default value if no setting value.
- * @return The maximum count of notifications shown in 24 hours when switching networks.
- */
- public static int getNetworkSwitchNotificationMaximumDailyCount(@NonNull Context context,
- int def) {
- return Settings.Global.getInt(
- context.getContentResolver(), NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT, def);
- }
-
- /**
- * Set maximum count (to {@link Settings}) of switching network notifications shown in 24 hours.
- * The count must be at least 0.
- *
- * @param context The {@link Context} to set the setting.
- * @param count The maximum count of switching network notifications shown in 24 hours.
- */
- public static void setNetworkSwitchNotificationMaximumDailyCount(@NonNull Context context,
- @IntRange(from = 0) int count) {
- if (count < 0) {
- throw new IllegalArgumentException("Count must be 0~10.");
- }
- Settings.Global.putInt(
- context.getContentResolver(), NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT, count);
- }
-
- /**
- * Get minimum duration (from {@link Settings}) between each switching network notifications.
- *
- * @param context The {@link Context} to query the setting.
- * @param def The default time if no setting value.
- * @return The minimum duration between notifications when switching networks.
- */
- @NonNull
- public static Duration getNetworkSwitchNotificationRateDuration(@NonNull Context context,
- @NonNull Duration def) {
- final int duration = Settings.Global.getInt(context.getContentResolver(),
- NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS, (int) def.toMillis());
- return Duration.ofMillis(duration);
- }
-
- /**
- * Set minimum duration (to {@link Settings}) between each switching network notifications.
- *
- * @param context The {@link Context} to set the setting.
- * @param duration The minimum duration between notifications when switching networks.
- */
- public static void setNetworkSwitchNotificationRateDuration(@NonNull Context context,
- @NonNull Duration duration) {
- final int time = (int) duration.toMillis();
- if (time < 0) {
- throw new IllegalArgumentException("Invalid duration.");
- }
- Settings.Global.putInt(context.getContentResolver(),
- NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS, time);
- }
-
- /**
- * Get URL (from {@link Settings}) used for HTTP captive portal detection upon a new connection.
- *
- * @param context The {@link Context} to query the setting.
- * @return The URL used for HTTP captive portal detection upon a new connection.
- */
- @Nullable
- public static String getCaptivePortalHttpUrl(@NonNull Context context) {
- return Settings.Global.getString(context.getContentResolver(), CAPTIVE_PORTAL_HTTP_URL);
- }
-
- /**
- * Set URL (to {@link Settings}) used for HTTP captive portal detection upon a new connection.
- * This URL should respond with a 204 response to a GET request to indicate no captive portal is
- * present. And this URL must be HTTP as redirect responses are used to find captive portal
- * sign-in pages. If the URL set to null or be incorrect, it will result in captive portal
- * detection failed and lost the connection.
- *
- * @param context The {@link Context} to set the setting.
- * @param url The URL used for HTTP captive portal detection upon a new connection.
- */
- public static void setCaptivePortalHttpUrl(@NonNull Context context, @Nullable String url) {
- Settings.Global.putString(context.getContentResolver(), CAPTIVE_PORTAL_HTTP_URL, url);
- }
-
- /**
- * Get mode (from {@link Settings}) when connecting a network that presents a captive portal.
- *
- * @param context The {@link Context} to query the setting.
- * @param def The default mode if no setting value.
- * @return The mode when connecting a network that presents a captive portal.
- */
- @CaptivePortalMode
- public static int getCaptivePortalMode(@NonNull Context context,
- @CaptivePortalMode int def) {
- return Settings.Global.getInt(context.getContentResolver(), CAPTIVE_PORTAL_MODE, def);
- }
-
- /**
- * Set mode (to {@link Settings}) when connecting a network that presents a captive portal.
- *
- * @param context The {@link Context} to set the setting.
- * @param mode The mode when connecting a network that presents a captive portal.
- */
- public static void setCaptivePortalMode(@NonNull Context context, @CaptivePortalMode int mode) {
- if (!(mode == CAPTIVE_PORTAL_MODE_IGNORE
- || mode == CAPTIVE_PORTAL_MODE_PROMPT
- || mode == CAPTIVE_PORTAL_MODE_AVOID)) {
- throw new IllegalArgumentException("Invalid captive portal mode");
- }
- Settings.Global.putInt(context.getContentResolver(), CAPTIVE_PORTAL_MODE, mode);
- }
-
- /**
- * Get the global HTTP proxy applied to the device, or null if none.
- *
- * @param context The {@link Context} to query the setting.
- * @return The {@link ProxyInfo} which build from global http proxy settings.
- */
- @Nullable
- public static ProxyInfo getGlobalProxy(@NonNull Context context) {
- final String host = Settings.Global.getString(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_HOST);
- final int port = Settings.Global.getInt(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_PORT, 0 /* def */);
- final String exclusionList = Settings.Global.getString(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
- final String pacFileUrl = Settings.Global.getString(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_PAC);
-
- if (TextUtils.isEmpty(host) && TextUtils.isEmpty(pacFileUrl)) {
- return null; // No global proxy.
- }
-
- if (TextUtils.isEmpty(pacFileUrl)) {
- return ProxyInfo.buildDirectProxy(
- host, port, ProxyUtils.exclusionStringAsList(exclusionList));
- } else {
- return ProxyInfo.buildPacProxy(Uri.parse(pacFileUrl));
- }
- }
-
- /**
- * Set global http proxy settings from given {@link ProxyInfo}.
- *
- * @param context The {@link Context} to set the setting.
- * @param proxyInfo The {@link ProxyInfo} for global http proxy settings which build from
- * {@link ProxyInfo#buildPacProxy(Uri)} or
- * {@link ProxyInfo#buildDirectProxy(String, int, List)}
- */
- public static void setGlobalProxy(@NonNull Context context, @NonNull ProxyInfo proxyInfo) {
- final String host = proxyInfo.getHost();
- final int port = proxyInfo.getPort();
- final String exclusionList = proxyInfo.getExclusionListAsString();
- final String pacFileUrl = proxyInfo.getPacFileUrl().toString();
-
- if (TextUtils.isEmpty(pacFileUrl)) {
- Settings.Global.putString(context.getContentResolver(), GLOBAL_HTTP_PROXY_HOST, host);
- Settings.Global.putInt(context.getContentResolver(), GLOBAL_HTTP_PROXY_PORT, port);
- Settings.Global.putString(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_EXCLUSION_LIST, exclusionList);
- Settings.Global.putString(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_PAC, "" /* value */);
- } else {
- Settings.Global.putString(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
- Settings.Global.putString(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_HOST, "" /* value */);
- Settings.Global.putInt(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_PORT, 0 /* value */);
- Settings.Global.putString(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_EXCLUSION_LIST, "" /* value */);
- }
- }
-
- /**
- * Clear all global http proxy settings.
- *
- * @param context The {@link Context} to set the setting.
- */
- public static void clearGlobalProxy(@NonNull Context context) {
- Settings.Global.putString(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_HOST, "" /* value */);
- Settings.Global.putInt(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_PORT, 0 /* value */);
- Settings.Global.putString(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_EXCLUSION_LIST, "" /* value */);
- Settings.Global.putString(
- context.getContentResolver(), GLOBAL_HTTP_PROXY_PAC, "" /* value */);
- }
-
- private static String getPrivateDnsModeAsString(@PrivateDnsMode int mode) {
- switch (mode) {
- case PRIVATE_DNS_MODE_OFF:
- return PRIVATE_DNS_MODE_OFF_STRING;
- case PRIVATE_DNS_MODE_OPPORTUNISTIC:
- return PRIVATE_DNS_MODE_OPPORTUNISTIC_STRING;
- case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
- return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING;
- default:
- throw new IllegalArgumentException("Invalid private dns mode: " + mode);
- }
- }
-
- private static int getPrivateDnsModeAsInt(String mode) {
- switch (mode) {
- case "off":
- return PRIVATE_DNS_MODE_OFF;
- case "hostname":
- return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
- case "opportunistic":
- return PRIVATE_DNS_MODE_OPPORTUNISTIC;
- default:
- throw new IllegalArgumentException("Invalid private dns mode: " + mode);
- }
- }
-
- /**
- * Get private DNS mode from settings.
- *
- * @param context The Context to query the private DNS mode from settings.
- * @return A string of private DNS mode.
- */
- @PrivateDnsMode
- public static int getPrivateDnsMode(@NonNull Context context) {
- final ContentResolver cr = context.getContentResolver();
- String mode = Settings.Global.getString(cr, PRIVATE_DNS_MODE);
- if (TextUtils.isEmpty(mode)) mode = Settings.Global.getString(cr, PRIVATE_DNS_DEFAULT_MODE);
- // If both PRIVATE_DNS_MODE and PRIVATE_DNS_DEFAULT_MODE are not set, choose
- // PRIVATE_DNS_MODE_OPPORTUNISTIC as default mode.
- if (TextUtils.isEmpty(mode)) return PRIVATE_DNS_MODE_OPPORTUNISTIC;
- return getPrivateDnsModeAsInt(mode);
- }
-
- /**
- * Set private DNS mode to settings.
- *
- * @param context The {@link Context} to set the private DNS mode.
- * @param mode The private dns mode. This should be one of the PRIVATE_DNS_MODE_* constants.
- */
- public static void setPrivateDnsMode(@NonNull Context context, @PrivateDnsMode int mode) {
- if (!(mode == PRIVATE_DNS_MODE_OFF
- || mode == PRIVATE_DNS_MODE_OPPORTUNISTIC
- || mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
- throw new IllegalArgumentException("Invalid private dns mode: " + mode);
- }
- Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_MODE,
- getPrivateDnsModeAsString(mode));
- }
-
- /**
- * Get specific private dns provider name from {@link Settings}.
- *
- * @param context The {@link Context} to query the setting.
- * @return The specific private dns provider name, or null if no setting value.
- */
- @Nullable
- public static String getPrivateDnsHostname(@NonNull Context context) {
- return Settings.Global.getString(context.getContentResolver(), PRIVATE_DNS_SPECIFIER);
- }
-
- /**
- * Set specific private dns provider name to {@link Settings}.
- *
- * @param context The {@link Context} to set the setting.
- * @param specifier The specific private dns provider name.
- */
- public static void setPrivateDnsHostname(@NonNull Context context,
- @Nullable String specifier) {
- Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_SPECIFIER, specifier);
- }
-
- /**
- * Get default private dns mode from {@link Settings}.
- *
- * @param context The {@link Context} to query the setting.
- * @return The default private dns mode.
- */
- @PrivateDnsMode
- @NonNull
- public static String getPrivateDnsDefaultMode(@NonNull Context context) {
- return Settings.Global.getString(context.getContentResolver(), PRIVATE_DNS_DEFAULT_MODE);
- }
-
- /**
- * Set default private dns mode to {@link Settings}.
- *
- * @param context The {@link Context} to set the setting.
- * @param mode The default private dns mode. This should be one of the PRIVATE_DNS_MODE_*
- * constants.
- */
- public static void setPrivateDnsDefaultMode(@NonNull Context context,
- @NonNull @PrivateDnsMode int mode) {
- if (!(mode == PRIVATE_DNS_MODE_OFF
- || mode == PRIVATE_DNS_MODE_OPPORTUNISTIC
- || mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
- throw new IllegalArgumentException("Invalid private dns mode");
- }
- Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_DEFAULT_MODE,
- getPrivateDnsModeAsString(mode));
- }
-
- /**
- * Get duration (from {@link Settings}) to keep a PendingIntent-based request.
- *
- * @param context The {@link Context} to query the setting.
- * @param def The default duration if no setting value.
- * @return The duration to keep a PendingIntent-based request.
- */
- @NonNull
- public static Duration getConnectivityKeepPendingIntentDuration(@NonNull Context context,
- @NonNull Duration def) {
- final int duration = Settings.Secure.getInt(context.getContentResolver(),
- CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, (int) def.toMillis());
- return Duration.ofMillis(duration);
- }
-
- /**
- * Set duration (to {@link Settings}) to keep a PendingIntent-based request.
- *
- * @param context The {@link Context} to set the setting.
- * @param duration The duration to keep a PendingIntent-based request.
- */
- public static void setConnectivityKeepPendingIntentDuration(@NonNull Context context,
- @NonNull Duration duration) {
- final int time = (int) duration.toMillis();
- if (time < 0) {
- throw new IllegalArgumentException("Invalid duration.");
- }
- Settings.Secure.putInt(
- context.getContentResolver(), CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, time);
- }
-
- /**
- * Read from {@link Settings} whether the mobile data connection should remain active
- * even when higher priority networks are active.
- *
- * @param context The {@link Context} to query the setting.
- * @param def The default value if no setting value.
- * @return Whether the mobile data connection should remain active even when higher
- * priority networks are active.
- */
- public static boolean getMobileDataAlwaysOn(@NonNull Context context, boolean def) {
- final int enable = Settings.Global.getInt(
- context.getContentResolver(), MOBILE_DATA_ALWAYS_ON, (def ? 1 : 0));
- return (enable != 0) ? true : false;
- }
-
- /**
- * Write into {@link Settings} whether the mobile data connection should remain active
- * even when higher priority networks are active.
- *
- * @param context The {@link Context} to set the setting.
- * @param enable Whether the mobile data connection should remain active even when higher
- * priority networks are active.
- */
- public static void setMobileDataAlwaysOn(@NonNull Context context, boolean enable) {
- Settings.Global.putInt(
- context.getContentResolver(), MOBILE_DATA_ALWAYS_ON, (enable ? 1 : 0));
- }
-
- /**
- * Read from {@link Settings} whether the wifi data connection should remain active
- * even when higher priority networks are active.
- *
- * @param context The {@link Context} to query the setting.
- * @param def The default value if no setting value.
- * @return Whether the wifi data connection should remain active even when higher
- * priority networks are active.
- */
- public static boolean getWifiAlwaysRequested(@NonNull Context context, boolean def) {
- final int enable = Settings.Global.getInt(
- context.getContentResolver(), WIFI_ALWAYS_REQUESTED, (def ? 1 : 0));
- return (enable != 0) ? true : false;
- }
-
- /**
- * Write into {@link Settings} whether the wifi data connection should remain active
- * even when higher priority networks are active.
- *
- * @param context The {@link Context} to set the setting.
- * @param enable Whether the wifi data connection should remain active even when higher
- * priority networks are active
- */
- public static void setWifiAlwaysRequested(@NonNull Context context, boolean enable) {
- Settings.Global.putInt(
- context.getContentResolver(), WIFI_ALWAYS_REQUESTED, (enable ? 1 : 0));
- }
-
- /**
- * Get avoid bad wifi setting from {@link Settings}.
- *
- * @param context The {@link Context} to query the setting.
- * @return The setting whether to automatically switch away from wifi networks that lose
- * internet access.
- */
- @NetworkAvoidBadWifi
- public static int getNetworkAvoidBadWifi(@NonNull Context context) {
- final String setting =
- Settings.Global.getString(context.getContentResolver(), NETWORK_AVOID_BAD_WIFI);
- if ("0".equals(setting)) {
- return NETWORK_AVOID_BAD_WIFI_IGNORE;
- } else if ("1".equals(setting)) {
- return NETWORK_AVOID_BAD_WIFI_AVOID;
- } else {
- return NETWORK_AVOID_BAD_WIFI_PROMPT;
- }
- }
-
- /**
- * Set avoid bad wifi setting to {@link Settings}.
- *
- * @param context The {@link Context} to set the setting.
- * @param value Whether to automatically switch away from wifi networks that lose internet
- * access.
- */
- public static void setNetworkAvoidBadWifi(@NonNull Context context,
- @NetworkAvoidBadWifi int value) {
- final String setting;
- if (value == NETWORK_AVOID_BAD_WIFI_IGNORE) {
- setting = "0";
- } else if (value == NETWORK_AVOID_BAD_WIFI_AVOID) {
- setting = "1";
- } else if (value == NETWORK_AVOID_BAD_WIFI_PROMPT) {
- setting = null;
- } else {
- throw new IllegalArgumentException("Invalid avoid bad wifi setting");
- }
- Settings.Global.putString(context.getContentResolver(), NETWORK_AVOID_BAD_WIFI, setting);
- }
-
- /**
- * Get network metered multipath preference from {@link Settings}.
- *
- * @param context The {@link Context} to query the setting.
- * @return The network metered multipath preference which should be one of
- * ConnectivityManager#MULTIPATH_PREFERENCE_* value or null if the value specified
- * by config_networkMeteredMultipathPreference is used.
- */
- @Nullable
- public static String getNetworkMeteredMultipathPreference(@NonNull Context context) {
- return Settings.Global.getString(
- context.getContentResolver(), NETWORK_METERED_MULTIPATH_PREFERENCE);
- }
-
- /**
- * Set network metered multipath preference to {@link Settings}.
- *
- * @param context The {@link Context} to set the setting.
- * @param preference The network metered multipath preference which should be one of
- * ConnectivityManager#MULTIPATH_PREFERENCE_* value or null if the value
- * specified by config_networkMeteredMultipathPreference is used.
- */
- public static void setNetworkMeteredMultipathPreference(@NonNull Context context,
- @NonNull @MultipathPreference String preference) {
- if (!(Integer.valueOf(preference) == MULTIPATH_PREFERENCE_HANDOVER
- || Integer.valueOf(preference) == MULTIPATH_PREFERENCE_RELIABILITY
- || Integer.valueOf(preference) == MULTIPATH_PREFERENCE_PERFORMANCE)) {
- throw new IllegalArgumentException("Invalid private dns mode");
- }
- Settings.Global.putString(
- context.getContentResolver(), NETWORK_METERED_MULTIPATH_PREFERENCE, preference);
- }
-
- /**
- * Get the list of uids(from {@link Settings}) that should go on cellular networks in preference
- * even when higher-priority networks are connected.
- *
- * @param context The {@link Context} to query the setting.
- * @return A list of uids that should go on cellular networks in preference even when
- * higher-priority networks are connected or null if no setting value.
- */
- @NonNull
- public static Set<Integer> getMobileDataPreferredUids(@NonNull Context context) {
- final String uidList = Settings.Secure.getString(
- context.getContentResolver(), MOBILE_DATA_PREFERRED_UIDS);
- final Set<Integer> uids = new ArraySet<>();
- if (TextUtils.isEmpty(uidList)) {
- return uids;
- }
- for (String uid : uidList.split(";")) {
- uids.add(Integer.valueOf(uid));
- }
- return uids;
- }
-
- /**
- * Set the list of uids(to {@link Settings}) that should go on cellular networks in preference
- * even when higher-priority networks are connected.
- *
- * @param context The {@link Context} to set the setting.
- * @param uidList A list of uids that should go on cellular networks in preference even when
- * higher-priority networks are connected.
- */
- public static void setMobileDataPreferredUids(@NonNull Context context,
- @NonNull Set<Integer> uidList) {
- final StringJoiner joiner = new StringJoiner(";");
- for (Integer uid : uidList) {
- if (uid < 0 || UserHandle.getAppId(uid) > Process.LAST_APPLICATION_UID) {
- throw new IllegalArgumentException("Invalid uid");
- }
- joiner.add(uid.toString());
- }
- Settings.Secure.putString(
- context.getContentResolver(), MOBILE_DATA_PREFERRED_UIDS, joiner.toString());
- }
-
- /**
- * Get the list of apps(from {@link Settings}) that is allowed on restricted networks.
- *
- * @param context The {@link Context} to query the setting.
- * @return A list of apps that is allowed on restricted networks or null if no setting
- * value.
- */
- @NonNull
- public static Set<String> getAppsAllowedOnRestrictedNetworks(@NonNull Context context) {
- final String appList = Settings.Secure.getString(
- context.getContentResolver(), APPS_ALLOWED_ON_RESTRICTED_NETWORKS);
- if (TextUtils.isEmpty(appList)) {
- return new ArraySet<>();
- }
- return new ArraySet<>(appList.split(";"));
- }
-
- /**
- * Set the list of apps(from {@link Settings}) that is allowed on restricted networks.
- *
- * Note: Please refer to android developer guidelines for valid app(package name).
- * https://developer.android.com/guide/topics/manifest/manifest-element.html#package
- *
- * @param context The {@link Context} to set the setting.
- * @param list A list of apps that is allowed on restricted networks.
- */
- public static void setAppsAllowedOnRestrictedNetworks(@NonNull Context context,
- @NonNull Set<String> list) {
- final StringJoiner joiner = new StringJoiner(";");
- for (String app : list) {
- if (app == null || app.contains(";")) {
- throw new IllegalArgumentException("Invalid app(package name)");
- }
- joiner.add(app);
- }
- Settings.Secure.putString(context.getContentResolver(), APPS_ALLOWED_ON_RESTRICTED_NETWORKS,
- joiner.toString());
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityThread.java b/packages/Connectivity/framework/src/android/net/ConnectivityThread.java
deleted file mode 100644
index 0b218e7..0000000
--- a/packages/Connectivity/framework/src/android/net/ConnectivityThread.java
+++ /dev/null
@@ -1,56 +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 android.os.HandlerThread;
-import android.os.Looper;
-
-/**
- * Shared singleton connectivity thread for the system. This is a thread for
- * connectivity operations such as AsyncChannel connections to system services.
- * Various connectivity manager objects can use this singleton as a common
- * resource for their handlers instead of creating separate threads of their own.
- * @hide
- */
-public final class ConnectivityThread extends HandlerThread {
-
- // A class implementing the lazy holder idiom: the unique static instance
- // of ConnectivityThread is instantiated in a thread-safe way (guaranteed by
- // the language specs) the first time that Singleton is referenced in get()
- // or getInstanceLooper().
- private static class Singleton {
- private static final ConnectivityThread INSTANCE = createInstance();
- }
-
- private ConnectivityThread() {
- super("ConnectivityThread");
- }
-
- private static ConnectivityThread createInstance() {
- ConnectivityThread t = new ConnectivityThread();
- t.start();
- return t;
- }
-
- public static ConnectivityThread get() {
- return Singleton.INSTANCE;
- }
-
- public static Looper getInstanceLooper() {
- return Singleton.INSTANCE.getLooper();
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/DhcpInfo.java b/packages/Connectivity/framework/src/android/net/DhcpInfo.java
deleted file mode 100644
index 912df67..0000000
--- a/packages/Connectivity/framework/src/android/net/DhcpInfo.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2008 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.Parcel;
-import android.os.Parcelable;
-
-/**
- * A simple object for retrieving the results of a DHCP request.
- */
-public class DhcpInfo implements Parcelable {
- public int ipAddress;
- public int gateway;
- public int netmask;
- public int dns1;
- public int dns2;
- public int serverAddress;
-
- public int leaseDuration;
-
- public DhcpInfo() {
- super();
- }
-
- /** copy constructor {@hide} */
- public DhcpInfo(DhcpInfo source) {
- if (source != null) {
- ipAddress = source.ipAddress;
- gateway = source.gateway;
- netmask = source.netmask;
- dns1 = source.dns1;
- dns2 = source.dns2;
- serverAddress = source.serverAddress;
- leaseDuration = source.leaseDuration;
- }
- }
-
- public String toString() {
- StringBuffer str = new StringBuffer();
-
- str.append("ipaddr "); putAddress(str, ipAddress);
- str.append(" gateway "); putAddress(str, gateway);
- str.append(" netmask "); putAddress(str, netmask);
- str.append(" dns1 "); putAddress(str, dns1);
- str.append(" dns2 "); putAddress(str, dns2);
- str.append(" DHCP server "); putAddress(str, serverAddress);
- str.append(" lease ").append(leaseDuration).append(" seconds");
-
- return str.toString();
- }
-
- private static void putAddress(StringBuffer buf, int addr) {
- buf.append(NetworkUtils.intToInetAddress(addr).getHostAddress());
- }
-
- /** Implement the Parcelable interface */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(ipAddress);
- dest.writeInt(gateway);
- dest.writeInt(netmask);
- dest.writeInt(dns1);
- dest.writeInt(dns2);
- dest.writeInt(serverAddress);
- dest.writeInt(leaseDuration);
- }
-
- /** Implement the Parcelable interface */
- public static final @android.annotation.NonNull Creator<DhcpInfo> CREATOR =
- new Creator<DhcpInfo>() {
- public DhcpInfo createFromParcel(Parcel in) {
- DhcpInfo info = new DhcpInfo();
- info.ipAddress = in.readInt();
- info.gateway = in.readInt();
- info.netmask = in.readInt();
- info.dns1 = in.readInt();
- info.dns2 = in.readInt();
- info.serverAddress = in.readInt();
- info.leaseDuration = in.readInt();
- return info;
- }
-
- public DhcpInfo[] newArray(int size) {
- return new DhcpInfo[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/DnsResolver.java b/packages/Connectivity/framework/src/android/net/DnsResolver.java
deleted file mode 100644
index dac88ad..0000000
--- a/packages/Connectivity/framework/src/android/net/DnsResolver.java
+++ /dev/null
@@ -1,577 +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 android.net.NetworkUtils.getDnsNetwork;
-import static android.net.NetworkUtils.resNetworkCancel;
-import static android.net.NetworkUtils.resNetworkQuery;
-import static android.net.NetworkUtils.resNetworkResult;
-import static android.net.NetworkUtils.resNetworkSend;
-import static android.net.util.DnsUtils.haveIpv4;
-import static android.net.util.DnsUtils.haveIpv6;
-import static android.net.util.DnsUtils.rfc6724Sort;
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
-import static android.system.OsConstants.ENONET;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.CancellationSignal;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.system.ErrnoException;
-import android.util.Log;
-
-import com.android.net.module.util.DnsPacket;
-
-import java.io.FileDescriptor;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * Dns resolver class for asynchronous dns querying
- *
- * Note that if a client sends a query with more than 1 record in the question section but
- * the remote dns server does not support this, it may not respond at all, leading to a timeout.
- *
- */
-public final class DnsResolver {
- private static final String TAG = "DnsResolver";
- private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR;
- private static final int MAXPACKET = 8 * 1024;
- private static final int SLEEP_TIME_MS = 2;
-
- @IntDef(prefix = { "CLASS_" }, value = {
- CLASS_IN
- })
- @Retention(RetentionPolicy.SOURCE)
- @interface QueryClass {}
- public static final int CLASS_IN = 1;
-
- @IntDef(prefix = { "TYPE_" }, value = {
- TYPE_A,
- TYPE_AAAA
- })
- @Retention(RetentionPolicy.SOURCE)
- @interface QueryType {}
- public static final int TYPE_A = 1;
- public static final int TYPE_AAAA = 28;
-
- @IntDef(prefix = { "FLAG_" }, value = {
- FLAG_EMPTY,
- FLAG_NO_RETRY,
- FLAG_NO_CACHE_STORE,
- FLAG_NO_CACHE_LOOKUP
- })
- @Retention(RetentionPolicy.SOURCE)
- @interface QueryFlag {}
- public static final int FLAG_EMPTY = 0;
- public static final int FLAG_NO_RETRY = 1 << 0;
- public static final int FLAG_NO_CACHE_STORE = 1 << 1;
- public static final int FLAG_NO_CACHE_LOOKUP = 1 << 2;
-
- @IntDef(prefix = { "ERROR_" }, value = {
- ERROR_PARSE,
- ERROR_SYSTEM
- })
- @Retention(RetentionPolicy.SOURCE)
- @interface DnsError {}
- /**
- * Indicates that there was an error parsing the response the query.
- * The cause of this error is available via getCause() and is a {@link ParseException}.
- */
- public static final int ERROR_PARSE = 0;
- /**
- * Indicates that there was an error sending the query.
- * The cause of this error is available via getCause() and is an ErrnoException.
- */
- public static final int ERROR_SYSTEM = 1;
-
- private static final int NETID_UNSET = 0;
-
- private static final DnsResolver sInstance = new DnsResolver();
-
- /**
- * Get instance for DnsResolver
- */
- public static @NonNull DnsResolver getInstance() {
- return sInstance;
- }
-
- private DnsResolver() {}
-
- /**
- * Base interface for answer callbacks
- *
- * @param <T> The type of the answer
- */
- public interface Callback<T> {
- /**
- * Success response to
- * {@link android.net.DnsResolver#query query()} or
- * {@link android.net.DnsResolver#rawQuery rawQuery()}.
- *
- * Invoked when the answer to a query was successfully parsed.
- *
- * @param answer <T> answer to the query.
- * @param rcode The response code in the DNS response.
- *
- * {@see android.net.DnsResolver#query query()}
- */
- void onAnswer(@NonNull T answer, int rcode);
- /**
- * Error response to
- * {@link android.net.DnsResolver#query query()} or
- * {@link android.net.DnsResolver#rawQuery rawQuery()}.
- *
- * Invoked when there is no valid answer to
- * {@link android.net.DnsResolver#query query()}
- * {@link android.net.DnsResolver#rawQuery rawQuery()}.
- *
- * @param error a {@link DnsException} object with additional
- * detail regarding the failure
- */
- void onError(@NonNull DnsException error);
- }
-
- /**
- * Class to represent DNS error
- */
- public static class DnsException extends Exception {
- /**
- * DNS error code as one of the ERROR_* constants
- */
- @DnsError public final int code;
-
- DnsException(@DnsError int code, @Nullable Throwable cause) {
- super(cause);
- this.code = code;
- }
- }
-
- /**
- * Send a raw DNS query.
- * The answer will be provided asynchronously through the provided {@link Callback}.
- *
- * @param network {@link Network} specifying which network to query on.
- * {@code null} for query on default network.
- * @param query blob message to query
- * @param flags flags as a combination of the FLAGS_* constants
- * @param executor The {@link Executor} that the callback should be executed on.
- * @param cancellationSignal used by the caller to signal if the query should be
- * cancelled. May be {@code null}.
- * @param callback a {@link Callback} which will be called to notify the caller
- * of the result of dns query.
- */
- public void rawQuery(@Nullable Network network, @NonNull byte[] query, @QueryFlag int flags,
- @NonNull @CallbackExecutor Executor executor,
- @Nullable CancellationSignal cancellationSignal,
- @NonNull Callback<? super byte[]> callback) {
- if (cancellationSignal != null && cancellationSignal.isCanceled()) {
- return;
- }
- final Object lock = new Object();
- final FileDescriptor queryfd;
- try {
- queryfd = resNetworkSend((network != null)
- ? network.getNetIdForResolv() : NETID_UNSET, query, query.length, flags);
- } catch (ErrnoException e) {
- executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
- return;
- }
-
- synchronized (lock) {
- registerFDListener(executor, queryfd, callback, cancellationSignal, lock);
- if (cancellationSignal == null) return;
- addCancellationSignal(cancellationSignal, queryfd, lock);
- }
- }
-
- /**
- * Send a DNS query with the specified name, class and query type.
- * The answer will be provided asynchronously through the provided {@link Callback}.
- *
- * @param network {@link Network} specifying which network to query on.
- * {@code null} for query on default network.
- * @param domain domain name to query
- * @param nsClass dns class as one of the CLASS_* constants
- * @param nsType dns resource record (RR) type as one of the TYPE_* constants
- * @param flags flags as a combination of the FLAGS_* constants
- * @param executor The {@link Executor} that the callback should be executed on.
- * @param cancellationSignal used by the caller to signal if the query should be
- * cancelled. May be {@code null}.
- * @param callback a {@link Callback} which will be called to notify the caller
- * of the result of dns query.
- */
- public void rawQuery(@Nullable Network network, @NonNull String domain,
- @QueryClass int nsClass, @QueryType int nsType, @QueryFlag int flags,
- @NonNull @CallbackExecutor Executor executor,
- @Nullable CancellationSignal cancellationSignal,
- @NonNull Callback<? super byte[]> callback) {
- if (cancellationSignal != null && cancellationSignal.isCanceled()) {
- return;
- }
- final Object lock = new Object();
- final FileDescriptor queryfd;
- try {
- queryfd = resNetworkQuery((network != null)
- ? network.getNetIdForResolv() : NETID_UNSET, domain, nsClass, nsType, flags);
- } catch (ErrnoException e) {
- executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
- return;
- }
- synchronized (lock) {
- registerFDListener(executor, queryfd, callback, cancellationSignal, lock);
- if (cancellationSignal == null) return;
- addCancellationSignal(cancellationSignal, queryfd, lock);
- }
- }
-
- private class InetAddressAnswerAccumulator implements Callback<byte[]> {
- private final List<InetAddress> mAllAnswers;
- private final Network mNetwork;
- private int mRcode;
- private DnsException mDnsException;
- private final Callback<? super List<InetAddress>> mUserCallback;
- private final int mTargetAnswerCount;
- private int mReceivedAnswerCount = 0;
-
- InetAddressAnswerAccumulator(@NonNull Network network, int size,
- @NonNull Callback<? super List<InetAddress>> callback) {
- mNetwork = network;
- mTargetAnswerCount = size;
- mAllAnswers = new ArrayList<>();
- mUserCallback = callback;
- }
-
- private boolean maybeReportError() {
- if (mRcode != 0) {
- mUserCallback.onAnswer(mAllAnswers, mRcode);
- return true;
- }
- if (mDnsException != null) {
- mUserCallback.onError(mDnsException);
- return true;
- }
- return false;
- }
-
- private void maybeReportAnswer() {
- if (++mReceivedAnswerCount != mTargetAnswerCount) return;
- if (mAllAnswers.isEmpty() && maybeReportError()) return;
- mUserCallback.onAnswer(rfc6724Sort(mNetwork, mAllAnswers), mRcode);
- }
-
- @Override
- public void onAnswer(@NonNull byte[] answer, int rcode) {
- // If at least one query succeeded, return an rcode of 0.
- // Otherwise, arbitrarily return the first rcode received.
- if (mReceivedAnswerCount == 0 || rcode == 0) {
- mRcode = rcode;
- }
- try {
- mAllAnswers.addAll(new DnsAddressAnswer(answer).getAddresses());
- } catch (DnsPacket.ParseException e) {
- // Convert the com.android.net.module.util.DnsPacket.ParseException to an
- // android.net.ParseException. This is the type that was used in Q and is implied
- // by the public documentation of ERROR_PARSE.
- //
- // DnsPacket cannot throw android.net.ParseException directly because it's @hide.
- ParseException pe = new ParseException(e.reason, e.getCause());
- pe.setStackTrace(e.getStackTrace());
- mDnsException = new DnsException(ERROR_PARSE, pe);
- }
- maybeReportAnswer();
- }
-
- @Override
- public void onError(@NonNull DnsException error) {
- mDnsException = error;
- maybeReportAnswer();
- }
- }
-
- /**
- * Send a DNS query with the specified name on a network with both IPv4 and IPv6,
- * get back a set of InetAddresses with rfc6724 sorting style asynchronously.
- *
- * This method will examine the connection ability on given network, and query IPv4
- * and IPv6 if connection is available.
- *
- * If at least one query succeeded with valid answer, rcode will be 0
- *
- * The answer will be provided asynchronously through the provided {@link Callback}.
- *
- * @param network {@link Network} specifying which network to query on.
- * {@code null} for query on default network.
- * @param domain domain name to query
- * @param flags flags as a combination of the FLAGS_* constants
- * @param executor The {@link Executor} that the callback should be executed on.
- * @param cancellationSignal used by the caller to signal if the query should be
- * cancelled. May be {@code null}.
- * @param callback a {@link Callback} which will be called to notify the
- * caller of the result of dns query.
- */
- public void query(@Nullable Network network, @NonNull String domain, @QueryFlag int flags,
- @NonNull @CallbackExecutor Executor executor,
- @Nullable CancellationSignal cancellationSignal,
- @NonNull Callback<? super List<InetAddress>> callback) {
- if (cancellationSignal != null && cancellationSignal.isCanceled()) {
- return;
- }
- final Object lock = new Object();
- final Network queryNetwork;
- try {
- queryNetwork = (network != null) ? network : getDnsNetwork();
- } catch (ErrnoException e) {
- executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
- return;
- }
- final boolean queryIpv6 = haveIpv6(queryNetwork);
- final boolean queryIpv4 = haveIpv4(queryNetwork);
-
- // This can only happen if queryIpv4 and queryIpv6 are both false.
- // This almost certainly means that queryNetwork does not exist or no longer exists.
- if (!queryIpv6 && !queryIpv4) {
- executor.execute(() -> callback.onError(
- new DnsException(ERROR_SYSTEM, new ErrnoException("resNetworkQuery", ENONET))));
- return;
- }
-
- final FileDescriptor v4fd;
- final FileDescriptor v6fd;
-
- int queryCount = 0;
-
- if (queryIpv6) {
- try {
- v6fd = resNetworkQuery(queryNetwork.getNetIdForResolv(), domain, CLASS_IN,
- TYPE_AAAA, flags);
- } catch (ErrnoException e) {
- executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
- return;
- }
- queryCount++;
- } else v6fd = null;
-
- // Avoiding gateways drop packets if queries are sent too close together
- try {
- Thread.sleep(SLEEP_TIME_MS);
- } catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
-
- if (queryIpv4) {
- try {
- v4fd = resNetworkQuery(queryNetwork.getNetIdForResolv(), domain, CLASS_IN, TYPE_A,
- flags);
- } catch (ErrnoException e) {
- if (queryIpv6) resNetworkCancel(v6fd); // Closes fd, marks it invalid.
- executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
- return;
- }
- queryCount++;
- } else v4fd = null;
-
- final InetAddressAnswerAccumulator accumulator =
- new InetAddressAnswerAccumulator(queryNetwork, queryCount, callback);
-
- synchronized (lock) {
- if (queryIpv6) {
- registerFDListener(executor, v6fd, accumulator, cancellationSignal, lock);
- }
- if (queryIpv4) {
- registerFDListener(executor, v4fd, accumulator, cancellationSignal, lock);
- }
- if (cancellationSignal == null) return;
- cancellationSignal.setOnCancelListener(() -> {
- synchronized (lock) {
- if (queryIpv4) cancelQuery(v4fd);
- if (queryIpv6) cancelQuery(v6fd);
- }
- });
- }
- }
-
- /**
- * Send a DNS query with the specified name and query type, get back a set of
- * InetAddresses with rfc6724 sorting style asynchronously.
- *
- * The answer will be provided asynchronously through the provided {@link Callback}.
- *
- * @param network {@link Network} specifying which network to query on.
- * {@code null} for query on default network.
- * @param domain domain name to query
- * @param nsType dns resource record (RR) type as one of the TYPE_* constants
- * @param flags flags as a combination of the FLAGS_* constants
- * @param executor The {@link Executor} that the callback should be executed on.
- * @param cancellationSignal used by the caller to signal if the query should be
- * cancelled. May be {@code null}.
- * @param callback a {@link Callback} which will be called to notify the caller
- * of the result of dns query.
- */
- public void query(@Nullable Network network, @NonNull String domain,
- @QueryType int nsType, @QueryFlag int flags,
- @NonNull @CallbackExecutor Executor executor,
- @Nullable CancellationSignal cancellationSignal,
- @NonNull Callback<? super List<InetAddress>> callback) {
- if (cancellationSignal != null && cancellationSignal.isCanceled()) {
- return;
- }
- final Object lock = new Object();
- final FileDescriptor queryfd;
- final Network queryNetwork;
- try {
- queryNetwork = (network != null) ? network : getDnsNetwork();
- queryfd = resNetworkQuery(queryNetwork.getNetIdForResolv(), domain, CLASS_IN, nsType,
- flags);
- } catch (ErrnoException e) {
- executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
- return;
- }
- final InetAddressAnswerAccumulator accumulator =
- new InetAddressAnswerAccumulator(queryNetwork, 1, callback);
- synchronized (lock) {
- registerFDListener(executor, queryfd, accumulator, cancellationSignal, lock);
- if (cancellationSignal == null) return;
- addCancellationSignal(cancellationSignal, queryfd, lock);
- }
- }
-
- /**
- * Class to retrieve DNS response
- *
- * @hide
- */
- public static final class DnsResponse {
- public final @NonNull byte[] answerbuf;
- public final int rcode;
- public DnsResponse(@NonNull byte[] answerbuf, int rcode) {
- this.answerbuf = answerbuf;
- this.rcode = rcode;
- }
- }
-
- private void registerFDListener(@NonNull Executor executor,
- @NonNull FileDescriptor queryfd, @NonNull Callback<? super byte[]> answerCallback,
- @Nullable CancellationSignal cancellationSignal, @NonNull Object lock) {
- final MessageQueue mainThreadMessageQueue = Looper.getMainLooper().getQueue();
- mainThreadMessageQueue.addOnFileDescriptorEventListener(
- queryfd,
- FD_EVENTS,
- (fd, events) -> {
- // b/134310704
- // Unregister fd event listener before resNetworkResult is called to prevent
- // race condition caused by fd reused.
- // For example when querying v4 and v6, it's possible that the first query ends
- // and the fd is closed before the second request starts, which might return
- // the same fd for the second request. By that time, the looper must have
- // unregistered the fd, otherwise another event listener can't be registered.
- mainThreadMessageQueue.removeOnFileDescriptorEventListener(fd);
-
- executor.execute(() -> {
- DnsResponse resp = null;
- ErrnoException exception = null;
- synchronized (lock) {
- if (cancellationSignal != null && cancellationSignal.isCanceled()) {
- return;
- }
- try {
- resp = resNetworkResult(fd); // Closes fd, marks it invalid.
- } catch (ErrnoException e) {
- Log.w(TAG, "resNetworkResult:" + e.toString());
- exception = e;
- }
- }
- if (exception != null) {
- answerCallback.onError(new DnsException(ERROR_SYSTEM, exception));
- return;
- }
- answerCallback.onAnswer(resp.answerbuf, resp.rcode);
- });
-
- // The file descriptor has already been unregistered, so it does not really
- // matter what is returned here. In spirit 0 (meaning "unregister this FD")
- // is still the closest to what the looper needs to do. When returning 0,
- // Looper knows to ignore the fd if it has already been unregistered.
- return 0;
- });
- }
-
- private void cancelQuery(@NonNull FileDescriptor queryfd) {
- if (!queryfd.valid()) return;
- Looper.getMainLooper().getQueue().removeOnFileDescriptorEventListener(queryfd);
- resNetworkCancel(queryfd); // Closes fd, marks it invalid.
- }
-
- private void addCancellationSignal(@NonNull CancellationSignal cancellationSignal,
- @NonNull FileDescriptor queryfd, @NonNull Object lock) {
- cancellationSignal.setOnCancelListener(() -> {
- synchronized (lock) {
- cancelQuery(queryfd);
- }
- });
- }
-
- private static class DnsAddressAnswer extends DnsPacket {
- private static final String TAG = "DnsResolver.DnsAddressAnswer";
- private static final boolean DBG = false;
-
- private final int mQueryType;
-
- DnsAddressAnswer(@NonNull byte[] data) throws ParseException {
- super(data);
- if ((mHeader.flags & (1 << 15)) == 0) {
- throw new ParseException("Not an answer packet");
- }
- if (mHeader.getRecordCount(QDSECTION) == 0) {
- throw new ParseException("No question found");
- }
- // Expect only one question in question section.
- mQueryType = mRecords[QDSECTION].get(0).nsType;
- }
-
- public @NonNull List<InetAddress> getAddresses() {
- final List<InetAddress> results = new ArrayList<InetAddress>();
- if (mHeader.getRecordCount(ANSECTION) == 0) return results;
-
- for (final DnsRecord ansSec : mRecords[ANSECTION]) {
- // Only support A and AAAA, also ignore answers if query type != answer type.
- int nsType = ansSec.nsType;
- if (nsType != mQueryType || (nsType != TYPE_A && nsType != TYPE_AAAA)) {
- continue;
- }
- try {
- results.add(InetAddress.getByAddress(ansSec.getRR()));
- } catch (UnknownHostException e) {
- if (DBG) {
- Log.w(TAG, "rr to address fail");
- }
- }
- }
- return results;
- }
- }
-
-}
diff --git a/packages/Connectivity/framework/src/android/net/DnsResolverServiceManager.java b/packages/Connectivity/framework/src/android/net/DnsResolverServiceManager.java
deleted file mode 100644
index 79009e8..0000000
--- a/packages/Connectivity/framework/src/android/net/DnsResolverServiceManager.java
+++ /dev/null
@@ -1,45 +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.annotation.NonNull;
-import android.os.IBinder;
-
-/**
- * Provides a way to obtain the DnsResolver binder objects.
- *
- * @hide
- */
-public class DnsResolverServiceManager {
- /** Service name for the DNS resolver. Keep in sync with DnsResolverService.h */
- public static final String DNS_RESOLVER_SERVICE = "dnsresolver";
-
- private final IBinder mResolver;
-
- DnsResolverServiceManager(IBinder resolver) {
- mResolver = resolver;
- }
-
- /**
- * Get an {@link IBinder} representing the DnsResolver stable AIDL interface
- *
- * @return {@link android.net.IDnsResolver} IBinder.
- */
- @NonNull
- public IBinder getService() {
- return mResolver;
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/ICaptivePortal.aidl b/packages/Connectivity/framework/src/android/net/ICaptivePortal.aidl
deleted file mode 100644
index e35f8d4..0000000
--- a/packages/Connectivity/framework/src/android/net/ICaptivePortal.aidl
+++ /dev/null
@@ -1,26 +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;
-
-/**
- * Interface to inform NetworkMonitor of decisions of app handling captive portal.
- * @hide
- */
-oneway interface ICaptivePortal {
- void appRequest(int request);
- void appResponse(int response);
-}
diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityDiagnosticsCallback.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityDiagnosticsCallback.aidl
deleted file mode 100644
index 82b64a9..0000000
--- a/packages/Connectivity/framework/src/android/net/IConnectivityDiagnosticsCallback.aidl
+++ /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 android.net;
-
-import android.net.ConnectivityDiagnosticsManager;
-import android.net.Network;
-
-/** @hide */
-oneway interface IConnectivityDiagnosticsCallback {
- void onConnectivityReportAvailable(in ConnectivityDiagnosticsManager.ConnectivityReport report);
- void onDataStallSuspected(in ConnectivityDiagnosticsManager.DataStallReport report);
- void onNetworkConnectivityReported(in Network n, boolean hasConnectivity);
-}
\ No newline at end of file
diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
deleted file mode 100644
index c434bbc..0000000
--- a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
+++ /dev/null
@@ -1,229 +0,0 @@
-/**
- * Copyright (c) 2008, 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.PendingIntent;
-import android.net.ConnectionInfo;
-import android.net.ConnectivityDiagnosticsManager;
-import android.net.IConnectivityDiagnosticsCallback;
-import android.net.INetworkAgent;
-import android.net.IOnCompleteListener;
-import android.net.INetworkActivityListener;
-import android.net.INetworkOfferCallback;
-import android.net.IQosCallback;
-import android.net.ISocketKeepaliveCallback;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkAgentConfig;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkRequest;
-import android.net.NetworkScore;
-import android.net.NetworkState;
-import android.net.NetworkStateSnapshot;
-import android.net.OemNetworkPreferences;
-import android.net.ProxyInfo;
-import android.net.UidRange;
-import android.net.QosSocketInfo;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Messenger;
-import android.os.ParcelFileDescriptor;
-import android.os.PersistableBundle;
-import android.os.ResultReceiver;
-import android.os.UserHandle;
-
-/**
- * Interface that answers queries about, and allows changing, the
- * state of network connectivity.
- */
-/** {@hide} */
-interface IConnectivityManager
-{
- Network getActiveNetwork();
- Network getActiveNetworkForUid(int uid, boolean ignoreBlocked);
- @UnsupportedAppUsage
- NetworkInfo getActiveNetworkInfo();
- NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked);
- @UnsupportedAppUsage(maxTargetSdk = 28)
- NetworkInfo getNetworkInfo(int networkType);
- NetworkInfo getNetworkInfoForUid(in Network network, int uid, boolean ignoreBlocked);
- @UnsupportedAppUsage
- NetworkInfo[] getAllNetworkInfo();
- Network getNetworkForType(int networkType);
- Network[] getAllNetworks();
- NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(
- int userId, String callingPackageName, String callingAttributionTag);
-
- boolean isNetworkSupported(int networkType);
-
- @UnsupportedAppUsage
- LinkProperties getActiveLinkProperties();
- LinkProperties getLinkPropertiesForType(int networkType);
- LinkProperties getLinkProperties(in Network network);
-
- NetworkCapabilities getNetworkCapabilities(in Network network, String callingPackageName,
- String callingAttributionTag);
-
- @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- NetworkState[] getAllNetworkState();
-
- List<NetworkStateSnapshot> getAllNetworkStateSnapshots();
-
- boolean isActiveNetworkMetered();
-
- boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress,
- String callingPackageName, String callingAttributionTag);
-
- @UnsupportedAppUsage(maxTargetSdk = 29,
- publicAlternatives = "Use {@code TetheringManager#getLastTetherError} as alternative")
- int getLastTetherError(String iface);
-
- @UnsupportedAppUsage(maxTargetSdk = 29,
- publicAlternatives = "Use {@code TetheringManager#getTetherableIfaces} as alternative")
- String[] getTetherableIfaces();
-
- @UnsupportedAppUsage(maxTargetSdk = 29,
- publicAlternatives = "Use {@code TetheringManager#getTetheredIfaces} as alternative")
- String[] getTetheredIfaces();
-
- @UnsupportedAppUsage(maxTargetSdk = 29,
- publicAlternatives = "Use {@code TetheringManager#getTetheringErroredIfaces} "
- + "as Alternative")
- String[] getTetheringErroredIfaces();
-
- @UnsupportedAppUsage(maxTargetSdk = 29,
- publicAlternatives = "Use {@code TetheringManager#getTetherableUsbRegexs} as alternative")
- String[] getTetherableUsbRegexs();
-
- @UnsupportedAppUsage(maxTargetSdk = 29,
- publicAlternatives = "Use {@code TetheringManager#getTetherableWifiRegexs} as alternative")
- String[] getTetherableWifiRegexs();
-
- @UnsupportedAppUsage(maxTargetSdk = 28)
- void reportInetCondition(int networkType, int percentage);
-
- void reportNetworkConnectivity(in Network network, boolean hasConnectivity);
-
- ProxyInfo getGlobalProxy();
-
- void setGlobalProxy(in ProxyInfo p);
-
- ProxyInfo getProxyForNetwork(in Network nework);
-
- void setRequireVpnForUids(boolean requireVpn, in UidRange[] ranges);
- void setLegacyLockdownVpnEnabled(boolean enabled);
-
- void setProvisioningNotificationVisible(boolean visible, int networkType, in String action);
-
- void setAirplaneMode(boolean enable);
-
- boolean requestBandwidthUpdate(in Network network);
-
- int registerNetworkProvider(in Messenger messenger, in String name);
- void unregisterNetworkProvider(in Messenger messenger);
-
- void declareNetworkRequestUnfulfillable(in NetworkRequest request);
-
- Network registerNetworkAgent(in INetworkAgent na, in NetworkInfo ni, in LinkProperties lp,
- in NetworkCapabilities nc, in NetworkScore score, in NetworkAgentConfig config,
- in int factorySerialNumber);
-
- NetworkRequest requestNetwork(int uid, in NetworkCapabilities networkCapabilities, int reqType,
- in Messenger messenger, int timeoutSec, in IBinder binder, int legacy,
- int callbackFlags, String callingPackageName, String callingAttributionTag);
-
- NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities,
- in PendingIntent operation, String callingPackageName, String callingAttributionTag);
-
- void releasePendingNetworkRequest(in PendingIntent operation);
-
- NetworkRequest listenForNetwork(in NetworkCapabilities networkCapabilities,
- in Messenger messenger, in IBinder binder, int callbackFlags, String callingPackageName,
- String callingAttributionTag);
-
- void pendingListenForNetwork(in NetworkCapabilities networkCapabilities,
- in PendingIntent operation, String callingPackageName,
- String callingAttributionTag);
-
- void releaseNetworkRequest(in NetworkRequest networkRequest);
-
- void setAcceptUnvalidated(in Network network, boolean accept, boolean always);
- void setAcceptPartialConnectivity(in Network network, boolean accept, boolean always);
- void setAvoidUnvalidated(in Network network);
- void startCaptivePortalApp(in Network network);
- void startCaptivePortalAppInternal(in Network network, in Bundle appExtras);
-
- boolean shouldAvoidBadWifi();
- int getMultipathPreference(in Network Network);
-
- NetworkRequest getDefaultRequest();
-
- int getRestoreDefaultNetworkDelay(int networkType);
-
- void factoryReset();
-
- void startNattKeepalive(in Network network, int intervalSeconds,
- in ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr);
-
- void startNattKeepaliveWithFd(in Network network, in ParcelFileDescriptor pfd, int resourceId,
- int intervalSeconds, in ISocketKeepaliveCallback cb, String srcAddr,
- String dstAddr);
-
- void startTcpKeepalive(in Network network, in ParcelFileDescriptor pfd, int intervalSeconds,
- in ISocketKeepaliveCallback cb);
-
- void stopKeepalive(in Network network, int slot);
-
- String getCaptivePortalServerUrl();
-
- byte[] getNetworkWatchlistConfigHash();
-
- int getConnectionOwnerUid(in ConnectionInfo connectionInfo);
-
- void registerConnectivityDiagnosticsCallback(in IConnectivityDiagnosticsCallback callback,
- in NetworkRequest request, String callingPackageName);
- void unregisterConnectivityDiagnosticsCallback(in IConnectivityDiagnosticsCallback callback);
-
- IBinder startOrGetTestNetworkService();
-
- void simulateDataStall(int detectionMethod, long timestampMillis, in Network network,
- in PersistableBundle extras);
-
- void systemReady();
-
- void registerNetworkActivityListener(in INetworkActivityListener l);
-
- void unregisterNetworkActivityListener(in INetworkActivityListener l);
-
- boolean isDefaultNetworkActive();
-
- void registerQosSocketCallback(in QosSocketInfo socketInfo, in IQosCallback callback);
- void unregisterQosCallback(in IQosCallback callback);
-
- void setOemNetworkPreference(in OemNetworkPreferences preference,
- in IOnCompleteListener listener);
-
- void setProfileNetworkPreference(in UserHandle profile, int preference,
- in IOnCompleteListener listener);
-
- int getRestrictBackgroundStatusByCaller();
-
- void offerNetwork(int providerId, in NetworkScore score,
- in NetworkCapabilities caps, in INetworkOfferCallback callback);
- void unofferNetwork(in INetworkOfferCallback callback);
-}
diff --git a/packages/Connectivity/framework/src/android/net/INetworkActivityListener.aidl b/packages/Connectivity/framework/src/android/net/INetworkActivityListener.aidl
deleted file mode 100644
index 79687dd..0000000
--- a/packages/Connectivity/framework/src/android/net/INetworkActivityListener.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Copyright 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;
-
-/**
- * @hide
- */
-oneway interface INetworkActivityListener
-{
- void onNetworkActive();
-}
diff --git a/packages/Connectivity/framework/src/android/net/INetworkAgent.aidl b/packages/Connectivity/framework/src/android/net/INetworkAgent.aidl
deleted file mode 100644
index d941d4b..0000000
--- a/packages/Connectivity/framework/src/android/net/INetworkAgent.aidl
+++ /dev/null
@@ -1,51 +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 perNmissions and
- * limitations under the License.
- */
-package android.net;
-
-import android.net.NattKeepalivePacketData;
-import android.net.QosFilterParcelable;
-import android.net.TcpKeepalivePacketData;
-
-import android.net.INetworkAgentRegistry;
-
-/**
- * Interface to notify NetworkAgent of connectivity events.
- * @hide
- */
-oneway interface INetworkAgent {
- void onRegistered(in INetworkAgentRegistry registry);
- void onDisconnected();
- void onBandwidthUpdateRequested();
- void onValidationStatusChanged(int validationStatus,
- in @nullable String captivePortalUrl);
- void onSaveAcceptUnvalidated(boolean acceptUnvalidated);
- void onStartNattSocketKeepalive(int slot, int intervalDurationMs,
- in NattKeepalivePacketData packetData);
- void onStartTcpSocketKeepalive(int slot, int intervalDurationMs,
- in TcpKeepalivePacketData packetData);
- void onStopSocketKeepalive(int slot);
- void onSignalStrengthThresholdsUpdated(in int[] thresholds);
- void onPreventAutomaticReconnect();
- void onAddNattKeepalivePacketFilter(int slot,
- in NattKeepalivePacketData packetData);
- void onAddTcpKeepalivePacketFilter(int slot,
- in TcpKeepalivePacketData packetData);
- void onRemoveKeepalivePacketFilter(int slot);
- void onQosFilterCallbackRegistered(int qosCallbackId, in QosFilterParcelable filterParcel);
- void onQosCallbackUnregistered(int qosCallbackId);
- void onNetworkCreated();
- void onNetworkDestroyed();
-}
diff --git a/packages/Connectivity/framework/src/android/net/INetworkAgentRegistry.aidl b/packages/Connectivity/framework/src/android/net/INetworkAgentRegistry.aidl
deleted file mode 100644
index 9a58add..0000000
--- a/packages/Connectivity/framework/src/android/net/INetworkAgentRegistry.aidl
+++ /dev/null
@@ -1,46 +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 perNmissions and
- * limitations under the License.
- */
-package android.net;
-
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkScore;
-import android.net.QosSession;
-import android.telephony.data.EpsBearerQosSessionAttributes;
-import android.telephony.data.NrQosSessionAttributes;
-
-/**
- * Interface for NetworkAgents to send network properties.
- * @hide
- */
-oneway interface INetworkAgentRegistry {
- void sendNetworkCapabilities(in NetworkCapabilities nc);
- void sendLinkProperties(in LinkProperties lp);
- // TODO: consider replacing this by "markConnected()" and removing
- void sendNetworkInfo(in NetworkInfo info);
- void sendScore(in NetworkScore score);
- void sendExplicitlySelected(boolean explicitlySelected, boolean acceptPartial);
- void sendSocketKeepaliveEvent(int slot, int reason);
- void sendUnderlyingNetworks(in @nullable List<Network> networks);
- void sendEpsQosSessionAvailable(int callbackId, in QosSession session, in EpsBearerQosSessionAttributes attributes);
- void sendNrQosSessionAvailable(int callbackId, in QosSession session, in NrQosSessionAttributes attributes);
- void sendQosSessionLost(int qosCallbackId, in QosSession session);
- void sendQosCallbackError(int qosCallbackId, int exceptionType);
- void sendTeardownDelayMs(int teardownDelayMs);
- void sendLingerDuration(int durationMs);
-}
diff --git a/packages/Connectivity/framework/src/android/net/INetworkOfferCallback.aidl b/packages/Connectivity/framework/src/android/net/INetworkOfferCallback.aidl
deleted file mode 100644
index ecfba21..0000000
--- a/packages/Connectivity/framework/src/android/net/INetworkOfferCallback.aidl
+++ /dev/null
@@ -1,61 +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.NetworkRequest;
-
-/**
- * A callback registered with connectivity by network providers together with
- * a NetworkOffer.
- *
- * When the network for this offer is needed to satisfy some application or
- * system component, connectivity will call onNetworkNeeded on this callback.
- * When this happens, the provider should try and bring up the network.
- *
- * When the network for this offer is no longer needed, for example because
- * the application has withdrawn the request or if the request is being
- * satisfied by a network that this offer will never be able to beat,
- * connectivity calls onNetworkUnneeded. When this happens, the provider
- * should stop trying to bring up the network, or tear it down if it has
- * already been brought up.
- *
- * When NetworkProvider#offerNetwork is called, the provider can expect to
- * immediately receive all requests that can be fulfilled by that offer and
- * are not already satisfied by a better network. It is possible no such
- * request is currently outstanding, because no requests have been made that
- * can be satisfied by this offer, or because all such requests are already
- * satisfied by a better network.
- * onNetworkNeeded can be called at any time after registration and until the
- * offer is withdrawn with NetworkProvider#unofferNetwork is called. This
- * typically happens when a new network request is filed by an application,
- * or when the network satisfying a request disconnects and this offer now
- * stands a chance to supply the best network for it.
- *
- * @hide
- */
-oneway interface INetworkOfferCallback {
- /**
- * Called when a network for this offer is needed to fulfill this request.
- * @param networkRequest the request to satisfy
- */
- void onNetworkNeeded(in NetworkRequest networkRequest);
-
- /**
- * Informs the registrant that the offer is no longer valuable to fulfill this request.
- */
- void onNetworkUnneeded(in NetworkRequest networkRequest);
-}
diff --git a/packages/Connectivity/framework/src/android/net/IOnCompleteListener.aidl b/packages/Connectivity/framework/src/android/net/IOnCompleteListener.aidl
deleted file mode 100644
index 4bb89f6c..0000000
--- a/packages/Connectivity/framework/src/android/net/IOnCompleteListener.aidl
+++ /dev/null
@@ -1,23 +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;
-
-/** @hide */
-oneway interface IOnCompleteListener {
- void onComplete();
-}
diff --git a/packages/Connectivity/framework/src/android/net/IQosCallback.aidl b/packages/Connectivity/framework/src/android/net/IQosCallback.aidl
deleted file mode 100644
index c973541..0000000
--- a/packages/Connectivity/framework/src/android/net/IQosCallback.aidl
+++ /dev/null
@@ -1,37 +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.Bundle;
-import android.net.QosSession;
-import android.telephony.data.EpsBearerQosSessionAttributes;
-import android.telephony.data.NrQosSessionAttributes;
-
-/**
- * AIDL interface for QosCallback
- *
- * @hide
- */
-oneway interface IQosCallback
-{
- void onQosEpsBearerSessionAvailable(in QosSession session,
- in EpsBearerQosSessionAttributes attributes);
- void onNrQosSessionAvailable(in QosSession session,
- in NrQosSessionAttributes attributes);
- void onQosSessionLost(in QosSession session);
- void onError(in int type);
-}
diff --git a/packages/Connectivity/framework/src/android/net/ISocketKeepaliveCallback.aidl b/packages/Connectivity/framework/src/android/net/ISocketKeepaliveCallback.aidl
deleted file mode 100644
index 020fbca..0000000
--- a/packages/Connectivity/framework/src/android/net/ISocketKeepaliveCallback.aidl
+++ /dev/null
@@ -1,34 +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;
-
-/**
- * Callback to provide status changes of keepalive offload.
- *
- * @hide
- */
-oneway interface ISocketKeepaliveCallback
-{
- /** The keepalive was successfully started. */
- void onStarted(int slot);
- /** The keepalive was successfully stopped. */
- void onStopped();
- /** The keepalive was stopped because of an error. */
- void onError(int error);
- /** The keepalive on a TCP socket was stopped because the socket received data. */
- void onDataReceived();
-}
diff --git a/packages/Connectivity/framework/src/android/net/ITestNetworkManager.aidl b/packages/Connectivity/framework/src/android/net/ITestNetworkManager.aidl
deleted file mode 100644
index 2a863ad..0000000
--- a/packages/Connectivity/framework/src/android/net/ITestNetworkManager.aidl
+++ /dev/null
@@ -1,39 +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 android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.TestNetworkInterface;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-
-/**
- * Interface that allows for creation and management of test-only networks.
- *
- * @hide
- */
-interface ITestNetworkManager
-{
- TestNetworkInterface createTunInterface(in LinkAddress[] linkAddrs);
- TestNetworkInterface createTapInterface();
-
- void setupTestNetwork(in String iface, in LinkProperties lp, in boolean isMetered,
- in int[] administratorUids, in IBinder binder);
-
- void teardownTestNetwork(int netId);
-}
diff --git a/packages/Connectivity/framework/src/android/net/InetAddressCompat.java b/packages/Connectivity/framework/src/android/net/InetAddressCompat.java
deleted file mode 100644
index 6b7e75c..0000000
--- a/packages/Connectivity/framework/src/android/net/InetAddressCompat.java
+++ /dev/null
@@ -1,88 +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.util.Log;
-
-import java.lang.reflect.InvocationTargetException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * Compatibility utility for InetAddress core platform APIs.
- *
- * Connectivity has access to such APIs, but they are not part of the module_current stubs yet
- * (only core_current). Most stable core platform APIs are included manually in the connectivity
- * build rules, but because InetAddress is also part of the base java SDK that is earlier on the
- * classpath, the extra core platform APIs are not seen.
- *
- * TODO (b/183097033): remove this utility as soon as core_current is part of module_current
- * @hide
- */
-public class InetAddressCompat {
-
- /**
- * @see InetAddress#clearDnsCache()
- */
- public static void clearDnsCache() {
- try {
- InetAddress.class.getMethod("clearDnsCache").invoke(null);
- } catch (InvocationTargetException e) {
- if (e.getCause() instanceof RuntimeException) {
- throw (RuntimeException) e.getCause();
- }
- throw new IllegalStateException("Unknown InvocationTargetException", e.getCause());
- } catch (IllegalAccessException | NoSuchMethodException e) {
- Log.wtf(InetAddressCompat.class.getSimpleName(), "Error clearing DNS cache", e);
- }
- }
-
- /**
- * @see InetAddress#getAllByNameOnNet(String, int)
- */
- public static InetAddress[] getAllByNameOnNet(String host, int netId) throws
- UnknownHostException {
- return (InetAddress[]) callGetByNameMethod("getAllByNameOnNet", host, netId);
- }
-
- /**
- * @see InetAddress#getByNameOnNet(String, int)
- */
- public static InetAddress getByNameOnNet(String host, int netId) throws
- UnknownHostException {
- return (InetAddress) callGetByNameMethod("getByNameOnNet", host, netId);
- }
-
- private static Object callGetByNameMethod(String method, String host, int netId)
- throws UnknownHostException {
- try {
- return InetAddress.class.getMethod(method, String.class, int.class)
- .invoke(null, host, netId);
- } catch (InvocationTargetException e) {
- if (e.getCause() instanceof UnknownHostException) {
- throw (UnknownHostException) e.getCause();
- }
- if (e.getCause() instanceof RuntimeException) {
- throw (RuntimeException) e.getCause();
- }
- throw new IllegalStateException("Unknown InvocationTargetException", e.getCause());
- } catch (IllegalAccessException | NoSuchMethodException e) {
- Log.wtf(InetAddressCompat.class.getSimpleName(), "Error calling " + method, e);
- throw new IllegalStateException("Error querying via " + method, e);
- }
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/InetAddresses.java b/packages/Connectivity/framework/src/android/net/InetAddresses.java
deleted file mode 100644
index 01b795e..0000000
--- a/packages/Connectivity/framework/src/android/net/InetAddresses.java
+++ /dev/null
@@ -1,65 +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 android.annotation.NonNull;
-
-import libcore.net.InetAddressUtils;
-
-import java.net.InetAddress;
-
-/**
- * Utility methods for {@link InetAddress} implementations.
- */
-public class InetAddresses {
-
- private InetAddresses() {}
-
- /**
- * Checks to see if the {@code address} is a numeric address (such as {@code "192.0.2.1"} or
- * {@code "2001:db8::1:2"}).
- *
- * <p>A numeric address is either an IPv4 address containing exactly 4 decimal numbers or an
- * IPv6 numeric address. IPv4 addresses that consist of either hexadecimal or octal digits or
- * do not have exactly 4 numbers are not treated as numeric.
- *
- * <p>This method will never do a DNS lookup.
- *
- * @param address the address to parse.
- * @return true if the supplied address is numeric, false otherwise.
- */
- public static boolean isNumericAddress(@NonNull String address) {
- return InetAddressUtils.isNumericAddress(address);
- }
-
- /**
- * Returns an InetAddress corresponding to the given numeric address (such
- * as {@code "192.168.0.1"} or {@code "2001:4860:800d::68"}).
- *
- * <p>See {@link #isNumericAddress(String)} (String)} for a definition as to what constitutes a
- * numeric address.
- *
- * <p>This method will never do a DNS lookup.
- *
- * @param address the address to parse, must be numeric.
- * @return an {@link InetAddress} instance corresponding to the address.
- * @throws IllegalArgumentException if {@code address} is not a numeric address.
- */
- public static @NonNull InetAddress parseNumericAddress(@NonNull String address) {
- return InetAddressUtils.parseNumericAddress(address);
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/InvalidPacketException.java b/packages/Connectivity/framework/src/android/net/InvalidPacketException.java
deleted file mode 100644
index 1873d77..0000000
--- a/packages/Connectivity/framework/src/android/net/InvalidPacketException.java
+++ /dev/null
@@ -1,66 +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.annotation.IntDef;
-import android.annotation.SystemApi;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Thrown when a packet is invalid.
- * @hide
- */
-@SystemApi
-public final class InvalidPacketException extends Exception {
- private final int mError;
-
- // Must match SocketKeepalive#ERROR_INVALID_IP_ADDRESS.
- /** Invalid IP address. */
- public static final int ERROR_INVALID_IP_ADDRESS = -21;
-
- // Must match SocketKeepalive#ERROR_INVALID_PORT.
- /** Invalid port number. */
- public static final int ERROR_INVALID_PORT = -22;
-
- // Must match SocketKeepalive#ERROR_INVALID_LENGTH.
- /** Invalid packet length. */
- public static final int ERROR_INVALID_LENGTH = -23;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "ERROR_" }, value = {
- ERROR_INVALID_IP_ADDRESS,
- ERROR_INVALID_PORT,
- ERROR_INVALID_LENGTH
- })
- public @interface ErrorCode {}
-
- /**
- * This packet is invalid.
- * See the error code for details.
- */
- public InvalidPacketException(@ErrorCode final int error) {
- this.mError = error;
- }
-
- /** Get error code. */
- public int getError() {
- return mError;
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/IpConfiguration.java b/packages/Connectivity/framework/src/android/net/IpConfiguration.java
deleted file mode 100644
index d5f8b2e..0000000
--- a/packages/Connectivity/framework/src/android/net/IpConfiguration.java
+++ /dev/null
@@ -1,223 +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 android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * A class representing a configured network.
- * @hide
- */
-@SystemApi
-public final class IpConfiguration implements Parcelable {
- private static final String TAG = "IpConfiguration";
-
- // This enum has been used by apps through reflection for many releases.
- // Therefore they can't just be removed. Duplicating these constants to
- // give an alternate SystemApi is a worse option than exposing them.
- @SuppressLint("Enum")
- public enum IpAssignment {
- /* Use statically configured IP settings. Configuration can be accessed
- * with staticIpConfiguration */
- STATIC,
- /* Use dynamically configured IP settings */
- DHCP,
- /* no IP details are assigned, this is used to indicate
- * that any existing IP settings should be retained */
- UNASSIGNED
- }
-
- /** @hide */
- public IpAssignment ipAssignment;
-
- /** @hide */
- public StaticIpConfiguration staticIpConfiguration;
-
- // This enum has been used by apps through reflection for many releases.
- // Therefore they can't just be removed. Duplicating these constants to
- // give an alternate SystemApi is a worse option than exposing them.
- @SuppressLint("Enum")
- public enum ProxySettings {
- /* No proxy is to be used. Any existing proxy settings
- * should be cleared. */
- NONE,
- /* Use statically configured proxy. Configuration can be accessed
- * with httpProxy. */
- STATIC,
- /* no proxy details are assigned, this is used to indicate
- * that any existing proxy settings should be retained */
- UNASSIGNED,
- /* Use a Pac based proxy.
- */
- PAC
- }
-
- /** @hide */
- public ProxySettings proxySettings;
-
- /** @hide */
- @UnsupportedAppUsage
- public ProxyInfo httpProxy;
-
- private void init(IpAssignment ipAssignment,
- ProxySettings proxySettings,
- StaticIpConfiguration staticIpConfiguration,
- ProxyInfo httpProxy) {
- this.ipAssignment = ipAssignment;
- this.proxySettings = proxySettings;
- this.staticIpConfiguration = (staticIpConfiguration == null) ?
- null : new StaticIpConfiguration(staticIpConfiguration);
- this.httpProxy = (httpProxy == null) ?
- null : new ProxyInfo(httpProxy);
- }
-
- public IpConfiguration() {
- init(IpAssignment.UNASSIGNED, ProxySettings.UNASSIGNED, null, null);
- }
-
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public IpConfiguration(IpAssignment ipAssignment,
- ProxySettings proxySettings,
- StaticIpConfiguration staticIpConfiguration,
- ProxyInfo httpProxy) {
- init(ipAssignment, proxySettings, staticIpConfiguration, httpProxy);
- }
-
- public IpConfiguration(@NonNull IpConfiguration source) {
- this();
- if (source != null) {
- init(source.ipAssignment, source.proxySettings,
- source.staticIpConfiguration, source.httpProxy);
- }
- }
-
- public @NonNull IpAssignment getIpAssignment() {
- return ipAssignment;
- }
-
- public void setIpAssignment(@NonNull IpAssignment ipAssignment) {
- this.ipAssignment = ipAssignment;
- }
-
- public @Nullable StaticIpConfiguration getStaticIpConfiguration() {
- return staticIpConfiguration;
- }
-
- public void setStaticIpConfiguration(@Nullable StaticIpConfiguration staticIpConfiguration) {
- this.staticIpConfiguration = staticIpConfiguration;
- }
-
- public @NonNull ProxySettings getProxySettings() {
- return proxySettings;
- }
-
- public void setProxySettings(@NonNull ProxySettings proxySettings) {
- this.proxySettings = proxySettings;
- }
-
- public @Nullable ProxyInfo getHttpProxy() {
- return httpProxy;
- }
-
- public void setHttpProxy(@Nullable ProxyInfo httpProxy) {
- this.httpProxy = httpProxy;
- }
-
- @Override
- public String toString() {
- StringBuilder sbuf = new StringBuilder();
- sbuf.append("IP assignment: " + ipAssignment.toString());
- sbuf.append("\n");
- if (staticIpConfiguration != null) {
- sbuf.append("Static configuration: " + staticIpConfiguration.toString());
- sbuf.append("\n");
- }
- sbuf.append("Proxy settings: " + proxySettings.toString());
- sbuf.append("\n");
- if (httpProxy != null) {
- sbuf.append("HTTP proxy: " + httpProxy.toString());
- sbuf.append("\n");
- }
-
- return sbuf.toString();
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof IpConfiguration)) {
- return false;
- }
-
- IpConfiguration other = (IpConfiguration) o;
- return this.ipAssignment == other.ipAssignment &&
- this.proxySettings == other.proxySettings &&
- Objects.equals(this.staticIpConfiguration, other.staticIpConfiguration) &&
- Objects.equals(this.httpProxy, other.httpProxy);
- }
-
- @Override
- public int hashCode() {
- return 13 + (staticIpConfiguration != null ? staticIpConfiguration.hashCode() : 0) +
- 17 * ipAssignment.ordinal() +
- 47 * proxySettings.ordinal() +
- 83 * httpProxy.hashCode();
- }
-
- /** Implement the Parcelable interface */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface */
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeString(ipAssignment.name());
- dest.writeString(proxySettings.name());
- dest.writeParcelable(staticIpConfiguration, flags);
- dest.writeParcelable(httpProxy, flags);
- }
-
- /** Implement the Parcelable interface */
- public static final @NonNull Creator<IpConfiguration> CREATOR =
- new Creator<IpConfiguration>() {
- public IpConfiguration createFromParcel(Parcel in) {
- IpConfiguration config = new IpConfiguration();
- config.ipAssignment = IpAssignment.valueOf(in.readString());
- config.proxySettings = ProxySettings.valueOf(in.readString());
- config.staticIpConfiguration = in.readParcelable(null);
- config.httpProxy = in.readParcelable(null);
- return config;
- }
-
- public IpConfiguration[] newArray(int size) {
- return new IpConfiguration[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/IpPrefix.java b/packages/Connectivity/framework/src/android/net/IpPrefix.java
deleted file mode 100644
index bf4481a..0000000
--- a/packages/Connectivity/framework/src/android/net/IpPrefix.java
+++ /dev/null
@@ -1,303 +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 android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Pair;
-
-import com.android.net.module.util.NetUtils;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Arrays;
-import java.util.Comparator;
-
-/**
- * This class represents an IP prefix, i.e., a contiguous block of IP addresses aligned on a
- * power of two boundary (also known as an "IP subnet"). A prefix is specified by two pieces of
- * information:
- *
- * <ul>
- * <li>A starting IP address (IPv4 or IPv6). This is the first IP address of the prefix.
- * <li>A prefix length. This specifies the length of the prefix by specifing the number of bits
- * in the IP address, starting from the most significant bit in network byte order, that
- * are constant for all addresses in the prefix.
- * </ul>
- *
- * For example, the prefix <code>192.0.2.0/24</code> covers the 256 IPv4 addresses from
- * <code>192.0.2.0</code> to <code>192.0.2.255</code>, inclusive, and the prefix
- * <code>2001:db8:1:2</code> covers the 2^64 IPv6 addresses from <code>2001:db8:1:2::</code> to
- * <code>2001:db8:1:2:ffff:ffff:ffff:ffff</code>, inclusive.
- *
- * Objects of this class are immutable.
- */
-public final class IpPrefix implements Parcelable {
- private final byte[] address; // network byte order
- private final int prefixLength;
-
- private void checkAndMaskAddressAndPrefixLength() {
- if (address.length != 4 && address.length != 16) {
- throw new IllegalArgumentException(
- "IpPrefix has " + address.length + " bytes which is neither 4 nor 16");
- }
- NetUtils.maskRawAddress(address, prefixLength);
- }
-
- /**
- * Constructs a new {@code IpPrefix} from a byte array containing an IPv4 or IPv6 address in
- * network byte order and a prefix length. Silently truncates the address to the prefix length,
- * so for example {@code 192.0.2.1/24} is silently converted to {@code 192.0.2.0/24}.
- *
- * @param address the IP address. Must be non-null and exactly 4 or 16 bytes long.
- * @param prefixLength the prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
- *
- * @hide
- */
- public IpPrefix(@NonNull byte[] address, @IntRange(from = 0, to = 128) int prefixLength) {
- this.address = address.clone();
- this.prefixLength = prefixLength;
- checkAndMaskAddressAndPrefixLength();
- }
-
- /**
- * Constructs a new {@code IpPrefix} from an IPv4 or IPv6 address and a prefix length. Silently
- * truncates the address to the prefix length, so for example {@code 192.0.2.1/24} is silently
- * converted to {@code 192.0.2.0/24}.
- *
- * @param address the IP address. Must be non-null.
- * @param prefixLength the prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
- * @hide
- */
- @SystemApi
- public IpPrefix(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength) {
- // We don't reuse the (byte[], int) constructor because it calls clone() on the byte array,
- // which is unnecessary because getAddress() already returns a clone.
- this.address = address.getAddress();
- this.prefixLength = prefixLength;
- checkAndMaskAddressAndPrefixLength();
- }
-
- /**
- * Constructs a new IpPrefix from a string such as "192.0.2.1/24" or "2001:db8::1/64".
- * Silently truncates the address to the prefix length, so for example {@code 192.0.2.1/24}
- * is silently converted to {@code 192.0.2.0/24}.
- *
- * @param prefix the prefix to parse
- *
- * @hide
- */
- @SystemApi
- public IpPrefix(@NonNull String prefix) {
- // We don't reuse the (InetAddress, int) constructor because "error: call to this must be
- // first statement in constructor". We could factor out setting the member variables to an
- // init() method, but if we did, then we'd have to make the members non-final, or "error:
- // cannot assign a value to final variable address". So we just duplicate the code here.
- Pair<InetAddress, Integer> ipAndMask = NetworkUtils.legacyParseIpAndMask(prefix);
- this.address = ipAndMask.first.getAddress();
- this.prefixLength = ipAndMask.second;
- checkAndMaskAddressAndPrefixLength();
- }
-
- /**
- * Compares this {@code IpPrefix} object against the specified object in {@code obj}. Two
- * objects are equal if they have the same startAddress and prefixLength.
- *
- * @param obj the object to be tested for equality.
- * @return {@code true} if both objects are equal, {@code false} otherwise.
- */
- @Override
- public boolean equals(@Nullable Object obj) {
- if (!(obj instanceof IpPrefix)) {
- return false;
- }
- IpPrefix that = (IpPrefix) obj;
- return Arrays.equals(this.address, that.address) && this.prefixLength == that.prefixLength;
- }
-
- /**
- * Gets the hashcode of the represented IP prefix.
- *
- * @return the appropriate hashcode value.
- */
- @Override
- public int hashCode() {
- return Arrays.hashCode(address) + 11 * prefixLength;
- }
-
- /**
- * Returns a copy of the first IP address in the prefix. Modifying the returned object does not
- * change this object's contents.
- *
- * @return the address in the form of a byte array.
- */
- public @NonNull InetAddress getAddress() {
- try {
- return InetAddress.getByAddress(address);
- } catch (UnknownHostException e) {
- // Cannot happen. InetAddress.getByAddress can only throw an exception if the byte
- // array is the wrong length, but we check that in the constructor.
- throw new IllegalArgumentException("Address is invalid");
- }
- }
-
- /**
- * Returns a copy of the IP address bytes in network order (the highest order byte is the zeroth
- * element). Modifying the returned array does not change this object's contents.
- *
- * @return the address in the form of a byte array.
- */
- public @NonNull byte[] getRawAddress() {
- return address.clone();
- }
-
- /**
- * Returns the prefix length of this {@code IpPrefix}.
- *
- * @return the prefix length.
- */
- @IntRange(from = 0, to = 128)
- public int getPrefixLength() {
- return prefixLength;
- }
-
- /**
- * Determines whether the prefix contains the specified address.
- *
- * @param address An {@link InetAddress} to test.
- * @return {@code true} if the prefix covers the given address. {@code false} otherwise.
- */
- public boolean contains(@NonNull InetAddress address) {
- byte[] addrBytes = address.getAddress();
- if (addrBytes == null || addrBytes.length != this.address.length) {
- return false;
- }
- NetUtils.maskRawAddress(addrBytes, prefixLength);
- return Arrays.equals(this.address, addrBytes);
- }
-
- /**
- * Returns whether the specified prefix is entirely contained in this prefix.
- *
- * Note this is mathematical inclusion, so a prefix is always contained within itself.
- * @param otherPrefix the prefix to test
- * @hide
- */
- public boolean containsPrefix(@NonNull IpPrefix otherPrefix) {
- if (otherPrefix.getPrefixLength() < prefixLength) return false;
- final byte[] otherAddress = otherPrefix.getRawAddress();
- NetUtils.maskRawAddress(otherAddress, prefixLength);
- return Arrays.equals(otherAddress, address);
- }
-
- /**
- * @hide
- */
- public boolean isIPv6() {
- return getAddress() instanceof Inet6Address;
- }
-
- /**
- * @hide
- */
- public boolean isIPv4() {
- return getAddress() instanceof Inet4Address;
- }
-
- /**
- * Returns a string representation of this {@code IpPrefix}.
- *
- * @return a string such as {@code "192.0.2.0/24"} or {@code "2001:db8:1:2::/64"}.
- */
- public String toString() {
- try {
- return InetAddress.getByAddress(address).getHostAddress() + "/" + prefixLength;
- } catch(UnknownHostException e) {
- // Cosmic rays?
- throw new IllegalStateException("IpPrefix with invalid address! Shouldn't happen.", e);
- }
- }
-
- /**
- * Implement the Parcelable interface.
- */
- public int describeContents() {
- return 0;
- }
-
- /**
- * Implement the Parcelable interface.
- */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeByteArray(address);
- dest.writeInt(prefixLength);
- }
-
- /**
- * Returns a comparator ordering IpPrefixes by length, shorter to longer.
- * Contents of the address will break ties.
- * @hide
- */
- public static Comparator<IpPrefix> lengthComparator() {
- return new Comparator<IpPrefix>() {
- @Override
- public int compare(IpPrefix prefix1, IpPrefix prefix2) {
- if (prefix1.isIPv4()) {
- if (prefix2.isIPv6()) return -1;
- } else {
- if (prefix2.isIPv4()) return 1;
- }
- final int p1len = prefix1.getPrefixLength();
- final int p2len = prefix2.getPrefixLength();
- if (p1len < p2len) return -1;
- if (p2len < p1len) return 1;
- final byte[] a1 = prefix1.address;
- final byte[] a2 = prefix2.address;
- final int len = a1.length < a2.length ? a1.length : a2.length;
- for (int i = 0; i < len; ++i) {
- if (a1[i] < a2[i]) return -1;
- if (a1[i] > a2[i]) return 1;
- }
- if (a2.length < len) return 1;
- if (a1.length < len) return -1;
- return 0;
- }
- };
- }
-
- /**
- * Implement the Parcelable interface.
- */
- public static final @android.annotation.NonNull Creator<IpPrefix> CREATOR =
- new Creator<IpPrefix>() {
- public IpPrefix createFromParcel(Parcel in) {
- byte[] address = in.createByteArray();
- int prefixLength = in.readInt();
- return new IpPrefix(address, prefixLength);
- }
-
- public IpPrefix[] newArray(int size) {
- return new IpPrefix[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/KeepalivePacketData.java b/packages/Connectivity/framework/src/android/net/KeepalivePacketData.java
deleted file mode 100644
index 5877f1f..0000000
--- a/packages/Connectivity/framework/src/android/net/KeepalivePacketData.java
+++ /dev/null
@@ -1,119 +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 android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS;
-import static android.net.InvalidPacketException.ERROR_INVALID_PORT;
-
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.util.Log;
-
-import com.android.net.module.util.IpUtils;
-
-import java.net.InetAddress;
-
-/**
- * Represents the actual packets that are sent by the
- * {@link android.net.SocketKeepalive} API.
- * @hide
- */
-@SystemApi
-public class KeepalivePacketData {
- private static final String TAG = "KeepalivePacketData";
-
- /** Source IP address */
- @NonNull
- private final InetAddress mSrcAddress;
-
- /** Destination IP address */
- @NonNull
- private final InetAddress mDstAddress;
-
- /** Source port */
- private final int mSrcPort;
-
- /** Destination port */
- private final int mDstPort;
-
- /** Packet data. A raw byte string of packet data, not including the link-layer header. */
- private final byte[] mPacket;
-
- // Note: If you add new fields, please modify the parcelling code in the child classes.
-
-
- // This should only be constructed via static factory methods, such as
- // nattKeepalivePacket.
- /**
- * A holding class for data necessary to build a keepalive packet.
- */
- protected KeepalivePacketData(@NonNull InetAddress srcAddress,
- @IntRange(from = 0, to = 65535) int srcPort, @NonNull InetAddress dstAddress,
- @IntRange(from = 0, to = 65535) int dstPort,
- @NonNull byte[] data) throws InvalidPacketException {
- this.mSrcAddress = srcAddress;
- this.mDstAddress = dstAddress;
- this.mSrcPort = srcPort;
- this.mDstPort = dstPort;
- this.mPacket = data;
-
- // Check we have two IP addresses of the same family.
- if (srcAddress == null || dstAddress == null || !srcAddress.getClass().getName()
- .equals(dstAddress.getClass().getName())) {
- Log.e(TAG, "Invalid or mismatched InetAddresses in KeepalivePacketData");
- throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
- }
-
- // Check the ports.
- if (!IpUtils.isValidUdpOrTcpPort(srcPort) || !IpUtils.isValidUdpOrTcpPort(dstPort)) {
- Log.e(TAG, "Invalid ports in KeepalivePacketData");
- throw new InvalidPacketException(ERROR_INVALID_PORT);
- }
- }
-
- /** Get source IP address. */
- @NonNull
- public InetAddress getSrcAddress() {
- return mSrcAddress;
- }
-
- /** Get destination IP address. */
- @NonNull
- public InetAddress getDstAddress() {
- return mDstAddress;
- }
-
- /** Get source port number. */
- public int getSrcPort() {
- return mSrcPort;
- }
-
- /** Get destination port number. */
- public int getDstPort() {
- return mDstPort;
- }
-
- /**
- * Returns a byte array of the given packet data.
- */
- @NonNull
- public byte[] getPacket() {
- return mPacket.clone();
- }
-
-}
diff --git a/packages/Connectivity/framework/src/android/net/LinkAddress.java b/packages/Connectivity/framework/src/android/net/LinkAddress.java
deleted file mode 100644
index d48b8c7..0000000
--- a/packages/Connectivity/framework/src/android/net/LinkAddress.java
+++ /dev/null
@@ -1,549 +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.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_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 android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.SystemClock;
-import android.util.Pair;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InterfaceAddress;
-import java.net.UnknownHostException;
-import java.util.Objects;
-
-/**
- * Identifies an IP address on a network link.
- *
- * A {@code LinkAddress} consists of:
- * <ul>
- * <li>An IP address and prefix length (e.g., {@code 2001:db8::1/64} or {@code 192.0.2.1/24}).
- * The address must be unicast, as multicast addresses cannot be assigned to interfaces.
- * <li>Address flags: A bitmask of {@code OsConstants.IFA_F_*} values representing properties
- * of the address (e.g., {@code android.system.OsConstants.IFA_F_OPTIMISTIC}).
- * <li>Address scope: One of the {@code OsConstants.IFA_F_*} values; defines the scope in which
- * the address is unique (e.g.,
- * {@code android.system.OsConstants.RT_SCOPE_LINK} or
- * {@code android.system.OsConstants.RT_SCOPE_UNIVERSE}).
- * </ul>
- */
-public class LinkAddress implements Parcelable {
-
- /**
- * Indicates the deprecation or expiration time is unknown
- * @hide
- */
- @SystemApi
- public static final long LIFETIME_UNKNOWN = -1;
-
- /**
- * Indicates this address is permanent.
- * @hide
- */
- @SystemApi
- public static final long LIFETIME_PERMANENT = Long.MAX_VALUE;
-
- /**
- * IPv4 or IPv6 address.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- private InetAddress address;
-
- /**
- * Prefix length.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- private int prefixLength;
-
- /**
- * Address flags. A bitmask of {@code IFA_F_*} values. Note that {@link #getFlags()} may not
- * return these exact values. For example, it may set or clear the {@code IFA_F_DEPRECATED}
- * flag depending on the current preferred lifetime.
- */
- private int flags;
-
- /**
- * Address scope. One of the RT_SCOPE_* constants.
- */
- private int scope;
-
- /**
- * The time, as reported by {@link SystemClock#elapsedRealtime}, when this LinkAddress will be
- * or was deprecated. At the time existing connections can still use this address until it
- * expires, but new connections should use the new address. {@link #LIFETIME_UNKNOWN} indicates
- * this information is not available. {@link #LIFETIME_PERMANENT} indicates this
- * {@link LinkAddress} will never be deprecated.
- */
- private long deprecationTime;
-
- /**
- * The time, as reported by {@link SystemClock#elapsedRealtime}, when this {@link LinkAddress}
- * will expire and be removed from the interface. {@link #LIFETIME_UNKNOWN} indicates this
- * information is not available. {@link #LIFETIME_PERMANENT} indicates this {@link LinkAddress}
- * will never expire.
- */
- private long expirationTime;
-
- /**
- * Utility function to determines the scope of a unicast address. Per RFC 4291 section 2.5 and
- * RFC 6724 section 3.2.
- * @hide
- */
- private static int scopeForUnicastAddress(InetAddress addr) {
- if (addr.isAnyLocalAddress()) {
- return RT_SCOPE_HOST;
- }
-
- if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()) {
- return RT_SCOPE_LINK;
- }
-
- // isSiteLocalAddress() returns true for private IPv4 addresses, but RFC 6724 section 3.2
- // says that they are assigned global scope.
- if (!(addr instanceof Inet4Address) && addr.isSiteLocalAddress()) {
- return RT_SCOPE_SITE;
- }
-
- return RT_SCOPE_UNIVERSE;
- }
-
- /**
- * Utility function to check if |address| is a Unique Local IPv6 Unicast Address
- * (a.k.a. "ULA"; RFC 4193).
- *
- * Per RFC 4193 section 8, fc00::/7 identifies these addresses.
- */
- private boolean isIpv6ULA() {
- if (isIpv6()) {
- byte[] bytes = address.getAddress();
- return ((bytes[0] & (byte)0xfe) == (byte)0xfc);
- }
- return false;
- }
-
- /**
- * @return true if the address is IPv6.
- * @hide
- */
- @SystemApi
- public boolean isIpv6() {
- return address instanceof Inet6Address;
- }
-
- /**
- * For backward compatibility.
- * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely
- * just yet.
- * @return true if the address is IPv6.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
- public boolean isIPv6() {
- return isIpv6();
- }
-
- /**
- * @return true if the address is IPv4 or is a mapped IPv4 address.
- * @hide
- */
- @SystemApi
- public boolean isIpv4() {
- return address instanceof Inet4Address;
- }
-
- /**
- * Utility function for the constructors.
- */
- private void init(InetAddress address, int prefixLength, int flags, int scope,
- long deprecationTime, long expirationTime) {
- if (address == null ||
- address.isMulticastAddress() ||
- prefixLength < 0 ||
- (address instanceof Inet4Address && prefixLength > 32) ||
- (prefixLength > 128)) {
- throw new IllegalArgumentException("Bad LinkAddress params " + address +
- "/" + prefixLength);
- }
-
- // deprecation time and expiration time must be both provided, or neither.
- if ((deprecationTime == LIFETIME_UNKNOWN) != (expirationTime == LIFETIME_UNKNOWN)) {
- throw new IllegalArgumentException(
- "Must not specify only one of deprecation time and expiration time");
- }
-
- // deprecation time needs to be a positive value.
- if (deprecationTime != LIFETIME_UNKNOWN && deprecationTime < 0) {
- throw new IllegalArgumentException("invalid deprecation time " + deprecationTime);
- }
-
- // expiration time needs to be a positive value.
- if (expirationTime != LIFETIME_UNKNOWN && expirationTime < 0) {
- throw new IllegalArgumentException("invalid expiration time " + expirationTime);
- }
-
- // expiration time can't be earlier than deprecation time
- if (deprecationTime != LIFETIME_UNKNOWN && expirationTime != LIFETIME_UNKNOWN
- && expirationTime < deprecationTime) {
- throw new IllegalArgumentException("expiration earlier than deprecation ("
- + deprecationTime + ", " + expirationTime + ")");
- }
-
- this.address = address;
- this.prefixLength = prefixLength;
- this.flags = flags;
- this.scope = scope;
- this.deprecationTime = deprecationTime;
- this.expirationTime = expirationTime;
- }
-
- /**
- * Constructs a new {@code LinkAddress} from an {@code InetAddress} and prefix length, with
- * the specified flags and scope. Flags and scope are not checked for validity.
- *
- * @param address The IP address.
- * @param prefixLength The prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
- * @param flags A bitmask of {@code IFA_F_*} values representing properties of the address.
- * @param scope An integer defining the scope in which the address is unique (e.g.,
- * {@link OsConstants#RT_SCOPE_LINK} or {@link OsConstants#RT_SCOPE_SITE}).
- * @hide
- */
- @SystemApi
- public LinkAddress(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength,
- int flags, int scope) {
- init(address, prefixLength, flags, scope, LIFETIME_UNKNOWN, LIFETIME_UNKNOWN);
- }
-
- /**
- * Constructs a new {@code LinkAddress} from an {@code InetAddress}, prefix length, with
- * the specified flags, scope, deprecation time, and expiration time. Flags and scope are not
- * checked for validity. The value of the {@code IFA_F_DEPRECATED} and {@code IFA_F_PERMANENT}
- * flag will be adjusted based on the passed-in lifetimes.
- *
- * @param address The IP address.
- * @param prefixLength The prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
- * @param flags A bitmask of {@code IFA_F_*} values representing properties of the address.
- * @param scope An integer defining the scope in which the address is unique (e.g.,
- * {@link OsConstants#RT_SCOPE_LINK} or {@link OsConstants#RT_SCOPE_SITE}).
- * @param deprecationTime The time, as reported by {@link SystemClock#elapsedRealtime}, when
- * this {@link LinkAddress} will be or was deprecated. At the time
- * existing connections can still use this address until it expires, but
- * new connections should use the new address. {@link #LIFETIME_UNKNOWN}
- * indicates this information is not available.
- * {@link #LIFETIME_PERMANENT} indicates this {@link LinkAddress} will
- * never be deprecated.
- * @param expirationTime The time, as reported by {@link SystemClock#elapsedRealtime}, when this
- * {@link LinkAddress} will expire and be removed from the interface.
- * {@link #LIFETIME_UNKNOWN} indicates this information is not available.
- * {@link #LIFETIME_PERMANENT} indicates this {@link LinkAddress} will
- * never expire.
- * @hide
- */
- @SystemApi
- public LinkAddress(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength,
- int flags, int scope, long deprecationTime, long expirationTime) {
- init(address, prefixLength, flags, scope, deprecationTime, expirationTime);
- }
-
- /**
- * Constructs a new {@code LinkAddress} from an {@code InetAddress} and a prefix length.
- * The flags are set to zero and the scope is determined from the address.
- * @param address The IP address.
- * @param prefixLength The prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
- * @hide
- */
- @SystemApi
- public LinkAddress(@NonNull InetAddress address,
- @IntRange(from = 0, to = 128) int prefixLength) {
- this(address, prefixLength, 0, 0);
- this.scope = scopeForUnicastAddress(address);
- }
-
- /**
- * Constructs a new {@code LinkAddress} from an {@code InterfaceAddress}.
- * The flags are set to zero and the scope is determined from the address.
- * @param interfaceAddress The interface address.
- * @hide
- */
- public LinkAddress(@NonNull InterfaceAddress interfaceAddress) {
- this(interfaceAddress.getAddress(),
- interfaceAddress.getNetworkPrefixLength());
- }
-
- /**
- * Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or
- * "2001:db8::1/64". The flags are set to zero and the scope is determined from the address.
- * @param address The string to parse.
- * @hide
- */
- @SystemApi
- public LinkAddress(@NonNull String address) {
- this(address, 0, 0);
- this.scope = scopeForUnicastAddress(this.address);
- }
-
- /**
- * Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or
- * "2001:db8::1/64", with the specified flags and scope.
- * @param address The string to parse.
- * @param flags The address flags.
- * @param scope The address scope.
- * @hide
- */
- @SystemApi
- public LinkAddress(@NonNull String address, int flags, int scope) {
- // This may throw an IllegalArgumentException; catching it is the caller's responsibility.
- // TODO: consider rejecting mapped IPv4 addresses such as "::ffff:192.0.2.5/24".
- Pair<InetAddress, Integer> ipAndMask = NetworkUtils.legacyParseIpAndMask(address);
- init(ipAndMask.first, ipAndMask.second, flags, scope, LIFETIME_UNKNOWN, LIFETIME_UNKNOWN);
- }
-
- /**
- * Returns a string representation of this address, such as "192.0.2.1/24" or "2001:db8::1/64".
- * The string representation does not contain the flags and scope, just the address and prefix
- * length.
- */
- @Override
- public String toString() {
- return address.getHostAddress() + "/" + prefixLength;
- }
-
- /**
- * Compares this {@code LinkAddress} instance against {@code obj}. Two addresses are equal if
- * their address, prefix length, flags and scope are equal. Thus, for example, two addresses
- * that have the same address and prefix length are not equal if one of them is deprecated and
- * the other is not.
- *
- * @param obj the object to be tested for equality.
- * @return {@code true} if both objects are equal, {@code false} otherwise.
- */
- @Override
- public boolean equals(@Nullable Object obj) {
- if (!(obj instanceof LinkAddress)) {
- return false;
- }
- LinkAddress linkAddress = (LinkAddress) obj;
- return this.address.equals(linkAddress.address)
- && this.prefixLength == linkAddress.prefixLength
- && this.flags == linkAddress.flags
- && this.scope == linkAddress.scope
- && this.deprecationTime == linkAddress.deprecationTime
- && this.expirationTime == linkAddress.expirationTime;
- }
-
- /**
- * Returns a hashcode for this address.
- */
- @Override
- public int hashCode() {
- return Objects.hash(address, prefixLength, flags, scope, deprecationTime, expirationTime);
- }
-
- /**
- * Determines whether this {@code LinkAddress} and the provided {@code LinkAddress}
- * represent the same address. Two {@code LinkAddresses} represent the same address
- * if they have the same IP address and prefix length, even if their properties are
- * different.
- *
- * @param other the {@code LinkAddress} to compare to.
- * @return {@code true} if both objects have the same address and prefix length, {@code false}
- * otherwise.
- * @hide
- */
- @SystemApi
- public boolean isSameAddressAs(@Nullable LinkAddress other) {
- if (other == null) {
- return false;
- }
- return address.equals(other.address) && prefixLength == other.prefixLength;
- }
-
- /**
- * Returns the {@link InetAddress} of this {@code LinkAddress}.
- */
- public InetAddress getAddress() {
- return address;
- }
-
- /**
- * Returns the prefix length of this {@code LinkAddress}.
- */
- @IntRange(from = 0, to = 128)
- public int getPrefixLength() {
- return prefixLength;
- }
-
- /**
- * Returns the prefix length of this {@code LinkAddress}.
- * TODO: Delete all callers and remove in favour of getPrefixLength().
- * @hide
- */
- @UnsupportedAppUsage
- @IntRange(from = 0, to = 128)
- public int getNetworkPrefixLength() {
- return getPrefixLength();
- }
-
- /**
- * Returns the flags of this {@code LinkAddress}.
- */
- public int getFlags() {
- int flags = this.flags;
- if (deprecationTime != LIFETIME_UNKNOWN) {
- if (SystemClock.elapsedRealtime() >= deprecationTime) {
- flags |= IFA_F_DEPRECATED;
- } else {
- // If deprecation time is in the future, or permanent.
- flags &= ~IFA_F_DEPRECATED;
- }
- }
-
- if (expirationTime == LIFETIME_PERMANENT) {
- flags |= IFA_F_PERMANENT;
- } else if (expirationTime != LIFETIME_UNKNOWN) {
- // If we know this address expired or will expire in the future, then this address
- // should not be permanent.
- flags &= ~IFA_F_PERMANENT;
- }
-
- // Do no touch the original flags. Return the adjusted flags here.
- return flags;
- }
-
- /**
- * Returns the scope of this {@code LinkAddress}.
- */
- public int getScope() {
- return scope;
- }
-
- /**
- * Get the deprecation time, as reported by {@link SystemClock#elapsedRealtime}, when this
- * {@link LinkAddress} will be or was deprecated. At the time existing connections can still use
- * this address until it expires, but new connections should use the new address.
- *
- * @return The deprecation time in milliseconds. {@link #LIFETIME_UNKNOWN} indicates this
- * information is not available. {@link #LIFETIME_PERMANENT} indicates this {@link LinkAddress}
- * will never be deprecated.
- *
- * @hide
- */
- @SystemApi
- public long getDeprecationTime() {
- return deprecationTime;
- }
-
- /**
- * Get the expiration time, as reported by {@link SystemClock#elapsedRealtime}, when this
- * {@link LinkAddress} will expire and be removed from the interface.
- *
- * @return The expiration time in milliseconds. {@link #LIFETIME_UNKNOWN} indicates this
- * information is not available. {@link #LIFETIME_PERMANENT} indicates this {@link LinkAddress}
- * will never expire.
- *
- * @hide
- */
- @SystemApi
- public long getExpirationTime() {
- return expirationTime;
- }
-
- /**
- * Returns true if this {@code LinkAddress} is global scope and preferred (i.e., not currently
- * deprecated).
- *
- * @hide
- */
- @SystemApi
- public boolean isGlobalPreferred() {
- /**
- * Note that addresses flagged as IFA_F_OPTIMISTIC are
- * simultaneously flagged as IFA_F_TENTATIVE (when the tentative
- * state has cleared either DAD has succeeded or failed, and both
- * flags are cleared regardless).
- */
- int flags = getFlags();
- return (scope == RT_SCOPE_UNIVERSE
- && !isIpv6ULA()
- && (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED)) == 0L
- && ((flags & IFA_F_TENTATIVE) == 0L || (flags & IFA_F_OPTIMISTIC) != 0L));
- }
-
- /**
- * Implement the Parcelable interface.
- */
- public int describeContents() {
- return 0;
- }
-
- /**
- * Implement the Parcelable interface.
- */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeByteArray(address.getAddress());
- dest.writeInt(prefixLength);
- dest.writeInt(this.flags);
- dest.writeInt(scope);
- dest.writeLong(deprecationTime);
- dest.writeLong(expirationTime);
- }
-
- /**
- * Implement the Parcelable interface.
- */
- public static final @android.annotation.NonNull Creator<LinkAddress> CREATOR =
- new Creator<LinkAddress>() {
- public LinkAddress createFromParcel(Parcel in) {
- InetAddress address = null;
- try {
- address = InetAddress.getByAddress(in.createByteArray());
- } catch (UnknownHostException e) {
- // Nothing we can do here. When we call the constructor, we'll throw an
- // IllegalArgumentException, because a LinkAddress can't have a null
- // InetAddress.
- }
- int prefixLength = in.readInt();
- int flags = in.readInt();
- int scope = in.readInt();
- long deprecationTime = in.readLong();
- long expirationTime = in.readLong();
- return new LinkAddress(address, prefixLength, flags, scope, deprecationTime,
- expirationTime);
- }
-
- public LinkAddress[] newArray(int size) {
- return new LinkAddress[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/LinkProperties.java b/packages/Connectivity/framework/src/android/net/LinkProperties.java
deleted file mode 100644
index 99f48b4..0000000
--- a/packages/Connectivity/framework/src/android/net/LinkProperties.java
+++ /dev/null
@@ -1,1823 +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 android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import com.android.net.module.util.LinkPropertiesUtils;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Objects;
-import java.util.StringJoiner;
-
-/**
- * Describes the properties of a network link.
- *
- * A link represents a connection to a network.
- * It may have multiple addresses and multiple gateways,
- * multiple dns servers but only one http proxy and one
- * network interface.
- *
- * Note that this is just a holder of data. Modifying it
- * does not affect live networks.
- *
- */
-public final class LinkProperties implements Parcelable {
- // The interface described by the network link.
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- private String mIfaceName;
- private final ArrayList<LinkAddress> mLinkAddresses = new ArrayList<>();
- private final ArrayList<InetAddress> mDnses = new ArrayList<>();
- // PCSCF addresses are addresses of SIP proxies that only exist for the IMS core service.
- private final ArrayList<InetAddress> mPcscfs = new ArrayList<InetAddress>();
- private final ArrayList<InetAddress> mValidatedPrivateDnses = new ArrayList<>();
- private boolean mUsePrivateDns;
- private String mPrivateDnsServerName;
- private String mDomains;
- private ArrayList<RouteInfo> mRoutes = new ArrayList<>();
- private Inet4Address mDhcpServerAddress;
- private ProxyInfo mHttpProxy;
- private int mMtu;
- // in the format "rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max"
- private String mTcpBufferSizes;
- private IpPrefix mNat64Prefix;
- private boolean mWakeOnLanSupported;
- private Uri mCaptivePortalApiUrl;
- private CaptivePortalData mCaptivePortalData;
-
- /**
- * Indicates whether parceling should preserve fields that are set based on permissions of
- * the process receiving the {@link LinkProperties}.
- */
- private final transient boolean mParcelSensitiveFields;
-
- private static final int MIN_MTU = 68;
-
- private static final int MIN_MTU_V6 = 1280;
-
- private static final int MAX_MTU = 10000;
-
- private static final int INET6_ADDR_LENGTH = 16;
-
- // Stores the properties of links that are "stacked" above this link.
- // Indexed by interface name to allow modification and to prevent duplicates being added.
- private Hashtable<String, LinkProperties> mStackedLinks = new Hashtable<>();
-
- /**
- * @hide
- */
- @UnsupportedAppUsage(implicitMember =
- "values()[Landroid/net/LinkProperties$ProvisioningChange;")
- public enum ProvisioningChange {
- @UnsupportedAppUsage
- STILL_NOT_PROVISIONED,
- @UnsupportedAppUsage
- LOST_PROVISIONING,
- @UnsupportedAppUsage
- GAINED_PROVISIONING,
- @UnsupportedAppUsage
- STILL_PROVISIONED,
- }
-
- /**
- * Compare the provisioning states of two LinkProperties instances.
- *
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static ProvisioningChange compareProvisioning(
- LinkProperties before, LinkProperties after) {
- if (before.isProvisioned() && after.isProvisioned()) {
- // On dual-stack networks, DHCPv4 renewals can occasionally fail.
- // When this happens, IPv6-reachable services continue to function
- // normally but IPv4-only services (naturally) fail.
- //
- // When an application using an IPv4-only service reports a bad
- // network condition to the framework, attempts to re-validate
- // the network succeed (since we support IPv6-only networks) and
- // nothing is changed.
- //
- // For users, this is confusing and unexpected behaviour, and is
- // not necessarily easy to diagnose. Therefore, we treat changing
- // from a dual-stack network to an IPv6-only network equivalent to
- // a total loss of provisioning.
- //
- // For one such example of this, see b/18867306.
- //
- // Additionally, losing IPv6 provisioning can result in TCP
- // connections getting stuck until timeouts fire and other
- // baffling failures. Therefore, loss of either IPv4 or IPv6 on a
- // previously dual-stack network is deemed a lost of provisioning.
- if ((before.isIpv4Provisioned() && !after.isIpv4Provisioned())
- || (before.isIpv6Provisioned() && !after.isIpv6Provisioned())) {
- return ProvisioningChange.LOST_PROVISIONING;
- }
- return ProvisioningChange.STILL_PROVISIONED;
- } else if (before.isProvisioned() && !after.isProvisioned()) {
- return ProvisioningChange.LOST_PROVISIONING;
- } else if (!before.isProvisioned() && after.isProvisioned()) {
- return ProvisioningChange.GAINED_PROVISIONING;
- } else { // !before.isProvisioned() && !after.isProvisioned()
- return ProvisioningChange.STILL_NOT_PROVISIONED;
- }
- }
-
- /**
- * Constructs a new {@code LinkProperties} with default values.
- */
- public LinkProperties() {
- mParcelSensitiveFields = false;
- }
-
- /**
- * @hide
- */
- @SystemApi
- public LinkProperties(@Nullable LinkProperties source) {
- this(source, false /* parcelSensitiveFields */);
- }
-
- /**
- * Create a copy of a {@link LinkProperties} that may preserve fields that were set
- * based on the permissions of the process that originally received it.
- *
- * <p>By default {@link LinkProperties} does not preserve such fields during parceling, as
- * they should not be shared outside of the process that receives them without appropriate
- * checks.
- * @param parcelSensitiveFields Whether the sensitive fields should be kept when parceling
- * @hide
- */
- @SystemApi
- public LinkProperties(@Nullable LinkProperties source, boolean parcelSensitiveFields) {
- mParcelSensitiveFields = parcelSensitiveFields;
- if (source == null) return;
- mIfaceName = source.mIfaceName;
- mLinkAddresses.addAll(source.mLinkAddresses);
- mDnses.addAll(source.mDnses);
- mValidatedPrivateDnses.addAll(source.mValidatedPrivateDnses);
- mUsePrivateDns = source.mUsePrivateDns;
- mPrivateDnsServerName = source.mPrivateDnsServerName;
- mPcscfs.addAll(source.mPcscfs);
- mDomains = source.mDomains;
- mRoutes.addAll(source.mRoutes);
- mHttpProxy = (source.mHttpProxy == null) ? null : new ProxyInfo(source.mHttpProxy);
- for (LinkProperties l: source.mStackedLinks.values()) {
- addStackedLink(l);
- }
- setMtu(source.mMtu);
- setDhcpServerAddress(source.getDhcpServerAddress());
- mTcpBufferSizes = source.mTcpBufferSizes;
- mNat64Prefix = source.mNat64Prefix;
- mWakeOnLanSupported = source.mWakeOnLanSupported;
- mCaptivePortalApiUrl = source.mCaptivePortalApiUrl;
- mCaptivePortalData = source.mCaptivePortalData;
- }
-
- /**
- * Sets the interface name for this link. All {@link RouteInfo} already set for this
- * will have their interface changed to match this new value.
- *
- * @param iface The name of the network interface used for this link.
- */
- public void setInterfaceName(@Nullable String iface) {
- mIfaceName = iface;
- ArrayList<RouteInfo> newRoutes = new ArrayList<>(mRoutes.size());
- for (RouteInfo route : mRoutes) {
- newRoutes.add(routeWithInterface(route));
- }
- mRoutes = newRoutes;
- }
-
- /**
- * Gets the interface name for this link. May be {@code null} if not set.
- *
- * @return The interface name set for this link or {@code null}.
- */
- public @Nullable String getInterfaceName() {
- return mIfaceName;
- }
-
- /**
- * @hide
- */
- @SystemApi
- public @NonNull List<String> getAllInterfaceNames() {
- List<String> interfaceNames = new ArrayList<>(mStackedLinks.size() + 1);
- if (mIfaceName != null) interfaceNames.add(mIfaceName);
- for (LinkProperties stacked: mStackedLinks.values()) {
- interfaceNames.addAll(stacked.getAllInterfaceNames());
- }
- return interfaceNames;
- }
-
- /**
- * Returns all the addresses on this link. We often think of a link having a single address,
- * however, particularly with Ipv6 several addresses are typical. Note that the
- * {@code LinkProperties} actually contains {@link LinkAddress} objects which also include
- * prefix lengths for each address. This is a simplified utility alternative to
- * {@link LinkProperties#getLinkAddresses}.
- *
- * @return An unmodifiable {@link List} of {@link InetAddress} for this link.
- * @hide
- */
- @SystemApi
- public @NonNull List<InetAddress> getAddresses() {
- final List<InetAddress> addresses = new ArrayList<>();
- for (LinkAddress linkAddress : mLinkAddresses) {
- addresses.add(linkAddress.getAddress());
- }
- return Collections.unmodifiableList(addresses);
- }
-
- /**
- * Returns all the addresses on this link and all the links stacked above it.
- * @hide
- */
- @UnsupportedAppUsage
- public @NonNull List<InetAddress> getAllAddresses() {
- List<InetAddress> addresses = new ArrayList<>();
- for (LinkAddress linkAddress : mLinkAddresses) {
- addresses.add(linkAddress.getAddress());
- }
- for (LinkProperties stacked: mStackedLinks.values()) {
- addresses.addAll(stacked.getAllAddresses());
- }
- return addresses;
- }
-
- private int findLinkAddressIndex(LinkAddress address) {
- for (int i = 0; i < mLinkAddresses.size(); i++) {
- if (mLinkAddresses.get(i).isSameAddressAs(address)) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Adds a {@link LinkAddress} to this {@code LinkProperties} if a {@link LinkAddress} of the
- * same address/prefix does not already exist. If it does exist it is replaced.
- * @param address The {@code LinkAddress} to add.
- * @return true if {@code address} was added or updated, false otherwise.
- * @hide
- */
- @SystemApi
- public boolean addLinkAddress(@NonNull LinkAddress address) {
- if (address == null) {
- return false;
- }
- int i = findLinkAddressIndex(address);
- if (i < 0) {
- // Address was not present. Add it.
- mLinkAddresses.add(address);
- return true;
- } else if (mLinkAddresses.get(i).equals(address)) {
- // Address was present and has same properties. Do nothing.
- return false;
- } else {
- // Address was present and has different properties. Update it.
- mLinkAddresses.set(i, address);
- return true;
- }
- }
-
- /**
- * Removes a {@link LinkAddress} from this {@code LinkProperties}. Specifically, matches
- * and {@link LinkAddress} with the same address and prefix.
- *
- * @param toRemove A {@link LinkAddress} specifying the address to remove.
- * @return true if the address was removed, false if it did not exist.
- * @hide
- */
- @SystemApi
- public boolean removeLinkAddress(@NonNull LinkAddress toRemove) {
- int i = findLinkAddressIndex(toRemove);
- if (i >= 0) {
- mLinkAddresses.remove(i);
- return true;
- }
- return false;
- }
-
- /**
- * Returns all the {@link LinkAddress} on this link. Typically a link will have
- * one IPv4 address and one or more IPv6 addresses.
- *
- * @return An unmodifiable {@link List} of {@link LinkAddress} for this link.
- */
- public @NonNull List<LinkAddress> getLinkAddresses() {
- return Collections.unmodifiableList(mLinkAddresses);
- }
-
- /**
- * Returns all the addresses on this link and all the links stacked above it.
- * @hide
- */
- @SystemApi
- public @NonNull List<LinkAddress> getAllLinkAddresses() {
- List<LinkAddress> addresses = new ArrayList<>(mLinkAddresses);
- for (LinkProperties stacked: mStackedLinks.values()) {
- addresses.addAll(stacked.getAllLinkAddresses());
- }
- return addresses;
- }
-
- /**
- * Replaces the {@link LinkAddress} in this {@code LinkProperties} with
- * the given {@link Collection} of {@link LinkAddress}.
- *
- * @param addresses The {@link Collection} of {@link LinkAddress} to set in this
- * object.
- */
- public void setLinkAddresses(@NonNull Collection<LinkAddress> addresses) {
- mLinkAddresses.clear();
- for (LinkAddress address: addresses) {
- addLinkAddress(address);
- }
- }
-
- /**
- * Adds the given {@link InetAddress} to the list of DNS servers, if not present.
- *
- * @param dnsServer The {@link InetAddress} to add to the list of DNS servers.
- * @return true if the DNS server was added, false if it was already present.
- * @hide
- */
- @SystemApi
- public boolean addDnsServer(@NonNull InetAddress dnsServer) {
- if (dnsServer != null && !mDnses.contains(dnsServer)) {
- mDnses.add(dnsServer);
- return true;
- }
- return false;
- }
-
- /**
- * Removes the given {@link InetAddress} from the list of DNS servers.
- *
- * @param dnsServer The {@link InetAddress} to remove from the list of DNS servers.
- * @return true if the DNS server was removed, false if it did not exist.
- * @hide
- */
- @SystemApi
- public boolean removeDnsServer(@NonNull InetAddress dnsServer) {
- return mDnses.remove(dnsServer);
- }
-
- /**
- * Replaces the DNS servers in this {@code LinkProperties} with
- * the given {@link Collection} of {@link InetAddress} objects.
- *
- * @param dnsServers The {@link Collection} of DNS servers to set in this object.
- */
- public void setDnsServers(@NonNull Collection<InetAddress> dnsServers) {
- mDnses.clear();
- for (InetAddress dnsServer: dnsServers) {
- addDnsServer(dnsServer);
- }
- }
-
- /**
- * Returns all the {@link InetAddress} for DNS servers on this link.
- *
- * @return An unmodifiable {@link List} of {@link InetAddress} for DNS servers on
- * this link.
- */
- public @NonNull List<InetAddress> getDnsServers() {
- return Collections.unmodifiableList(mDnses);
- }
-
- /**
- * Set whether private DNS is currently in use on this network.
- *
- * @param usePrivateDns The private DNS state.
- * @hide
- */
- @SystemApi
- public void setUsePrivateDns(boolean usePrivateDns) {
- mUsePrivateDns = usePrivateDns;
- }
-
- /**
- * Returns whether private DNS is currently in use on this network. When
- * private DNS is in use, applications must not send unencrypted DNS
- * queries as doing so could reveal private user information. Furthermore,
- * if private DNS is in use and {@link #getPrivateDnsServerName} is not
- * {@code null}, DNS queries must be sent to the specified DNS server.
- *
- * @return {@code true} if private DNS is in use, {@code false} otherwise.
- */
- public boolean isPrivateDnsActive() {
- return mUsePrivateDns;
- }
-
- /**
- * Set the name of the private DNS server to which private DNS queries
- * should be sent when in strict mode. This value should be {@code null}
- * when private DNS is off or in opportunistic mode.
- *
- * @param privateDnsServerName The private DNS server name.
- * @hide
- */
- @SystemApi
- public void setPrivateDnsServerName(@Nullable String privateDnsServerName) {
- mPrivateDnsServerName = privateDnsServerName;
- }
-
- /**
- * Set DHCP server address.
- *
- * @param serverAddress the server address to set.
- */
- public void setDhcpServerAddress(@Nullable Inet4Address serverAddress) {
- mDhcpServerAddress = serverAddress;
- }
-
- /**
- * Get DHCP server address
- *
- * @return The current DHCP server address.
- */
- public @Nullable Inet4Address getDhcpServerAddress() {
- return mDhcpServerAddress;
- }
-
- /**
- * Returns the private DNS server name that is in use. If not {@code null},
- * private DNS is in strict mode. In this mode, applications should ensure
- * that all DNS queries are encrypted and sent to this hostname and that
- * queries are only sent if the hostname's certificate is valid. If
- * {@code null} and {@link #isPrivateDnsActive} is {@code true}, private
- * DNS is in opportunistic mode, and applications should ensure that DNS
- * queries are encrypted and sent to a DNS server returned by
- * {@link #getDnsServers}. System DNS will handle each of these cases
- * correctly, but applications implementing their own DNS lookups must make
- * sure to follow these requirements.
- *
- * @return The private DNS server name.
- */
- public @Nullable String getPrivateDnsServerName() {
- return mPrivateDnsServerName;
- }
-
- /**
- * Adds the given {@link InetAddress} to the list of validated private DNS servers,
- * if not present. This is distinct from the server name in that these are actually
- * resolved addresses.
- *
- * @param dnsServer The {@link InetAddress} to add to the list of validated private DNS servers.
- * @return true if the DNS server was added, false if it was already present.
- * @hide
- */
- public boolean addValidatedPrivateDnsServer(@NonNull InetAddress dnsServer) {
- if (dnsServer != null && !mValidatedPrivateDnses.contains(dnsServer)) {
- mValidatedPrivateDnses.add(dnsServer);
- return true;
- }
- return false;
- }
-
- /**
- * Removes the given {@link InetAddress} from the list of validated private DNS servers.
- *
- * @param dnsServer The {@link InetAddress} to remove from the list of validated private DNS
- * servers.
- * @return true if the DNS server was removed, false if it did not exist.
- * @hide
- */
- public boolean removeValidatedPrivateDnsServer(@NonNull InetAddress dnsServer) {
- return mValidatedPrivateDnses.remove(dnsServer);
- }
-
- /**
- * Replaces the validated private DNS servers in this {@code LinkProperties} with
- * the given {@link Collection} of {@link InetAddress} objects.
- *
- * @param dnsServers The {@link Collection} of validated private DNS servers to set in this
- * object.
- * @hide
- */
- @SystemApi
- public void setValidatedPrivateDnsServers(@NonNull Collection<InetAddress> dnsServers) {
- mValidatedPrivateDnses.clear();
- for (InetAddress dnsServer: dnsServers) {
- addValidatedPrivateDnsServer(dnsServer);
- }
- }
-
- /**
- * Returns all the {@link InetAddress} for validated private DNS servers on this link.
- * These are resolved from the private DNS server name.
- *
- * @return An unmodifiable {@link List} of {@link InetAddress} for validated private
- * DNS servers on this link.
- * @hide
- */
- @SystemApi
- public @NonNull List<InetAddress> getValidatedPrivateDnsServers() {
- return Collections.unmodifiableList(mValidatedPrivateDnses);
- }
-
- /**
- * Adds the given {@link InetAddress} to the list of PCSCF servers, if not present.
- *
- * @param pcscfServer The {@link InetAddress} to add to the list of PCSCF servers.
- * @return true if the PCSCF server was added, false otherwise.
- * @hide
- */
- @SystemApi
- public boolean addPcscfServer(@NonNull InetAddress pcscfServer) {
- if (pcscfServer != null && !mPcscfs.contains(pcscfServer)) {
- mPcscfs.add(pcscfServer);
- return true;
- }
- return false;
- }
-
- /**
- * Removes the given {@link InetAddress} from the list of PCSCF servers.
- *
- * @param pcscfServer The {@link InetAddress} to remove from the list of PCSCF servers.
- * @return true if the PCSCF server was removed, false otherwise.
- * @hide
- */
- public boolean removePcscfServer(@NonNull InetAddress pcscfServer) {
- return mPcscfs.remove(pcscfServer);
- }
-
- /**
- * Replaces the PCSCF servers in this {@code LinkProperties} with
- * the given {@link Collection} of {@link InetAddress} objects.
- *
- * @param pcscfServers The {@link Collection} of PCSCF servers to set in this object.
- * @hide
- */
- @SystemApi
- public void setPcscfServers(@NonNull Collection<InetAddress> pcscfServers) {
- mPcscfs.clear();
- for (InetAddress pcscfServer: pcscfServers) {
- addPcscfServer(pcscfServer);
- }
- }
-
- /**
- * Returns all the {@link InetAddress} for PCSCF servers on this link.
- *
- * @return An unmodifiable {@link List} of {@link InetAddress} for PCSCF servers on
- * this link.
- * @hide
- */
- @SystemApi
- public @NonNull List<InetAddress> getPcscfServers() {
- return Collections.unmodifiableList(mPcscfs);
- }
-
- /**
- * Sets the DNS domain search path used on this link.
- *
- * @param domains A {@link String} listing in priority order the comma separated
- * domains to search when resolving host names on this link.
- */
- public void setDomains(@Nullable String domains) {
- mDomains = domains;
- }
-
- /**
- * Get the DNS domains search path set for this link. May be {@code null} if not set.
- *
- * @return A {@link String} containing the comma separated domains to search when resolving host
- * names on this link or {@code null}.
- */
- public @Nullable String getDomains() {
- return mDomains;
- }
-
- /**
- * Sets the Maximum Transmission Unit size to use on this link. This should not be used
- * unless the system default (1500) is incorrect. Values less than 68 or greater than
- * 10000 will be ignored.
- *
- * @param mtu The MTU to use for this link.
- */
- public void setMtu(int mtu) {
- mMtu = mtu;
- }
-
- /**
- * Gets any non-default MTU size set for this link. Note that if the default is being used
- * this will return 0.
- *
- * @return The mtu value set for this link.
- */
- public int getMtu() {
- return mMtu;
- }
-
- /**
- * Sets the tcp buffers sizes to be used when this link is the system default.
- * Should be of the form "rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max".
- *
- * @param tcpBufferSizes The tcp buffers sizes to use.
- *
- * @hide
- */
- @SystemApi
- public void setTcpBufferSizes(@Nullable String tcpBufferSizes) {
- mTcpBufferSizes = tcpBufferSizes;
- }
-
- /**
- * Gets the tcp buffer sizes. May be {@code null} if not set.
- *
- * @return the tcp buffer sizes to use when this link is the system default or {@code null}.
- *
- * @hide
- */
- @SystemApi
- public @Nullable String getTcpBufferSizes() {
- return mTcpBufferSizes;
- }
-
- private RouteInfo routeWithInterface(RouteInfo route) {
- return new RouteInfo(
- route.getDestination(),
- route.getGateway(),
- mIfaceName,
- route.getType(),
- route.getMtu());
- }
-
- private int findRouteIndexByRouteKey(RouteInfo route) {
- for (int i = 0; i < mRoutes.size(); i++) {
- if (mRoutes.get(i).getRouteKey().equals(route.getRouteKey())) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Adds a {@link RouteInfo} to this {@code LinkProperties}. If there is a {@link RouteInfo}
- * with the same destination, gateway and interface with different properties
- * (e.g., different MTU), it will be updated. If the {@link RouteInfo} had an
- * interface name set and that differs from the interface set for this
- * {@code LinkProperties} an {@link IllegalArgumentException} will be thrown.
- * The proper course is to add either un-named or properly named {@link RouteInfo}.
- *
- * @param route A {@link RouteInfo} to add to this object.
- * @return {@code true} was added or updated, false otherwise.
- */
- public boolean addRoute(@NonNull RouteInfo route) {
- String routeIface = route.getInterface();
- if (routeIface != null && !routeIface.equals(mIfaceName)) {
- throw new IllegalArgumentException(
- "Route added with non-matching interface: " + routeIface
- + " vs. " + mIfaceName);
- }
- route = routeWithInterface(route);
-
- int i = findRouteIndexByRouteKey(route);
- if (i == -1) {
- // Route was not present. Add it.
- mRoutes.add(route);
- return true;
- } else if (mRoutes.get(i).equals(route)) {
- // Route was present and has same properties. Do nothing.
- return false;
- } else {
- // Route was present and has different properties. Update it.
- mRoutes.set(i, route);
- return true;
- }
- }
-
- /**
- * Removes a {@link RouteInfo} from this {@code LinkProperties}, if present. The route must
- * specify an interface and the interface must match the interface of this
- * {@code LinkProperties}, or it will not be removed.
- *
- * @param route A {@link RouteInfo} specifying the route to remove.
- * @return {@code true} if the route was removed, {@code false} if it was not present.
- *
- * @hide
- */
- @SystemApi
- public boolean removeRoute(@NonNull RouteInfo route) {
- return Objects.equals(mIfaceName, route.getInterface()) && mRoutes.remove(route);
- }
-
- /**
- * Returns all the {@link RouteInfo} set on this link.
- *
- * @return An unmodifiable {@link List} of {@link RouteInfo} for this link.
- */
- public @NonNull List<RouteInfo> getRoutes() {
- return Collections.unmodifiableList(mRoutes);
- }
-
- /**
- * Make sure this LinkProperties instance contains routes that cover the local subnet
- * of its link addresses. Add any route that is missing.
- * @hide
- */
- public void ensureDirectlyConnectedRoutes() {
- for (LinkAddress addr : mLinkAddresses) {
- addRoute(new RouteInfo(addr, null, mIfaceName));
- }
- }
-
- /**
- * Returns all the routes on this link and all the links stacked above it.
- * @hide
- */
- @SystemApi
- public @NonNull List<RouteInfo> getAllRoutes() {
- List<RouteInfo> routes = new ArrayList<>(mRoutes);
- for (LinkProperties stacked: mStackedLinks.values()) {
- routes.addAll(stacked.getAllRoutes());
- }
- return routes;
- }
-
- /**
- * Sets the recommended {@link ProxyInfo} to use on this link, or {@code null} for none.
- * Note that Http Proxies are only a hint - the system recommends their use, but it does
- * not enforce it and applications may ignore them.
- *
- * @param proxy A {@link ProxyInfo} defining the HTTP Proxy to use on this link.
- */
- public void setHttpProxy(@Nullable ProxyInfo proxy) {
- mHttpProxy = proxy;
- }
-
- /**
- * Gets the recommended {@link ProxyInfo} (or {@code null}) set on this link.
- *
- * @return The {@link ProxyInfo} set on this link or {@code null}.
- */
- public @Nullable ProxyInfo getHttpProxy() {
- return mHttpProxy;
- }
-
- /**
- * Returns the NAT64 prefix in use on this link, if any.
- *
- * @return the NAT64 prefix or {@code null}.
- */
- public @Nullable IpPrefix getNat64Prefix() {
- return mNat64Prefix;
- }
-
- /**
- * Sets the NAT64 prefix in use on this link.
- *
- * Currently, only 96-bit prefixes (i.e., where the 32-bit IPv4 address is at the end of the
- * 128-bit IPv6 address) are supported or {@code null} for no prefix.
- *
- * @param prefix the NAT64 prefix.
- */
- public void setNat64Prefix(@Nullable IpPrefix prefix) {
- if (prefix != null && prefix.getPrefixLength() != 96) {
- throw new IllegalArgumentException("Only 96-bit prefixes are supported: " + prefix);
- }
- mNat64Prefix = prefix; // IpPrefix objects are immutable.
- }
-
- /**
- * Adds a stacked link.
- *
- * If there is already a stacked link with the same interface name as link,
- * that link is replaced with link. Otherwise, link is added to the list
- * of stacked links.
- *
- * @param link The link to add.
- * @return true if the link was stacked, false otherwise.
- * @hide
- */
- @UnsupportedAppUsage
- public boolean addStackedLink(@NonNull LinkProperties link) {
- if (link.getInterfaceName() != null) {
- mStackedLinks.put(link.getInterfaceName(), link);
- return true;
- }
- return false;
- }
-
- /**
- * Removes a stacked link.
- *
- * If there is a stacked link with the given interface name, it is
- * removed. Otherwise, nothing changes.
- *
- * @param iface The interface name of the link to remove.
- * @return true if the link was removed, false otherwise.
- * @hide
- */
- public boolean removeStackedLink(@NonNull String iface) {
- LinkProperties removed = mStackedLinks.remove(iface);
- return removed != null;
- }
-
- /**
- * Returns all the links stacked on top of this link.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public @NonNull List<LinkProperties> getStackedLinks() {
- if (mStackedLinks.isEmpty()) {
- return Collections.emptyList();
- }
- final List<LinkProperties> stacked = new ArrayList<>();
- for (LinkProperties link : mStackedLinks.values()) {
- stacked.add(new LinkProperties(link));
- }
- return Collections.unmodifiableList(stacked);
- }
-
- /**
- * Clears this object to its initial state.
- */
- public void clear() {
- if (mParcelSensitiveFields) {
- throw new UnsupportedOperationException(
- "Cannot clear LinkProperties when parcelSensitiveFields is set");
- }
-
- mIfaceName = null;
- mLinkAddresses.clear();
- mDnses.clear();
- mUsePrivateDns = false;
- mPrivateDnsServerName = null;
- mPcscfs.clear();
- mDomains = null;
- mRoutes.clear();
- mHttpProxy = null;
- mStackedLinks.clear();
- mMtu = 0;
- mDhcpServerAddress = null;
- mTcpBufferSizes = null;
- mNat64Prefix = null;
- mWakeOnLanSupported = false;
- mCaptivePortalApiUrl = null;
- mCaptivePortalData = null;
- }
-
- /**
- * Implement the Parcelable interface
- */
- public int describeContents() {
- return 0;
- }
-
- @Override
- public String toString() {
- // Space as a separator, so no need for spaces at start/end of the individual fragments.
- final StringJoiner resultJoiner = new StringJoiner(" ", "{", "}");
-
- if (mIfaceName != null) {
- resultJoiner.add("InterfaceName:");
- resultJoiner.add(mIfaceName);
- }
-
- resultJoiner.add("LinkAddresses: [");
- if (!mLinkAddresses.isEmpty()) {
- resultJoiner.add(TextUtils.join(",", mLinkAddresses));
- }
- resultJoiner.add("]");
-
- resultJoiner.add("DnsAddresses: [");
- if (!mDnses.isEmpty()) {
- resultJoiner.add(TextUtils.join(",", mDnses));
- }
- resultJoiner.add("]");
-
- if (mUsePrivateDns) {
- resultJoiner.add("UsePrivateDns: true");
- }
-
- if (mPrivateDnsServerName != null) {
- resultJoiner.add("PrivateDnsServerName:");
- resultJoiner.add(mPrivateDnsServerName);
- }
-
- if (!mPcscfs.isEmpty()) {
- resultJoiner.add("PcscfAddresses: [");
- resultJoiner.add(TextUtils.join(",", mPcscfs));
- resultJoiner.add("]");
- }
-
- if (!mValidatedPrivateDnses.isEmpty()) {
- final StringJoiner validatedPrivateDnsesJoiner =
- new StringJoiner(",", "ValidatedPrivateDnsAddresses: [", "]");
- for (final InetAddress addr : mValidatedPrivateDnses) {
- validatedPrivateDnsesJoiner.add(addr.getHostAddress());
- }
- resultJoiner.add(validatedPrivateDnsesJoiner.toString());
- }
-
- resultJoiner.add("Domains:");
- resultJoiner.add(mDomains);
-
- resultJoiner.add("MTU:");
- resultJoiner.add(Integer.toString(mMtu));
-
- if (mWakeOnLanSupported) {
- resultJoiner.add("WakeOnLanSupported: true");
- }
-
- if (mDhcpServerAddress != null) {
- resultJoiner.add("ServerAddress:");
- resultJoiner.add(mDhcpServerAddress.toString());
- }
-
- if (mCaptivePortalApiUrl != null) {
- resultJoiner.add("CaptivePortalApiUrl: " + mCaptivePortalApiUrl);
- }
-
- if (mCaptivePortalData != null) {
- resultJoiner.add("CaptivePortalData: " + mCaptivePortalData);
- }
-
- if (mTcpBufferSizes != null) {
- resultJoiner.add("TcpBufferSizes:");
- resultJoiner.add(mTcpBufferSizes);
- }
-
- resultJoiner.add("Routes: [");
- if (!mRoutes.isEmpty()) {
- resultJoiner.add(TextUtils.join(",", mRoutes));
- }
- resultJoiner.add("]");
-
- if (mHttpProxy != null) {
- resultJoiner.add("HttpProxy:");
- resultJoiner.add(mHttpProxy.toString());
- }
-
- if (mNat64Prefix != null) {
- resultJoiner.add("Nat64Prefix:");
- resultJoiner.add(mNat64Prefix.toString());
- }
-
- final Collection<LinkProperties> stackedLinksValues = mStackedLinks.values();
- if (!stackedLinksValues.isEmpty()) {
- final StringJoiner stackedLinksJoiner = new StringJoiner(",", "Stacked: [", "]");
- for (final LinkProperties lp : stackedLinksValues) {
- stackedLinksJoiner.add("[ " + lp + " ]");
- }
- resultJoiner.add(stackedLinksJoiner.toString());
- }
-
- return resultJoiner.toString();
- }
-
- /**
- * Returns true if this link has an IPv4 address.
- *
- * @return {@code true} if there is an IPv4 address, {@code false} otherwise.
- * @hide
- */
- @SystemApi
- public boolean hasIpv4Address() {
- for (LinkAddress address : mLinkAddresses) {
- if (address.getAddress() instanceof Inet4Address) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * For backward compatibility.
- * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely
- * just yet.
- * @return {@code true} if there is an IPv4 address, {@code false} otherwise.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
- public boolean hasIPv4Address() {
- return hasIpv4Address();
- }
-
- /**
- * Returns true if this link or any of its stacked interfaces has an IPv4 address.
- *
- * @return {@code true} if there is an IPv4 address, {@code false} otherwise.
- */
- private boolean hasIpv4AddressOnInterface(String iface) {
- // mIfaceName can be null.
- return (Objects.equals(iface, mIfaceName) && hasIpv4Address())
- || (iface != null && mStackedLinks.containsKey(iface)
- && mStackedLinks.get(iface).hasIpv4Address());
- }
-
- /**
- * Returns true if this link has a global preferred IPv6 address.
- *
- * @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise.
- * @hide
- */
- @SystemApi
- public boolean hasGlobalIpv6Address() {
- for (LinkAddress address : mLinkAddresses) {
- if (address.getAddress() instanceof Inet6Address && address.isGlobalPreferred()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns true if this link has an IPv4 unreachable default route.
- *
- * @return {@code true} if there is an IPv4 unreachable default route, {@code false} otherwise.
- * @hide
- */
- public boolean hasIpv4UnreachableDefaultRoute() {
- for (RouteInfo r : mRoutes) {
- if (r.isIPv4UnreachableDefault()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * For backward compatibility.
- * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely
- * just yet.
- * @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
- public boolean hasGlobalIPv6Address() {
- return hasGlobalIpv6Address();
- }
-
- /**
- * Returns true if this link has an IPv4 default route.
- *
- * @return {@code true} if there is an IPv4 default route, {@code false} otherwise.
- * @hide
- */
- @SystemApi
- public boolean hasIpv4DefaultRoute() {
- for (RouteInfo r : mRoutes) {
- if (r.isIPv4Default()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns true if this link has an IPv6 unreachable default route.
- *
- * @return {@code true} if there is an IPv6 unreachable default route, {@code false} otherwise.
- * @hide
- */
- public boolean hasIpv6UnreachableDefaultRoute() {
- for (RouteInfo r : mRoutes) {
- if (r.isIPv6UnreachableDefault()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * For backward compatibility.
- * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely
- * just yet.
- * @return {@code true} if there is an IPv4 default route, {@code false} otherwise.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
- public boolean hasIPv4DefaultRoute() {
- return hasIpv4DefaultRoute();
- }
-
- /**
- * Returns true if this link has an IPv6 default route.
- *
- * @return {@code true} if there is an IPv6 default route, {@code false} otherwise.
- * @hide
- */
- @SystemApi
- public boolean hasIpv6DefaultRoute() {
- for (RouteInfo r : mRoutes) {
- if (r.isIPv6Default()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * For backward compatibility.
- * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely
- * just yet.
- * @return {@code true} if there is an IPv6 default route, {@code false} otherwise.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
- public boolean hasIPv6DefaultRoute() {
- return hasIpv6DefaultRoute();
- }
-
- /**
- * Returns true if this link has an IPv4 DNS server.
- *
- * @return {@code true} if there is an IPv4 DNS server, {@code false} otherwise.
- * @hide
- */
- @SystemApi
- public boolean hasIpv4DnsServer() {
- for (InetAddress ia : mDnses) {
- if (ia instanceof Inet4Address) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * For backward compatibility.
- * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely
- * just yet.
- * @return {@code true} if there is an IPv4 DNS server, {@code false} otherwise.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
- public boolean hasIPv4DnsServer() {
- return hasIpv4DnsServer();
- }
-
- /**
- * Returns true if this link has an IPv6 DNS server.
- *
- * @return {@code true} if there is an IPv6 DNS server, {@code false} otherwise.
- * @hide
- */
- @SystemApi
- public boolean hasIpv6DnsServer() {
- for (InetAddress ia : mDnses) {
- if (ia instanceof Inet6Address) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * For backward compatibility.
- * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely
- * just yet.
- * @return {@code true} if there is an IPv6 DNS server, {@code false} otherwise.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
- public boolean hasIPv6DnsServer() {
- return hasIpv6DnsServer();
- }
-
- /**
- * Returns true if this link has an IPv4 PCSCF server.
- *
- * @return {@code true} if there is an IPv4 PCSCF server, {@code false} otherwise.
- * @hide
- */
- public boolean hasIpv4PcscfServer() {
- for (InetAddress ia : mPcscfs) {
- if (ia instanceof Inet4Address) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns true if this link has an IPv6 PCSCF server.
- *
- * @return {@code true} if there is an IPv6 PCSCF server, {@code false} otherwise.
- * @hide
- */
- public boolean hasIpv6PcscfServer() {
- for (InetAddress ia : mPcscfs) {
- if (ia instanceof Inet6Address) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns true if this link is provisioned for global IPv4 connectivity.
- * This requires an IP address, default route, and DNS server.
- *
- * @return {@code true} if the link is provisioned, {@code false} otherwise.
- * @hide
- */
- @SystemApi
- public boolean isIpv4Provisioned() {
- return (hasIpv4Address()
- && hasIpv4DefaultRoute()
- && hasIpv4DnsServer());
- }
-
- /**
- * Returns true if this link is provisioned for global IPv6 connectivity.
- * This requires an IP address, default route, and DNS server.
- *
- * @return {@code true} if the link is provisioned, {@code false} otherwise.
- * @hide
- */
- @SystemApi
- public boolean isIpv6Provisioned() {
- return (hasGlobalIpv6Address()
- && hasIpv6DefaultRoute()
- && hasIpv6DnsServer());
- }
-
- /**
- * For backward compatibility.
- * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely
- * just yet.
- * @return {@code true} if the link is provisioned, {@code false} otherwise.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
- public boolean isIPv6Provisioned() {
- return isIpv6Provisioned();
- }
-
-
- /**
- * Returns true if this link is provisioned for global connectivity,
- * for at least one Internet Protocol family.
- *
- * @return {@code true} if the link is provisioned, {@code false} otherwise.
- * @hide
- */
- @SystemApi
- public boolean isProvisioned() {
- return (isIpv4Provisioned() || isIpv6Provisioned());
- }
-
- /**
- * Evaluate whether the {@link InetAddress} is considered reachable.
- *
- * @return {@code true} if the given {@link InetAddress} is considered reachable,
- * {@code false} otherwise.
- * @hide
- */
- @SystemApi
- public boolean isReachable(@NonNull InetAddress ip) {
- final List<RouteInfo> allRoutes = getAllRoutes();
- // If we don't have a route to this IP address, it's not reachable.
- final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, ip);
- if (bestRoute == null) {
- return false;
- }
-
- // TODO: better source address evaluation for destination addresses.
-
- if (ip instanceof Inet4Address) {
- // For IPv4, it suffices for now to simply have any address.
- return hasIpv4AddressOnInterface(bestRoute.getInterface());
- } else if (ip instanceof Inet6Address) {
- if (ip.isLinkLocalAddress()) {
- // For now, just make sure link-local destinations have
- // scopedIds set, since transmits will generally fail otherwise.
- // TODO: verify it matches the ifindex of one of the interfaces.
- return (((Inet6Address)ip).getScopeId() != 0);
- } else {
- // For non-link-local destinations check that either the best route
- // is directly connected or that some global preferred address exists.
- // TODO: reconsider all cases (disconnected ULA networks, ...).
- return (!bestRoute.hasGateway() || hasGlobalIpv6Address());
- }
- }
-
- return false;
- }
-
- /**
- * Compares this {@code LinkProperties} interface name against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- @UnsupportedAppUsage
- public boolean isIdenticalInterfaceName(@NonNull LinkProperties target) {
- return LinkPropertiesUtils.isIdenticalInterfaceName(target, this);
- }
-
- /**
- * Compares this {@code LinkProperties} DHCP server address against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalDhcpServerAddress(@NonNull LinkProperties target) {
- return Objects.equals(mDhcpServerAddress, target.mDhcpServerAddress);
- }
-
- /**
- * Compares this {@code LinkProperties} interface addresses against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- @UnsupportedAppUsage
- public boolean isIdenticalAddresses(@NonNull LinkProperties target) {
- return LinkPropertiesUtils.isIdenticalAddresses(target, this);
- }
-
- /**
- * Compares this {@code LinkProperties} DNS addresses against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- @UnsupportedAppUsage
- public boolean isIdenticalDnses(@NonNull LinkProperties target) {
- return LinkPropertiesUtils.isIdenticalDnses(target, this);
- }
-
- /**
- * Compares this {@code LinkProperties} private DNS settings against the
- * target.
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalPrivateDns(@NonNull LinkProperties target) {
- return (isPrivateDnsActive() == target.isPrivateDnsActive()
- && TextUtils.equals(getPrivateDnsServerName(),
- target.getPrivateDnsServerName()));
- }
-
- /**
- * Compares this {@code LinkProperties} validated private DNS addresses against
- * the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalValidatedPrivateDnses(@NonNull LinkProperties target) {
- Collection<InetAddress> targetDnses = target.getValidatedPrivateDnsServers();
- return (mValidatedPrivateDnses.size() == targetDnses.size())
- ? mValidatedPrivateDnses.containsAll(targetDnses) : false;
- }
-
- /**
- * Compares this {@code LinkProperties} PCSCF addresses against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalPcscfs(@NonNull LinkProperties target) {
- Collection<InetAddress> targetPcscfs = target.getPcscfServers();
- return (mPcscfs.size() == targetPcscfs.size()) ?
- mPcscfs.containsAll(targetPcscfs) : false;
- }
-
- /**
- * Compares this {@code LinkProperties} Routes against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- @UnsupportedAppUsage
- public boolean isIdenticalRoutes(@NonNull LinkProperties target) {
- return LinkPropertiesUtils.isIdenticalRoutes(target, this);
- }
-
- /**
- * Compares this {@code LinkProperties} HttpProxy against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public boolean isIdenticalHttpProxy(@NonNull LinkProperties target) {
- return LinkPropertiesUtils.isIdenticalHttpProxy(target, this);
- }
-
- /**
- * Compares this {@code LinkProperties} stacked links against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public boolean isIdenticalStackedLinks(@NonNull LinkProperties target) {
- if (!mStackedLinks.keySet().equals(target.mStackedLinks.keySet())) {
- return false;
- }
- for (LinkProperties stacked : mStackedLinks.values()) {
- // Hashtable values can never be null.
- String iface = stacked.getInterfaceName();
- if (!stacked.equals(target.mStackedLinks.get(iface))) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Compares this {@code LinkProperties} MTU against the target
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalMtu(@NonNull LinkProperties target) {
- return getMtu() == target.getMtu();
- }
-
- /**
- * Compares this {@code LinkProperties} Tcp buffer sizes against the target.
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalTcpBufferSizes(@NonNull LinkProperties target) {
- return Objects.equals(mTcpBufferSizes, target.mTcpBufferSizes);
- }
-
- /**
- * Compares this {@code LinkProperties} NAT64 prefix against the target.
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalNat64Prefix(@NonNull LinkProperties target) {
- return Objects.equals(mNat64Prefix, target.mNat64Prefix);
- }
-
- /**
- * Compares this {@code LinkProperties} WakeOnLan supported against the target.
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalWakeOnLan(LinkProperties target) {
- return isWakeOnLanSupported() == target.isWakeOnLanSupported();
- }
-
- /**
- * Compares this {@code LinkProperties}'s CaptivePortalApiUrl against the target.
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalCaptivePortalApiUrl(LinkProperties target) {
- return Objects.equals(mCaptivePortalApiUrl, target.mCaptivePortalApiUrl);
- }
-
- /**
- * Compares this {@code LinkProperties}'s CaptivePortalData against the target.
- *
- * @param target LinkProperties to compare.
- * @return {@code true} if both are identical, {@code false} otherwise.
- * @hide
- */
- public boolean isIdenticalCaptivePortalData(LinkProperties target) {
- return Objects.equals(mCaptivePortalData, target.mCaptivePortalData);
- }
-
- /**
- * Set whether the network interface supports WakeOnLAN
- *
- * @param supported WakeOnLAN supported value
- *
- * @hide
- */
- public void setWakeOnLanSupported(boolean supported) {
- mWakeOnLanSupported = supported;
- }
-
- /**
- * Returns whether the network interface supports WakeOnLAN
- *
- * @return {@code true} if interface supports WakeOnLAN, {@code false} otherwise.
- */
- public boolean isWakeOnLanSupported() {
- return mWakeOnLanSupported;
- }
-
- /**
- * Set the URL of the captive portal API endpoint to get more information about the network.
- * @hide
- */
- @SystemApi
- public void setCaptivePortalApiUrl(@Nullable Uri url) {
- mCaptivePortalApiUrl = url;
- }
-
- /**
- * Get the URL of the captive portal API endpoint to get more information about the network.
- *
- * <p>This is null unless the application has
- * {@link android.Manifest.permission.NETWORK_SETTINGS} or
- * {@link NetworkStack#PERMISSION_MAINLINE_NETWORK_STACK} permissions, and the network provided
- * the URL.
- * @hide
- */
- @SystemApi
- @Nullable
- public Uri getCaptivePortalApiUrl() {
- return mCaptivePortalApiUrl;
- }
-
- /**
- * Set the CaptivePortalData obtained from the captive portal API (RFC7710bis).
- * @hide
- */
- @SystemApi
- public void setCaptivePortalData(@Nullable CaptivePortalData data) {
- mCaptivePortalData = data;
- }
-
- /**
- * Get the CaptivePortalData obtained from the captive portal API (RFC7710bis).
- *
- * <p>This is null unless the application has
- * {@link android.Manifest.permission.NETWORK_SETTINGS} or
- * {@link NetworkStack#PERMISSION_MAINLINE_NETWORK_STACK} permissions.
- * @hide
- */
- @SystemApi
- @Nullable
- public CaptivePortalData getCaptivePortalData() {
- return mCaptivePortalData;
- }
-
- /**
- * Compares this {@code LinkProperties} instance against the target
- * LinkProperties in {@code obj}. Two LinkPropertieses are equal if
- * all their fields are equal in values.
- *
- * For collection fields, such as mDnses, containsAll() is used to check
- * if two collections contains the same elements, independent of order.
- * There are two thoughts regarding containsAll()
- * 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal.
- * 2. Worst case performance is O(n^2).
- *
- * @param obj the object to be tested for equality.
- * @return {@code true} if both objects are equal, {@code false} otherwise.
- */
- @Override
- public boolean equals(@Nullable Object obj) {
- if (this == obj) return true;
-
- if (!(obj instanceof LinkProperties)) return false;
-
- LinkProperties target = (LinkProperties) obj;
- /*
- * This method does not check that stacked interfaces are equal, because
- * stacked interfaces are not so much a property of the link as a
- * description of connections between links.
- */
- return isIdenticalInterfaceName(target)
- && isIdenticalAddresses(target)
- && isIdenticalDhcpServerAddress(target)
- && isIdenticalDnses(target)
- && isIdenticalPrivateDns(target)
- && isIdenticalValidatedPrivateDnses(target)
- && isIdenticalPcscfs(target)
- && isIdenticalRoutes(target)
- && isIdenticalHttpProxy(target)
- && isIdenticalStackedLinks(target)
- && isIdenticalMtu(target)
- && isIdenticalTcpBufferSizes(target)
- && isIdenticalNat64Prefix(target)
- && isIdenticalWakeOnLan(target)
- && isIdenticalCaptivePortalApiUrl(target)
- && isIdenticalCaptivePortalData(target);
- }
-
- /**
- * Generate hashcode based on significant fields
- *
- * Equal objects must produce the same hash code, while unequal objects
- * may have the same hash codes.
- */
- @Override
- public int hashCode() {
- return ((null == mIfaceName) ? 0 : mIfaceName.hashCode()
- + mLinkAddresses.size() * 31
- + mDnses.size() * 37
- + mValidatedPrivateDnses.size() * 61
- + ((null == mDomains) ? 0 : mDomains.hashCode())
- + mRoutes.size() * 41
- + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode())
- + mStackedLinks.hashCode() * 47)
- + mMtu * 51
- + ((null == mTcpBufferSizes) ? 0 : mTcpBufferSizes.hashCode())
- + (mUsePrivateDns ? 57 : 0)
- + ((null == mDhcpServerAddress) ? 0 : mDhcpServerAddress.hashCode())
- + mPcscfs.size() * 67
- + ((null == mPrivateDnsServerName) ? 0 : mPrivateDnsServerName.hashCode())
- + Objects.hash(mNat64Prefix)
- + (mWakeOnLanSupported ? 71 : 0)
- + Objects.hash(mCaptivePortalApiUrl, mCaptivePortalData);
- }
-
- /**
- * Implement the Parcelable interface.
- */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(getInterfaceName());
- dest.writeInt(mLinkAddresses.size());
- for (LinkAddress linkAddress : mLinkAddresses) {
- dest.writeParcelable(linkAddress, flags);
- }
-
- writeAddresses(dest, mDnses);
- writeAddresses(dest, mValidatedPrivateDnses);
- dest.writeBoolean(mUsePrivateDns);
- dest.writeString(mPrivateDnsServerName);
- writeAddresses(dest, mPcscfs);
- dest.writeString(mDomains);
- writeAddress(dest, mDhcpServerAddress);
- dest.writeInt(mMtu);
- dest.writeString(mTcpBufferSizes);
- dest.writeInt(mRoutes.size());
- for (RouteInfo route : mRoutes) {
- dest.writeParcelable(route, flags);
- }
-
- if (mHttpProxy != null) {
- dest.writeByte((byte)1);
- dest.writeParcelable(mHttpProxy, flags);
- } else {
- dest.writeByte((byte)0);
- }
- dest.writeParcelable(mNat64Prefix, 0);
-
- ArrayList<LinkProperties> stackedLinks = new ArrayList<>(mStackedLinks.values());
- dest.writeList(stackedLinks);
-
- dest.writeBoolean(mWakeOnLanSupported);
- dest.writeParcelable(mParcelSensitiveFields ? mCaptivePortalApiUrl : null, 0);
- dest.writeParcelable(mParcelSensitiveFields ? mCaptivePortalData : null, 0);
- }
-
- private static void writeAddresses(@NonNull Parcel dest, @NonNull List<InetAddress> list) {
- dest.writeInt(list.size());
- for (InetAddress d : list) {
- writeAddress(dest, d);
- }
- }
-
- private static void writeAddress(@NonNull Parcel dest, @Nullable InetAddress addr) {
- byte[] addressBytes = (addr == null ? null : addr.getAddress());
- dest.writeByteArray(addressBytes);
- if (addr instanceof Inet6Address) {
- final Inet6Address v6Addr = (Inet6Address) addr;
- final boolean hasScopeId = v6Addr.getScopeId() != 0;
- dest.writeBoolean(hasScopeId);
- if (hasScopeId) dest.writeInt(v6Addr.getScopeId());
- }
- }
-
- @Nullable
- private static InetAddress readAddress(@NonNull Parcel p) throws UnknownHostException {
- final byte[] addr = p.createByteArray();
- if (addr == null) return null;
-
- if (addr.length == INET6_ADDR_LENGTH) {
- final boolean hasScopeId = p.readBoolean();
- final int scopeId = hasScopeId ? p.readInt() : 0;
- return Inet6Address.getByAddress(null /* host */, addr, scopeId);
- }
-
- return InetAddress.getByAddress(addr);
- }
-
- /**
- * Implement the Parcelable interface.
- */
- public static final @android.annotation.NonNull Creator<LinkProperties> CREATOR =
- new Creator<LinkProperties>() {
- public LinkProperties createFromParcel(Parcel in) {
- LinkProperties netProp = new LinkProperties();
-
- String iface = in.readString();
- if (iface != null) {
- netProp.setInterfaceName(iface);
- }
- int addressCount = in.readInt();
- for (int i = 0; i < addressCount; i++) {
- netProp.addLinkAddress(in.readParcelable(null));
- }
- addressCount = in.readInt();
- for (int i = 0; i < addressCount; i++) {
- try {
- netProp.addDnsServer(readAddress(in));
- } catch (UnknownHostException e) { }
- }
- addressCount = in.readInt();
- for (int i = 0; i < addressCount; i++) {
- try {
- netProp.addValidatedPrivateDnsServer(readAddress(in));
- } catch (UnknownHostException e) { }
- }
- netProp.setUsePrivateDns(in.readBoolean());
- netProp.setPrivateDnsServerName(in.readString());
- addressCount = in.readInt();
- for (int i = 0; i < addressCount; i++) {
- try {
- netProp.addPcscfServer(readAddress(in));
- } catch (UnknownHostException e) { }
- }
- netProp.setDomains(in.readString());
- try {
- netProp.setDhcpServerAddress((Inet4Address) InetAddress
- .getByAddress(in.createByteArray()));
- } catch (UnknownHostException e) { }
- netProp.setMtu(in.readInt());
- netProp.setTcpBufferSizes(in.readString());
- addressCount = in.readInt();
- for (int i = 0; i < addressCount; i++) {
- netProp.addRoute(in.readParcelable(null));
- }
- if (in.readByte() == 1) {
- netProp.setHttpProxy(in.readParcelable(null));
- }
- netProp.setNat64Prefix(in.readParcelable(null));
- ArrayList<LinkProperties> stackedLinks = new ArrayList<LinkProperties>();
- in.readList(stackedLinks, LinkProperties.class.getClassLoader());
- for (LinkProperties stackedLink: stackedLinks) {
- netProp.addStackedLink(stackedLink);
- }
- netProp.setWakeOnLanSupported(in.readBoolean());
-
- netProp.setCaptivePortalApiUrl(in.readParcelable(null));
- netProp.setCaptivePortalData(in.readParcelable(null));
- return netProp;
- }
-
- public LinkProperties[] newArray(int size) {
- return new LinkProperties[size];
- }
- };
-
- /**
- * Check the valid MTU range based on IPv4 or IPv6.
- * @hide
- */
- public static boolean isValidMtu(int mtu, boolean ipv6) {
- if (ipv6) {
- return mtu >= MIN_MTU_V6 && mtu <= MAX_MTU;
- } else {
- return mtu >= MIN_MTU && mtu <= MAX_MTU;
- }
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/MacAddress.java b/packages/Connectivity/framework/src/android/net/MacAddress.java
deleted file mode 100644
index 26a504a..0000000
--- a/packages/Connectivity/framework/src/android/net/MacAddress.java
+++ /dev/null
@@ -1,400 +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 android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.wifi.WifiInfo;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.net.module.util.MacAddressUtils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.Inet6Address;
-import java.net.UnknownHostException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * Representation of a MAC address.
- *
- * This class only supports 48 bits long addresses and does not support 64 bits long addresses.
- * Instances of this class are immutable. This class provides implementations of hashCode()
- * and equals() that make it suitable for use as keys in standard implementations of
- * {@link java.util.Map}.
- */
-public final class MacAddress implements Parcelable {
-
- private static final int ETHER_ADDR_LEN = 6;
- private static final byte[] ETHER_ADDR_BROADCAST = addr(0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
-
- /**
- * The MacAddress representing the unique broadcast MAC address.
- */
- public static final MacAddress BROADCAST_ADDRESS = MacAddress.fromBytes(ETHER_ADDR_BROADCAST);
-
- /**
- * The MacAddress zero MAC address.
- *
- * <p>Not publicly exposed or treated specially since the OUI 00:00:00 is registered.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final MacAddress ALL_ZEROS_ADDRESS = new MacAddress(0);
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "TYPE_" }, value = {
- TYPE_UNKNOWN,
- TYPE_UNICAST,
- TYPE_MULTICAST,
- TYPE_BROADCAST,
- })
- public @interface MacAddressType { }
-
- /** @hide Indicates a MAC address of unknown type. */
- public static final int TYPE_UNKNOWN = 0;
- /** Indicates a MAC address is a unicast address. */
- public static final int TYPE_UNICAST = 1;
- /** Indicates a MAC address is a multicast address. */
- public static final int TYPE_MULTICAST = 2;
- /** Indicates a MAC address is the broadcast address. */
- public static final int TYPE_BROADCAST = 3;
-
- private static final long VALID_LONG_MASK = (1L << 48) - 1;
- private static final long LOCALLY_ASSIGNED_MASK = MacAddress.fromString("2:0:0:0:0:0").mAddr;
- private static final long MULTICAST_MASK = MacAddress.fromString("1:0:0:0:0:0").mAddr;
- private static final long OUI_MASK = MacAddress.fromString("ff:ff:ff:0:0:0").mAddr;
- private static final long NIC_MASK = MacAddress.fromString("0:0:0:ff:ff:ff").mAddr;
- private static final MacAddress BASE_GOOGLE_MAC = MacAddress.fromString("da:a1:19:0:0:0");
- /** Default wifi MAC address used for a special purpose **/
- private static final MacAddress DEFAULT_MAC_ADDRESS =
- MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
-
- // Internal representation of the MAC address as a single 8 byte long.
- // The encoding scheme sets the two most significant bytes to 0. The 6 bytes of the
- // MAC address are encoded in the 6 least significant bytes of the long, where the first
- // byte of the array is mapped to the 3rd highest logical byte of the long, the second
- // byte of the array is mapped to the 4th highest logical byte of the long, and so on.
- private final long mAddr;
-
- private MacAddress(long addr) {
- mAddr = (VALID_LONG_MASK & addr);
- }
-
- /**
- * Returns the type of this address.
- *
- * @return the int constant representing the MAC address type of this MacAddress.
- */
- public @MacAddressType int getAddressType() {
- if (equals(BROADCAST_ADDRESS)) {
- return TYPE_BROADCAST;
- }
- if ((mAddr & MULTICAST_MASK) != 0) {
- return TYPE_MULTICAST;
- }
- return TYPE_UNICAST;
- }
-
- /**
- * @return true if this MacAddress is a locally assigned address.
- */
- public boolean isLocallyAssigned() {
- return (mAddr & LOCALLY_ASSIGNED_MASK) != 0;
- }
-
- /**
- * Convert this MacAddress to a byte array.
- *
- * The returned array is in network order. For example, if this MacAddress is 1:2:3:4:5:6,
- * the returned array is [1, 2, 3, 4, 5, 6].
- *
- * @return a byte array representation of this MacAddress.
- */
- public @NonNull byte[] toByteArray() {
- return byteAddrFromLongAddr(mAddr);
- }
-
- /**
- * Returns a human-readable representation of this MacAddress.
- * The exact format is implementation-dependent and should not be assumed to have any
- * particular format.
- */
- @Override
- public @NonNull String toString() {
- return stringAddrFromLongAddr(mAddr);
- }
-
- /**
- * @return a String representation of the OUI part of this MacAddress made of 3 hexadecimal
- * numbers in [0,ff] joined by ':' characters.
- */
- public @NonNull String toOuiString() {
- return String.format(
- "%02x:%02x:%02x", (mAddr >> 40) & 0xff, (mAddr >> 32) & 0xff, (mAddr >> 24) & 0xff);
- }
-
- @Override
- public int hashCode() {
- return (int) ((mAddr >> 32) ^ mAddr);
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- return (o instanceof MacAddress) && ((MacAddress) o).mAddr == mAddr;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeLong(mAddr);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<MacAddress> CREATOR =
- new Parcelable.Creator<MacAddress>() {
- public MacAddress createFromParcel(Parcel in) {
- return new MacAddress(in.readLong());
- }
-
- public MacAddress[] newArray(int size) {
- return new MacAddress[size];
- }
- };
-
- /**
- * Returns true if the given byte array is an valid MAC address.
- * A valid byte array representation for a MacAddress is a non-null array of length 6.
- *
- * @param addr a byte array.
- * @return true if the given byte array is not null and has the length of a MAC address.
- *
- * @hide
- */
- public static boolean isMacAddress(byte[] addr) {
- return MacAddressUtils.isMacAddress(addr);
- }
-
- /**
- * Returns the MAC address type of the MAC address represented by the given byte array,
- * or null if the given byte array does not represent a MAC address.
- * A valid byte array representation for a MacAddress is a non-null array of length 6.
- *
- * @param addr a byte array representing a MAC address.
- * @return the int constant representing the MAC address type of the MAC address represented
- * by the given byte array, or type UNKNOWN if the byte array is not a valid MAC address.
- *
- * @hide
- */
- public static int macAddressType(byte[] addr) {
- if (!isMacAddress(addr)) {
- return TYPE_UNKNOWN;
- }
- return MacAddress.fromBytes(addr).getAddressType();
- }
-
- /**
- * Converts a String representation of a MAC address to a byte array representation.
- * A valid String representation for a MacAddress is a series of 6 values in the
- * range [0,ff] printed in hexadecimal and joined by ':' characters.
- *
- * @param addr a String representation of a MAC address.
- * @return the byte representation of the MAC address.
- * @throws IllegalArgumentException if the given String is not a valid representation.
- *
- * @hide
- */
- public static @NonNull byte[] byteAddrFromStringAddr(String addr) {
- Objects.requireNonNull(addr);
- String[] parts = addr.split(":");
- if (parts.length != ETHER_ADDR_LEN) {
- throw new IllegalArgumentException(addr + " was not a valid MAC address");
- }
- byte[] bytes = new byte[ETHER_ADDR_LEN];
- for (int i = 0; i < ETHER_ADDR_LEN; i++) {
- int x = Integer.valueOf(parts[i], 16);
- if (x < 0 || 0xff < x) {
- throw new IllegalArgumentException(addr + "was not a valid MAC address");
- }
- bytes[i] = (byte) x;
- }
- return bytes;
- }
-
- /**
- * Converts a byte array representation of a MAC address to a String representation made
- * of 6 hexadecimal numbers in [0,ff] joined by ':' characters.
- * A valid byte array representation for a MacAddress is a non-null array of length 6.
- *
- * @param addr a byte array representation of a MAC address.
- * @return the String representation of the MAC address.
- * @throws IllegalArgumentException if the given byte array is not a valid representation.
- *
- * @hide
- */
- public static @NonNull String stringAddrFromByteAddr(byte[] addr) {
- if (!isMacAddress(addr)) {
- return null;
- }
- return String.format("%02x:%02x:%02x:%02x:%02x:%02x",
- addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
- }
-
- private static byte[] byteAddrFromLongAddr(long addr) {
- return MacAddressUtils.byteAddrFromLongAddr(addr);
- }
-
- private static long longAddrFromByteAddr(byte[] addr) {
- return MacAddressUtils.longAddrFromByteAddr(addr);
- }
-
- // Internal conversion function equivalent to longAddrFromByteAddr(byteAddrFromStringAddr(addr))
- // that avoids the allocation of an intermediary byte[].
- private static long longAddrFromStringAddr(String addr) {
- Objects.requireNonNull(addr);
- String[] parts = addr.split(":");
- if (parts.length != ETHER_ADDR_LEN) {
- throw new IllegalArgumentException(addr + " was not a valid MAC address");
- }
- long longAddr = 0;
- for (int i = 0; i < parts.length; i++) {
- int x = Integer.valueOf(parts[i], 16);
- if (x < 0 || 0xff < x) {
- throw new IllegalArgumentException(addr + "was not a valid MAC address");
- }
- longAddr = x + (longAddr << 8);
- }
- return longAddr;
- }
-
- // Internal conversion function equivalent to stringAddrFromByteAddr(byteAddrFromLongAddr(addr))
- // that avoids the allocation of an intermediary byte[].
- private static @NonNull String stringAddrFromLongAddr(long addr) {
- return String.format("%02x:%02x:%02x:%02x:%02x:%02x",
- (addr >> 40) & 0xff,
- (addr >> 32) & 0xff,
- (addr >> 24) & 0xff,
- (addr >> 16) & 0xff,
- (addr >> 8) & 0xff,
- addr & 0xff);
- }
-
- /**
- * Creates a MacAddress from the given String representation. A valid String representation
- * for a MacAddress is a series of 6 values in the range [0,ff] printed in hexadecimal
- * and joined by ':' characters.
- *
- * @param addr a String representation of a MAC address.
- * @return the MacAddress corresponding to the given String representation.
- * @throws IllegalArgumentException if the given String is not a valid representation.
- */
- public static @NonNull MacAddress fromString(@NonNull String addr) {
- return new MacAddress(longAddrFromStringAddr(addr));
- }
-
- /**
- * Creates a MacAddress from the given byte array representation.
- * A valid byte array representation for a MacAddress is a non-null array of length 6.
- *
- * @param addr a byte array representation of a MAC address.
- * @return the MacAddress corresponding to the given byte array representation.
- * @throws IllegalArgumentException if the given byte array is not a valid representation.
- */
- public static @NonNull MacAddress fromBytes(@NonNull byte[] addr) {
- return new MacAddress(longAddrFromByteAddr(addr));
- }
-
- /**
- * Returns a generated MAC address whose 24 least significant bits constituting the
- * NIC part of the address are randomly selected and has Google OUI base.
- *
- * The locally assigned bit is always set to 1. The multicast bit is always set to 0.
- *
- * @return a random locally assigned, unicast MacAddress with Google OUI.
- *
- * @hide
- */
- public static @NonNull MacAddress createRandomUnicastAddressWithGoogleBase() {
- return MacAddressUtils.createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom());
- }
-
- // Convenience function for working around the lack of byte literals.
- private static byte[] addr(int... in) {
- if (in.length != ETHER_ADDR_LEN) {
- throw new IllegalArgumentException(Arrays.toString(in)
- + " was not an array with length equal to " + ETHER_ADDR_LEN);
- }
- byte[] out = new byte[ETHER_ADDR_LEN];
- for (int i = 0; i < ETHER_ADDR_LEN; i++) {
- out[i] = (byte) in[i];
- }
- return out;
- }
-
- /**
- * Checks if this MAC Address matches the provided range.
- *
- * @param baseAddress MacAddress representing the base address to compare with.
- * @param mask MacAddress representing the mask to use during comparison.
- * @return true if this MAC Address matches the given range.
- *
- */
- public boolean matches(@NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
- Objects.requireNonNull(baseAddress);
- Objects.requireNonNull(mask);
- return (mAddr & mask.mAddr) == (baseAddress.mAddr & mask.mAddr);
- }
-
- /**
- * Create a link-local Inet6Address from the MAC address. The EUI-48 MAC address is converted
- * to an EUI-64 MAC address per RFC 4291. The resulting EUI-64 is used to construct a link-local
- * IPv6 address per RFC 4862.
- *
- * @return A link-local Inet6Address constructed from the MAC address.
- */
- public @Nullable Inet6Address getLinkLocalIpv6FromEui48Mac() {
- byte[] macEui48Bytes = toByteArray();
- byte[] addr = new byte[16];
-
- addr[0] = (byte) 0xfe;
- addr[1] = (byte) 0x80;
- addr[8] = (byte) (macEui48Bytes[0] ^ (byte) 0x02); // flip the link-local bit
- addr[9] = macEui48Bytes[1];
- addr[10] = macEui48Bytes[2];
- addr[11] = (byte) 0xff;
- addr[12] = (byte) 0xfe;
- addr[13] = macEui48Bytes[3];
- addr[14] = macEui48Bytes[4];
- addr[15] = macEui48Bytes[5];
-
- try {
- return Inet6Address.getByAddress(null, addr, 0);
- } catch (UnknownHostException e) {
- return null;
- }
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/NattKeepalivePacketData.java b/packages/Connectivity/framework/src/android/net/NattKeepalivePacketData.java
deleted file mode 100644
index c4f8fc2..0000000
--- a/packages/Connectivity/framework/src/android/net/NattKeepalivePacketData.java
+++ /dev/null
@@ -1,144 +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 android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS;
-import static android.net.InvalidPacketException.ERROR_INVALID_PORT;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.system.OsConstants;
-
-import com.android.net.module.util.IpUtils;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Objects;
-
-/** @hide */
-@SystemApi
-public final class NattKeepalivePacketData extends KeepalivePacketData implements Parcelable {
- private static final int IPV4_HEADER_LENGTH = 20;
- private static final int UDP_HEADER_LENGTH = 8;
-
- // This should only be constructed via static factory methods, such as
- // nattKeepalivePacket
- public NattKeepalivePacketData(@NonNull InetAddress srcAddress, int srcPort,
- @NonNull InetAddress dstAddress, int dstPort, @NonNull byte[] data) throws
- InvalidPacketException {
- super(srcAddress, srcPort, dstAddress, dstPort, data);
- }
-
- /**
- * Factory method to create Nat-T keepalive packet structure.
- * @hide
- */
- public static NattKeepalivePacketData nattKeepalivePacket(
- InetAddress srcAddress, int srcPort, InetAddress dstAddress, int dstPort)
- throws InvalidPacketException {
-
- if (!(srcAddress instanceof Inet4Address) || !(dstAddress instanceof Inet4Address)) {
- throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
- }
-
- if (dstPort != NattSocketKeepalive.NATT_PORT) {
- throw new InvalidPacketException(ERROR_INVALID_PORT);
- }
-
- int length = IPV4_HEADER_LENGTH + UDP_HEADER_LENGTH + 1;
- ByteBuffer buf = ByteBuffer.allocate(length);
- buf.order(ByteOrder.BIG_ENDIAN);
- buf.putShort((short) 0x4500); // IP version and TOS
- buf.putShort((short) length);
- buf.putInt(0); // ID, flags, offset
- buf.put((byte) 64); // TTL
- buf.put((byte) OsConstants.IPPROTO_UDP);
- int ipChecksumOffset = buf.position();
- buf.putShort((short) 0); // IP checksum
- buf.put(srcAddress.getAddress());
- buf.put(dstAddress.getAddress());
- buf.putShort((short) srcPort);
- buf.putShort((short) dstPort);
- buf.putShort((short) (length - 20)); // UDP length
- int udpChecksumOffset = buf.position();
- buf.putShort((short) 0); // UDP checksum
- buf.put((byte) 0xff); // NAT-T keepalive
- buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0));
- buf.putShort(udpChecksumOffset, IpUtils.udpChecksum(buf, 0, IPV4_HEADER_LENGTH));
-
- return new NattKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, buf.array());
- }
-
- /** Parcelable Implementation */
- public int describeContents() {
- return 0;
- }
-
- /** Write to parcel */
- public void writeToParcel(@NonNull Parcel out, int flags) {
- out.writeString(getSrcAddress().getHostAddress());
- out.writeString(getDstAddress().getHostAddress());
- out.writeInt(getSrcPort());
- out.writeInt(getDstPort());
- }
-
- /** Parcelable Creator */
- public static final @NonNull Parcelable.Creator<NattKeepalivePacketData> CREATOR =
- new Parcelable.Creator<NattKeepalivePacketData>() {
- public NattKeepalivePacketData createFromParcel(Parcel in) {
- final InetAddress srcAddress =
- InetAddresses.parseNumericAddress(in.readString());
- final InetAddress dstAddress =
- InetAddresses.parseNumericAddress(in.readString());
- final int srcPort = in.readInt();
- final int dstPort = in.readInt();
- try {
- return NattKeepalivePacketData.nattKeepalivePacket(srcAddress, srcPort,
- dstAddress, dstPort);
- } catch (InvalidPacketException e) {
- throw new IllegalArgumentException(
- "Invalid NAT-T keepalive data: " + e.getError());
- }
- }
-
- public NattKeepalivePacketData[] newArray(int size) {
- return new NattKeepalivePacketData[size];
- }
- };
-
- @Override
- public boolean equals(@Nullable final Object o) {
- if (!(o instanceof NattKeepalivePacketData)) return false;
- final NattKeepalivePacketData other = (NattKeepalivePacketData) o;
- final InetAddress srcAddress = getSrcAddress();
- final InetAddress dstAddress = getDstAddress();
- return srcAddress.equals(other.getSrcAddress())
- && dstAddress.equals(other.getDstAddress())
- && getSrcPort() == other.getSrcPort()
- && getDstPort() == other.getDstPort();
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(getSrcAddress(), getDstAddress(), getSrcPort(), getDstPort());
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/NattSocketKeepalive.java b/packages/Connectivity/framework/src/android/net/NattSocketKeepalive.java
deleted file mode 100644
index a15d165..0000000
--- a/packages/Connectivity/framework/src/android/net/NattSocketKeepalive.java
+++ /dev/null
@@ -1,77 +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 android.annotation.NonNull;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.net.InetAddress;
-import java.util.concurrent.Executor;
-
-/** @hide */
-public final class NattSocketKeepalive extends SocketKeepalive {
- /** The NAT-T destination port for IPsec */
- public static final int NATT_PORT = 4500;
-
- @NonNull private final InetAddress mSource;
- @NonNull private final InetAddress mDestination;
- private final int mResourceId;
-
- NattSocketKeepalive(@NonNull IConnectivityManager service,
- @NonNull Network network,
- @NonNull ParcelFileDescriptor pfd,
- int resourceId,
- @NonNull InetAddress source,
- @NonNull InetAddress destination,
- @NonNull Executor executor,
- @NonNull Callback callback) {
- super(service, network, pfd, executor, callback);
- mSource = source;
- mDestination = destination;
- mResourceId = resourceId;
- }
-
- @Override
- void startImpl(int intervalSec) {
- mExecutor.execute(() -> {
- try {
- mService.startNattKeepaliveWithFd(mNetwork, mPfd, mResourceId,
- intervalSec, mCallback,
- mSource.getHostAddress(), mDestination.getHostAddress());
- } catch (RemoteException e) {
- Log.e(TAG, "Error starting socket keepalive: ", e);
- throw e.rethrowFromSystemServer();
- }
- });
- }
-
- @Override
- void stopImpl() {
- mExecutor.execute(() -> {
- try {
- if (mSlot != null) {
- mService.stopKeepalive(mNetwork, mSlot);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Error stopping socket keepalive: ", e);
- throw e.rethrowFromSystemServer();
- }
- });
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/Network.java b/packages/Connectivity/framework/src/android/net/Network.java
deleted file mode 100644
index 1f49033..0000000
--- a/packages/Connectivity/framework/src/android/net/Network.java
+++ /dev/null
@@ -1,530 +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 android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
-
-import com.android.internal.annotations.GuardedBy;
-
-import libcore.io.IoUtils;
-import libcore.net.http.Dns;
-import libcore.net.http.HttpURLConnectionFactory;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.MalformedURLException;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.net.UnknownHostException;
-import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
-
-import javax.net.SocketFactory;
-
-/**
- * Identifies a {@code Network}. This is supplied to applications via
- * {@link ConnectivityManager.NetworkCallback} in response to the active
- * {@link ConnectivityManager#requestNetwork} or passive
- * {@link ConnectivityManager#registerNetworkCallback} calls.
- * It is used to direct traffic to the given {@code Network}, either on a {@link Socket} basis
- * through a targeted {@link SocketFactory} or process-wide via
- * {@link ConnectivityManager#bindProcessToNetwork}.
- */
-public class Network implements Parcelable {
-
- /**
- * The unique id of the network.
- * @hide
- */
- @UnsupportedAppUsage
- public final int netId;
-
- // Objects used to perform per-network operations such as getSocketFactory
- // and openConnection, and a lock to protect access to them.
- private volatile NetworkBoundSocketFactory mNetworkBoundSocketFactory = null;
- // mUrlConnectionFactory is initialized lazily when it is first needed.
- @GuardedBy("mLock")
- private HttpURLConnectionFactory mUrlConnectionFactory;
- private final Object mLock = new Object();
-
- // Default connection pool values. These are evaluated at startup, just
- // like the OkHttp code. Also like the OkHttp code, we will throw parse
- // exceptions at class loading time if the properties are set but are not
- // valid integers.
- private static final boolean httpKeepAlive =
- Boolean.parseBoolean(System.getProperty("http.keepAlive", "true"));
- private static final int httpMaxConnections =
- httpKeepAlive ? Integer.parseInt(System.getProperty("http.maxConnections", "5")) : 0;
- private static final long httpKeepAliveDurationMs =
- Long.parseLong(System.getProperty("http.keepAliveDuration", "300000")); // 5 minutes.
- // Value used to obfuscate network handle longs.
- // The HANDLE_MAGIC value MUST be kept in sync with the corresponding
- // value in the native/android/net.c NDK implementation.
- private static final long HANDLE_MAGIC = 0xcafed00dL;
- private static final int HANDLE_MAGIC_SIZE = 32;
- private static final int USE_LOCAL_NAMESERVERS_FLAG = 0x80000000;
-
- // A boolean to control how getAllByName()/getByName() behaves in the face
- // of Private DNS.
- //
- // When true, these calls will request that DNS resolution bypass any
- // Private DNS that might otherwise apply. Use of this feature is restricted
- // and permission checks are made by netd (attempts to bypass Private DNS
- // without appropriate permission are silently turned into vanilla DNS
- // requests). This only affects DNS queries made using this network object.
- //
- // It it not parceled to receivers because (a) it can be set or cleared at
- // anytime and (b) receivers should be explicit about attempts to bypass
- // Private DNS so that the intent of the code is easily determined and
- // code search audits are possible.
- private final transient boolean mPrivateDnsBypass;
-
- /**
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public Network(int netId) {
- this(netId, false);
- }
-
- /**
- * @hide
- */
- public Network(int netId, boolean privateDnsBypass) {
- this.netId = netId;
- this.mPrivateDnsBypass = privateDnsBypass;
- }
-
- /**
- * @hide
- */
- @SystemApi
- public Network(@NonNull Network that) {
- this(that.netId, that.mPrivateDnsBypass);
- }
-
- /**
- * Operates the same as {@code InetAddress.getAllByName} except that host
- * resolution is done on this network.
- *
- * @param host the hostname or literal IP string to be resolved.
- * @return the array of addresses associated with the specified host.
- * @throws UnknownHostException if the address lookup fails.
- */
- public InetAddress[] getAllByName(String host) throws UnknownHostException {
- return InetAddressCompat.getAllByNameOnNet(host, getNetIdForResolv());
- }
-
- /**
- * Operates the same as {@code InetAddress.getByName} except that host
- * resolution is done on this network.
- *
- * @param host the hostname to be resolved to an address or {@code null}.
- * @return the {@code InetAddress} instance representing the host.
- * @throws UnknownHostException
- * if the address lookup fails.
- */
- public InetAddress getByName(String host) throws UnknownHostException {
- return InetAddressCompat.getByNameOnNet(host, getNetIdForResolv());
- }
-
- /**
- * Obtain a Network object for which Private DNS is to be bypassed when attempting
- * to use {@link #getAllByName(String)}/{@link #getByName(String)} methods on the given
- * instance for hostname resolution.
- *
- * @hide
- */
- @SystemApi
- public @NonNull Network getPrivateDnsBypassingCopy() {
- return new Network(netId, true);
- }
-
- /**
- * Get the unique id of the network.
- *
- * @hide
- */
- @SystemApi
- public int getNetId() {
- return netId;
- }
-
- /**
- * Returns a netid marked with the Private DNS bypass flag.
- *
- * This flag must be kept in sync with the NETID_USE_LOCAL_NAMESERVERS flag
- * in system/netd/include/NetdClient.h.
- *
- * @hide
- */
- public int getNetIdForResolv() {
- return mPrivateDnsBypass
- ? (USE_LOCAL_NAMESERVERS_FLAG | netId) // Non-portable DNS resolution flag.
- : netId;
- }
-
- /**
- * A {@code SocketFactory} that produces {@code Socket}'s bound to this network.
- */
- private class NetworkBoundSocketFactory extends SocketFactory {
- private Socket connectToHost(String host, int port, SocketAddress localAddress)
- throws IOException {
- // Lookup addresses only on this Network.
- InetAddress[] hostAddresses = getAllByName(host);
- // Try all addresses.
- for (int i = 0; i < hostAddresses.length; i++) {
- try {
- Socket socket = createSocket();
- boolean failed = true;
- try {
- if (localAddress != null) socket.bind(localAddress);
- socket.connect(new InetSocketAddress(hostAddresses[i], port));
- failed = false;
- return socket;
- } finally {
- if (failed) IoUtils.closeQuietly(socket);
- }
- } catch (IOException e) {
- if (i == (hostAddresses.length - 1)) throw e;
- }
- }
- throw new UnknownHostException(host);
- }
-
- @Override
- public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
- throws IOException {
- return connectToHost(host, port, new InetSocketAddress(localHost, localPort));
- }
-
- @Override
- public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
- int localPort) throws IOException {
- Socket socket = createSocket();
- boolean failed = true;
- try {
- socket.bind(new InetSocketAddress(localAddress, localPort));
- socket.connect(new InetSocketAddress(address, port));
- failed = false;
- } finally {
- if (failed) IoUtils.closeQuietly(socket);
- }
- return socket;
- }
-
- @Override
- public Socket createSocket(InetAddress host, int port) throws IOException {
- Socket socket = createSocket();
- boolean failed = true;
- try {
- socket.connect(new InetSocketAddress(host, port));
- failed = false;
- } finally {
- if (failed) IoUtils.closeQuietly(socket);
- }
- return socket;
- }
-
- @Override
- public Socket createSocket(String host, int port) throws IOException {
- return connectToHost(host, port, null);
- }
-
- @Override
- public Socket createSocket() throws IOException {
- Socket socket = new Socket();
- boolean failed = true;
- try {
- bindSocket(socket);
- failed = false;
- } finally {
- if (failed) IoUtils.closeQuietly(socket);
- }
- return socket;
- }
- }
-
- /**
- * Returns a {@link SocketFactory} bound to this network. Any {@link Socket} created by
- * this factory will have its traffic sent over this {@code Network}. Note that if this
- * {@code Network} ever disconnects, this factory and any {@link Socket} it produced in the
- * past or future will cease to work.
- *
- * @return a {@link SocketFactory} which produces {@link Socket} instances bound to this
- * {@code Network}.
- */
- public SocketFactory getSocketFactory() {
- if (mNetworkBoundSocketFactory == null) {
- synchronized (mLock) {
- if (mNetworkBoundSocketFactory == null) {
- mNetworkBoundSocketFactory = new NetworkBoundSocketFactory();
- }
- }
- }
- return mNetworkBoundSocketFactory;
- }
-
- private static HttpURLConnectionFactory createUrlConnectionFactory(Dns dnsLookup) {
- // Set configuration on the HttpURLConnectionFactory that will be good for all
- // connections created by this Network. Configuration that might vary is left
- // until openConnection() and passed as arguments.
- HttpURLConnectionFactory urlConnectionFactory = HttpURLConnectionFactory.createInstance();
- urlConnectionFactory.setDns(dnsLookup); // Let traffic go via dnsLookup
- // A private connection pool just for this Network.
- urlConnectionFactory.setNewConnectionPool(httpMaxConnections,
- httpKeepAliveDurationMs, TimeUnit.MILLISECONDS);
- return urlConnectionFactory;
- }
-
- /**
- * Opens the specified {@link URL} on this {@code Network}, such that all traffic will be sent
- * on this Network. The URL protocol must be {@code HTTP} or {@code HTTPS}.
- *
- * @return a {@code URLConnection} to the resource referred to by this URL.
- * @throws MalformedURLException if the URL protocol is not HTTP or HTTPS.
- * @throws IOException if an error occurs while opening the connection.
- * @see java.net.URL#openConnection()
- */
- public URLConnection openConnection(URL url) throws IOException {
- final ConnectivityManager cm = ConnectivityManager.getInstanceOrNull();
- if (cm == null) {
- throw new IOException("No ConnectivityManager yet constructed, please construct one");
- }
- // TODO: Should this be optimized to avoid fetching the global proxy for every request?
- final ProxyInfo proxyInfo = cm.getProxyForNetwork(this);
- final java.net.Proxy proxy;
- if (proxyInfo != null) {
- proxy = proxyInfo.makeProxy();
- } else {
- proxy = java.net.Proxy.NO_PROXY;
- }
- return openConnection(url, proxy);
- }
-
- /**
- * Opens the specified {@link URL} on this {@code Network}, such that all traffic will be sent
- * on this Network. The URL protocol must be {@code HTTP} or {@code HTTPS}.
- *
- * @param proxy the proxy through which the connection will be established.
- * @return a {@code URLConnection} to the resource referred to by this URL.
- * @throws MalformedURLException if the URL protocol is not HTTP or HTTPS.
- * @throws IllegalArgumentException if the argument proxy is null.
- * @throws IOException if an error occurs while opening the connection.
- * @see java.net.URL#openConnection()
- */
- public URLConnection openConnection(URL url, java.net.Proxy proxy) throws IOException {
- if (proxy == null) throw new IllegalArgumentException("proxy is null");
- // TODO: This creates a connection pool and host resolver for
- // every Network object, instead of one for every NetId. This is
- // suboptimal, because an app could potentially have more than one
- // Network object for the same NetId, causing increased memory footprint
- // and performance penalties due to lack of connection reuse (connection
- // setup time, congestion window growth time, etc.).
- //
- // Instead, investigate only having one connection pool and host resolver
- // for every NetId, perhaps by using a static HashMap of NetIds to
- // connection pools and host resolvers. The tricky part is deciding when
- // to remove a map entry; a WeakHashMap shouldn't be used because whether
- // a Network is referenced doesn't correlate with whether a new Network
- // will be instantiated in the near future with the same NetID. A good
- // solution would involve purging empty (or when all connections are timed
- // out) ConnectionPools.
- final HttpURLConnectionFactory urlConnectionFactory;
- synchronized (mLock) {
- if (mUrlConnectionFactory == null) {
- Dns dnsLookup = hostname -> Arrays.asList(getAllByName(hostname));
- mUrlConnectionFactory = createUrlConnectionFactory(dnsLookup);
- }
- urlConnectionFactory = mUrlConnectionFactory;
- }
- SocketFactory socketFactory = getSocketFactory();
- return urlConnectionFactory.openConnection(url, socketFactory, proxy);
- }
-
- /**
- * Binds the specified {@link DatagramSocket} to this {@code Network}. All data traffic on the
- * socket will be sent on this {@code Network}, irrespective of any process-wide network binding
- * set by {@link ConnectivityManager#bindProcessToNetwork}. The socket must not be
- * connected.
- */
- public void bindSocket(DatagramSocket socket) throws IOException {
- // Query a property of the underlying socket to ensure that the socket's file descriptor
- // exists, is available to bind to a network and is not closed.
- socket.getReuseAddress();
- final ParcelFileDescriptor pfd = ParcelFileDescriptor.fromDatagramSocket(socket);
- bindSocket(pfd.getFileDescriptor());
- // ParcelFileDescriptor.fromSocket() creates a dup of the original fd. The original and the
- // dup share the underlying socket in the kernel. The socket is never truly closed until the
- // last fd pointing to the socket being closed. So close the dup one after binding the
- // socket to control the lifetime of the dup fd.
- pfd.close();
- }
-
- /**
- * Binds the specified {@link Socket} to this {@code Network}. All data traffic on the socket
- * will be sent on this {@code Network}, irrespective of any process-wide network binding set by
- * {@link ConnectivityManager#bindProcessToNetwork}. The socket must not be connected.
- */
- public void bindSocket(Socket socket) throws IOException {
- // Query a property of the underlying socket to ensure that the socket's file descriptor
- // exists, is available to bind to a network and is not closed.
- socket.getReuseAddress();
- final ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
- bindSocket(pfd.getFileDescriptor());
- // ParcelFileDescriptor.fromSocket() creates a dup of the original fd. The original and the
- // dup share the underlying socket in the kernel. The socket is never truly closed until the
- // last fd pointing to the socket being closed. So close the dup one after binding the
- // socket to control the lifetime of the dup fd.
- pfd.close();
- }
-
- /**
- * Binds the specified {@link FileDescriptor} to this {@code Network}. All data traffic on the
- * socket represented by this file descriptor will be sent on this {@code Network},
- * irrespective of any process-wide network binding set by
- * {@link ConnectivityManager#bindProcessToNetwork}. The socket must not be connected.
- */
- public void bindSocket(FileDescriptor fd) throws IOException {
- try {
- final SocketAddress peer = Os.getpeername(fd);
- final InetAddress inetPeer = ((InetSocketAddress) peer).getAddress();
- if (!inetPeer.isAnyLocalAddress()) {
- // Apparently, the kernel doesn't update a connected UDP socket's
- // routing upon mark changes.
- throw new SocketException("Socket is connected");
- }
- } catch (ErrnoException e) {
- // getpeername() failed.
- if (e.errno != OsConstants.ENOTCONN) {
- throw e.rethrowAsSocketException();
- }
- } catch (ClassCastException e) {
- // Wasn't an InetSocketAddress.
- throw new SocketException("Only AF_INET/AF_INET6 sockets supported");
- }
-
- final int err = NetworkUtils.bindSocketToNetwork(fd, netId);
- if (err != 0) {
- // bindSocketToNetwork returns negative errno.
- throw new ErrnoException("Binding socket to network " + netId, -err)
- .rethrowAsSocketException();
- }
- }
-
- /**
- * Returns a {@link Network} object given a handle returned from {@link #getNetworkHandle}.
- *
- * @param networkHandle a handle returned from {@link #getNetworkHandle}.
- * @return A {@link Network} object derived from {@code networkHandle}.
- */
- public static Network fromNetworkHandle(long networkHandle) {
- if (networkHandle == 0) {
- throw new IllegalArgumentException(
- "Network.fromNetworkHandle refusing to instantiate NETID_UNSET Network.");
- }
- if ((networkHandle & ((1L << HANDLE_MAGIC_SIZE) - 1)) != HANDLE_MAGIC) {
- throw new IllegalArgumentException(
- "Value passed to fromNetworkHandle() is not a network handle.");
- }
- final int netIdForResolv = (int) (networkHandle >>> HANDLE_MAGIC_SIZE);
- return new Network((netIdForResolv & ~USE_LOCAL_NAMESERVERS_FLAG),
- ((netIdForResolv & USE_LOCAL_NAMESERVERS_FLAG) != 0) /* privateDnsBypass */);
- }
-
- /**
- * Returns a handle representing this {@code Network}, for use with the NDK API.
- */
- public long getNetworkHandle() {
- // The network handle is explicitly not the same as the netId.
- //
- // The netId is an implementation detail which might be changed in the
- // future, or which alone (i.e. in the absence of some additional
- // context) might not be sufficient to fully identify a Network.
- //
- // As such, the intention is to prevent accidental misuse of the API
- // that might result if a developer assumed that handles and netIds
- // were identical and passing a netId to a call expecting a handle
- // "just worked". Such accidental misuse, if widely deployed, might
- // prevent future changes to the semantics of the netId field or
- // inhibit the expansion of state required for Network objects.
- //
- // This extra layer of indirection might be seen as paranoia, and might
- // never end up being necessary, but the added complexity is trivial.
- // At some future date it may be desirable to realign the handle with
- // Multiple Provisioning Domains API recommendations, as made by the
- // IETF mif working group.
- if (netId == 0) {
- return 0L; // make this zero condition obvious for debugging
- }
- return (((long) getNetIdForResolv()) << HANDLE_MAGIC_SIZE) | HANDLE_MAGIC;
- }
-
- // implement the Parcelable interface
- public int describeContents() {
- return 0;
- }
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(netId);
- }
-
- public static final @android.annotation.NonNull Creator<Network> CREATOR =
- new Creator<Network>() {
- public Network createFromParcel(Parcel in) {
- int netId = in.readInt();
-
- return new Network(netId);
- }
-
- public Network[] newArray(int size) {
- return new Network[size];
- }
- };
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (!(obj instanceof Network)) return false;
- Network other = (Network)obj;
- return this.netId == other.netId;
- }
-
- @Override
- public int hashCode() {
- return netId * 11;
- }
-
- @Override
- public String toString() {
- return Integer.toString(netId);
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkAgent.java b/packages/Connectivity/framework/src/android/net/NetworkAgent.java
deleted file mode 100644
index adcf338..0000000
--- a/packages/Connectivity/framework/src/android/net/NetworkAgent.java
+++ /dev/null
@@ -1,1324 +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 android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.telephony.data.EpsBearerQosSessionAttributes;
-import android.telephony.data.NrQosSessionAttributes;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * A utility class for handling for communicating between bearer-specific
- * code and ConnectivityService.
- *
- * An agent manages the life cycle of a network. A network starts its
- * life cycle when {@link register} is called on NetworkAgent. The network
- * is then connecting. When full L3 connectivity has been established,
- * the agent should call {@link markConnected} to inform the system that
- * this network is ready to use. When the network disconnects its life
- * ends and the agent should call {@link unregister}, at which point the
- * system will clean up and free resources.
- * Any reconnection becomes a new logical network, so after a network
- * is disconnected the agent cannot be used any more. Network providers
- * should create a new NetworkAgent instance to handle new connections.
- *
- * A bearer may have more than one NetworkAgent if it can simultaneously
- * support separate networks (IMS / Internet / MMS Apns on cellular, or
- * perhaps connections with different SSID or P2P for Wi-Fi).
- *
- * This class supports methods to start and stop sending keepalive packets.
- * Keepalive packets are typically sent at periodic intervals over a network
- * with NAT when there is no other traffic to avoid the network forcefully
- * closing the connection. NetworkAgents that manage technologies that
- * have hardware support for keepalive should implement the related
- * methods to save battery life. NetworkAgent that cannot get support
- * without waking up the CPU should not, as this would be prohibitive in
- * terms of battery - these agents should simply not override the related
- * methods, which results in the implementation returning
- * {@link SocketKeepalive.ERROR_UNSUPPORTED} as appropriate.
- *
- * Keepalive packets need to be sent at relatively frequent intervals
- * (a few seconds to a few minutes). As the contents of keepalive packets
- * depend on the current network status, hardware needs to be configured
- * to send them and has a limited amount of memory to do so. The HAL
- * formalizes this as slots that an implementation can configure to send
- * the correct packets. Devices typically have a small number of slots
- * per radio technology, and the specific number of slots for each
- * technology is specified in configuration files.
- * {@see SocketKeepalive} for details.
- *
- * @hide
- */
-@SystemApi
-public abstract class NetworkAgent {
- /**
- * The {@link Network} corresponding to this object.
- */
- @Nullable
- private volatile Network mNetwork;
-
- @Nullable
- private volatile INetworkAgentRegistry mRegistry;
-
- private interface RegistryAction {
- void execute(@NonNull INetworkAgentRegistry registry) throws RemoteException;
- }
-
- private final Handler mHandler;
- private final String LOG_TAG;
- private static final boolean DBG = true;
- private static final boolean VDBG = false;
- /** @hide */
- @TestApi
- public static final int MIN_LINGER_TIMER_MS = 2000;
- private final ArrayList<RegistryAction> mPreConnectedQueue = new ArrayList<>();
- private volatile long mLastBwRefreshTime = 0;
- private static final long BW_REFRESH_MIN_WIN_MS = 500;
- private boolean mBandwidthUpdateScheduled = false;
- private AtomicBoolean mBandwidthUpdatePending = new AtomicBoolean(false);
- @NonNull
- private NetworkInfo mNetworkInfo;
- @NonNull
- private final Object mRegisterLock = new Object();
-
- /**
- * The ID of the {@link NetworkProvider} that created this object, or
- * {@link NetworkProvider#ID_NONE} if unknown.
- * @hide
- */
- public final int providerId;
-
- // ConnectivityService parses message constants from itself and NetworkAgent with MessageUtils
- // for debugging purposes, and crashes if some messages have the same values.
- // TODO: have ConnectivityService store message names in different maps and remove this base
- private static final int BASE = 200;
-
- /**
- * Sent by ConnectivityService to the NetworkAgent to inform it of
- * suspected connectivity problems on its network. The NetworkAgent
- * should take steps to verify and correct connectivity.
- * @hide
- */
- public static final int CMD_SUSPECT_BAD = BASE;
-
- /**
- * Sent by the NetworkAgent (note the EVENT vs CMD prefix) to
- * ConnectivityService to pass the current NetworkInfo (connection state).
- * Sent when the NetworkInfo changes, mainly due to change of state.
- * obj = NetworkInfo
- * @hide
- */
- public static final int EVENT_NETWORK_INFO_CHANGED = BASE + 1;
-
- /**
- * Sent by the NetworkAgent to ConnectivityService to pass the current
- * NetworkCapabilties.
- * obj = NetworkCapabilities
- * @hide
- */
- public static final int EVENT_NETWORK_CAPABILITIES_CHANGED = BASE + 2;
-
- /**
- * Sent by the NetworkAgent to ConnectivityService to pass the current
- * NetworkProperties.
- * obj = NetworkProperties
- * @hide
- */
- public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3;
-
- /**
- * Centralize the place where base network score, and network score scaling, will be
- * stored, so as we can consistently compare apple and oranges, or wifi, ethernet and LTE
- * @hide
- */
- public static final int WIFI_BASE_SCORE = 60;
-
- /**
- * Sent by the NetworkAgent to ConnectivityService to pass the current
- * network score.
- * arg1 = network score int
- * @hide
- */
- public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4;
-
- /**
- * Sent by the NetworkAgent to ConnectivityService to pass the current
- * list of underlying networks.
- * obj = array of Network objects
- * @hide
- */
- public static final int EVENT_UNDERLYING_NETWORKS_CHANGED = BASE + 5;
-
- /**
- * Sent by the NetworkAgent to ConnectivityService to pass the current value of the teardown
- * delay.
- * arg1 = teardown delay in milliseconds
- * @hide
- */
- public static final int EVENT_TEARDOWN_DELAY_CHANGED = BASE + 6;
-
- /**
- * The maximum value for the teardown delay, in milliseconds.
- * @hide
- */
- public static final int MAX_TEARDOWN_DELAY_MS = 5000;
-
- /**
- * Sent by ConnectivityService to the NetworkAgent to inform the agent of the
- * networks status - whether we could use the network or could not, due to
- * either a bad network configuration (no internet link) or captive portal.
- *
- * arg1 = either {@code VALID_NETWORK} or {@code INVALID_NETWORK}
- * obj = Bundle containing map from {@code REDIRECT_URL_KEY} to {@code String}
- * representing URL that Internet probe was redirect to, if it was redirected,
- * or mapping to {@code null} otherwise.
- * @hide
- */
- public static final int CMD_REPORT_NETWORK_STATUS = BASE + 7;
-
- /**
- * Network validation suceeded.
- * Corresponds to {@link NetworkCapabilities.NET_CAPABILITY_VALIDATED}.
- */
- public static final int VALIDATION_STATUS_VALID = 1;
-
- /**
- * Network validation was attempted and failed. This may be received more than once as
- * subsequent validation attempts are made.
- */
- public static final int VALIDATION_STATUS_NOT_VALID = 2;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "VALIDATION_STATUS_" }, value = {
- VALIDATION_STATUS_VALID,
- VALIDATION_STATUS_NOT_VALID
- })
- public @interface ValidationStatus {}
-
- // TODO: remove.
- /** @hide */
- public static final int VALID_NETWORK = 1;
- /** @hide */
- public static final int INVALID_NETWORK = 2;
-
- /**
- * The key for the redirect URL in the Bundle argument of {@code CMD_REPORT_NETWORK_STATUS}.
- * @hide
- */
- public static final String REDIRECT_URL_KEY = "redirect URL";
-
- /**
- * Sent by the NetworkAgent to ConnectivityService to indicate this network was
- * explicitly selected. This should be sent before the NetworkInfo is marked
- * CONNECTED so it can be given special treatment at that time.
- *
- * obj = boolean indicating whether to use this network even if unvalidated
- * @hide
- */
- public static final int EVENT_SET_EXPLICITLY_SELECTED = BASE + 8;
-
- /**
- * Sent by ConnectivityService to the NetworkAgent to inform the agent of
- * whether the network should in the future be used even if not validated.
- * This decision is made by the user, but it is the network transport's
- * responsibility to remember it.
- *
- * arg1 = 1 if true, 0 if false
- * @hide
- */
- public static final int CMD_SAVE_ACCEPT_UNVALIDATED = BASE + 9;
-
- /**
- * Sent by ConnectivityService to the NetworkAgent to inform the agent to pull
- * the underlying network connection for updated bandwidth information.
- * @hide
- */
- public static final int CMD_REQUEST_BANDWIDTH_UPDATE = BASE + 10;
-
- /**
- * Sent by ConnectivityService to the NetworkAgent to request that the specified packet be sent
- * periodically on the given interval.
- *
- * arg1 = the hardware slot number of the keepalive to start
- * arg2 = interval in seconds
- * obj = KeepalivePacketData object describing the data to be sent
- *
- * Also used internally by ConnectivityService / KeepaliveTracker, with different semantics.
- * @hide
- */
- public static final int CMD_START_SOCKET_KEEPALIVE = BASE + 11;
-
- /**
- * Requests that the specified keepalive packet be stopped.
- *
- * arg1 = hardware slot number of the keepalive to stop.
- *
- * Also used internally by ConnectivityService / KeepaliveTracker, with different semantics.
- * @hide
- */
- public static final int CMD_STOP_SOCKET_KEEPALIVE = BASE + 12;
-
- /**
- * Sent by the NetworkAgent to ConnectivityService to provide status on a socket keepalive
- * request. This may either be the reply to a CMD_START_SOCKET_KEEPALIVE, or an asynchronous
- * error notification.
- *
- * This is also sent by KeepaliveTracker to the app's {@link SocketKeepalive},
- * so that the app's {@link SocketKeepalive.Callback} methods can be called.
- *
- * arg1 = hardware slot number of the keepalive
- * arg2 = error code
- * @hide
- */
- public static final int EVENT_SOCKET_KEEPALIVE = BASE + 13;
-
- /**
- * Sent by ConnectivityService to inform this network transport of signal strength thresholds
- * that when crossed should trigger a system wakeup and a NetworkCapabilities update.
- *
- * obj = int[] describing signal strength thresholds.
- * @hide
- */
- public static final int CMD_SET_SIGNAL_STRENGTH_THRESHOLDS = BASE + 14;
-
- /**
- * Sent by ConnectivityService to the NeworkAgent to inform the agent to avoid
- * automatically reconnecting to this network (e.g. via autojoin). Happens
- * when user selects "No" option on the "Stay connected?" dialog box.
- * @hide
- */
- public static final int CMD_PREVENT_AUTOMATIC_RECONNECT = BASE + 15;
-
- /**
- * Sent by the KeepaliveTracker to NetworkAgent to add a packet filter.
- *
- * For TCP keepalive offloads, keepalive packets are sent by the firmware. However, because the
- * remote site will send ACK packets in response to the keepalive packets, the firmware also
- * needs to be configured to properly filter the ACKs to prevent the system from waking up.
- * This does not happen with UDP, so this message is TCP-specific.
- * arg1 = hardware slot number of the keepalive to filter for.
- * obj = the keepalive packet to send repeatedly.
- * @hide
- */
- public static final int CMD_ADD_KEEPALIVE_PACKET_FILTER = BASE + 16;
-
- /**
- * Sent by the KeepaliveTracker to NetworkAgent to remove a packet filter. See
- * {@link #CMD_ADD_KEEPALIVE_PACKET_FILTER}.
- * arg1 = hardware slot number of the keepalive packet filter to remove.
- * @hide
- */
- public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17;
-
- /**
- * Sent by ConnectivityService to the NetworkAgent to complete the bidirectional connection.
- * obj = INetworkAgentRegistry
- */
- private static final int EVENT_AGENT_CONNECTED = BASE + 18;
-
- /**
- * Sent by ConnectivityService to the NetworkAgent to inform the agent that it was disconnected.
- */
- private static final int EVENT_AGENT_DISCONNECTED = BASE + 19;
-
- /**
- * Sent by QosCallbackTracker to {@link NetworkAgent} to register a new filter with
- * callback.
- *
- * arg1 = QoS agent callback ID
- * obj = {@link QosFilter}
- * @hide
- */
- public static final int CMD_REGISTER_QOS_CALLBACK = BASE + 20;
-
- /**
- * Sent by QosCallbackTracker to {@link NetworkAgent} to unregister a callback.
- *
- * arg1 = QoS agent callback ID
- * @hide
- */
- public static final int CMD_UNREGISTER_QOS_CALLBACK = BASE + 21;
-
- /**
- * Sent by ConnectivityService to {@link NetworkAgent} to inform the agent that its native
- * network was created and the Network object is now valid.
- *
- * @hide
- */
- public static final int CMD_NETWORK_CREATED = BASE + 22;
-
- /**
- * Sent by ConnectivityService to {@link NetworkAgent} to inform the agent that its native
- * network was destroyed.
- *
- * @hide
- */
- public static final int CMD_NETWORK_DESTROYED = BASE + 23;
-
- /**
- * Sent by the NetworkAgent to ConnectivityService to set the linger duration for this network
- * agent.
- * arg1 = the linger duration, represents by {@link Duration}.
- *
- * @hide
- */
- public static final int EVENT_LINGER_DURATION_CHANGED = BASE + 24;
-
- private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) {
- final NetworkInfo ni = new NetworkInfo(config.legacyType, config.legacySubType,
- config.legacyTypeName, config.legacySubTypeName);
- ni.setIsAvailable(true);
- ni.setDetailedState(NetworkInfo.DetailedState.CONNECTING, null /* reason */,
- config.getLegacyExtraInfo());
- return ni;
- }
-
- // Temporary backward compatibility constructor
- public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag,
- @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
- @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) {
- this(context, looper, logTag, nc, lp,
- new NetworkScore.Builder().setLegacyInt(score).build(), config, provider);
- }
-
- /**
- * Create a new network agent.
- * @param context a {@link Context} to get system services from.
- * @param looper the {@link Looper} on which to invoke the callbacks.
- * @param logTag the tag for logs
- * @param nc the initial {@link NetworkCapabilities} of this network. Update with
- * sendNetworkCapabilities.
- * @param lp the initial {@link LinkProperties} of this network. Update with sendLinkProperties.
- * @param score the initial score of this network. Update with sendNetworkScore.
- * @param config an immutable {@link NetworkAgentConfig} for this agent.
- * @param provider the {@link NetworkProvider} managing this agent.
- */
- public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag,
- @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp,
- @NonNull NetworkScore score, @NonNull NetworkAgentConfig config,
- @Nullable NetworkProvider provider) {
- this(looper, context, logTag, nc, lp, score, config,
- provider == null ? NetworkProvider.ID_NONE : provider.getProviderId(),
- getLegacyNetworkInfo(config));
- }
-
- private static class InitialConfiguration {
- public final Context context;
- public final NetworkCapabilities capabilities;
- public final LinkProperties properties;
- public final NetworkScore score;
- public final NetworkAgentConfig config;
- public final NetworkInfo info;
- InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities,
- @NonNull LinkProperties properties, @NonNull NetworkScore score,
- @NonNull NetworkAgentConfig config, @NonNull NetworkInfo info) {
- this.context = context;
- this.capabilities = capabilities;
- this.properties = properties;
- this.score = score;
- this.config = config;
- this.info = info;
- }
- }
- private volatile InitialConfiguration mInitialConfiguration;
-
- private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag,
- @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp,
- @NonNull NetworkScore score, @NonNull NetworkAgentConfig config, int providerId,
- @NonNull NetworkInfo ni) {
- mHandler = new NetworkAgentHandler(looper);
- LOG_TAG = logTag;
- mNetworkInfo = new NetworkInfo(ni);
- this.providerId = providerId;
- if (ni == null || nc == null || lp == null) {
- throw new IllegalArgumentException();
- }
-
- mInitialConfiguration = new InitialConfiguration(context,
- new NetworkCapabilities(nc, NetworkCapabilities.REDACT_NONE),
- new LinkProperties(lp), score, config, ni);
- }
-
- private class NetworkAgentHandler extends Handler {
- NetworkAgentHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_AGENT_CONNECTED: {
- if (mRegistry != null) {
- log("Received new connection while already connected!");
- } else {
- if (VDBG) log("NetworkAgent fully connected");
- synchronized (mPreConnectedQueue) {
- final INetworkAgentRegistry registry = (INetworkAgentRegistry) msg.obj;
- mRegistry = registry;
- for (RegistryAction a : mPreConnectedQueue) {
- try {
- a.execute(registry);
- } catch (RemoteException e) {
- Log.wtf(LOG_TAG, "Communication error with registry", e);
- // Fall through
- }
- }
- mPreConnectedQueue.clear();
- }
- }
- break;
- }
- case EVENT_AGENT_DISCONNECTED: {
- if (DBG) log("NetworkAgent channel lost");
- // let the client know CS is done with us.
- onNetworkUnwanted();
- synchronized (mPreConnectedQueue) {
- mRegistry = null;
- }
- break;
- }
- case CMD_SUSPECT_BAD: {
- log("Unhandled Message " + msg);
- break;
- }
- case CMD_REQUEST_BANDWIDTH_UPDATE: {
- long currentTimeMs = System.currentTimeMillis();
- if (VDBG) {
- log("CMD_REQUEST_BANDWIDTH_UPDATE request received.");
- }
- if (currentTimeMs >= (mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS)) {
- mBandwidthUpdateScheduled = false;
- if (!mBandwidthUpdatePending.getAndSet(true)) {
- onBandwidthUpdateRequested();
- }
- } else {
- // deliver the request at a later time rather than discard it completely.
- if (!mBandwidthUpdateScheduled) {
- long waitTime = mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS
- - currentTimeMs + 1;
- mBandwidthUpdateScheduled = sendEmptyMessageDelayed(
- CMD_REQUEST_BANDWIDTH_UPDATE, waitTime);
- }
- }
- break;
- }
- case CMD_REPORT_NETWORK_STATUS: {
- String redirectUrl = ((Bundle) msg.obj).getString(REDIRECT_URL_KEY);
- if (VDBG) {
- log("CMD_REPORT_NETWORK_STATUS("
- + (msg.arg1 == VALID_NETWORK ? "VALID, " : "INVALID, ")
- + redirectUrl);
- }
- Uri uri = null;
- try {
- if (null != redirectUrl) {
- uri = Uri.parse(redirectUrl);
- }
- } catch (Exception e) {
- Log.wtf(LOG_TAG, "Surprising URI : " + redirectUrl, e);
- }
- onValidationStatus(msg.arg1 /* status */, uri);
- break;
- }
- case CMD_SAVE_ACCEPT_UNVALIDATED: {
- onSaveAcceptUnvalidated(msg.arg1 != 0);
- break;
- }
- case CMD_START_SOCKET_KEEPALIVE: {
- onStartSocketKeepalive(msg.arg1 /* slot */,
- Duration.ofSeconds(msg.arg2) /* interval */,
- (KeepalivePacketData) msg.obj /* packet */);
- break;
- }
- case CMD_STOP_SOCKET_KEEPALIVE: {
- onStopSocketKeepalive(msg.arg1 /* slot */);
- break;
- }
-
- case CMD_SET_SIGNAL_STRENGTH_THRESHOLDS: {
- onSignalStrengthThresholdsUpdated((int[]) msg.obj);
- break;
- }
- case CMD_PREVENT_AUTOMATIC_RECONNECT: {
- onAutomaticReconnectDisabled();
- break;
- }
- case CMD_ADD_KEEPALIVE_PACKET_FILTER: {
- onAddKeepalivePacketFilter(msg.arg1 /* slot */,
- (KeepalivePacketData) msg.obj /* packet */);
- break;
- }
- case CMD_REMOVE_KEEPALIVE_PACKET_FILTER: {
- onRemoveKeepalivePacketFilter(msg.arg1 /* slot */);
- break;
- }
- case CMD_REGISTER_QOS_CALLBACK: {
- onQosCallbackRegistered(
- msg.arg1 /* QoS callback id */,
- (QosFilter) msg.obj /* QoS filter */);
- break;
- }
- case CMD_UNREGISTER_QOS_CALLBACK: {
- onQosCallbackUnregistered(
- msg.arg1 /* QoS callback id */);
- break;
- }
- case CMD_NETWORK_CREATED: {
- onNetworkCreated();
- break;
- }
- case CMD_NETWORK_DESTROYED: {
- onNetworkDestroyed();
- break;
- }
- }
- }
- }
-
- /**
- * Register this network agent with ConnectivityService.
- *
- * This method can only be called once per network agent.
- *
- * @return the Network associated with this network agent (which can also be obtained later
- * by calling getNetwork() on this agent).
- * @throws IllegalStateException thrown by the system server if this network agent is
- * already registered.
- */
- @NonNull
- public Network register() {
- if (VDBG) log("Registering NetworkAgent");
- synchronized (mRegisterLock) {
- if (mNetwork != null) {
- throw new IllegalStateException("Agent already registered");
- }
- final ConnectivityManager cm = (ConnectivityManager) mInitialConfiguration.context
- .getSystemService(Context.CONNECTIVITY_SERVICE);
- mNetwork = cm.registerNetworkAgent(new NetworkAgentBinder(mHandler),
- new NetworkInfo(mInitialConfiguration.info),
- mInitialConfiguration.properties, mInitialConfiguration.capabilities,
- mInitialConfiguration.score, mInitialConfiguration.config, providerId);
- mInitialConfiguration = null; // All this memory can now be GC'd
- }
- return mNetwork;
- }
-
- private static class NetworkAgentBinder extends INetworkAgent.Stub {
- private static final String LOG_TAG = NetworkAgentBinder.class.getSimpleName();
-
- private final Handler mHandler;
-
- private NetworkAgentBinder(Handler handler) {
- mHandler = handler;
- }
-
- @Override
- public void onRegistered(@NonNull INetworkAgentRegistry registry) {
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_AGENT_CONNECTED, registry));
- }
-
- @Override
- public void onDisconnected() {
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_AGENT_DISCONNECTED));
- }
-
- @Override
- public void onBandwidthUpdateRequested() {
- mHandler.sendMessage(mHandler.obtainMessage(CMD_REQUEST_BANDWIDTH_UPDATE));
- }
-
- @Override
- public void onValidationStatusChanged(
- int validationStatus, @Nullable String captivePortalUrl) {
- // TODO: consider using a parcelable as argument when the interface is structured
- Bundle redirectUrlBundle = new Bundle();
- redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, captivePortalUrl);
- mHandler.sendMessage(mHandler.obtainMessage(CMD_REPORT_NETWORK_STATUS,
- validationStatus, 0, redirectUrlBundle));
- }
-
- @Override
- public void onSaveAcceptUnvalidated(boolean acceptUnvalidated) {
- mHandler.sendMessage(mHandler.obtainMessage(CMD_SAVE_ACCEPT_UNVALIDATED,
- acceptUnvalidated ? 1 : 0, 0));
- }
-
- @Override
- public void onStartNattSocketKeepalive(int slot, int intervalDurationMs,
- @NonNull NattKeepalivePacketData packetData) {
- mHandler.sendMessage(mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE,
- slot, intervalDurationMs, packetData));
- }
-
- @Override
- public void onStartTcpSocketKeepalive(int slot, int intervalDurationMs,
- @NonNull TcpKeepalivePacketData packetData) {
- mHandler.sendMessage(mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE,
- slot, intervalDurationMs, packetData));
- }
-
- @Override
- public void onStopSocketKeepalive(int slot) {
- mHandler.sendMessage(mHandler.obtainMessage(CMD_STOP_SOCKET_KEEPALIVE, slot, 0));
- }
-
- @Override
- public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) {
- mHandler.sendMessage(mHandler.obtainMessage(
- CMD_SET_SIGNAL_STRENGTH_THRESHOLDS, thresholds));
- }
-
- @Override
- public void onPreventAutomaticReconnect() {
- mHandler.sendMessage(mHandler.obtainMessage(CMD_PREVENT_AUTOMATIC_RECONNECT));
- }
-
- @Override
- public void onAddNattKeepalivePacketFilter(int slot,
- @NonNull NattKeepalivePacketData packetData) {
- mHandler.sendMessage(mHandler.obtainMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER,
- slot, 0, packetData));
- }
-
- @Override
- public void onAddTcpKeepalivePacketFilter(int slot,
- @NonNull TcpKeepalivePacketData packetData) {
- mHandler.sendMessage(mHandler.obtainMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER,
- slot, 0, packetData));
- }
-
- @Override
- public void onRemoveKeepalivePacketFilter(int slot) {
- mHandler.sendMessage(mHandler.obtainMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER,
- slot, 0));
- }
-
- @Override
- public void onQosFilterCallbackRegistered(final int qosCallbackId,
- final QosFilterParcelable qosFilterParcelable) {
- if (qosFilterParcelable.getQosFilter() != null) {
- mHandler.sendMessage(
- mHandler.obtainMessage(CMD_REGISTER_QOS_CALLBACK, qosCallbackId, 0,
- qosFilterParcelable.getQosFilter()));
- return;
- }
-
- Log.wtf(LOG_TAG, "onQosFilterCallbackRegistered: qos filter is null.");
- }
-
- @Override
- public void onQosCallbackUnregistered(final int qosCallbackId) {
- mHandler.sendMessage(mHandler.obtainMessage(
- CMD_UNREGISTER_QOS_CALLBACK, qosCallbackId, 0, null));
- }
-
- @Override
- public void onNetworkCreated() {
- mHandler.sendMessage(mHandler.obtainMessage(CMD_NETWORK_CREATED));
- }
-
- @Override
- public void onNetworkDestroyed() {
- mHandler.sendMessage(mHandler.obtainMessage(CMD_NETWORK_DESTROYED));
- }
- }
-
- /**
- * Register this network agent with a testing harness.
- *
- * The returned Messenger sends messages to the Handler. This allows a test to send
- * this object {@code CMD_*} messages as if they came from ConnectivityService, which
- * is useful for testing the behavior.
- *
- * @hide
- */
- public INetworkAgent registerForTest(final Network network) {
- log("Registering NetworkAgent for test");
- synchronized (mRegisterLock) {
- mNetwork = network;
- mInitialConfiguration = null;
- }
- return new NetworkAgentBinder(mHandler);
- }
-
- /**
- * Waits for the handler to be idle.
- * This is useful for testing, and has smaller scope than an accessor to mHandler.
- * TODO : move the implementation in common library with the tests
- * @hide
- */
- @VisibleForTesting
- public boolean waitForIdle(final long timeoutMs) {
- final ConditionVariable cv = new ConditionVariable(false);
- mHandler.post(cv::open);
- return cv.block(timeoutMs);
- }
-
- /**
- * @return The Network associated with this agent, or null if it's not registered yet.
- */
- @Nullable
- public Network getNetwork() {
- return mNetwork;
- }
-
- private void queueOrSendMessage(@NonNull RegistryAction action) {
- synchronized (mPreConnectedQueue) {
- if (mRegistry != null) {
- try {
- action.execute(mRegistry);
- } catch (RemoteException e) {
- Log.wtf(LOG_TAG, "Error executing registry action", e);
- // Fall through: the channel is asynchronous and does not report errors back
- }
- } else {
- mPreConnectedQueue.add(action);
- }
- }
- }
-
- /**
- * Must be called by the agent when the network's {@link LinkProperties} change.
- * @param linkProperties the new LinkProperties.
- */
- public final void sendLinkProperties(@NonNull LinkProperties linkProperties) {
- Objects.requireNonNull(linkProperties);
- final LinkProperties lp = new LinkProperties(linkProperties);
- queueOrSendMessage(reg -> reg.sendLinkProperties(lp));
- }
-
- /**
- * Must be called by the agent when the network's underlying networks change.
- *
- * <p>{@code networks} is one of the following:
- * <ul>
- * <li><strong>a non-empty array</strong>: an array of one or more {@link Network}s, in
- * decreasing preference order. For example, if this VPN uses both wifi and mobile (cellular)
- * networks to carry app traffic, but prefers or uses wifi more than mobile, wifi should appear
- * first in the array.</li>
- * <li><strong>an empty array</strong>: a zero-element array, meaning that the VPN has no
- * underlying network connection, and thus, app traffic will not be sent or received.</li>
- * <li><strong>null</strong>: (default) signifies that the VPN uses whatever is the system's
- * default network. I.e., it doesn't use the {@code bindSocket} or {@code bindDatagramSocket}
- * APIs mentioned above to send traffic over specific channels.</li>
- * </ul>
- *
- * @param underlyingNetworks the new list of underlying networks.
- * @see {@link VpnService.Builder#setUnderlyingNetworks(Network[])}
- */
- public final void setUnderlyingNetworks(
- @SuppressLint("NullableCollection") @Nullable List<Network> underlyingNetworks) {
- final ArrayList<Network> underlyingArray = (underlyingNetworks != null)
- ? new ArrayList<>(underlyingNetworks) : null;
- queueOrSendMessage(reg -> reg.sendUnderlyingNetworks(underlyingArray));
- }
-
- /**
- * Inform ConnectivityService that this agent has now connected.
- * Call {@link #unregister} to disconnect.
- */
- public void markConnected() {
- mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null /* reason */,
- mNetworkInfo.getExtraInfo());
- queueOrSendNetworkInfo(mNetworkInfo);
- }
-
- /**
- * Unregister this network agent.
- *
- * This signals the network has disconnected and ends its lifecycle. After this is called,
- * the network is torn down and this agent can no longer be used.
- */
- public void unregister() {
- // When unregistering an agent nobody should use the extrainfo (or reason) any more.
- mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null /* reason */,
- null /* extraInfo */);
- queueOrSendNetworkInfo(mNetworkInfo);
- }
-
- /**
- * Sets the value of the teardown delay.
- *
- * The teardown delay is the time between when the network disconnects and when the native
- * network corresponding to this {@code NetworkAgent} is destroyed. By default, the native
- * network is destroyed immediately. If {@code teardownDelayMs} is non-zero, then when this
- * network disconnects, the system will instead immediately mark the network as restricted
- * and unavailable to unprivileged apps, but will defer destroying the native network until the
- * teardown delay timer expires.
- *
- * The interfaces in use by this network will remain in use until the native network is
- * destroyed and cannot be reused until {@link #onNetworkDestroyed()} is called.
- *
- * This method may be called at any time while the network is connected. It has no effect if
- * the network is already disconnected and the teardown delay timer is running.
- *
- * @param teardownDelayMillis the teardown delay to set, or 0 to disable teardown delay.
- */
- public void setTeardownDelayMillis(
- @IntRange(from = 0, to = MAX_TEARDOWN_DELAY_MS) int teardownDelayMillis) {
- queueOrSendMessage(reg -> reg.sendTeardownDelayMs(teardownDelayMillis));
- }
-
- /**
- * Change the legacy subtype of this network agent.
- *
- * This is only for backward compatibility and should not be used by non-legacy network agents,
- * or agents that did not use to set a subtype. As such, only TYPE_MOBILE type agents can use
- * this and others will be thrown an exception if they try.
- *
- * @deprecated this is for backward compatibility only.
- * @param legacySubtype the legacy subtype.
- * @hide
- */
- @Deprecated
- @SystemApi
- public void setLegacySubtype(final int legacySubtype, @NonNull final String legacySubtypeName) {
- mNetworkInfo.setSubtype(legacySubtype, legacySubtypeName);
- queueOrSendNetworkInfo(mNetworkInfo);
- }
-
- /**
- * Set the ExtraInfo of this network agent.
- *
- * This sets the ExtraInfo field inside the NetworkInfo returned by legacy public API and the
- * broadcasts about the corresponding Network.
- * This is only for backward compatibility and should not be used by non-legacy network agents,
- * who will be thrown an exception if they try. The extra info should only be :
- * <ul>
- * <li>For cellular agents, the APN name.</li>
- * <li>For ethernet agents, the interface name.</li>
- * </ul>
- *
- * @deprecated this is for backward compatibility only.
- * @param extraInfo the ExtraInfo.
- * @hide
- */
- @Deprecated
- public void setLegacyExtraInfo(@Nullable final String extraInfo) {
- mNetworkInfo.setExtraInfo(extraInfo);
- queueOrSendNetworkInfo(mNetworkInfo);
- }
-
- /**
- * Must be called by the agent when it has a new NetworkInfo object.
- * @hide TODO: expose something better.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public final void sendNetworkInfo(NetworkInfo networkInfo) {
- queueOrSendNetworkInfo(new NetworkInfo(networkInfo));
- }
-
- private void queueOrSendNetworkInfo(NetworkInfo networkInfo) {
- queueOrSendMessage(reg -> reg.sendNetworkInfo(networkInfo));
- }
-
- /**
- * Must be called by the agent when the network's {@link NetworkCapabilities} change.
- * @param networkCapabilities the new NetworkCapabilities.
- */
- public final void sendNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) {
- Objects.requireNonNull(networkCapabilities);
- mBandwidthUpdatePending.set(false);
- mLastBwRefreshTime = System.currentTimeMillis();
- final NetworkCapabilities nc =
- new NetworkCapabilities(networkCapabilities, NetworkCapabilities.REDACT_NONE);
- queueOrSendMessage(reg -> reg.sendNetworkCapabilities(nc));
- }
-
- /**
- * Must be called by the agent to update the score of this network.
- *
- * @param score the new score.
- */
- public final void sendNetworkScore(@NonNull NetworkScore score) {
- Objects.requireNonNull(score);
- queueOrSendMessage(reg -> reg.sendScore(score));
- }
-
- /**
- * Must be called by the agent to update the score of this network.
- *
- * @param score the new score, between 0 and 99.
- * deprecated use sendNetworkScore(NetworkScore) TODO : remove in S.
- */
- public final void sendNetworkScore(@IntRange(from = 0, to = 99) int score) {
- sendNetworkScore(new NetworkScore.Builder().setLegacyInt(score).build());
- }
-
- /**
- * Must be called by the agent to indicate this network was manually selected by the user.
- * This should be called before the NetworkInfo is marked CONNECTED so that this
- * Network can be given special treatment at that time. If {@code acceptUnvalidated} is
- * {@code true}, then the system will switch to this network. If it is {@code false} and the
- * network cannot be validated, the system will ask the user whether to switch to this network.
- * If the user confirms and selects "don't ask again", then the system will call
- * {@link #saveAcceptUnvalidated} to persist the user's choice. Thus, if the transport ever
- * calls this method with {@code acceptUnvalidated} set to {@code false}, it must also implement
- * {@link #saveAcceptUnvalidated} to respect the user's choice.
- * @hide should move to NetworkAgentConfig.
- */
- public void explicitlySelected(boolean acceptUnvalidated) {
- explicitlySelected(true /* explicitlySelected */, acceptUnvalidated);
- }
-
- /**
- * Must be called by the agent to indicate whether the network was manually selected by the
- * user. This should be called before the network becomes connected, so it can be given
- * special treatment when it does.
- *
- * If {@code explicitlySelected} is {@code true}, and {@code acceptUnvalidated} is {@code true},
- * then the system will switch to this network. If {@code explicitlySelected} is {@code true}
- * and {@code acceptUnvalidated} is {@code false}, and the network cannot be validated, the
- * system will ask the user whether to switch to this network. If the user confirms and selects
- * "don't ask again", then the system will call {@link #saveAcceptUnvalidated} to persist the
- * user's choice. Thus, if the transport ever calls this method with {@code explicitlySelected}
- * set to {@code true} and {@code acceptUnvalidated} set to {@code false}, it must also
- * implement {@link #saveAcceptUnvalidated} to respect the user's choice.
- *
- * If {@code explicitlySelected} is {@code false} and {@code acceptUnvalidated} is
- * {@code true}, the system will interpret this as the user having accepted partial connectivity
- * on this network. Thus, the system will switch to the network and consider it validated even
- * if it only provides partial connectivity, but the network is not otherwise treated specially.
- * @hide should move to NetworkAgentConfig.
- */
- public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) {
- queueOrSendMessage(reg -> reg.sendExplicitlySelected(
- explicitlySelected, acceptUnvalidated));
- }
-
- /**
- * Called when ConnectivityService has indicated they no longer want this network.
- * The parent factory should (previously) have received indication of the change
- * as well, either canceling NetworkRequests or altering their score such that this
- * network won't be immediately requested again.
- */
- public void onNetworkUnwanted() {
- unwanted();
- }
- /** @hide TODO delete once subclasses have moved to onNetworkUnwanted. */
- protected void unwanted() {
- }
-
- /**
- * Called when ConnectivityService request a bandwidth update. The parent factory
- * shall try to overwrite this method and produce a bandwidth update if capable.
- * @hide
- */
- @SystemApi
- public void onBandwidthUpdateRequested() {
- pollLceData();
- }
- /** @hide TODO delete once subclasses have moved to onBandwidthUpdateRequested. */
- protected void pollLceData() {
- }
-
- /**
- * Called when the system determines the usefulness of this network.
- *
- * The system attempts to validate Internet connectivity on networks that provide the
- * {@link NetworkCapabilities#NET_CAPABILITY_INTERNET} capability.
- *
- * Currently there are two possible values:
- * {@code VALIDATION_STATUS_VALID} if Internet connectivity was validated,
- * {@code VALIDATION_STATUS_NOT_VALID} if Internet connectivity was not validated.
- *
- * This is guaranteed to be called again when the network status changes, but the system
- * may also call this multiple times even if the status does not change.
- *
- * @param status one of {@code VALIDATION_STATUS_VALID} or {@code VALIDATION_STATUS_NOT_VALID}.
- * @param redirectUri If Internet connectivity is being redirected (e.g., on a captive portal),
- * this is the destination the probes are being redirected to, otherwise {@code null}.
- */
- public void onValidationStatus(@ValidationStatus int status, @Nullable Uri redirectUri) {
- networkStatus(status, null == redirectUri ? "" : redirectUri.toString());
- }
- /** @hide TODO delete once subclasses have moved to onValidationStatus */
- protected void networkStatus(int status, String redirectUrl) {
- }
-
-
- /**
- * Called when the user asks to remember the choice to use this network even if unvalidated.
- * The transport is responsible for remembering the choice, and the next time the user connects
- * to the network, should explicitlySelected with {@code acceptUnvalidated} set to {@code true}.
- * This method will only be called if {@link #explicitlySelected} was called with
- * {@code acceptUnvalidated} set to {@code false}.
- * @param accept whether the user wants to use the network even if unvalidated.
- */
- public void onSaveAcceptUnvalidated(boolean accept) {
- saveAcceptUnvalidated(accept);
- }
- /** @hide TODO delete once subclasses have moved to onSaveAcceptUnvalidated */
- protected void saveAcceptUnvalidated(boolean accept) {
- }
-
- /**
- * Called when ConnectivityService has successfully created this NetworkAgent's native network.
- */
- public void onNetworkCreated() {}
-
-
- /**
- * Called when ConnectivityService has successfully destroy this NetworkAgent's native network.
- */
- public void onNetworkDestroyed() {}
-
- /**
- * Requests that the network hardware send the specified packet at the specified interval.
- *
- * @param slot the hardware slot on which to start the keepalive.
- * @param interval the interval between packets, between 10 and 3600. Note that this API
- * does not support sub-second precision and will round off the request.
- * @param packet the packet to send.
- */
- // seconds is from SocketKeepalive.MIN_INTERVAL_SEC to MAX_INTERVAL_SEC, but these should
- // not be exposed as constants because they may change in the future (API guideline 4.8)
- // and should have getters if exposed at all. Getters can't be used in the annotation,
- // so the values unfortunately need to be copied.
- public void onStartSocketKeepalive(int slot, @NonNull Duration interval,
- @NonNull KeepalivePacketData packet) {
- final long intervalSeconds = interval.getSeconds();
- if (intervalSeconds < SocketKeepalive.MIN_INTERVAL_SEC
- || intervalSeconds > SocketKeepalive.MAX_INTERVAL_SEC) {
- throw new IllegalArgumentException("Interval needs to be comprised between "
- + SocketKeepalive.MIN_INTERVAL_SEC + " and " + SocketKeepalive.MAX_INTERVAL_SEC
- + " but was " + intervalSeconds);
- }
- final Message msg = mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, slot,
- (int) intervalSeconds, packet);
- startSocketKeepalive(msg);
- msg.recycle();
- }
- /** @hide TODO delete once subclasses have moved to onStartSocketKeepalive */
- protected void startSocketKeepalive(Message msg) {
- onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
- }
-
- /**
- * Requests that the network hardware stop a previously-started keepalive.
- *
- * @param slot the hardware slot on which to stop the keepalive.
- */
- public void onStopSocketKeepalive(int slot) {
- Message msg = mHandler.obtainMessage(CMD_STOP_SOCKET_KEEPALIVE, slot, 0, null);
- stopSocketKeepalive(msg);
- msg.recycle();
- }
- /** @hide TODO delete once subclasses have moved to onStopSocketKeepalive */
- protected void stopSocketKeepalive(Message msg) {
- onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
- }
-
- /**
- * Must be called by the agent when a socket keepalive event occurs.
- *
- * @param slot the hardware slot on which the event occurred.
- * @param event the event that occurred, as one of the SocketKeepalive.ERROR_*
- * or SocketKeepalive.SUCCESS constants.
- */
- public final void sendSocketKeepaliveEvent(int slot,
- @SocketKeepalive.KeepaliveEvent int event) {
- queueOrSendMessage(reg -> reg.sendSocketKeepaliveEvent(slot, event));
- }
- /** @hide TODO delete once callers have moved to sendSocketKeepaliveEvent */
- public void onSocketKeepaliveEvent(int slot, int reason) {
- sendSocketKeepaliveEvent(slot, reason);
- }
-
- /**
- * Called by ConnectivityService to add specific packet filter to network hardware to block
- * replies (e.g., TCP ACKs) matching the sent keepalive packets. Implementations that support
- * this feature must override this method.
- *
- * @param slot the hardware slot on which the keepalive should be sent.
- * @param packet the packet that is being sent.
- */
- public void onAddKeepalivePacketFilter(int slot, @NonNull KeepalivePacketData packet) {
- Message msg = mHandler.obtainMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER, slot, 0, packet);
- addKeepalivePacketFilter(msg);
- msg.recycle();
- }
- /** @hide TODO delete once subclasses have moved to onAddKeepalivePacketFilter */
- protected void addKeepalivePacketFilter(Message msg) {
- }
-
- /**
- * Called by ConnectivityService to remove a packet filter installed with
- * {@link #addKeepalivePacketFilter(Message)}. Implementations that support this feature
- * must override this method.
- *
- * @param slot the hardware slot on which the keepalive is being sent.
- */
- public void onRemoveKeepalivePacketFilter(int slot) {
- Message msg = mHandler.obtainMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, slot, 0, null);
- removeKeepalivePacketFilter(msg);
- msg.recycle();
- }
- /** @hide TODO delete once subclasses have moved to onRemoveKeepalivePacketFilter */
- protected void removeKeepalivePacketFilter(Message msg) {
- }
-
- /**
- * Called by ConnectivityService to inform this network agent of signal strength thresholds
- * that when crossed should trigger a system wakeup and a NetworkCapabilities update.
- *
- * When the system updates the list of thresholds that should wake up the CPU for a
- * given agent it will call this method on the agent. The agent that implement this
- * should implement it in hardware so as to ensure the CPU will be woken up on breach.
- * Agents are expected to react to a breach by sending an updated NetworkCapabilities
- * object with the appropriate signal strength to sendNetworkCapabilities.
- *
- * The specific units are bearer-dependent. See details on the units and requests in
- * {@link NetworkCapabilities.Builder#setSignalStrength}.
- *
- * @param thresholds the array of thresholds that should trigger wakeups.
- */
- public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) {
- setSignalStrengthThresholds(thresholds);
- }
- /** @hide TODO delete once subclasses have moved to onSetSignalStrengthThresholds */
- protected void setSignalStrengthThresholds(int[] thresholds) {
- }
-
- /**
- * Called when the user asks to not stay connected to this network because it was found to not
- * provide Internet access. Usually followed by call to {@code unwanted}. The transport is
- * responsible for making sure the device does not automatically reconnect to the same network
- * after the {@code unwanted} call.
- */
- public void onAutomaticReconnectDisabled() {
- preventAutomaticReconnect();
- }
- /** @hide TODO delete once subclasses have moved to onAutomaticReconnectDisabled */
- protected void preventAutomaticReconnect() {
- }
-
- /**
- * Called when a qos callback is registered with a filter.
- * @param qosCallbackId the id for the callback registered
- * @param filter the filter being registered
- */
- public void onQosCallbackRegistered(final int qosCallbackId, final @NonNull QosFilter filter) {
- }
-
- /**
- * Called when a qos callback is registered with a filter.
- * <p/>
- * Any QoS events that are sent with the same callback id after this method is called
- * are a no-op.
- *
- * @param qosCallbackId the id for the callback being unregistered
- */
- public void onQosCallbackUnregistered(final int qosCallbackId) {
- }
-
-
- /**
- * Sends the attributes of Qos Session back to the Application
- *
- * @param qosCallbackId the callback id that the session belongs to
- * @param sessionId the unique session id across all Qos Sessions
- * @param attributes the attributes of the Qos Session
- */
- public final void sendQosSessionAvailable(final int qosCallbackId, final int sessionId,
- @NonNull final QosSessionAttributes attributes) {
- Objects.requireNonNull(attributes, "The attributes must be non-null");
- if (attributes instanceof EpsBearerQosSessionAttributes) {
- queueOrSendMessage(ra -> ra.sendEpsQosSessionAvailable(qosCallbackId,
- new QosSession(sessionId, QosSession.TYPE_EPS_BEARER),
- (EpsBearerQosSessionAttributes)attributes));
- } else if (attributes instanceof NrQosSessionAttributes) {
- queueOrSendMessage(ra -> ra.sendNrQosSessionAvailable(qosCallbackId,
- new QosSession(sessionId, QosSession.TYPE_NR_BEARER),
- (NrQosSessionAttributes)attributes));
- }
- }
-
- /**
- * Sends event that the Qos Session was lost.
- *
- * @param qosCallbackId the callback id that the session belongs to
- * @param sessionId the unique session id across all Qos Sessions
- * @param qosSessionType the session type {@code QosSesson#QosSessionType}
- */
- public final void sendQosSessionLost(final int qosCallbackId,
- final int sessionId, final int qosSessionType) {
- queueOrSendMessage(ra -> ra.sendQosSessionLost(qosCallbackId,
- new QosSession(sessionId, qosSessionType)));
- }
-
- /**
- * Sends the exception type back to the application.
- *
- * The NetworkAgent should not send anymore messages with this id.
- *
- * @param qosCallbackId the callback id this exception belongs to
- * @param exceptionType the type of exception
- */
- public final void sendQosCallbackError(final int qosCallbackId,
- @QosCallbackException.ExceptionType final int exceptionType) {
- queueOrSendMessage(ra -> ra.sendQosCallbackError(qosCallbackId, exceptionType));
- }
-
- /**
- * Set the linger duration for this network agent.
- * @param duration the delay between the moment the network becomes unneeded and the
- * moment the network is disconnected or moved into the background.
- * Note that If this duration has greater than millisecond precision, then
- * the internal implementation will drop any excess precision.
- */
- public void setLingerDuration(@NonNull final Duration duration) {
- Objects.requireNonNull(duration);
- final long durationMs = duration.toMillis();
- if (durationMs < MIN_LINGER_TIMER_MS || durationMs > Integer.MAX_VALUE) {
- throw new IllegalArgumentException("Duration must be within ["
- + MIN_LINGER_TIMER_MS + "," + Integer.MAX_VALUE + "]ms");
- }
- queueOrSendMessage(ra -> ra.sendLingerDuration((int) durationMs));
- }
-
- /** @hide */
- protected void log(final String s) {
- Log.d(LOG_TAG, "NetworkAgent: " + s);
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
deleted file mode 100644
index ad8396b..0000000
--- a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
+++ /dev/null
@@ -1,505 +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 android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * Allows a network transport to provide the system with policy and configuration information about
- * a particular network when registering a {@link NetworkAgent}. This information cannot change once the agent is registered.
- *
- * @hide
- */
-@SystemApi
-public final class NetworkAgentConfig implements Parcelable {
-
- /**
- * If the {@link Network} is a VPN, whether apps are allowed to bypass the
- * VPN. This is set by a {@link VpnService} and used by
- * {@link ConnectivityManager} when creating a VPN.
- *
- * @hide
- */
- public boolean allowBypass;
-
- /**
- * Set if the network was manually/explicitly connected to by the user either from settings
- * or a 3rd party app. For example, turning on cell data is not explicit but tapping on a wifi
- * ap in the wifi settings to trigger a connection is explicit. A 3rd party app asking to
- * connect to a particular access point is also explicit, though this may change in the future
- * as we want apps to use the multinetwork apis.
- * TODO : this is a bad name, because it sounds like the user just tapped on the network.
- * It's not necessarily the case ; auto-reconnection to WiFi has this true for example.
- * @hide
- */
- public boolean explicitlySelected;
-
- /**
- * @return whether this network was explicitly selected by the user.
- */
- public boolean isExplicitlySelected() {
- return explicitlySelected;
- }
-
- /**
- * @return whether this VPN connection can be bypassed by the apps.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public boolean isBypassableVpn() {
- return allowBypass;
- }
-
- /**
- * Set if the user desires to use this network even if it is unvalidated. This field has meaning
- * only if {@link explicitlySelected} is true. If it is, this field must also be set to the
- * appropriate value based on previous user choice.
- *
- * TODO : rename this field to match its accessor
- * @hide
- */
- public boolean acceptUnvalidated;
-
- /**
- * @return whether the system should accept this network even if it doesn't validate.
- */
- public boolean isUnvalidatedConnectivityAcceptable() {
- return acceptUnvalidated;
- }
-
- /**
- * Whether the user explicitly set that this network should be validated even if presence of
- * only partial internet connectivity.
- *
- * TODO : rename this field to match its accessor
- * @hide
- */
- public boolean acceptPartialConnectivity;
-
- /**
- * @return whether the system should validate this network even if it only offers partial
- * Internet connectivity.
- */
- public boolean isPartialConnectivityAcceptable() {
- return acceptPartialConnectivity;
- }
-
- /**
- * Set to avoid surfacing the "Sign in to network" notification.
- * if carrier receivers/apps are registered to handle the carrier-specific provisioning
- * procedure, a carrier specific provisioning notification will be placed.
- * only one notification should be displayed. This field is set based on
- * which notification should be used for provisioning.
- *
- * @hide
- */
- public boolean provisioningNotificationDisabled;
-
- /**
- *
- * @return whether the sign in to network notification is enabled by this configuration.
- * @hide
- */
- public boolean isProvisioningNotificationEnabled() {
- return !provisioningNotificationDisabled;
- }
-
- /**
- * For mobile networks, this is the subscriber ID (such as IMSI).
- *
- * @hide
- */
- public String subscriberId;
-
- /**
- * @return the subscriber ID, or null if none.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @Nullable
- public String getSubscriberId() {
- return subscriberId;
- }
-
- /**
- * Set to skip 464xlat. This means the device will treat the network as IPv6-only and
- * will not attempt to detect a NAT64 via RFC 7050 DNS lookups.
- *
- * @hide
- */
- public boolean skip464xlat;
-
- /**
- * @return whether NAT64 prefix detection is enabled.
- * @hide
- */
- public boolean isNat64DetectionEnabled() {
- return !skip464xlat;
- }
-
- /**
- * The legacy type of this network agent, or TYPE_NONE if unset.
- * @hide
- */
- public int legacyType = ConnectivityManager.TYPE_NONE;
-
- /**
- * @return the legacy type
- */
- @ConnectivityManager.LegacyNetworkType
- public int getLegacyType() {
- return legacyType;
- }
-
- /**
- * The legacy Sub type of this network agent, or TYPE_NONE if unset.
- * @hide
- */
- public int legacySubType = ConnectivityManager.TYPE_NONE;
-
- /**
- * Set to true if the PRIVATE_DNS_BROKEN notification has shown for this network.
- * Reset this bit when private DNS mode is changed from strict mode to opportunistic/off mode.
- *
- * This is not parceled, because it would not make sense.
- *
- * @hide
- */
- public transient boolean hasShownBroken;
-
- /**
- * The name of the legacy network type. It's a free-form string used in logging.
- * @hide
- */
- @NonNull
- public String legacyTypeName = "";
-
- /**
- * @return the name of the legacy network type. It's a free-form string used in logging.
- */
- @NonNull
- public String getLegacyTypeName() {
- return legacyTypeName;
- }
-
- /**
- * The name of the legacy Sub network type. It's a free-form string.
- * @hide
- */
- @NonNull
- public String legacySubTypeName = "";
-
- /**
- * The legacy extra info of the agent. The extra info should only be :
- * <ul>
- * <li>For cellular agents, the APN name.</li>
- * <li>For ethernet agents, the interface name.</li>
- * </ul>
- * @hide
- */
- @NonNull
- private String mLegacyExtraInfo = "";
-
- /**
- * The legacy extra info of the agent.
- * @hide
- */
- @NonNull
- public String getLegacyExtraInfo() {
- return mLegacyExtraInfo;
- }
-
- /** @hide */
- public NetworkAgentConfig() {
- }
-
- /** @hide */
- public NetworkAgentConfig(@Nullable NetworkAgentConfig nac) {
- if (nac != null) {
- allowBypass = nac.allowBypass;
- explicitlySelected = nac.explicitlySelected;
- acceptUnvalidated = nac.acceptUnvalidated;
- acceptPartialConnectivity = nac.acceptPartialConnectivity;
- subscriberId = nac.subscriberId;
- provisioningNotificationDisabled = nac.provisioningNotificationDisabled;
- skip464xlat = nac.skip464xlat;
- legacyType = nac.legacyType;
- legacyTypeName = nac.legacyTypeName;
- legacySubType = nac.legacySubType;
- legacySubTypeName = nac.legacySubTypeName;
- mLegacyExtraInfo = nac.mLegacyExtraInfo;
- }
- }
-
- /**
- * Builder class to facilitate constructing {@link NetworkAgentConfig} objects.
- */
- public static final class Builder {
- private final NetworkAgentConfig mConfig = new NetworkAgentConfig();
-
- /**
- * Sets whether the network was explicitly selected by the user.
- *
- * @return this builder, to facilitate chaining.
- */
- @NonNull
- public Builder setExplicitlySelected(final boolean explicitlySelected) {
- mConfig.explicitlySelected = explicitlySelected;
- return this;
- }
-
- /**
- * Sets whether the system should validate this network even if it is found not to offer
- * Internet connectivity.
- *
- * @return this builder, to facilitate chaining.
- */
- @NonNull
- public Builder setUnvalidatedConnectivityAcceptable(
- final boolean unvalidatedConnectivityAcceptable) {
- mConfig.acceptUnvalidated = unvalidatedConnectivityAcceptable;
- return this;
- }
-
- /**
- * Sets whether the system should validate this network even if it is found to only offer
- * partial Internet connectivity.
- *
- * @return this builder, to facilitate chaining.
- */
- @NonNull
- public Builder setPartialConnectivityAcceptable(
- final boolean partialConnectivityAcceptable) {
- mConfig.acceptPartialConnectivity = partialConnectivityAcceptable;
- return this;
- }
-
- /**
- * Sets the subscriber ID for this network.
- *
- * @return this builder, to facilitate chaining.
- * @hide
- */
- @NonNull
- @SystemApi(client = MODULE_LIBRARIES)
- public Builder setSubscriberId(@Nullable String subscriberId) {
- mConfig.subscriberId = subscriberId;
- return this;
- }
-
- /**
- * Enables or disables active detection of NAT64 (e.g., via RFC 7050 DNS lookups). Used to
- * save power and reduce idle traffic on networks that are known to be IPv6-only without a
- * NAT64. By default, NAT64 detection is enabled.
- *
- * @return this builder, to facilitate chaining.
- */
- @NonNull
- public Builder setNat64DetectionEnabled(boolean enabled) {
- mConfig.skip464xlat = !enabled;
- return this;
- }
-
- /**
- * Enables or disables the "Sign in to network" notification. Used if the network transport
- * will perform its own carrier-specific provisioning procedure. By default, the
- * notification is enabled.
- *
- * @return this builder, to facilitate chaining.
- */
- @NonNull
- public Builder setProvisioningNotificationEnabled(boolean enabled) {
- mConfig.provisioningNotificationDisabled = !enabled;
- return this;
- }
-
- /**
- * Sets the legacy type for this network.
- *
- * @param legacyType the type
- * @return this builder, to facilitate chaining.
- */
- @NonNull
- public Builder setLegacyType(int legacyType) {
- mConfig.legacyType = legacyType;
- return this;
- }
-
- /**
- * Sets the legacy sub-type for this network.
- *
- * @param legacySubType the type
- * @return this builder, to facilitate chaining.
- */
- @NonNull
- public Builder setLegacySubType(final int legacySubType) {
- mConfig.legacySubType = legacySubType;
- return this;
- }
-
- /**
- * Sets the name of the legacy type of the agent. It's a free-form string used in logging.
- * @param legacyTypeName the name
- * @return this builder, to facilitate chaining.
- */
- @NonNull
- public Builder setLegacyTypeName(@NonNull String legacyTypeName) {
- mConfig.legacyTypeName = legacyTypeName;
- return this;
- }
-
- /**
- * Sets the name of the legacy Sub-type of the agent. It's a free-form string.
- * @param legacySubTypeName the name
- * @return this builder, to facilitate chaining.
- */
- @NonNull
- public Builder setLegacySubTypeName(@NonNull String legacySubTypeName) {
- mConfig.legacySubTypeName = legacySubTypeName;
- return this;
- }
-
- /**
- * Sets the legacy extra info of the agent.
- * @param legacyExtraInfo the legacy extra info.
- * @return this builder, to facilitate chaining.
- */
- @NonNull
- public Builder setLegacyExtraInfo(@NonNull String legacyExtraInfo) {
- mConfig.mLegacyExtraInfo = legacyExtraInfo;
- return this;
- }
-
- /**
- * Sets whether the apps can bypass the VPN connection.
- *
- * @return this builder, to facilitate chaining.
- * @hide
- */
- @NonNull
- @SystemApi(client = MODULE_LIBRARIES)
- public Builder setBypassableVpn(boolean allowBypass) {
- mConfig.allowBypass = allowBypass;
- return this;
- }
-
- /**
- * Returns the constructed {@link NetworkAgentConfig} object.
- */
- @NonNull
- public NetworkAgentConfig build() {
- return mConfig;
- }
- }
-
- @Override
- public boolean equals(final Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- final NetworkAgentConfig that = (NetworkAgentConfig) o;
- return allowBypass == that.allowBypass
- && explicitlySelected == that.explicitlySelected
- && acceptUnvalidated == that.acceptUnvalidated
- && acceptPartialConnectivity == that.acceptPartialConnectivity
- && provisioningNotificationDisabled == that.provisioningNotificationDisabled
- && skip464xlat == that.skip464xlat
- && legacyType == that.legacyType
- && Objects.equals(subscriberId, that.subscriberId)
- && Objects.equals(legacyTypeName, that.legacyTypeName)
- && Objects.equals(mLegacyExtraInfo, that.mLegacyExtraInfo);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(allowBypass, explicitlySelected, acceptUnvalidated,
- acceptPartialConnectivity, provisioningNotificationDisabled, subscriberId,
- skip464xlat, legacyType, legacyTypeName, mLegacyExtraInfo);
- }
-
- @Override
- public String toString() {
- return "NetworkAgentConfig {"
- + " allowBypass = " + allowBypass
- + ", explicitlySelected = " + explicitlySelected
- + ", acceptUnvalidated = " + acceptUnvalidated
- + ", acceptPartialConnectivity = " + acceptPartialConnectivity
- + ", provisioningNotificationDisabled = " + provisioningNotificationDisabled
- + ", subscriberId = '" + subscriberId + '\''
- + ", skip464xlat = " + skip464xlat
- + ", legacyType = " + legacyType
- + ", hasShownBroken = " + hasShownBroken
- + ", legacyTypeName = '" + legacyTypeName + '\''
- + ", legacyExtraInfo = '" + mLegacyExtraInfo + '\''
- + "}";
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel out, int flags) {
- out.writeInt(allowBypass ? 1 : 0);
- out.writeInt(explicitlySelected ? 1 : 0);
- out.writeInt(acceptUnvalidated ? 1 : 0);
- out.writeInt(acceptPartialConnectivity ? 1 : 0);
- out.writeString(subscriberId);
- out.writeInt(provisioningNotificationDisabled ? 1 : 0);
- out.writeInt(skip464xlat ? 1 : 0);
- out.writeInt(legacyType);
- out.writeString(legacyTypeName);
- out.writeInt(legacySubType);
- out.writeString(legacySubTypeName);
- out.writeString(mLegacyExtraInfo);
- }
-
- public static final @NonNull Creator<NetworkAgentConfig> CREATOR =
- new Creator<NetworkAgentConfig>() {
- @Override
- public NetworkAgentConfig createFromParcel(Parcel in) {
- NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig();
- networkAgentConfig.allowBypass = in.readInt() != 0;
- networkAgentConfig.explicitlySelected = in.readInt() != 0;
- networkAgentConfig.acceptUnvalidated = in.readInt() != 0;
- networkAgentConfig.acceptPartialConnectivity = in.readInt() != 0;
- networkAgentConfig.subscriberId = in.readString();
- networkAgentConfig.provisioningNotificationDisabled = in.readInt() != 0;
- networkAgentConfig.skip464xlat = in.readInt() != 0;
- networkAgentConfig.legacyType = in.readInt();
- networkAgentConfig.legacyTypeName = in.readString();
- networkAgentConfig.legacySubType = in.readInt();
- networkAgentConfig.legacySubTypeName = in.readString();
- networkAgentConfig.mLegacyExtraInfo = in.readString();
- return networkAgentConfig;
- }
-
- @Override
- public NetworkAgentConfig[] newArray(int size) {
- return new NetworkAgentConfig[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
deleted file mode 100644
index 4932952..0000000
--- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
+++ /dev/null
@@ -1,2779 +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.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
-
-import android.annotation.IntDef;
-import android.annotation.LongDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.wifi.WifiNetworkSuggestion;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.Process;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.Range;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.net.module.util.CollectionUtils;
-import com.android.net.module.util.NetworkCapabilitiesUtils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.Objects;
-import java.util.Set;
-import java.util.StringJoiner;
-
-/**
- * Representation of the capabilities of an active network. Instances are
- * typically obtained through
- * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)}
- * or {@link ConnectivityManager#getNetworkCapabilities(Network)}.
- * <p>
- * This replaces the old {@link ConnectivityManager#TYPE_MOBILE} method of
- * network selection. Rather than indicate a need for Wi-Fi because an
- * application needs high bandwidth and risk obsolescence when a new, fast
- * network appears (like LTE), the application should specify it needs high
- * bandwidth. Similarly if an application needs an unmetered network for a bulk
- * transfer it can specify that rather than assuming all cellular based
- * connections are metered and all Wi-Fi based connections are not.
- */
-public final class NetworkCapabilities implements Parcelable {
- private static final String TAG = "NetworkCapabilities";
-
- /**
- * Mechanism to support redaction of fields in NetworkCapabilities that are guarded by specific
- * app permissions.
- **/
- /**
- * Don't redact any fields since the receiving app holds all the necessary permissions.
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final long REDACT_NONE = 0;
-
- /**
- * Redact any fields that need {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
- * permission since the receiving app does not hold this permission or the location toggle
- * is off.
- *
- * @see android.Manifest.permission#ACCESS_FINE_LOCATION
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1 << 0;
-
- /**
- * Redact any fields that need {@link android.Manifest.permission#LOCAL_MAC_ADDRESS}
- * permission since the receiving app does not hold this permission.
- *
- * @see android.Manifest.permission#LOCAL_MAC_ADDRESS
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 1 << 1;
-
- /**
- *
- * Redact any fields that need {@link android.Manifest.permission#NETWORK_SETTINGS}
- * permission since the receiving app does not hold this permission.
- *
- * @see android.Manifest.permission#NETWORK_SETTINGS
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final long REDACT_FOR_NETWORK_SETTINGS = 1 << 2;
-
- /**
- * Redact all fields in this object that require any relevant permission.
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final long REDACT_ALL = -1L;
-
- /** @hide */
- @LongDef(flag = true, prefix = { "REDACT_" }, value = {
- REDACT_NONE,
- REDACT_FOR_ACCESS_FINE_LOCATION,
- REDACT_FOR_LOCAL_MAC_ADDRESS,
- REDACT_FOR_NETWORK_SETTINGS,
- REDACT_ALL
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface RedactionType {}
-
- // Set to true when private DNS is broken.
- private boolean mPrivateDnsBroken;
-
- /**
- * Uid of the app making the request.
- */
- private int mRequestorUid;
-
- /**
- * Package name of the app making the request.
- */
- private String mRequestorPackageName;
-
- public NetworkCapabilities() {
- clearAll();
- mNetworkCapabilities = DEFAULT_CAPABILITIES;
- }
-
- public NetworkCapabilities(NetworkCapabilities nc) {
- this(nc, REDACT_NONE);
- }
-
- /**
- * Make a copy of NetworkCapabilities.
- *
- * @param nc Original NetworkCapabilities
- * @param redactions bitmask of redactions that needs to be performed on this new instance of
- * {@link NetworkCapabilities}.
- * @hide
- */
- public NetworkCapabilities(@Nullable NetworkCapabilities nc, @RedactionType long redactions) {
- if (nc != null) {
- set(nc);
- }
- if (mTransportInfo != null) {
- mTransportInfo = nc.mTransportInfo.makeCopy(redactions);
- }
- }
-
- /**
- * Completely clears the contents of this object, removing even the capabilities that are set
- * by default when the object is constructed.
- * @hide
- */
- public void clearAll() {
- mNetworkCapabilities = mTransportTypes = mForbiddenNetworkCapabilities = 0;
- mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
- mNetworkSpecifier = null;
- mTransportInfo = null;
- mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
- mUids = null;
- mAdministratorUids = new int[0];
- mOwnerUid = Process.INVALID_UID;
- mSSID = null;
- mPrivateDnsBroken = false;
- mRequestorUid = Process.INVALID_UID;
- mRequestorPackageName = null;
- mSubIds = new ArraySet<>();
- }
-
- /**
- * Set all contents of this object to the contents of a NetworkCapabilities.
- *
- * @param nc Original NetworkCapabilities
- * @hide
- */
- public void set(@NonNull NetworkCapabilities nc) {
- mNetworkCapabilities = nc.mNetworkCapabilities;
- mTransportTypes = nc.mTransportTypes;
- mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
- mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
- mNetworkSpecifier = nc.mNetworkSpecifier;
- if (nc.getTransportInfo() != null) {
- setTransportInfo(nc.getTransportInfo());
- } else {
- setTransportInfo(null);
- }
- mSignalStrength = nc.mSignalStrength;
- mUids = (nc.mUids == null) ? null : new ArraySet<>(nc.mUids);
- setAdministratorUids(nc.getAdministratorUids());
- mOwnerUid = nc.mOwnerUid;
- mForbiddenNetworkCapabilities = nc.mForbiddenNetworkCapabilities;
- mSSID = nc.mSSID;
- mPrivateDnsBroken = nc.mPrivateDnsBroken;
- mRequestorUid = nc.mRequestorUid;
- mRequestorPackageName = nc.mRequestorPackageName;
- mSubIds = new ArraySet<>(nc.mSubIds);
- }
-
- /**
- * Represents the network's capabilities. If any are specified they will be satisfied
- * by any Network that matches all of them.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private long mNetworkCapabilities;
-
- /**
- * If any capabilities specified here they must not exist in the matching Network.
- */
- private long mForbiddenNetworkCapabilities;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "NET_CAPABILITY_" }, value = {
- NET_CAPABILITY_MMS,
- NET_CAPABILITY_SUPL,
- NET_CAPABILITY_DUN,
- NET_CAPABILITY_FOTA,
- NET_CAPABILITY_IMS,
- NET_CAPABILITY_CBS,
- NET_CAPABILITY_WIFI_P2P,
- NET_CAPABILITY_IA,
- NET_CAPABILITY_RCS,
- NET_CAPABILITY_XCAP,
- NET_CAPABILITY_EIMS,
- NET_CAPABILITY_NOT_METERED,
- NET_CAPABILITY_INTERNET,
- NET_CAPABILITY_NOT_RESTRICTED,
- NET_CAPABILITY_TRUSTED,
- NET_CAPABILITY_NOT_VPN,
- NET_CAPABILITY_VALIDATED,
- NET_CAPABILITY_CAPTIVE_PORTAL,
- NET_CAPABILITY_NOT_ROAMING,
- NET_CAPABILITY_FOREGROUND,
- NET_CAPABILITY_NOT_CONGESTED,
- NET_CAPABILITY_NOT_SUSPENDED,
- NET_CAPABILITY_OEM_PAID,
- NET_CAPABILITY_MCX,
- NET_CAPABILITY_PARTIAL_CONNECTIVITY,
- NET_CAPABILITY_TEMPORARILY_NOT_METERED,
- NET_CAPABILITY_OEM_PRIVATE,
- NET_CAPABILITY_VEHICLE_INTERNAL,
- NET_CAPABILITY_NOT_VCN_MANAGED,
- NET_CAPABILITY_ENTERPRISE,
- NET_CAPABILITY_VSIM,
- NET_CAPABILITY_BIP,
- NET_CAPABILITY_HEAD_UNIT,
- })
- public @interface NetCapability { }
-
- /**
- * Indicates this is a network that has the ability to reach the
- * carrier's MMSC for sending and receiving MMS messages.
- */
- public static final int NET_CAPABILITY_MMS = 0;
-
- /**
- * Indicates this is a network that has the ability to reach the carrier's
- * SUPL server, used to retrieve GPS information.
- */
- public static final int NET_CAPABILITY_SUPL = 1;
-
- /**
- * Indicates this is a network that has the ability to reach the carrier's
- * DUN or tethering gateway.
- */
- public static final int NET_CAPABILITY_DUN = 2;
-
- /**
- * Indicates this is a network that has the ability to reach the carrier's
- * FOTA portal, used for over the air updates.
- */
- public static final int NET_CAPABILITY_FOTA = 3;
-
- /**
- * Indicates this is a network that has the ability to reach the carrier's
- * IMS servers, used for network registration and signaling.
- */
- public static final int NET_CAPABILITY_IMS = 4;
-
- /**
- * Indicates this is a network that has the ability to reach the carrier's
- * CBS servers, used for carrier specific services.
- */
- public static final int NET_CAPABILITY_CBS = 5;
-
- /**
- * Indicates this is a network that has the ability to reach a Wi-Fi direct
- * peer.
- */
- public static final int NET_CAPABILITY_WIFI_P2P = 6;
-
- /**
- * Indicates this is a network that has the ability to reach a carrier's
- * Initial Attach servers.
- */
- public static final int NET_CAPABILITY_IA = 7;
-
- /**
- * Indicates this is a network that has the ability to reach a carrier's
- * RCS servers, used for Rich Communication Services.
- */
- public static final int NET_CAPABILITY_RCS = 8;
-
- /**
- * Indicates this is a network that has the ability to reach a carrier's
- * XCAP servers, used for configuration and control.
- */
- public static final int NET_CAPABILITY_XCAP = 9;
-
- /**
- * Indicates this is a network that has the ability to reach a carrier's
- * Emergency IMS servers or other services, used for network signaling
- * during emergency calls.
- */
- public static final int NET_CAPABILITY_EIMS = 10;
-
- /**
- * Indicates that this network is unmetered.
- */
- public static final int NET_CAPABILITY_NOT_METERED = 11;
-
- /**
- * Indicates that this network should be able to reach the internet.
- */
- public static final int NET_CAPABILITY_INTERNET = 12;
-
- /**
- * Indicates that this network is available for general use. If this is not set
- * applications should not attempt to communicate on this network. Note that this
- * is simply informative and not enforcement - enforcement is handled via other means.
- * Set by default.
- */
- public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
-
- /**
- * Indicates that the user has indicated implicit trust of this network. This
- * generally means it's a sim-selected carrier, a plugged in ethernet, a paired
- * BT device or a wifi the user asked to connect to. Untrusted networks
- * are probably limited to unknown wifi AP. Set by default.
- */
- public static final int NET_CAPABILITY_TRUSTED = 14;
-
- /**
- * Indicates that this network is not a VPN. This capability is set by default and should be
- * explicitly cleared for VPN networks.
- */
- public static final int NET_CAPABILITY_NOT_VPN = 15;
-
- /**
- * Indicates that connectivity on this network was successfully validated. For example, for a
- * network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully
- * detected.
- */
- public static final int NET_CAPABILITY_VALIDATED = 16;
-
- /**
- * Indicates that this network was found to have a captive portal in place last time it was
- * probed.
- */
- public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17;
-
- /**
- * Indicates that this network is not roaming.
- */
- public static final int NET_CAPABILITY_NOT_ROAMING = 18;
-
- /**
- * Indicates that this network is available for use by apps, and not a network that is being
- * kept up in the background to facilitate fast network switching.
- */
- public static final int NET_CAPABILITY_FOREGROUND = 19;
-
- /**
- * Indicates that this network is not congested.
- * <p>
- * When a network is congested, applications should defer network traffic
- * that can be done at a later time, such as uploading analytics.
- */
- public static final int NET_CAPABILITY_NOT_CONGESTED = 20;
-
- /**
- * Indicates that this network is not currently suspended.
- * <p>
- * When a network is suspended, the network's IP addresses and any connections
- * established on the network remain valid, but the network is temporarily unable
- * to transfer data. This can happen, for example, if a cellular network experiences
- * a temporary loss of signal, such as when driving through a tunnel, etc.
- * A network with this capability is not suspended, so is expected to be able to
- * transfer data.
- */
- public static final int NET_CAPABILITY_NOT_SUSPENDED = 21;
-
- /**
- * Indicates that traffic that goes through this network is paid by oem. For example,
- * this network can be used by system apps to upload telemetry data.
- * @hide
- */
- @SystemApi
- public static final int NET_CAPABILITY_OEM_PAID = 22;
-
- /**
- * Indicates this is a network that has the ability to reach a carrier's Mission Critical
- * servers.
- */
- public static final int NET_CAPABILITY_MCX = 23;
-
- /**
- * Indicates that this network was tested to only provide partial connectivity.
- * @hide
- */
- @SystemApi
- public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24;
-
- /**
- * Indicates that this network is temporarily unmetered.
- * <p>
- * This capability will be set for networks that are generally metered, but are currently
- * unmetered, e.g., because the user is in a particular area. This capability can be changed at
- * any time. When it is removed, applications are responsible for stopping any data transfer
- * that should not occur on a metered network.
- * Note that most apps should use {@link #NET_CAPABILITY_NOT_METERED} instead. For more
- * information, see https://developer.android.com/about/versions/11/features/5g#meteredness.
- */
- public static final int NET_CAPABILITY_TEMPORARILY_NOT_METERED = 25;
-
- /**
- * Indicates that this network is private to the OEM and meant only for OEM use.
- * @hide
- */
- @SystemApi
- public static final int NET_CAPABILITY_OEM_PRIVATE = 26;
-
- /**
- * Indicates this is an internal vehicle network, meant to communicate with other
- * automotive systems.
- *
- * @hide
- */
- @SystemApi
- public static final int NET_CAPABILITY_VEHICLE_INTERNAL = 27;
-
- /**
- * Indicates that this network is not subsumed by a Virtual Carrier Network (VCN).
- * <p>
- * To provide an experience on a VCN similar to a single traditional carrier network, in
- * some cases the system sets this bit is set by default in application's network requests,
- * and may choose to remove it at its own discretion when matching the request to a network.
- * <p>
- * Applications that want to know about a Virtual Carrier Network's underlying networks,
- * for example to use them for multipath purposes, should remove this bit from their network
- * requests ; the system will not add it back once removed.
- * @hide
- */
- @SystemApi
- public static final int NET_CAPABILITY_NOT_VCN_MANAGED = 28;
-
- /**
- * Indicates that this network is intended for enterprise use.
- * <p>
- * 5G URSP rules may indicate that all data should use a connection dedicated for enterprise
- * use. If the enterprise capability is requested, all enterprise traffic will be routed over
- * the connection with this capability.
- */
- public static final int NET_CAPABILITY_ENTERPRISE = 29;
-
- /**
- * Indicates that this network has ability to access the carrier's Virtual Sim service.
- * @hide
- */
- @SystemApi
- public static final int NET_CAPABILITY_VSIM = 30;
-
- /**
- * Indicates that this network has ability to support Bearer Independent Protol.
- * @hide
- */
- @SystemApi
- public static final int NET_CAPABILITY_BIP = 31;
-
- /**
- * Indicates that this network is connected to an automotive head unit.
- */
- public static final int NET_CAPABILITY_HEAD_UNIT = 32;
-
- private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
- private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_HEAD_UNIT;
-
- /**
- * Network capabilities that are expected to be mutable, i.e., can change while a particular
- * network is connected.
- */
- private static final long MUTABLE_CAPABILITIES =
- // TRUSTED can change when user explicitly connects to an untrusted network in Settings.
- // http://b/18206275
- (1 << NET_CAPABILITY_TRUSTED)
- | (1 << NET_CAPABILITY_VALIDATED)
- | (1 << NET_CAPABILITY_CAPTIVE_PORTAL)
- | (1 << NET_CAPABILITY_NOT_ROAMING)
- | (1 << NET_CAPABILITY_FOREGROUND)
- | (1 << NET_CAPABILITY_NOT_CONGESTED)
- | (1 << NET_CAPABILITY_NOT_SUSPENDED)
- | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY)
- | (1 << NET_CAPABILITY_TEMPORARILY_NOT_METERED)
- | (1 << NET_CAPABILITY_NOT_VCN_MANAGED)
- // The value of NET_CAPABILITY_HEAD_UNIT is 32, which cannot use int to do bit shift,
- // otherwise there will be an overflow. Use long to do bit shift instead.
- | (1L << NET_CAPABILITY_HEAD_UNIT);
-
- /**
- * Network capabilities that are not allowed in NetworkRequests. This exists because the
- * NetworkFactory / NetworkAgent model does not deal well with the situation where a
- * capability's presence cannot be known in advance. If such a capability is requested, then we
- * can get into a cycle where the NetworkFactory endlessly churns out NetworkAgents that then
- * get immediately torn down because they do not have the requested capability.
- */
- // Note that as a historical exception, the TRUSTED and NOT_VCN_MANAGED capabilities
- // are mutable but requestable. Factories are responsible for not getting
- // in an infinite loop about these.
- private static final long NON_REQUESTABLE_CAPABILITIES =
- MUTABLE_CAPABILITIES
- & ~(1 << NET_CAPABILITY_TRUSTED)
- & ~(1 << NET_CAPABILITY_NOT_VCN_MANAGED);
-
- /**
- * Capabilities that are set by default when the object is constructed.
- */
- private static final long DEFAULT_CAPABILITIES =
- (1 << NET_CAPABILITY_NOT_RESTRICTED)
- | (1 << NET_CAPABILITY_TRUSTED)
- | (1 << NET_CAPABILITY_NOT_VPN);
-
- /**
- * Capabilities that are managed by ConnectivityService.
- */
- private static final long CONNECTIVITY_MANAGED_CAPABILITIES =
- (1 << NET_CAPABILITY_VALIDATED)
- | (1 << NET_CAPABILITY_CAPTIVE_PORTAL)
- | (1 << NET_CAPABILITY_FOREGROUND)
- | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY);
-
- /**
- * Capabilities that are allowed for test networks. This list must be set so that it is safe
- * for an unprivileged user to create a network with these capabilities via shell. As such,
- * it must never contain capabilities that are generally useful to the system, such as
- * INTERNET, IMS, SUPL, etc.
- */
- private static final long TEST_NETWORKS_ALLOWED_CAPABILITIES =
- (1 << NET_CAPABILITY_NOT_METERED)
- | (1 << NET_CAPABILITY_TEMPORARILY_NOT_METERED)
- | (1 << NET_CAPABILITY_NOT_RESTRICTED)
- | (1 << NET_CAPABILITY_NOT_VPN)
- | (1 << NET_CAPABILITY_NOT_ROAMING)
- | (1 << NET_CAPABILITY_NOT_CONGESTED)
- | (1 << NET_CAPABILITY_NOT_SUSPENDED)
- | (1 << NET_CAPABILITY_NOT_VCN_MANAGED);
-
- /**
- * Adds the given capability to this {@code NetworkCapability} instance.
- * Note that when searching for a network to satisfy a request, all capabilities
- * requested must be satisfied.
- *
- * @param capability the capability to be added.
- * @return This NetworkCapabilities instance, to facilitate chaining.
- * @hide
- */
- public @NonNull NetworkCapabilities addCapability(@NetCapability int capability) {
- // If the given capability was previously added to the list of forbidden capabilities
- // then the capability will also be removed from the list of forbidden capabilities.
- // TODO: Consider adding forbidden capabilities to the public API and mention this
- // in the documentation.
- checkValidCapability(capability);
- mNetworkCapabilities |= 1L << capability;
- // remove from forbidden capability list
- mForbiddenNetworkCapabilities &= ~(1L << capability);
- return this;
- }
-
- /**
- * Adds the given capability to the list of forbidden capabilities of this
- * {@code NetworkCapability} instance. Note that when searching for a network to
- * satisfy a request, the network must not contain any capability from forbidden capability
- * list.
- * <p>
- * If the capability was previously added to the list of required capabilities (for
- * example, it was there by default or added using {@link #addCapability(int)} method), then
- * it will be removed from the list of required capabilities as well.
- *
- * @see #addCapability(int)
- * @hide
- */
- public void addForbiddenCapability(@NetCapability int capability) {
- checkValidCapability(capability);
- mForbiddenNetworkCapabilities |= 1L << capability;
- mNetworkCapabilities &= ~(1L << capability); // remove from requested capabilities
- }
-
- /**
- * Removes (if found) the given capability from this {@code NetworkCapability}
- * instance that were added via addCapability(int) or setCapabilities(int[], int[]).
- *
- * @param capability the capability to be removed.
- * @return This NetworkCapabilities instance, to facilitate chaining.
- * @hide
- */
- public @NonNull NetworkCapabilities removeCapability(@NetCapability int capability) {
- checkValidCapability(capability);
- final long mask = ~(1L << capability);
- mNetworkCapabilities &= mask;
- return this;
- }
-
- /**
- * Removes (if found) the given forbidden capability from this {@code NetworkCapability}
- * instance that were added via addForbiddenCapability(int) or setCapabilities(int[], int[]).
- *
- * @param capability the capability to be removed.
- * @return This NetworkCapabilities instance, to facilitate chaining.
- * @hide
- */
- public @NonNull NetworkCapabilities removeForbiddenCapability(@NetCapability int capability) {
- checkValidCapability(capability);
- mForbiddenNetworkCapabilities &= ~(1L << capability);
- return this;
- }
-
- /**
- * Sets (or clears) the given capability on this {@link NetworkCapabilities}
- * instance.
- * @hide
- */
- public @NonNull NetworkCapabilities setCapability(@NetCapability int capability,
- boolean value) {
- if (value) {
- addCapability(capability);
- } else {
- removeCapability(capability);
- }
- return this;
- }
-
- /**
- * Gets all the capabilities set on this {@code NetworkCapability} instance.
- *
- * @return an array of capability values for this instance.
- */
- public @NonNull @NetCapability int[] getCapabilities() {
- return NetworkCapabilitiesUtils.unpackBits(mNetworkCapabilities);
- }
-
- /**
- * Gets all the forbidden capabilities set on this {@code NetworkCapability} instance.
- *
- * @return an array of forbidden capability values for this instance.
- * @hide
- */
- public @NetCapability int[] getForbiddenCapabilities() {
- return NetworkCapabilitiesUtils.unpackBits(mForbiddenNetworkCapabilities);
- }
-
-
- /**
- * Sets all the capabilities set on this {@code NetworkCapability} instance.
- * This overwrites any existing capabilities.
- *
- * @hide
- */
- public void setCapabilities(@NetCapability int[] capabilities,
- @NetCapability int[] forbiddenCapabilities) {
- mNetworkCapabilities = NetworkCapabilitiesUtils.packBits(capabilities);
- mForbiddenNetworkCapabilities = NetworkCapabilitiesUtils.packBits(forbiddenCapabilities);
- }
-
- /**
- * @deprecated use {@link #setCapabilities(int[], int[])}
- * @hide
- */
- @Deprecated
- public void setCapabilities(@NetCapability int[] capabilities) {
- setCapabilities(capabilities, new int[] {});
- }
-
- /**
- * Tests for the presence of a capability on this instance.
- *
- * @param capability the capabilities to be tested for.
- * @return {@code true} if set on this instance.
- */
- public boolean hasCapability(@NetCapability int capability) {
- return isValidCapability(capability)
- && ((mNetworkCapabilities & (1L << capability)) != 0);
- }
-
- /** @hide */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public boolean hasForbiddenCapability(@NetCapability int capability) {
- return isValidCapability(capability)
- && ((mForbiddenNetworkCapabilities & (1L << capability)) != 0);
- }
-
- /**
- * Check if this NetworkCapabilities has system managed capabilities or not.
- * @hide
- */
- public boolean hasConnectivityManagedCapability() {
- return ((mNetworkCapabilities & CONNECTIVITY_MANAGED_CAPABILITIES) != 0);
- }
-
- /**
- * Get the name of the given capability that carriers use.
- * If the capability does not have a carrier-name, returns null.
- *
- * @param capability The capability to get the carrier-name of.
- * @return The carrier-name of the capability, or null if it doesn't exist.
- * @hide
- */
- @SystemApi
- public static @Nullable String getCapabilityCarrierName(@NetCapability int capability) {
- if (capability == NET_CAPABILITY_ENTERPRISE) {
- return capabilityNameOf(capability);
- } else {
- return null;
- }
- }
-
- private void combineNetCapabilities(@NonNull NetworkCapabilities nc) {
- final long wantedCaps = this.mNetworkCapabilities | nc.mNetworkCapabilities;
- final long forbiddenCaps =
- this.mForbiddenNetworkCapabilities | nc.mForbiddenNetworkCapabilities;
- if ((wantedCaps & forbiddenCaps) != 0) {
- throw new IllegalArgumentException(
- "Cannot have the same capability in wanted and forbidden lists.");
- }
- this.mNetworkCapabilities = wantedCaps;
- this.mForbiddenNetworkCapabilities = forbiddenCaps;
- }
-
- /**
- * Convenience function that returns a human-readable description of the first mutable
- * capability we find. Used to present an error message to apps that request mutable
- * capabilities.
- *
- * @hide
- */
- public @Nullable String describeFirstNonRequestableCapability() {
- final long nonRequestable = (mNetworkCapabilities | mForbiddenNetworkCapabilities)
- & NON_REQUESTABLE_CAPABILITIES;
-
- if (nonRequestable != 0) {
- return capabilityNameOf(NetworkCapabilitiesUtils.unpackBits(nonRequestable)[0]);
- }
- if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth";
- if (hasSignalStrength()) return "signalStrength";
- if (isPrivateDnsBroken()) {
- return "privateDnsBroken";
- }
- return null;
- }
-
- private boolean satisfiedByNetCapabilities(@NonNull NetworkCapabilities nc,
- boolean onlyImmutable) {
- long requestedCapabilities = mNetworkCapabilities;
- long requestedForbiddenCapabilities = mForbiddenNetworkCapabilities;
- long providedCapabilities = nc.mNetworkCapabilities;
-
- if (onlyImmutable) {
- requestedCapabilities &= ~MUTABLE_CAPABILITIES;
- requestedForbiddenCapabilities &= ~MUTABLE_CAPABILITIES;
- }
- return ((providedCapabilities & requestedCapabilities) == requestedCapabilities)
- && ((requestedForbiddenCapabilities & providedCapabilities) == 0);
- }
-
- /** @hide */
- public boolean equalsNetCapabilities(@NonNull NetworkCapabilities nc) {
- return (nc.mNetworkCapabilities == this.mNetworkCapabilities)
- && (nc.mForbiddenNetworkCapabilities == this.mForbiddenNetworkCapabilities);
- }
-
- private boolean equalsNetCapabilitiesRequestable(@NonNull NetworkCapabilities that) {
- return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)
- == (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES))
- && ((this.mForbiddenNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)
- == (that.mForbiddenNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES));
- }
-
- /**
- * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if inferring the network is restricted.
- *
- * @hide
- */
- public void maybeMarkCapabilitiesRestricted() {
- if (NetworkCapabilitiesUtils.inferRestrictedCapability(this)) {
- removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
- }
- }
-
- /**
- * Test networks have strong restrictions on what capabilities they can have. Enforce these
- * restrictions.
- * @hide
- */
- public void restrictCapabilitesForTestNetwork(int creatorUid) {
- final long originalCapabilities = mNetworkCapabilities;
- final long originalTransportTypes = mTransportTypes;
- final NetworkSpecifier originalSpecifier = mNetworkSpecifier;
- final int originalSignalStrength = mSignalStrength;
- final int originalOwnerUid = getOwnerUid();
- final int[] originalAdministratorUids = getAdministratorUids();
- final TransportInfo originalTransportInfo = getTransportInfo();
- clearAll();
- if (0 != (originalCapabilities & NET_CAPABILITY_NOT_RESTRICTED)) {
- // If the test network is not restricted, then it is only allowed to declare some
- // specific transports. This is to minimize impact on running apps in case an app
- // run from the shell creates a test a network.
- mTransportTypes =
- (originalTransportTypes & UNRESTRICTED_TEST_NETWORKS_ALLOWED_TRANSPORTS)
- | (1 << TRANSPORT_TEST);
- } else {
- // If the test transport is restricted, then it may declare any transport.
- mTransportTypes = (originalTransportTypes | (1 << TRANSPORT_TEST));
- }
- mNetworkCapabilities = originalCapabilities & TEST_NETWORKS_ALLOWED_CAPABILITIES;
- mNetworkSpecifier = originalSpecifier;
- mSignalStrength = originalSignalStrength;
- mTransportInfo = originalTransportInfo;
-
- // Only retain the owner and administrator UIDs if they match the app registering the remote
- // caller that registered the network.
- if (originalOwnerUid == creatorUid) {
- setOwnerUid(creatorUid);
- }
- if (CollectionUtils.contains(originalAdministratorUids, creatorUid)) {
- setAdministratorUids(new int[] {creatorUid});
- }
- // There is no need to clear the UIDs, they have already been cleared by clearAll() above.
- }
-
- /**
- * Representing the transport type. Apps should generally not care about transport. A
- * request for a fast internet connection could be satisfied by a number of different
- * transports. If any are specified here it will be satisfied a Network that matches
- * any of them. If a caller doesn't care about the transport it should not specify any.
- */
- private long mTransportTypes;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "TRANSPORT_" }, value = {
- TRANSPORT_CELLULAR,
- TRANSPORT_WIFI,
- TRANSPORT_BLUETOOTH,
- TRANSPORT_ETHERNET,
- TRANSPORT_VPN,
- TRANSPORT_WIFI_AWARE,
- TRANSPORT_LOWPAN,
- TRANSPORT_TEST,
- TRANSPORT_USB,
- })
- public @interface Transport { }
-
- /**
- * Indicates this network uses a Cellular transport.
- */
- public static final int TRANSPORT_CELLULAR = 0;
-
- /**
- * Indicates this network uses a Wi-Fi transport.
- */
- public static final int TRANSPORT_WIFI = 1;
-
- /**
- * Indicates this network uses a Bluetooth transport.
- */
- public static final int TRANSPORT_BLUETOOTH = 2;
-
- /**
- * Indicates this network uses an Ethernet transport.
- */
- public static final int TRANSPORT_ETHERNET = 3;
-
- /**
- * Indicates this network uses a VPN transport.
- */
- public static final int TRANSPORT_VPN = 4;
-
- /**
- * Indicates this network uses a Wi-Fi Aware transport.
- */
- public static final int TRANSPORT_WIFI_AWARE = 5;
-
- /**
- * Indicates this network uses a LoWPAN transport.
- */
- public static final int TRANSPORT_LOWPAN = 6;
-
- /**
- * Indicates this network uses a Test-only virtual interface as a transport.
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final int TRANSPORT_TEST = 7;
-
- /**
- * Indicates this network uses a USB transport.
- */
- public static final int TRANSPORT_USB = 8;
-
- /** @hide */
- public static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
- /** @hide */
- public static final int MAX_TRANSPORT = TRANSPORT_USB;
-
- /** @hide */
- public static boolean isValidTransport(@Transport int transportType) {
- return (MIN_TRANSPORT <= transportType) && (transportType <= MAX_TRANSPORT);
- }
-
- private static final String[] TRANSPORT_NAMES = {
- "CELLULAR",
- "WIFI",
- "BLUETOOTH",
- "ETHERNET",
- "VPN",
- "WIFI_AWARE",
- "LOWPAN",
- "TEST",
- "USB"
- };
-
- /**
- * Allowed transports on an unrestricted test network (in addition to TRANSPORT_TEST).
- */
- private static final int UNRESTRICTED_TEST_NETWORKS_ALLOWED_TRANSPORTS =
- 1 << TRANSPORT_TEST
- // Test ethernet networks can be created with EthernetManager#setIncludeTestInterfaces
- | 1 << TRANSPORT_ETHERNET
- // Test VPN networks can be created but their UID ranges must be empty.
- | 1 << TRANSPORT_VPN;
-
- /**
- * Adds the given transport type to this {@code NetworkCapability} instance.
- * Multiple transports may be applied. Note that when searching
- * for a network to satisfy a request, any listed in the request will satisfy the request.
- * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
- * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
- * to be selected. This is logically different than
- * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
- *
- * @param transportType the transport type to be added.
- * @return This NetworkCapabilities instance, to facilitate chaining.
- * @hide
- */
- public @NonNull NetworkCapabilities addTransportType(@Transport int transportType) {
- checkValidTransportType(transportType);
- mTransportTypes |= 1 << transportType;
- setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
- return this;
- }
-
- /**
- * Removes (if found) the given transport from this {@code NetworkCapability} instance.
- *
- * @param transportType the transport type to be removed.
- * @return This NetworkCapabilities instance, to facilitate chaining.
- * @hide
- */
- public @NonNull NetworkCapabilities removeTransportType(@Transport int transportType) {
- checkValidTransportType(transportType);
- mTransportTypes &= ~(1 << transportType);
- setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
- return this;
- }
-
- /**
- * Sets (or clears) the given transport on this {@link NetworkCapabilities}
- * instance.
- *
- * @hide
- */
- public @NonNull NetworkCapabilities setTransportType(@Transport int transportType,
- boolean value) {
- if (value) {
- addTransportType(transportType);
- } else {
- removeTransportType(transportType);
- }
- return this;
- }
-
- /**
- * Gets all the transports set on this {@code NetworkCapability} instance.
- *
- * @return an array of transport type values for this instance.
- * @hide
- */
- @SystemApi
- @NonNull public @Transport int[] getTransportTypes() {
- return NetworkCapabilitiesUtils.unpackBits(mTransportTypes);
- }
-
- /**
- * Sets all the transports set on this {@code NetworkCapability} instance.
- * This overwrites any existing transports.
- *
- * @hide
- */
- public void setTransportTypes(@Transport int[] transportTypes) {
- mTransportTypes = NetworkCapabilitiesUtils.packBits(transportTypes);
- }
-
- /**
- * Tests for the presence of a transport on this instance.
- *
- * @param transportType the transport type to be tested for.
- * @return {@code true} if set on this instance.
- */
- public boolean hasTransport(@Transport int transportType) {
- return isValidTransport(transportType) && ((mTransportTypes & (1 << transportType)) != 0);
- }
-
- private void combineTransportTypes(NetworkCapabilities nc) {
- this.mTransportTypes |= nc.mTransportTypes;
- }
-
- private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
- return ((this.mTransportTypes == 0)
- || ((this.mTransportTypes & nc.mTransportTypes) != 0));
- }
-
- /** @hide */
- public boolean equalsTransportTypes(NetworkCapabilities nc) {
- return (nc.mTransportTypes == this.mTransportTypes);
- }
-
- /**
- * UID of the app that owns this network, or Process#INVALID_UID if none/unknown.
- *
- * <p>This field keeps track of the UID of the app that created this network and is in charge of
- * its lifecycle. This could be the UID of apps such as the Wifi network suggestor, the running
- * VPN, or Carrier Service app managing a cellular data connection.
- *
- * <p>For NetworkCapability instances being sent from ConnectivityService, this value MUST be
- * reset to Process.INVALID_UID unless all the following conditions are met:
- *
- * <p>The caller is the network owner, AND one of the following sets of requirements is met:
- *
- * <ol>
- * <li>The described Network is a VPN
- * </ol>
- *
- * <p>OR:
- *
- * <ol>
- * <li>The calling app is the network owner
- * <li>The calling app has the ACCESS_FINE_LOCATION permission granted
- * <li>The user's location toggle is on
- * </ol>
- *
- * This is because the owner UID is location-sensitive. The apps that request a network could
- * know where the device is if they can tell for sure the system has connected to the network
- * they requested.
- *
- * <p>This is populated by the network agents and for the NetworkCapabilities instance sent by
- * an app to the System Server, the value MUST be reset to Process.INVALID_UID by the system
- * server.
- */
- private int mOwnerUid = Process.INVALID_UID;
-
- /**
- * Set the UID of the owner app.
- * @hide
- */
- public @NonNull NetworkCapabilities setOwnerUid(final int uid) {
- mOwnerUid = uid;
- return this;
- }
-
- /**
- * Retrieves the UID of the app that owns this network.
- *
- * <p>For user privacy reasons, this field will only be populated if the following conditions
- * are met:
- *
- * <p>The caller is the network owner, AND one of the following sets of requirements is met:
- *
- * <ol>
- * <li>The described Network is a VPN
- * </ol>
- *
- * <p>OR:
- *
- * <ol>
- * <li>The calling app is the network owner
- * <li>The calling app has the ACCESS_FINE_LOCATION permission granted
- * <li>The user's location toggle is on
- * </ol>
- *
- * Instances of NetworkCapabilities sent to apps without the appropriate permissions will have
- * this field cleared out.
- *
- * <p>
- * This field will only be populated for VPN and wifi network suggestor apps (i.e using
- * {@link WifiNetworkSuggestion}), and only for the network they own.
- * In the case of wifi network suggestors apps, this field is also location sensitive, so the
- * app needs to hold {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission. If the
- * app targets SDK version greater than or equal to {@link Build.VERSION_CODES#S}, then they
- * also need to use {@link NetworkCallback#FLAG_INCLUDE_LOCATION_INFO} to get the info in their
- * callback. If the apps targets SDK version equal to {{@link Build.VERSION_CODES#R}, this field
- * will always be included. The app will be blamed for location access if this field is
- * included.
- * </p>
- */
- public int getOwnerUid() {
- return mOwnerUid;
- }
-
- private boolean equalsOwnerUid(@NonNull final NetworkCapabilities nc) {
- return mOwnerUid == nc.mOwnerUid;
- }
-
- /**
- * UIDs of packages that are administrators of this network, or empty if none.
- *
- * <p>This field tracks the UIDs of packages that have permission to manage this network.
- *
- * <p>Network owners will also be listed as administrators.
- *
- * <p>For NetworkCapability instances being sent from the System Server, this value MUST be
- * empty unless the destination is 1) the System Server, or 2) Telephony. In either case, the
- * receiving entity must have the ACCESS_FINE_LOCATION permission and target R+.
- *
- * <p>When received from an app in a NetworkRequest this is always cleared out by the system
- * server. This field is never used for matching NetworkRequests to NetworkAgents.
- */
- @NonNull private int[] mAdministratorUids = new int[0];
-
- /**
- * Sets the int[] of UIDs that are administrators of this network.
- *
- * <p>UIDs included in administratorUids gain administrator privileges over this Network.
- * Examples of UIDs that should be included in administratorUids are:
- *
- * <ul>
- * <li>Carrier apps with privileges for the relevant subscription
- * <li>Active VPN apps
- * <li>Other application groups with a particular Network-related role
- * </ul>
- *
- * <p>In general, user-supplied networks (such as WiFi networks) do not have an administrator.
- *
- * <p>An app is granted owner privileges over Networks that it supplies. The owner UID MUST
- * always be included in administratorUids.
- *
- * <p>The administrator UIDs are set by network agents.
- *
- * @param administratorUids the UIDs to be set as administrators of this Network.
- * @throws IllegalArgumentException if duplicate UIDs are contained in administratorUids
- * @see #mAdministratorUids
- * @hide
- */
- @NonNull
- public NetworkCapabilities setAdministratorUids(@NonNull final int[] administratorUids) {
- mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length);
- Arrays.sort(mAdministratorUids);
- for (int i = 0; i < mAdministratorUids.length - 1; i++) {
- if (mAdministratorUids[i] >= mAdministratorUids[i + 1]) {
- throw new IllegalArgumentException("All administrator UIDs must be unique");
- }
- }
- return this;
- }
-
- /**
- * Retrieves the UIDs that are administrators of this Network.
- *
- * <p>This is only populated in NetworkCapabilities objects that come from network agents for
- * networks that are managed by specific apps on the system, such as carrier privileged apps or
- * wifi suggestion apps. This will include the network owner.
- *
- * @return the int[] of UIDs that are administrators of this Network
- * @see #mAdministratorUids
- * @hide
- */
- @NonNull
- @SystemApi
- public int[] getAdministratorUids() {
- return Arrays.copyOf(mAdministratorUids, mAdministratorUids.length);
- }
-
- /**
- * Tests if the set of administrator UIDs of this network is the same as that of the passed one.
- *
- * <p>The administrator UIDs must be in sorted order.
- *
- * <p>nc is assumed non-null. Else, NPE.
- *
- * @hide
- */
- @VisibleForTesting(visibility = PRIVATE)
- public boolean equalsAdministratorUids(@NonNull final NetworkCapabilities nc) {
- return Arrays.equals(mAdministratorUids, nc.mAdministratorUids);
- }
-
- /**
- * Combine the administrator UIDs of the capabilities.
- *
- * <p>This is only legal if either of the administrators lists are empty, or if they are equal.
- * Combining administrator UIDs is only possible for combining non-overlapping sets of UIDs.
- *
- * <p>If both administrator lists are non-empty but not equal, they conflict with each other. In
- * this case, it would not make sense to add them together.
- */
- private void combineAdministratorUids(@NonNull final NetworkCapabilities nc) {
- if (nc.mAdministratorUids.length == 0) return;
- if (mAdministratorUids.length == 0) {
- mAdministratorUids = Arrays.copyOf(nc.mAdministratorUids, nc.mAdministratorUids.length);
- return;
- }
- if (!equalsAdministratorUids(nc)) {
- throw new IllegalStateException("Can't combine two different administrator UID lists");
- }
- }
-
- /**
- * Value indicating that link bandwidth is unspecified.
- * @hide
- */
- public static final int LINK_BANDWIDTH_UNSPECIFIED = 0;
-
- /**
- * Passive link bandwidth. This is a rough guide of the expected peak bandwidth
- * for the first hop on the given transport. It is not measured, but may take into account
- * link parameters (Radio technology, allocated channels, etc).
- */
- private int mLinkUpBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
- private int mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
-
- /**
- * Sets the upstream bandwidth for this network in Kbps. This always only refers to
- * the estimated first hop transport bandwidth.
- * <p>
- * {@see Builder#setLinkUpstreamBandwidthKbps}
- *
- * @param upKbps the estimated first hop upstream (device to network) bandwidth.
- * @hide
- */
- public @NonNull NetworkCapabilities setLinkUpstreamBandwidthKbps(int upKbps) {
- mLinkUpBandwidthKbps = upKbps;
- return this;
- }
-
- /**
- * Retrieves the upstream bandwidth for this network in Kbps. This always only refers to
- * the estimated first hop transport bandwidth.
- *
- * @return The estimated first hop upstream (device to network) bandwidth.
- */
- public int getLinkUpstreamBandwidthKbps() {
- return mLinkUpBandwidthKbps;
- }
-
- /**
- * Sets the downstream bandwidth for this network in Kbps. This always only refers to
- * the estimated first hop transport bandwidth.
- * <p>
- * {@see Builder#setLinkUpstreamBandwidthKbps}
- *
- * @param downKbps the estimated first hop downstream (network to device) bandwidth.
- * @hide
- */
- public @NonNull NetworkCapabilities setLinkDownstreamBandwidthKbps(int downKbps) {
- mLinkDownBandwidthKbps = downKbps;
- return this;
- }
-
- /**
- * Retrieves the downstream bandwidth for this network in Kbps. This always only refers to
- * the estimated first hop transport bandwidth.
- *
- * @return The estimated first hop downstream (network to device) bandwidth.
- */
- public int getLinkDownstreamBandwidthKbps() {
- return mLinkDownBandwidthKbps;
- }
-
- private void combineLinkBandwidths(NetworkCapabilities nc) {
- this.mLinkUpBandwidthKbps =
- Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps);
- this.mLinkDownBandwidthKbps =
- Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
- }
- private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
- return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps
- || this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
- }
- private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
- return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps
- && this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
- }
- /** @hide */
- public static int minBandwidth(int a, int b) {
- if (a == LINK_BANDWIDTH_UNSPECIFIED) {
- return b;
- } else if (b == LINK_BANDWIDTH_UNSPECIFIED) {
- return a;
- } else {
- return Math.min(a, b);
- }
- }
- /** @hide */
- public static int maxBandwidth(int a, int b) {
- return Math.max(a, b);
- }
-
- private NetworkSpecifier mNetworkSpecifier = null;
- private TransportInfo mTransportInfo = null;
-
- /**
- * Sets the optional bearer specific network specifier.
- * This has no meaning if a single transport is also not specified, so calling
- * this without a single transport set will generate an exception, as will
- * subsequently adding or removing transports after this is set.
- * </p>
- *
- * @param networkSpecifier A concrete, parcelable framework class that extends
- * NetworkSpecifier.
- * @return This NetworkCapabilities instance, to facilitate chaining.
- * @hide
- */
- public @NonNull NetworkCapabilities setNetworkSpecifier(
- @NonNull NetworkSpecifier networkSpecifier) {
- if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) {
- throw new IllegalStateException("Must have a single transport specified to use " +
- "setNetworkSpecifier");
- }
-
- mNetworkSpecifier = networkSpecifier;
-
- return this;
- }
-
- /**
- * Sets the optional transport specific information.
- *
- * @param transportInfo A concrete, parcelable framework class that extends
- * {@link TransportInfo}.
- * @return This NetworkCapabilities instance, to facilitate chaining.
- * @hide
- */
- public @NonNull NetworkCapabilities setTransportInfo(@NonNull TransportInfo transportInfo) {
- mTransportInfo = transportInfo;
- return this;
- }
-
- /**
- * Gets the optional bearer specific network specifier. May be {@code null} if not set.
- *
- * @return The optional {@link NetworkSpecifier} specifying the bearer specific network
- * specifier or {@code null}.
- */
- public @Nullable NetworkSpecifier getNetworkSpecifier() {
- return mNetworkSpecifier;
- }
-
- /**
- * Returns a transport-specific information container. The application may cast this
- * container to a concrete sub-class based on its knowledge of the network request. The
- * application should be able to deal with a {@code null} return value or an invalid case,
- * e.g. use {@code instanceof} operator to verify expected type.
- *
- * @return A concrete implementation of the {@link TransportInfo} class or null if not
- * available for the network.
- */
- @Nullable public TransportInfo getTransportInfo() {
- return mTransportInfo;
- }
-
- private void combineSpecifiers(NetworkCapabilities nc) {
- if (mNetworkSpecifier != null && !mNetworkSpecifier.equals(nc.mNetworkSpecifier)) {
- throw new IllegalStateException("Can't combine two networkSpecifiers");
- }
- setNetworkSpecifier(nc.mNetworkSpecifier);
- }
-
- private boolean satisfiedBySpecifier(NetworkCapabilities nc) {
- return mNetworkSpecifier == null || mNetworkSpecifier.canBeSatisfiedBy(nc.mNetworkSpecifier)
- || nc.mNetworkSpecifier instanceof MatchAllNetworkSpecifier;
- }
-
- private boolean equalsSpecifier(NetworkCapabilities nc) {
- return Objects.equals(mNetworkSpecifier, nc.mNetworkSpecifier);
- }
-
- private void combineTransportInfos(NetworkCapabilities nc) {
- if (mTransportInfo != null && !mTransportInfo.equals(nc.mTransportInfo)) {
- throw new IllegalStateException("Can't combine two TransportInfos");
- }
- setTransportInfo(nc.mTransportInfo);
- }
-
- private boolean equalsTransportInfo(NetworkCapabilities nc) {
- return Objects.equals(mTransportInfo, nc.mTransportInfo);
- }
-
- /**
- * Magic value that indicates no signal strength provided. A request specifying this value is
- * always satisfied.
- */
- public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE;
-
- /**
- * Signal strength. This is a signed integer, and higher values indicate better signal.
- * The exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
- private int mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
-
- /**
- * Sets the signal strength. This is a signed integer, with higher values indicating a stronger
- * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units
- * reported by wifi code.
- * <p>
- * Note that when used to register a network callback, this specifies the minimum acceptable
- * signal strength. When received as the state of an existing network it specifies the current
- * value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no
- * effect when requesting a callback.
- *
- * @param signalStrength the bearer-specific signal strength.
- * @hide
- */
- public @NonNull NetworkCapabilities setSignalStrength(int signalStrength) {
- mSignalStrength = signalStrength;
- return this;
- }
-
- /**
- * Returns {@code true} if this object specifies a signal strength.
- *
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public boolean hasSignalStrength() {
- return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED;
- }
-
- /**
- * Retrieves the signal strength.
- *
- * @return The bearer-specific signal strength.
- */
- public int getSignalStrength() {
- return mSignalStrength;
- }
-
- private void combineSignalStrength(NetworkCapabilities nc) {
- this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength);
- }
-
- private boolean satisfiedBySignalStrength(NetworkCapabilities nc) {
- return this.mSignalStrength <= nc.mSignalStrength;
- }
-
- private boolean equalsSignalStrength(NetworkCapabilities nc) {
- return this.mSignalStrength == nc.mSignalStrength;
- }
-
- /**
- * List of UIDs this network applies to. No restriction if null.
- * <p>
- * For networks, mUids represent the list of network this applies to, and null means this
- * network applies to all UIDs.
- * For requests, mUids is the list of UIDs this network MUST apply to to match ; ALL UIDs
- * must be included in a network so that they match. As an exception to the general rule,
- * a null mUids field for requests mean "no requirements" rather than what the general rule
- * would suggest ("must apply to all UIDs") : this is because this has shown to be what users
- * of this API expect in practice. A network that must match all UIDs can still be
- * expressed with a set ranging the entire set of possible UIDs.
- * <p>
- * mUids is typically (and at this time, only) used by VPN. This network is only available to
- * the UIDs in this list, and it is their default network. Apps in this list that wish to
- * bypass the VPN can do so iff the VPN app allows them to or if they are privileged. If this
- * member is null, then the network is not restricted by app UID. If it's an empty list, then
- * it means nobody can use it.
- * As a special exception, the app managing this network (as identified by its UID stored in
- * mOwnerUid) can always see this network. This is embodied by a special check in
- * satisfiedByUids. That still does not mean the network necessarily <strong>applies</strong>
- * to the app that manages it as determined by #appliesToUid.
- * <p>
- * Please note that in principle a single app can be associated with multiple UIDs because
- * each app will have a different UID when it's run as a different (macro-)user. A single
- * macro user can only have a single active VPN app at any given time however.
- * <p>
- * Also please be aware this class does not try to enforce any normalization on this. Callers
- * can only alter the UIDs by setting them wholesale : this class does not provide any utility
- * to add or remove individual UIDs or ranges. If callers have any normalization needs on
- * their own (like requiring sortedness or no overlap) they need to enforce it
- * themselves. Some of the internal methods also assume this is normalized as in no adjacent
- * or overlapping ranges are present.
- *
- * @hide
- */
- private ArraySet<UidRange> mUids = null;
-
- /**
- * Convenience method to set the UIDs this network applies to to a single UID.
- * @hide
- */
- public @NonNull NetworkCapabilities setSingleUid(int uid) {
- mUids = new ArraySet<>(1);
- mUids.add(new UidRange(uid, uid));
- return this;
- }
-
- /**
- * Set the list of UIDs this network applies to.
- * This makes a copy of the set so that callers can't modify it after the call.
- * @hide
- */
- public @NonNull NetworkCapabilities setUids(@Nullable Set<Range<Integer>> uids) {
- mUids = UidRange.fromIntRanges(uids);
- return this;
- }
-
- /**
- * Get the list of UIDs this network applies to.
- * This returns a copy of the set so that callers can't modify the original object.
- *
- * @return the list of UIDs this network applies to. If {@code null}, then the network applies
- * to all UIDs.
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- @SuppressLint("NullableCollection")
- public @Nullable Set<Range<Integer>> getUids() {
- return UidRange.toIntRanges(mUids);
- }
-
- /**
- * Get the list of UIDs this network applies to.
- * This returns a copy of the set so that callers can't modify the original object.
- * @hide
- */
- public @Nullable Set<UidRange> getUidRanges() {
- if (mUids == null) return null;
-
- return new ArraySet<>(mUids);
- }
-
- /**
- * Test whether this network applies to this UID.
- * @hide
- */
- public boolean appliesToUid(int uid) {
- if (null == mUids) return true;
- for (UidRange range : mUids) {
- if (range.contains(uid)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Tests if the set of UIDs that this network applies to is the same as the passed network.
- * <p>
- * This test only checks whether equal range objects are in both sets. It will
- * return false if the ranges are not exactly the same, even if the covered UIDs
- * are for an equivalent result.
- * <p>
- * Note that this method is not very optimized, which is fine as long as it's not used very
- * often.
- * <p>
- * nc is assumed nonnull.
- *
- * @hide
- */
- @VisibleForTesting
- public boolean equalsUids(@NonNull NetworkCapabilities nc) {
- Set<UidRange> comparedUids = nc.mUids;
- if (null == comparedUids) return null == mUids;
- if (null == mUids) return false;
- // Make a copy so it can be mutated to check that all ranges in mUids
- // also are in uids.
- final Set<UidRange> uids = new ArraySet<>(mUids);
- for (UidRange range : comparedUids) {
- if (!uids.contains(range)) {
- return false;
- }
- uids.remove(range);
- }
- return uids.isEmpty();
- }
-
- /**
- * Test whether the passed NetworkCapabilities satisfies the UIDs this capabilities require.
- *
- * This method is called on the NetworkCapabilities embedded in a request with the
- * capabilities of an available network. It checks whether all the UIDs from this listen
- * (representing the UIDs that must have access to the network) are satisfied by the UIDs
- * in the passed nc (representing the UIDs that this network is available to).
- * <p>
- * As a special exception, the UID that created the passed network (as represented by its
- * mOwnerUid field) always satisfies a NetworkRequest requiring it (of LISTEN
- * or REQUEST types alike), even if the network does not apply to it. That is so a VPN app
- * can see its own network when it listens for it.
- * <p>
- * nc is assumed nonnull. Else, NPE.
- * @see #appliesToUid
- * @hide
- */
- public boolean satisfiedByUids(@NonNull NetworkCapabilities nc) {
- if (null == nc.mUids || null == mUids) return true; // The network satisfies everything.
- for (UidRange requiredRange : mUids) {
- if (requiredRange.contains(nc.mOwnerUid)) return true;
- if (!nc.appliesToUidRange(requiredRange)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Returns whether this network applies to the passed ranges.
- * This assumes that to apply, the passed range has to be entirely contained
- * within one of the ranges this network applies to. If the ranges are not normalized,
- * this method may return false even though all required UIDs are covered because no
- * single range contained them all.
- * @hide
- */
- @VisibleForTesting
- public boolean appliesToUidRange(@Nullable UidRange requiredRange) {
- if (null == mUids) return true;
- for (UidRange uidRange : mUids) {
- if (uidRange.containsRange(requiredRange)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Combine the UIDs this network currently applies to with the UIDs the passed
- * NetworkCapabilities apply to.
- * nc is assumed nonnull.
- */
- private void combineUids(@NonNull NetworkCapabilities nc) {
- if (null == nc.mUids || null == mUids) {
- mUids = null;
- return;
- }
- mUids.addAll(nc.mUids);
- }
-
-
- /**
- * The SSID of the network, or null if not applicable or unknown.
- * <p>
- * This is filled in by wifi code.
- * @hide
- */
- private String mSSID;
-
- /**
- * Sets the SSID of this network.
- * @hide
- */
- public @NonNull NetworkCapabilities setSSID(@Nullable String ssid) {
- mSSID = ssid;
- return this;
- }
-
- /**
- * Gets the SSID of this network, or null if none or unknown.
- * @hide
- */
- @SystemApi
- public @Nullable String getSsid() {
- return mSSID;
- }
-
- /**
- * Tests if the SSID of this network is the same as the SSID of the passed network.
- * @hide
- */
- public boolean equalsSSID(@NonNull NetworkCapabilities nc) {
- return Objects.equals(mSSID, nc.mSSID);
- }
-
- /**
- * Check if the SSID requirements of this object are matched by the passed object.
- * @hide
- */
- public boolean satisfiedBySSID(@NonNull NetworkCapabilities nc) {
- return mSSID == null || mSSID.equals(nc.mSSID);
- }
-
- /**
- * Combine SSIDs of the capabilities.
- * <p>
- * This is only legal if either the SSID of this object is null, or both SSIDs are
- * equal.
- * @hide
- */
- private void combineSSIDs(@NonNull NetworkCapabilities nc) {
- if (mSSID != null && !mSSID.equals(nc.mSSID)) {
- throw new IllegalStateException("Can't combine two SSIDs");
- }
- setSSID(nc.mSSID);
- }
-
- /**
- * Combine a set of Capabilities to this one. Useful for coming up with the complete set.
- * <p>
- * Note that this method may break an invariant of having a particular capability in either
- * wanted or forbidden lists but never in both. Requests that have the same capability in
- * both lists will never be satisfied.
- * @hide
- */
- public void combineCapabilities(@NonNull NetworkCapabilities nc) {
- combineNetCapabilities(nc);
- combineTransportTypes(nc);
- combineLinkBandwidths(nc);
- combineSpecifiers(nc);
- combineTransportInfos(nc);
- combineSignalStrength(nc);
- combineUids(nc);
- combineSSIDs(nc);
- combineRequestor(nc);
- combineAdministratorUids(nc);
- combineSubscriptionIds(nc);
- }
-
- /**
- * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
- *
- * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
- * @param onlyImmutable if {@code true}, do not consider mutable requirements such as link
- * bandwidth, signal strength, or validation / captive portal status.
- *
- * @hide
- */
- private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
- return (nc != null
- && satisfiedByNetCapabilities(nc, onlyImmutable)
- && satisfiedByTransportTypes(nc)
- && (onlyImmutable || satisfiedByLinkBandwidths(nc))
- && satisfiedBySpecifier(nc)
- && (onlyImmutable || satisfiedBySignalStrength(nc))
- && (onlyImmutable || satisfiedByUids(nc))
- && (onlyImmutable || satisfiedBySSID(nc))
- && (onlyImmutable || satisfiedByRequestor(nc))
- && (onlyImmutable || satisfiedBySubscriptionIds(nc)));
- }
-
- /**
- * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
- *
- * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
- *
- * @hide
- */
- @SystemApi
- public boolean satisfiedByNetworkCapabilities(@Nullable NetworkCapabilities nc) {
- return satisfiedByNetworkCapabilities(nc, false);
- }
-
- /**
- * Check if our immutable requirements are satisfied by the given {@code NetworkCapabilities}.
- *
- * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
- *
- * @hide
- */
- public boolean satisfiedByImmutableNetworkCapabilities(@Nullable NetworkCapabilities nc) {
- return satisfiedByNetworkCapabilities(nc, true);
- }
-
- /**
- * Checks that our immutable capabilities are the same as those of the given
- * {@code NetworkCapabilities} and return a String describing any difference.
- * The returned String is empty if there is no difference.
- *
- * @hide
- */
- public String describeImmutableDifferences(@Nullable NetworkCapabilities that) {
- if (that == null) {
- return "other NetworkCapabilities was null";
- }
-
- StringJoiner joiner = new StringJoiner(", ");
-
- // Ignore NOT_METERED being added or removed as it is effectively dynamic. http://b/63326103
- // TODO: properly support NOT_METERED as a mutable and requestable capability.
- final long mask = ~MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_NOT_METERED);
- long oldImmutableCapabilities = this.mNetworkCapabilities & mask;
- long newImmutableCapabilities = that.mNetworkCapabilities & mask;
- if (oldImmutableCapabilities != newImmutableCapabilities) {
- String before = capabilityNamesOf(NetworkCapabilitiesUtils.unpackBits(
- oldImmutableCapabilities));
- String after = capabilityNamesOf(NetworkCapabilitiesUtils.unpackBits(
- newImmutableCapabilities));
- joiner.add(String.format("immutable capabilities changed: %s -> %s", before, after));
- }
-
- if (!equalsSpecifier(that)) {
- NetworkSpecifier before = this.getNetworkSpecifier();
- NetworkSpecifier after = that.getNetworkSpecifier();
- joiner.add(String.format("specifier changed: %s -> %s", before, after));
- }
-
- if (!equalsTransportTypes(that)) {
- String before = transportNamesOf(this.getTransportTypes());
- String after = transportNamesOf(that.getTransportTypes());
- joiner.add(String.format("transports changed: %s -> %s", before, after));
- }
-
- return joiner.toString();
- }
-
- /**
- * Checks that our requestable capabilities are the same as those of the given
- * {@code NetworkCapabilities}.
- *
- * @hide
- */
- public boolean equalRequestableCapabilities(@Nullable NetworkCapabilities nc) {
- if (nc == null) return false;
- return (equalsNetCapabilitiesRequestable(nc)
- && equalsTransportTypes(nc)
- && equalsSpecifier(nc));
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
- NetworkCapabilities that = (NetworkCapabilities) obj;
- return equalsNetCapabilities(that)
- && equalsTransportTypes(that)
- && equalsLinkBandwidths(that)
- && equalsSignalStrength(that)
- && equalsSpecifier(that)
- && equalsTransportInfo(that)
- && equalsUids(that)
- && equalsSSID(that)
- && equalsOwnerUid(that)
- && equalsPrivateDnsBroken(that)
- && equalsRequestor(that)
- && equalsAdministratorUids(that)
- && equalsSubscriptionIds(that);
- }
-
- @Override
- public int hashCode() {
- return (int) (mNetworkCapabilities & 0xFFFFFFFF)
- + ((int) (mNetworkCapabilities >> 32) * 3)
- + ((int) (mForbiddenNetworkCapabilities & 0xFFFFFFFF) * 5)
- + ((int) (mForbiddenNetworkCapabilities >> 32) * 7)
- + ((int) (mTransportTypes & 0xFFFFFFFF) * 11)
- + ((int) (mTransportTypes >> 32) * 13)
- + mLinkUpBandwidthKbps * 17
- + mLinkDownBandwidthKbps * 19
- + Objects.hashCode(mNetworkSpecifier) * 23
- + mSignalStrength * 29
- + mOwnerUid * 31
- + Objects.hashCode(mUids) * 37
- + Objects.hashCode(mSSID) * 41
- + Objects.hashCode(mTransportInfo) * 43
- + Objects.hashCode(mPrivateDnsBroken) * 47
- + Objects.hashCode(mRequestorUid) * 53
- + Objects.hashCode(mRequestorPackageName) * 59
- + Arrays.hashCode(mAdministratorUids) * 61
- + Objects.hashCode(mSubIds) * 67;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- private <T extends Parcelable> void writeParcelableArraySet(Parcel in,
- @Nullable ArraySet<T> val, int flags) {
- final int size = (val != null) ? val.size() : -1;
- in.writeInt(size);
- for (int i = 0; i < size; i++) {
- in.writeParcelable(val.valueAt(i), flags);
- }
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(mNetworkCapabilities);
- dest.writeLong(mForbiddenNetworkCapabilities);
- dest.writeLong(mTransportTypes);
- dest.writeInt(mLinkUpBandwidthKbps);
- dest.writeInt(mLinkDownBandwidthKbps);
- dest.writeParcelable((Parcelable) mNetworkSpecifier, flags);
- dest.writeParcelable((Parcelable) mTransportInfo, flags);
- dest.writeInt(mSignalStrength);
- writeParcelableArraySet(dest, mUids, flags);
- dest.writeString(mSSID);
- dest.writeBoolean(mPrivateDnsBroken);
- dest.writeIntArray(getAdministratorUids());
- dest.writeInt(mOwnerUid);
- dest.writeInt(mRequestorUid);
- dest.writeString(mRequestorPackageName);
- dest.writeIntArray(CollectionUtils.toIntArray(mSubIds));
- }
-
- public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
- new Creator<NetworkCapabilities>() {
- @Override
- public NetworkCapabilities createFromParcel(Parcel in) {
- NetworkCapabilities netCap = new NetworkCapabilities();
-
- netCap.mNetworkCapabilities = in.readLong();
- netCap.mForbiddenNetworkCapabilities = in.readLong();
- netCap.mTransportTypes = in.readLong();
- netCap.mLinkUpBandwidthKbps = in.readInt();
- netCap.mLinkDownBandwidthKbps = in.readInt();
- netCap.mNetworkSpecifier = in.readParcelable(null);
- netCap.mTransportInfo = in.readParcelable(null);
- netCap.mSignalStrength = in.readInt();
- netCap.mUids = readParcelableArraySet(in, null /* ClassLoader, null for default */);
- netCap.mSSID = in.readString();
- netCap.mPrivateDnsBroken = in.readBoolean();
- netCap.setAdministratorUids(in.createIntArray());
- netCap.mOwnerUid = in.readInt();
- netCap.mRequestorUid = in.readInt();
- netCap.mRequestorPackageName = in.readString();
- netCap.mSubIds = new ArraySet<>();
- final int[] subIdInts = Objects.requireNonNull(in.createIntArray());
- for (int i = 0; i < subIdInts.length; i++) {
- netCap.mSubIds.add(subIdInts[i]);
- }
- return netCap;
- }
- @Override
- public NetworkCapabilities[] newArray(int size) {
- return new NetworkCapabilities[size];
- }
-
- private @Nullable <T extends Parcelable> ArraySet<T> readParcelableArraySet(Parcel in,
- @Nullable ClassLoader loader) {
- final int size = in.readInt();
- if (size < 0) {
- return null;
- }
- final ArraySet<T> result = new ArraySet<>(size);
- for (int i = 0; i < size; i++) {
- final T value = in.readParcelable(loader);
- result.add(value);
- }
- return result;
- }
- };
-
- @Override
- public @NonNull String toString() {
- final StringBuilder sb = new StringBuilder("[");
- if (0 != mTransportTypes) {
- sb.append(" Transports: ");
- appendStringRepresentationOfBitMaskToStringBuilder(sb, mTransportTypes,
- NetworkCapabilities::transportNameOf, "|");
- }
- if (0 != mNetworkCapabilities) {
- sb.append(" Capabilities: ");
- appendStringRepresentationOfBitMaskToStringBuilder(sb, mNetworkCapabilities,
- NetworkCapabilities::capabilityNameOf, "&");
- }
- if (0 != mForbiddenNetworkCapabilities) {
- sb.append(" Forbidden: ");
- appendStringRepresentationOfBitMaskToStringBuilder(sb, mForbiddenNetworkCapabilities,
- NetworkCapabilities::capabilityNameOf, "&");
- }
- if (mLinkUpBandwidthKbps > 0) {
- sb.append(" LinkUpBandwidth>=").append(mLinkUpBandwidthKbps).append("Kbps");
- }
- if (mLinkDownBandwidthKbps > 0) {
- sb.append(" LinkDnBandwidth>=").append(mLinkDownBandwidthKbps).append("Kbps");
- }
- if (mNetworkSpecifier != null) {
- sb.append(" Specifier: <").append(mNetworkSpecifier).append(">");
- }
- if (mTransportInfo != null) {
- sb.append(" TransportInfo: <").append(mTransportInfo).append(">");
- }
- if (hasSignalStrength()) {
- sb.append(" SignalStrength: ").append(mSignalStrength);
- }
-
- if (null != mUids) {
- if ((1 == mUids.size()) && (mUids.valueAt(0).count() == 1)) {
- sb.append(" Uid: ").append(mUids.valueAt(0).start);
- } else {
- sb.append(" Uids: <").append(mUids).append(">");
- }
- }
- if (mOwnerUid != Process.INVALID_UID) {
- sb.append(" OwnerUid: ").append(mOwnerUid);
- }
-
- if (mAdministratorUids != null && mAdministratorUids.length != 0) {
- sb.append(" AdminUids: ").append(Arrays.toString(mAdministratorUids));
- }
-
- if (mRequestorUid != Process.INVALID_UID) {
- sb.append(" RequestorUid: ").append(mRequestorUid);
- }
-
- if (mRequestorPackageName != null) {
- sb.append(" RequestorPkg: ").append(mRequestorPackageName);
- }
-
- if (null != mSSID) {
- sb.append(" SSID: ").append(mSSID);
- }
-
- if (mPrivateDnsBroken) {
- sb.append(" PrivateDnsBroken");
- }
-
- if (!mSubIds.isEmpty()) {
- sb.append(" SubscriptionIds: ").append(mSubIds);
- }
-
- sb.append("]");
- return sb.toString();
- }
-
-
- private interface NameOf {
- String nameOf(int value);
- }
-
- /**
- * @hide
- */
- public static void appendStringRepresentationOfBitMaskToStringBuilder(@NonNull StringBuilder sb,
- long bitMask, @NonNull NameOf nameFetcher, @NonNull String separator) {
- int bitPos = 0;
- boolean firstElementAdded = false;
- while (bitMask != 0) {
- if ((bitMask & 1) != 0) {
- if (firstElementAdded) {
- sb.append(separator);
- } else {
- firstElementAdded = true;
- }
- sb.append(nameFetcher.nameOf(bitPos));
- }
- bitMask >>= 1;
- ++bitPos;
- }
- }
-
- /**
- * @hide
- */
- public static @NonNull String capabilityNamesOf(@Nullable @NetCapability int[] capabilities) {
- StringJoiner joiner = new StringJoiner("|");
- if (capabilities != null) {
- for (int c : capabilities) {
- joiner.add(capabilityNameOf(c));
- }
- }
- return joiner.toString();
- }
-
- /**
- * @hide
- */
- public static @NonNull String capabilityNameOf(@NetCapability int capability) {
- switch (capability) {
- case NET_CAPABILITY_MMS: return "MMS";
- case NET_CAPABILITY_SUPL: return "SUPL";
- case NET_CAPABILITY_DUN: return "DUN";
- case NET_CAPABILITY_FOTA: return "FOTA";
- case NET_CAPABILITY_IMS: return "IMS";
- case NET_CAPABILITY_CBS: return "CBS";
- case NET_CAPABILITY_WIFI_P2P: return "WIFI_P2P";
- case NET_CAPABILITY_IA: return "IA";
- case NET_CAPABILITY_RCS: return "RCS";
- case NET_CAPABILITY_XCAP: return "XCAP";
- case NET_CAPABILITY_EIMS: return "EIMS";
- case NET_CAPABILITY_NOT_METERED: return "NOT_METERED";
- case NET_CAPABILITY_INTERNET: return "INTERNET";
- case NET_CAPABILITY_NOT_RESTRICTED: return "NOT_RESTRICTED";
- case NET_CAPABILITY_TRUSTED: return "TRUSTED";
- case NET_CAPABILITY_NOT_VPN: return "NOT_VPN";
- case NET_CAPABILITY_VALIDATED: return "VALIDATED";
- case NET_CAPABILITY_CAPTIVE_PORTAL: return "CAPTIVE_PORTAL";
- case NET_CAPABILITY_NOT_ROAMING: return "NOT_ROAMING";
- case NET_CAPABILITY_FOREGROUND: return "FOREGROUND";
- case NET_CAPABILITY_NOT_CONGESTED: return "NOT_CONGESTED";
- case NET_CAPABILITY_NOT_SUSPENDED: return "NOT_SUSPENDED";
- case NET_CAPABILITY_OEM_PAID: return "OEM_PAID";
- case NET_CAPABILITY_MCX: return "MCX";
- case NET_CAPABILITY_PARTIAL_CONNECTIVITY: return "PARTIAL_CONNECTIVITY";
- case NET_CAPABILITY_TEMPORARILY_NOT_METERED: return "TEMPORARILY_NOT_METERED";
- case NET_CAPABILITY_OEM_PRIVATE: return "OEM_PRIVATE";
- case NET_CAPABILITY_VEHICLE_INTERNAL: return "VEHICLE_INTERNAL";
- case NET_CAPABILITY_NOT_VCN_MANAGED: return "NOT_VCN_MANAGED";
- case NET_CAPABILITY_ENTERPRISE: return "ENTERPRISE";
- case NET_CAPABILITY_VSIM: return "VSIM";
- case NET_CAPABILITY_BIP: return "BIP";
- case NET_CAPABILITY_HEAD_UNIT: return "HEAD_UNIT";
- default: return Integer.toString(capability);
- }
- }
-
- /**
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static @NonNull String transportNamesOf(@Nullable @Transport int[] types) {
- StringJoiner joiner = new StringJoiner("|");
- if (types != null) {
- for (int t : types) {
- joiner.add(transportNameOf(t));
- }
- }
- return joiner.toString();
- }
-
- /**
- * @hide
- */
- public static @NonNull String transportNameOf(@Transport int transport) {
- if (!isValidTransport(transport)) {
- return "UNKNOWN";
- }
- return TRANSPORT_NAMES[transport];
- }
-
- private static void checkValidTransportType(@Transport int transport) {
- if (!isValidTransport(transport)) {
- throw new IllegalArgumentException("Invalid TransportType " + transport);
- }
- }
-
- private static boolean isValidCapability(@NetworkCapabilities.NetCapability int capability) {
- return capability >= MIN_NET_CAPABILITY && capability <= MAX_NET_CAPABILITY;
- }
-
- private static void checkValidCapability(@NetworkCapabilities.NetCapability int capability) {
- if (!isValidCapability(capability)) {
- throw new IllegalArgumentException("NetworkCapability " + capability + "out of range");
- }
- }
-
- /**
- * Check if this {@code NetworkCapability} instance is metered.
- *
- * @return {@code true} if {@code NET_CAPABILITY_NOT_METERED} is not set on this instance.
- * @hide
- */
- public boolean isMetered() {
- return !hasCapability(NET_CAPABILITY_NOT_METERED);
- }
-
- /**
- * Check if private dns is broken.
- *
- * @return {@code true} if private DNS is broken on this network.
- * @hide
- */
- @SystemApi
- public boolean isPrivateDnsBroken() {
- return mPrivateDnsBroken;
- }
-
- /**
- * Set mPrivateDnsBroken to true when private dns is broken.
- *
- * @param broken the status of private DNS to be set.
- * @hide
- */
- public void setPrivateDnsBroken(boolean broken) {
- mPrivateDnsBroken = broken;
- }
-
- private boolean equalsPrivateDnsBroken(NetworkCapabilities nc) {
- return mPrivateDnsBroken == nc.mPrivateDnsBroken;
- }
-
- /**
- * Set the UID of the app making the request.
- *
- * For instances of NetworkCapabilities representing a request, sets the
- * UID of the app making the request. For a network created by the system,
- * sets the UID of the only app whose requests can match this network.
- * This can be set to {@link Process#INVALID_UID} if there is no such app,
- * or if this instance of NetworkCapabilities is about to be sent to a
- * party that should not learn about this.
- *
- * @param uid UID of the app.
- * @hide
- */
- public @NonNull NetworkCapabilities setRequestorUid(int uid) {
- mRequestorUid = uid;
- return this;
- }
-
- /**
- * Returns the UID of the app making the request.
- *
- * For a NetworkRequest being made by an app, contains the app's UID. For a network
- * created by the system, contains the UID of the only app whose requests can match
- * this network, or {@link Process#INVALID_UID} if none or if the
- * caller does not have permission to learn about this.
- *
- * @return the uid of the app making the request.
- * @hide
- */
- public int getRequestorUid() {
- return mRequestorUid;
- }
-
- /**
- * Set the package name of the app making the request.
- *
- * For instances of NetworkCapabilities representing a request, sets the
- * package name of the app making the request. For a network created by the system,
- * sets the package name of the only app whose requests can match this network.
- * This can be set to null if there is no such app, or if this instance of
- * NetworkCapabilities is about to be sent to a party that should not learn about this.
- *
- * @param packageName package name of the app.
- * @hide
- */
- public @NonNull NetworkCapabilities setRequestorPackageName(@NonNull String packageName) {
- mRequestorPackageName = packageName;
- return this;
- }
-
- /**
- * Returns the package name of the app making the request.
- *
- * For a NetworkRequest being made by an app, contains the app's package name. For a
- * network created by the system, contains the package name of the only app whose
- * requests can match this network, or null if none or if the caller does not have
- * permission to learn about this.
- *
- * @return the package name of the app making the request.
- * @hide
- */
- @Nullable
- public String getRequestorPackageName() {
- return mRequestorPackageName;
- }
-
- /**
- * Set the uid and package name of the app causing this network to exist.
- *
- * {@see #setRequestorUid} and {@link #setRequestorPackageName}
- *
- * @param uid UID of the app.
- * @param packageName package name of the app.
- * @hide
- */
- public @NonNull NetworkCapabilities setRequestorUidAndPackageName(
- int uid, @NonNull String packageName) {
- return setRequestorUid(uid).setRequestorPackageName(packageName);
- }
-
- /**
- * Test whether the passed NetworkCapabilities satisfies the requestor restrictions of this
- * capabilities.
- *
- * This method is called on the NetworkCapabilities embedded in a request with the
- * capabilities of an available network. If the available network, sets a specific
- * requestor (by uid and optionally package name), then this will only match a request from the
- * same app. If either of the capabilities have an unset uid or package name, then it matches
- * everything.
- * <p>
- * nc is assumed nonnull. Else, NPE.
- */
- private boolean satisfiedByRequestor(NetworkCapabilities nc) {
- // No uid set, matches everything.
- if (mRequestorUid == Process.INVALID_UID || nc.mRequestorUid == Process.INVALID_UID) {
- return true;
- }
- // uids don't match.
- if (mRequestorUid != nc.mRequestorUid) return false;
- // No package names set, matches everything
- if (null == nc.mRequestorPackageName || null == mRequestorPackageName) return true;
- // check for package name match.
- return TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName);
- }
-
- /**
- * Combine requestor info of the capabilities.
- * <p>
- * This is only legal if either the requestor info of this object is reset, or both info are
- * equal.
- * nc is assumed nonnull.
- */
- private void combineRequestor(@NonNull NetworkCapabilities nc) {
- if (mRequestorUid != Process.INVALID_UID && mRequestorUid != nc.mOwnerUid) {
- throw new IllegalStateException("Can't combine two uids");
- }
- if (mRequestorPackageName != null
- && !mRequestorPackageName.equals(nc.mRequestorPackageName)) {
- throw new IllegalStateException("Can't combine two package names");
- }
- setRequestorUid(nc.mRequestorUid);
- setRequestorPackageName(nc.mRequestorPackageName);
- }
-
- private boolean equalsRequestor(NetworkCapabilities nc) {
- return mRequestorUid == nc.mRequestorUid
- && TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName);
- }
-
- /**
- * Set of the subscription IDs that identifies the network or request, empty if none.
- */
- @NonNull
- private ArraySet<Integer> mSubIds = new ArraySet<>();
-
- /**
- * Sets the subscription ID set that associated to this network or request.
- *
- * @hide
- */
- @NonNull
- public NetworkCapabilities setSubscriptionIds(@NonNull Set<Integer> subIds) {
- mSubIds = new ArraySet(Objects.requireNonNull(subIds));
- return this;
- }
-
- /**
- * Gets the subscription ID set that associated to this network or request.
- *
- * <p>Instances of NetworkCapabilities will only have this field populated by the system if the
- * receiver holds the NETWORK_FACTORY permission. In all other cases, it will be the empty set.
- *
- * @return
- * @hide
- */
- @NonNull
- @SystemApi
- public Set<Integer> getSubscriptionIds() {
- return new ArraySet<>(mSubIds);
- }
-
- /**
- * Tests if the subscription ID set of this network is the same as that of the passed one.
- */
- private boolean equalsSubscriptionIds(@NonNull NetworkCapabilities nc) {
- return Objects.equals(mSubIds, nc.mSubIds);
- }
-
- /**
- * Check if the subscription ID set requirements of this object are matched by the passed one.
- * If specified in the request, the passed one need to have at least one subId and at least
- * one of them needs to be in the request set.
- */
- private boolean satisfiedBySubscriptionIds(@NonNull NetworkCapabilities nc) {
- if (mSubIds.isEmpty()) return true;
- if (nc.mSubIds.isEmpty()) return false;
- for (final Integer subId : nc.mSubIds) {
- if (mSubIds.contains(subId)) return true;
- }
- return false;
- }
-
- /**
- * Combine subscription ID set of the capabilities.
- *
- * <p>This is only legal if the subscription Ids are equal.
- *
- * <p>If both subscription IDs are not equal, they belong to different subscription
- * (or no subscription). In this case, it would not make sense to add them together.
- */
- private void combineSubscriptionIds(@NonNull NetworkCapabilities nc) {
- if (!Objects.equals(mSubIds, nc.mSubIds)) {
- throw new IllegalStateException("Can't combine two subscription ID sets");
- }
- }
-
- /**
- * Returns a bitmask of all the applicable redactions (based on the permissions held by the
- * receiving app) to be performed on this object.
- *
- * @return bitmask of redactions applicable on this instance.
- * @hide
- */
- public @RedactionType long getApplicableRedactions() {
- // Currently, there are no fields redacted in NetworkCapabilities itself, so we just
- // passthrough the redactions required by the embedded TransportInfo. If this changes
- // in the future, modify this method.
- if (mTransportInfo == null) {
- return NetworkCapabilities.REDACT_NONE;
- }
- return mTransportInfo.getApplicableRedactions();
- }
-
- private NetworkCapabilities removeDefaultCapabilites() {
- mNetworkCapabilities &= ~DEFAULT_CAPABILITIES;
- return this;
- }
-
- /**
- * Builder class for NetworkCapabilities.
- *
- * This class is mainly for for {@link NetworkAgent} instances to use. Many fields in
- * the built class require holding a signature permission to use - mostly
- * {@link android.Manifest.permission.NETWORK_FACTORY}, but refer to the specific
- * description of each setter. As this class lives entirely in app space it does not
- * enforce these restrictions itself but the system server clears out the relevant
- * fields when receiving a NetworkCapabilities object from a caller without the
- * appropriate permission.
- *
- * Apps don't use this builder directly. Instead, they use {@link NetworkRequest} via
- * its builder object.
- *
- * @hide
- */
- @SystemApi
- public static final class Builder {
- private final NetworkCapabilities mCaps;
-
- /**
- * Creates a new Builder to construct NetworkCapabilities objects.
- */
- public Builder() {
- mCaps = new NetworkCapabilities();
- }
-
- /**
- * Creates a new Builder of NetworkCapabilities from an existing instance.
- */
- public Builder(@NonNull final NetworkCapabilities nc) {
- Objects.requireNonNull(nc);
- mCaps = new NetworkCapabilities(nc);
- }
-
- /**
- * Creates a new Builder without the default capabilities.
- */
- @NonNull
- public static Builder withoutDefaultCapabilities() {
- final NetworkCapabilities nc = new NetworkCapabilities();
- nc.removeDefaultCapabilites();
- return new Builder(nc);
- }
-
- /**
- * Adds the given transport type.
- *
- * Multiple transports may be added. Note that when searching for a network to satisfy a
- * request, satisfying any of the transports listed in the request will satisfy the request.
- * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
- * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
- * to be selected. This is logically different than
- * {@code NetworkCapabilities.NET_CAPABILITY_*}. Also note that multiple networks with the
- * same transport type may be active concurrently.
- *
- * @param transportType the transport type to be added or removed.
- * @return this builder
- */
- @NonNull
- public Builder addTransportType(@Transport int transportType) {
- checkValidTransportType(transportType);
- mCaps.addTransportType(transportType);
- return this;
- }
-
- /**
- * Removes the given transport type.
- *
- * {@see #addTransportType}.
- *
- * @param transportType the transport type to be added or removed.
- * @return this builder
- */
- @NonNull
- public Builder removeTransportType(@Transport int transportType) {
- checkValidTransportType(transportType);
- mCaps.removeTransportType(transportType);
- return this;
- }
-
- /**
- * Adds the given capability.
- *
- * @param capability the capability
- * @return this builder
- */
- @NonNull
- public Builder addCapability(@NetCapability final int capability) {
- mCaps.setCapability(capability, true);
- return this;
- }
-
- /**
- * Removes the given capability.
- *
- * @param capability the capability
- * @return this builder
- */
- @NonNull
- public Builder removeCapability(@NetCapability final int capability) {
- mCaps.setCapability(capability, false);
- return this;
- }
-
- /**
- * Sets the owner UID.
- *
- * The default value is {@link Process#INVALID_UID}. Pass this value to reset.
- *
- * Note: for security the system will clear out this field when received from a
- * non-privileged source.
- *
- * @param ownerUid the owner UID
- * @return this builder
- */
- @NonNull
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
- public Builder setOwnerUid(final int ownerUid) {
- mCaps.setOwnerUid(ownerUid);
- return this;
- }
-
- /**
- * Sets the list of UIDs that are administrators of this network.
- *
- * <p>UIDs included in administratorUids gain administrator privileges over this
- * Network. Examples of UIDs that should be included in administratorUids are:
- * <ul>
- * <li>Carrier apps with privileges for the relevant subscription
- * <li>Active VPN apps
- * <li>Other application groups with a particular Network-related role
- * </ul>
- *
- * <p>In general, user-supplied networks (such as WiFi networks) do not have
- * administrators.
- *
- * <p>An app is granted owner privileges over Networks that it supplies. The owner
- * UID MUST always be included in administratorUids.
- *
- * The default value is the empty array. Pass an empty array to reset.
- *
- * Note: for security the system will clear out this field when received from a
- * non-privileged source, such as an app using reflection to call this or
- * mutate the member in the built object.
- *
- * @param administratorUids the UIDs to be set as administrators of this Network.
- * @return this builder
- */
- @NonNull
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
- public Builder setAdministratorUids(@NonNull final int[] administratorUids) {
- Objects.requireNonNull(administratorUids);
- mCaps.setAdministratorUids(administratorUids);
- return this;
- }
-
- /**
- * Sets the upstream bandwidth of the link.
- *
- * Sets the upstream bandwidth for this network in Kbps. This always only refers to
- * the estimated first hop transport bandwidth.
- * <p>
- * Note that when used to request a network, this specifies the minimum acceptable.
- * When received as the state of an existing network this specifies the typical
- * first hop bandwidth expected. This is never measured, but rather is inferred
- * from technology type and other link parameters. It could be used to differentiate
- * between very slow 1xRTT cellular links and other faster networks or even between
- * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
- * fast backhauls and slow backhauls.
- *
- * @param upKbps the estimated first hop upstream (device to network) bandwidth.
- * @return this builder
- */
- @NonNull
- public Builder setLinkUpstreamBandwidthKbps(final int upKbps) {
- mCaps.setLinkUpstreamBandwidthKbps(upKbps);
- return this;
- }
-
- /**
- * Sets the downstream bandwidth for this network in Kbps. This always only refers to
- * the estimated first hop transport bandwidth.
- * <p>
- * Note that when used to request a network, this specifies the minimum acceptable.
- * When received as the state of an existing network this specifies the typical
- * first hop bandwidth expected. This is never measured, but rather is inferred
- * from technology type and other link parameters. It could be used to differentiate
- * between very slow 1xRTT cellular links and other faster networks or even between
- * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
- * fast backhauls and slow backhauls.
- *
- * @param downKbps the estimated first hop downstream (network to device) bandwidth.
- * @return this builder
- */
- @NonNull
- public Builder setLinkDownstreamBandwidthKbps(final int downKbps) {
- mCaps.setLinkDownstreamBandwidthKbps(downKbps);
- return this;
- }
-
- /**
- * Sets the optional bearer specific network specifier.
- * This has no meaning if a single transport is also not specified, so calling
- * this without a single transport set will generate an exception, as will
- * subsequently adding or removing transports after this is set.
- * </p>
- *
- * @param specifier a concrete, parcelable framework class that extends NetworkSpecifier,
- * or null to clear it.
- * @return this builder
- */
- @NonNull
- public Builder setNetworkSpecifier(@Nullable final NetworkSpecifier specifier) {
- mCaps.setNetworkSpecifier(specifier);
- return this;
- }
-
- /**
- * Sets the optional transport specific information.
- *
- * @param info A concrete, parcelable framework class that extends {@link TransportInfo},
- * or null to clear it.
- * @return this builder
- */
- @NonNull
- public Builder setTransportInfo(@Nullable final TransportInfo info) {
- mCaps.setTransportInfo(info);
- return this;
- }
-
- /**
- * Sets the signal strength. This is a signed integer, with higher values indicating a
- * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the
- * same RSSI units reported by wifi code.
- * <p>
- * Note that when used to register a network callback, this specifies the minimum
- * acceptable signal strength. When received as the state of an existing network it
- * specifies the current value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means
- * no value when received and has no effect when requesting a callback.
- *
- * Note: for security the system will throw if it receives a NetworkRequest where
- * the underlying NetworkCapabilities has this member set from a source that does
- * not hold the {@link android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP}
- * permission. Apps with this permission can use this indirectly through
- * {@link android.net.NetworkRequest}.
- *
- * @param signalStrength the bearer-specific signal strength.
- * @return this builder
- */
- @NonNull
- @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP)
- public Builder setSignalStrength(final int signalStrength) {
- mCaps.setSignalStrength(signalStrength);
- return this;
- }
-
- /**
- * Sets the SSID of this network.
- *
- * Note: for security the system will clear out this field when received from a
- * non-privileged source, like an app using reflection to set this.
- *
- * @param ssid the SSID, or null to clear it.
- * @return this builder
- */
- @NonNull
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
- public Builder setSsid(@Nullable final String ssid) {
- mCaps.setSSID(ssid);
- return this;
- }
-
- /**
- * Set the uid of the app causing this network to exist.
- *
- * Note: for security the system will clear out this field when received from a
- * non-privileged source.
- *
- * @param uid UID of the app.
- * @return this builder
- */
- @NonNull
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
- public Builder setRequestorUid(final int uid) {
- mCaps.setRequestorUid(uid);
- return this;
- }
-
- /**
- * Set the package name of the app causing this network to exist.
- *
- * Note: for security the system will clear out this field when received from a
- * non-privileged source.
- *
- * @param packageName package name of the app, or null to clear it.
- * @return this builder
- */
- @NonNull
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
- public Builder setRequestorPackageName(@Nullable final String packageName) {
- mCaps.setRequestorPackageName(packageName);
- return this;
- }
-
- /**
- * Set the subscription ID set.
- *
- * <p>SubIds are populated in NetworkCapability instances from the system only for callers
- * that hold the NETWORK_FACTORY permission. Similarly, the system will reject any
- * NetworkRequests filed with a non-empty set of subIds unless the caller holds the
- * NETWORK_FACTORY permission.
- *
- * @param subIds a set that represent the subscription IDs. Empty if clean up.
- * @return this builder.
- * @hide
- */
- @NonNull
- @SystemApi
- public Builder setSubscriptionIds(@NonNull final Set<Integer> subIds) {
- mCaps.setSubscriptionIds(subIds);
- return this;
- }
-
- /**
- * Set the list of UIDs this network applies to.
- *
- * @param uids the list of UIDs this network applies to, or {@code null} if this network
- * applies to all UIDs.
- * @return this builder
- * @hide
- */
- @NonNull
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public Builder setUids(@Nullable Set<Range<Integer>> uids) {
- mCaps.setUids(uids);
- return this;
- }
-
- /**
- * Builds the instance of the capabilities.
- *
- * @return the built instance of NetworkCapabilities.
- */
- @NonNull
- public NetworkCapabilities build() {
- if (mCaps.getOwnerUid() != Process.INVALID_UID) {
- if (!CollectionUtils.contains(mCaps.getAdministratorUids(), mCaps.getOwnerUid())) {
- throw new IllegalStateException("The owner UID must be included in "
- + " administrator UIDs.");
- }
- }
- return new NetworkCapabilities(mCaps);
- }
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkConfig.java b/packages/Connectivity/framework/src/android/net/NetworkConfig.java
deleted file mode 100644
index 32a2cda..0000000
--- a/packages/Connectivity/framework/src/android/net/NetworkConfig.java
+++ /dev/null
@@ -1,80 +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 java.util.Locale;
-
-/**
- * Describes the buildtime configuration of a network.
- * Holds settings read from resources.
- * @hide
- */
-public class NetworkConfig {
- /**
- * Human readable string
- */
- public String name;
-
- /**
- * Type from ConnectivityManager
- */
- public int type;
-
- /**
- * the radio number from radio attributes config
- */
- public int radio;
-
- /**
- * higher number == higher priority when turning off connections
- */
- public int priority;
-
- /**
- * indicates the boot time dependencyMet setting
- */
- public boolean dependencyMet;
-
- /**
- * indicates the default restoral timer in seconds
- * if the network is used as a special network feature
- * -1 indicates no restoration of default
- */
- public int restoreTime;
-
- /**
- * input string from config.xml resource. Uses the form:
- * [Connection name],[ConnectivityManager connection type],
- * [associated radio-type],[priority],[dependencyMet]
- */
- public NetworkConfig(String init) {
- String fragments[] = init.split(",");
- name = fragments[0].trim().toLowerCase(Locale.ROOT);
- type = Integer.parseInt(fragments[1]);
- radio = Integer.parseInt(fragments[2]);
- priority = Integer.parseInt(fragments[3]);
- restoreTime = Integer.parseInt(fragments[4]);
- dependencyMet = Boolean.parseBoolean(fragments[5]);
- }
-
- /**
- * Indicates if this network is supposed to be default-routable
- */
- public boolean isDefault() {
- return (type == radio);
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkInfo.java b/packages/Connectivity/framework/src/android/net/NetworkInfo.java
deleted file mode 100644
index bb23494..0000000
--- a/packages/Connectivity/framework/src/android/net/NetworkInfo.java
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
- * Copyright (C) 2008 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.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.EnumMap;
-
-/**
- * Describes the status of a network interface.
- * <p>Use {@link ConnectivityManager#getActiveNetworkInfo()} to get an instance that represents
- * the current network connection.
- *
- * @deprecated Callers should instead use the {@link ConnectivityManager.NetworkCallback} API to
- * learn about connectivity changes, or switch to use
- * {@link ConnectivityManager#getNetworkCapabilities} or
- * {@link ConnectivityManager#getLinkProperties} to get information synchronously. Keep
- * in mind that while callbacks are guaranteed to be called for every event in order,
- * synchronous calls have no such constraints, and as such it is unadvisable to use the
- * synchronous methods inside the callbacks as they will often not offer a view of
- * networking that is consistent (that is: they may return a past or a future state with
- * respect to the event being processed by the callback). Instead, callers are advised
- * to only use the arguments of the callbacks, possibly memorizing the specific bits of
- * information they need to keep from one callback to another.
- */
-@Deprecated
-public class NetworkInfo implements Parcelable {
-
- /**
- * Coarse-grained network state. This is probably what most applications should
- * use, rather than {@link android.net.NetworkInfo.DetailedState DetailedState}.
- * The mapping between the two is as follows:
- * <br/><br/>
- * <table>
- * <tr><td><b>Detailed state</b></td><td><b>Coarse-grained state</b></td></tr>
- * <tr><td><code>IDLE</code></td><td><code>DISCONNECTED</code></td></tr>
- * <tr><td><code>SCANNING</code></td><td><code>DISCONNECTED</code></td></tr>
- * <tr><td><code>CONNECTING</code></td><td><code>CONNECTING</code></td></tr>
- * <tr><td><code>AUTHENTICATING</code></td><td><code>CONNECTING</code></td></tr>
- * <tr><td><code>OBTAINING_IPADDR</code></td><td><code>CONNECTING</code></td></tr>
- * <tr><td><code>VERIFYING_POOR_LINK</code></td><td><code>CONNECTING</code></td></tr>
- * <tr><td><code>CAPTIVE_PORTAL_CHECK</code></td><td><code>CONNECTING</code></td></tr>
- * <tr><td><code>CONNECTED</code></td><td><code>CONNECTED</code></td></tr>
- * <tr><td><code>SUSPENDED</code></td><td><code>SUSPENDED</code></td></tr>
- * <tr><td><code>DISCONNECTING</code></td><td><code>DISCONNECTING</code></td></tr>
- * <tr><td><code>DISCONNECTED</code></td><td><code>DISCONNECTED</code></td></tr>
- * <tr><td><code>FAILED</code></td><td><code>DISCONNECTED</code></td></tr>
- * <tr><td><code>BLOCKED</code></td><td><code>DISCONNECTED</code></td></tr>
- * </table>
- *
- * @deprecated See {@link NetworkInfo}.
- */
- @Deprecated
- public enum State {
- CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN
- }
-
- /**
- * The fine-grained state of a network connection. This level of detail
- * is probably of interest to few applications. Most should use
- * {@link android.net.NetworkInfo.State State} instead.
- *
- * @deprecated See {@link NetworkInfo}.
- */
- @Deprecated
- public enum DetailedState {
- /** Ready to start data connection setup. */
- IDLE,
- /** Searching for an available access point. */
- SCANNING,
- /** Currently setting up data connection. */
- CONNECTING,
- /** Network link established, performing authentication. */
- AUTHENTICATING,
- /** Awaiting response from DHCP server in order to assign IP address information. */
- OBTAINING_IPADDR,
- /** IP traffic should be available. */
- CONNECTED,
- /** IP traffic is suspended */
- SUSPENDED,
- /** Currently tearing down data connection. */
- DISCONNECTING,
- /** IP traffic not available. */
- DISCONNECTED,
- /** Attempt to connect failed. */
- FAILED,
- /** Access to this network is blocked. */
- BLOCKED,
- /** Link has poor connectivity. */
- VERIFYING_POOR_LINK,
- /** Checking if network is a captive portal */
- CAPTIVE_PORTAL_CHECK
- }
-
- /**
- * This is the map described in the Javadoc comment above. The positions
- * of the elements of the array must correspond to the ordinal values
- * of <code>DetailedState</code>.
- */
- private static final EnumMap<DetailedState, State> stateMap =
- new EnumMap<DetailedState, State>(DetailedState.class);
-
- static {
- stateMap.put(DetailedState.IDLE, State.DISCONNECTED);
- stateMap.put(DetailedState.SCANNING, State.DISCONNECTED);
- stateMap.put(DetailedState.CONNECTING, State.CONNECTING);
- stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
- stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
- stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING);
- stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING);
- stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
- stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
- stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
- stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
- stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
- stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED);
- }
-
- private int mNetworkType;
- private int mSubtype;
- private String mTypeName;
- private String mSubtypeName;
- @NonNull
- private State mState;
- @NonNull
- private DetailedState mDetailedState;
- private String mReason;
- private String mExtraInfo;
- private boolean mIsFailover;
- private boolean mIsAvailable;
- private boolean mIsRoaming;
-
- /**
- * Create a new instance of NetworkInfo.
- *
- * This may be useful for apps to write unit tests.
- *
- * @param type the legacy type of the network, as one of the ConnectivityManager.TYPE_*
- * constants.
- * @param subtype the subtype if applicable, as one of the TelephonyManager.NETWORK_TYPE_*
- * constants.
- * @param typeName a human-readable string for the network type, or an empty string or null.
- * @param subtypeName a human-readable string for the subtype, or an empty string or null.
- */
- public NetworkInfo(int type, int subtype,
- @Nullable String typeName, @Nullable String subtypeName) {
- if (!ConnectivityManager.isNetworkTypeValid(type)
- && type != ConnectivityManager.TYPE_NONE) {
- throw new IllegalArgumentException("Invalid network type: " + type);
- }
- mNetworkType = type;
- mSubtype = subtype;
- mTypeName = typeName;
- mSubtypeName = subtypeName;
- setDetailedState(DetailedState.IDLE, null, null);
- mState = State.UNKNOWN;
- }
-
- /** {@hide} */
- @UnsupportedAppUsage
- public NetworkInfo(NetworkInfo source) {
- if (source != null) {
- synchronized (source) {
- mNetworkType = source.mNetworkType;
- mSubtype = source.mSubtype;
- mTypeName = source.mTypeName;
- mSubtypeName = source.mSubtypeName;
- mState = source.mState;
- mDetailedState = source.mDetailedState;
- mReason = source.mReason;
- mExtraInfo = source.mExtraInfo;
- mIsFailover = source.mIsFailover;
- mIsAvailable = source.mIsAvailable;
- mIsRoaming = source.mIsRoaming;
- }
- }
- }
-
- /**
- * Reports the type of network to which the
- * info in this {@code NetworkInfo} pertains.
- * @return one of {@link ConnectivityManager#TYPE_MOBILE}, {@link
- * ConnectivityManager#TYPE_WIFI}, {@link ConnectivityManager#TYPE_WIMAX}, {@link
- * ConnectivityManager#TYPE_ETHERNET}, {@link ConnectivityManager#TYPE_BLUETOOTH}, or other
- * types defined by {@link ConnectivityManager}.
- * @deprecated Callers should switch to checking {@link NetworkCapabilities#hasTransport}
- * instead with one of the NetworkCapabilities#TRANSPORT_* constants :
- * {@link #getType} and {@link #getTypeName} cannot account for networks using
- * multiple transports. Note that generally apps should not care about transport;
- * {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED} and
- * {@link NetworkCapabilities#getLinkDownstreamBandwidthKbps} are calls that
- * apps concerned with meteredness or bandwidth should be looking at, as they
- * offer this information with much better accuracy.
- */
- @Deprecated
- public int getType() {
- synchronized (this) {
- return mNetworkType;
- }
- }
-
- /**
- * @deprecated Use {@link NetworkCapabilities} instead
- * @hide
- */
- @Deprecated
- public void setType(int type) {
- synchronized (this) {
- mNetworkType = type;
- }
- }
-
- /**
- * Return a network-type-specific integer describing the subtype
- * of the network.
- * @return the network subtype
- * @deprecated Use {@link android.telephony.TelephonyManager#getDataNetworkType} instead.
- */
- @Deprecated
- public int getSubtype() {
- synchronized (this) {
- return mSubtype;
- }
- }
-
- /**
- * @hide
- */
- @UnsupportedAppUsage
- public void setSubtype(int subtype, String subtypeName) {
- synchronized (this) {
- mSubtype = subtype;
- mSubtypeName = subtypeName;
- }
- }
-
- /**
- * Return a human-readable name describe the type of the network,
- * for example "WIFI" or "MOBILE".
- * @return the name of the network type
- * @deprecated Callers should switch to checking {@link NetworkCapabilities#hasTransport}
- * instead with one of the NetworkCapabilities#TRANSPORT_* constants :
- * {@link #getType} and {@link #getTypeName} cannot account for networks using
- * multiple transports. Note that generally apps should not care about transport;
- * {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED} and
- * {@link NetworkCapabilities#getLinkDownstreamBandwidthKbps} are calls that
- * apps concerned with meteredness or bandwidth should be looking at, as they
- * offer this information with much better accuracy.
- */
- @Deprecated
- public String getTypeName() {
- synchronized (this) {
- return mTypeName;
- }
- }
-
- /**
- * Return a human-readable name describing the subtype of the network.
- * @return the name of the network subtype
- * @deprecated Use {@link android.telephony.TelephonyManager#getDataNetworkType} instead.
- */
- @Deprecated
- public String getSubtypeName() {
- synchronized (this) {
- return mSubtypeName;
- }
- }
-
- /**
- * Indicates whether network connectivity exists or is in the process
- * of being established. This is good for applications that need to
- * do anything related to the network other than read or write data.
- * For the latter, call {@link #isConnected()} instead, which guarantees
- * that the network is fully usable.
- * @return {@code true} if network connectivity exists or is in the process
- * of being established, {@code false} otherwise.
- * @deprecated Apps should instead use the
- * {@link android.net.ConnectivityManager.NetworkCallback} API to
- * learn about connectivity changes.
- * {@link ConnectivityManager#registerDefaultNetworkCallback} and
- * {@link ConnectivityManager#registerNetworkCallback}. These will
- * give a more accurate picture of the connectivity state of
- * the device and let apps react more easily and quickly to changes.
- */
- @Deprecated
- public boolean isConnectedOrConnecting() {
- synchronized (this) {
- return mState == State.CONNECTED || mState == State.CONNECTING;
- }
- }
-
- /**
- * Indicates whether network connectivity exists and it is possible to establish
- * connections and pass data.
- * <p>Always call this before attempting to perform data transactions.
- * @return {@code true} if network connectivity exists, {@code false} otherwise.
- * @deprecated Apps should instead use the
- * {@link android.net.ConnectivityManager.NetworkCallback} API to
- * learn about connectivity changes. See
- * {@link ConnectivityManager#registerDefaultNetworkCallback} and
- * {@link ConnectivityManager#registerNetworkCallback}. These will
- * give a more accurate picture of the connectivity state of
- * the device and let apps react more easily and quickly to changes.
- */
- @Deprecated
- public boolean isConnected() {
- synchronized (this) {
- return mState == State.CONNECTED;
- }
- }
-
- /**
- * Indicates whether network connectivity is possible. A network is unavailable
- * when a persistent or semi-persistent condition prevents the possibility
- * of connecting to that network. Examples include
- * <ul>
- * <li>The device is out of the coverage area for any network of this type.</li>
- * <li>The device is on a network other than the home network (i.e., roaming), and
- * data roaming has been disabled.</li>
- * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li>
- * </ul>
- * Since Android L, this always returns {@code true}, because the system only
- * returns info for available networks.
- * @return {@code true} if the network is available, {@code false} otherwise
- * @deprecated Apps should instead use the
- * {@link android.net.ConnectivityManager.NetworkCallback} API to
- * learn about connectivity changes.
- * {@link ConnectivityManager#registerDefaultNetworkCallback} and
- * {@link ConnectivityManager#registerNetworkCallback}. These will
- * give a more accurate picture of the connectivity state of
- * the device and let apps react more easily and quickly to changes.
- */
- @Deprecated
- public boolean isAvailable() {
- synchronized (this) {
- return mIsAvailable;
- }
- }
-
- /**
- * Sets if the network is available, ie, if the connectivity is possible.
- * @param isAvailable the new availability value.
- * @deprecated Use {@link NetworkCapabilities} instead
- *
- * @hide
- */
- @Deprecated
- @UnsupportedAppUsage
- public void setIsAvailable(boolean isAvailable) {
- synchronized (this) {
- mIsAvailable = isAvailable;
- }
- }
-
- /**
- * Indicates whether the current attempt to connect to the network
- * resulted from the ConnectivityManager trying to fail over to this
- * network following a disconnect from another network.
- * @return {@code true} if this is a failover attempt, {@code false}
- * otherwise.
- * @deprecated This field is not populated in recent Android releases,
- * and does not make a lot of sense in a multi-network world.
- */
- @Deprecated
- public boolean isFailover() {
- synchronized (this) {
- return mIsFailover;
- }
- }
-
- /**
- * Set the failover boolean.
- * @param isFailover {@code true} to mark the current connection attempt
- * as a failover.
- * @deprecated This hasn't been set in any recent Android release.
- * @hide
- */
- @Deprecated
- @UnsupportedAppUsage
- public void setFailover(boolean isFailover) {
- synchronized (this) {
- mIsFailover = isFailover;
- }
- }
-
- /**
- * Indicates whether the device is currently roaming on this network. When
- * {@code true}, it suggests that use of data on this network may incur
- * extra costs.
- *
- * @return {@code true} if roaming is in effect, {@code false} otherwise.
- * @deprecated Callers should switch to checking
- * {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING}
- * instead, since that handles more complex situations, such as
- * VPNs.
- */
- @Deprecated
- public boolean isRoaming() {
- synchronized (this) {
- return mIsRoaming;
- }
- }
-
- /**
- * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING} instead.
- * {@hide}
- */
- @VisibleForTesting
- @Deprecated
- @UnsupportedAppUsage
- public void setRoaming(boolean isRoaming) {
- synchronized (this) {
- mIsRoaming = isRoaming;
- }
- }
-
- /**
- * Reports the current coarse-grained state of the network.
- * @return the coarse-grained state
- * @deprecated Apps should instead use the
- * {@link android.net.ConnectivityManager.NetworkCallback} API to
- * learn about connectivity changes.
- * {@link ConnectivityManager#registerDefaultNetworkCallback} and
- * {@link ConnectivityManager#registerNetworkCallback}. These will
- * give a more accurate picture of the connectivity state of
- * the device and let apps react more easily and quickly to changes.
- */
- @Deprecated
- public State getState() {
- synchronized (this) {
- return mState;
- }
- }
-
- /**
- * Reports the current fine-grained state of the network.
- * @return the fine-grained state
- * @deprecated Apps should instead use the
- * {@link android.net.ConnectivityManager.NetworkCallback} API to
- * learn about connectivity changes. See
- * {@link ConnectivityManager#registerDefaultNetworkCallback} and
- * {@link ConnectivityManager#registerNetworkCallback}. These will
- * give a more accurate picture of the connectivity state of
- * the device and let apps react more easily and quickly to changes.
- */
- @Deprecated
- public @NonNull DetailedState getDetailedState() {
- synchronized (this) {
- return mDetailedState;
- }
- }
-
- /**
- * Sets the fine-grained state of the network.
- *
- * This is only useful for testing.
- *
- * @param detailedState the {@link DetailedState}.
- * @param reason a {@code String} indicating the reason for the state change,
- * if one was supplied. May be {@code null}.
- * @param extraInfo an optional {@code String} providing addditional network state
- * information passed up from the lower networking layers.
- * @deprecated Use {@link NetworkCapabilities} instead.
- */
- @Deprecated
- public void setDetailedState(@NonNull DetailedState detailedState, @Nullable String reason,
- @Nullable String extraInfo) {
- synchronized (this) {
- this.mDetailedState = detailedState;
- this.mState = stateMap.get(detailedState);
- this.mReason = reason;
- this.mExtraInfo = extraInfo;
- }
- }
-
- /**
- * Set the extraInfo field.
- * @param extraInfo an optional {@code String} providing addditional network state
- * information passed up from the lower networking layers.
- * @deprecated See {@link NetworkInfo#getExtraInfo}.
- * @hide
- */
- @Deprecated
- public void setExtraInfo(String extraInfo) {
- synchronized (this) {
- this.mExtraInfo = extraInfo;
- }
- }
-
- /**
- * Report the reason an attempt to establish connectivity failed,
- * if one is available.
- * @return the reason for failure, or null if not available
- * @deprecated This method does not have a consistent contract that could make it useful
- * to callers.
- */
- public String getReason() {
- synchronized (this) {
- return mReason;
- }
- }
-
- /**
- * Report the extra information about the network state, if any was
- * provided by the lower networking layers.
- * @return the extra information, or null if not available
- * @deprecated Use other services e.g. WifiManager to get additional information passed up from
- * the lower networking layers.
- */
- @Deprecated
- public String getExtraInfo() {
- synchronized (this) {
- return mExtraInfo;
- }
- }
-
- @Override
- public String toString() {
- synchronized (this) {
- final StringBuilder builder = new StringBuilder("[");
- builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()).
- append("], state: ").append(mState).append("/").append(mDetailedState).
- append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
- append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo).
- append(", failover: ").append(mIsFailover).
- append(", available: ").append(mIsAvailable).
- append(", roaming: ").append(mIsRoaming).
- append("]");
- return builder.toString();
- }
- }
-
- /**
- * Returns a brief summary string suitable for debugging.
- * @hide
- */
- public String toShortString() {
- synchronized (this) {
- final StringBuilder builder = new StringBuilder();
- builder.append(getTypeName());
-
- final String subtype = getSubtypeName();
- if (!TextUtils.isEmpty(subtype)) {
- builder.append("[").append(subtype).append("]");
- }
-
- builder.append(" ");
- builder.append(mDetailedState);
- if (mIsRoaming) {
- builder.append(" ROAMING");
- }
- if (mExtraInfo != null) {
- builder.append(" extra: ").append(mExtraInfo);
- }
- return builder.toString();
- }
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- synchronized (this) {
- dest.writeInt(mNetworkType);
- dest.writeInt(mSubtype);
- dest.writeString(mTypeName);
- dest.writeString(mSubtypeName);
- dest.writeString(mState.name());
- dest.writeString(mDetailedState.name());
- dest.writeInt(mIsFailover ? 1 : 0);
- dest.writeInt(mIsAvailable ? 1 : 0);
- dest.writeInt(mIsRoaming ? 1 : 0);
- dest.writeString(mReason);
- dest.writeString(mExtraInfo);
- }
- }
-
- public static final @android.annotation.NonNull Creator<NetworkInfo> CREATOR = new Creator<NetworkInfo>() {
- @Override
- public NetworkInfo createFromParcel(Parcel in) {
- int netType = in.readInt();
- int subtype = in.readInt();
- String typeName = in.readString();
- String subtypeName = in.readString();
- NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName);
- netInfo.mState = State.valueOf(in.readString());
- netInfo.mDetailedState = DetailedState.valueOf(in.readString());
- netInfo.mIsFailover = in.readInt() != 0;
- netInfo.mIsAvailable = in.readInt() != 0;
- netInfo.mIsRoaming = in.readInt() != 0;
- netInfo.mReason = in.readString();
- netInfo.mExtraInfo = in.readString();
- return netInfo;
- }
-
- @Override
- public NetworkInfo[] newArray(int size) {
- return new NetworkInfo[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkProvider.java b/packages/Connectivity/framework/src/android/net/NetworkProvider.java
deleted file mode 100644
index 0665af5..0000000
--- a/packages/Connectivity/framework/src/android/net/NetworkProvider.java
+++ /dev/null
@@ -1,332 +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.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.ArrayList;
-import java.util.concurrent.Executor;
-
-/**
- * Base class for network providers such as telephony or Wi-Fi. NetworkProviders connect the device
- * to networks and makes them available to the core network stack by creating
- * {@link NetworkAgent}s. The networks can then provide connectivity to apps and can be interacted
- * with via networking APIs such as {@link ConnectivityManager}.
- *
- * Subclasses should implement {@link #onNetworkRequested} and {@link #onNetworkRequestWithdrawn}
- * to receive {@link NetworkRequest}s sent by the system and by apps. A network that is not the
- * best (highest-scoring) network for any request is generally not used by the system, and torn
- * down.
- *
- * @hide
- */
-@SystemApi
-public class NetworkProvider {
- /**
- * {@code providerId} value that indicates the absence of a provider. It is the providerId of
- * any NetworkProvider that is not currently registered, and of any NetworkRequest that is not
- * currently being satisfied by a network.
- */
- public static final int ID_NONE = -1;
-
- /**
- * The first providerId value that will be allocated.
- * @hide only used by ConnectivityService.
- */
- public static final int FIRST_PROVIDER_ID = 1;
-
- /** @hide only used by ConnectivityService */
- public static final int CMD_REQUEST_NETWORK = 1;
- /** @hide only used by ConnectivityService */
- public static final int CMD_CANCEL_REQUEST = 2;
-
- private final Messenger mMessenger;
- private final String mName;
- private final Context mContext;
-
- private int mProviderId = ID_NONE;
-
- /**
- * Constructs a new NetworkProvider.
- *
- * @param looper the Looper on which to run {@link #onNetworkRequested} and
- * {@link #onNetworkRequestWithdrawn}.
- * @param name the name of the listener, used only for debugging.
- *
- * @hide
- */
- @SystemApi
- public NetworkProvider(@NonNull Context context, @NonNull Looper looper, @NonNull String name) {
- // TODO (b/174636568) : this class should be able to cache an instance of
- // ConnectivityManager so it doesn't have to fetch it again every time.
- final Handler handler = new Handler(looper) {
- @Override
- public void handleMessage(Message m) {
- switch (m.what) {
- case CMD_REQUEST_NETWORK:
- onNetworkRequested((NetworkRequest) m.obj, m.arg1, m.arg2);
- break;
- case CMD_CANCEL_REQUEST:
- onNetworkRequestWithdrawn((NetworkRequest) m.obj);
- break;
- default:
- Log.e(mName, "Unhandled message: " + m.what);
- }
- }
- };
- mContext = context;
- mMessenger = new Messenger(handler);
- mName = name;
- }
-
- // TODO: consider adding a register() method so ConnectivityManager does not need to call this.
- /** @hide */
- public @Nullable Messenger getMessenger() {
- return mMessenger;
- }
-
- /** @hide */
- public @NonNull String getName() {
- return mName;
- }
-
- /**
- * Returns the ID of this provider. This is known only once the provider is registered via
- * {@link ConnectivityManager#registerNetworkProvider()}, otherwise the ID is {@link #ID_NONE}.
- * This ID must be used when registering any {@link NetworkAgent}s.
- */
- public int getProviderId() {
- return mProviderId;
- }
-
- /** @hide */
- public void setProviderId(int providerId) {
- mProviderId = providerId;
- }
-
- /**
- * Called when a NetworkRequest is received. The request may be a new request or an existing
- * request with a different score.
- *
- * @param request the NetworkRequest being received
- * @param score the score of the network currently satisfying the request, or 0 if none.
- * @param providerId the ID of the provider that created the network currently satisfying this
- * request, or {@link #ID_NONE} if none.
- *
- * @hide
- */
- @SystemApi
- public void onNetworkRequested(@NonNull NetworkRequest request,
- @IntRange(from = 0, to = 99) int score, int providerId) {}
-
- /**
- * Called when a NetworkRequest is withdrawn.
- * @hide
- */
- @SystemApi
- public void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {}
-
- /**
- * Asserts that no provider will ever be able to satisfy the specified request. The provider
- * must only call this method if it knows that it is the only provider on the system capable of
- * satisfying this request, and that the request cannot be satisfied. The application filing the
- * request will receive an {@link NetworkCallback#onUnavailable()} callback.
- *
- * @param request the request that permanently cannot be fulfilled
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
- public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) {
- ConnectivityManager.from(mContext).declareNetworkRequestUnfulfillable(request);
- }
-
- /**
- * A callback for parties registering a NetworkOffer.
- *
- * This is used with {@link ConnectivityManager#offerNetwork}. When offering a network,
- * the system will use this callback to inform the caller that a network corresponding to
- * this offer is needed or unneeded.
- *
- * @hide
- */
- @SystemApi
- public interface NetworkOfferCallback {
- /**
- * Called by the system when a network for this offer is needed to satisfy some
- * networking request.
- */
- void onNetworkNeeded(@NonNull NetworkRequest request);
- /**
- * Called by the system when this offer is no longer valuable for this request.
- */
- void onNetworkUnneeded(@NonNull NetworkRequest request);
- }
-
- private class NetworkOfferCallbackProxy extends INetworkOfferCallback.Stub {
- @NonNull public final NetworkOfferCallback callback;
- @NonNull private final Executor mExecutor;
-
- NetworkOfferCallbackProxy(@NonNull final NetworkOfferCallback callback,
- @NonNull final Executor executor) {
- this.callback = callback;
- this.mExecutor = executor;
- }
-
- @Override
- public void onNetworkNeeded(final @NonNull NetworkRequest request) {
- mExecutor.execute(() -> callback.onNetworkNeeded(request));
- }
-
- @Override
- public void onNetworkUnneeded(final @NonNull NetworkRequest request) {
- mExecutor.execute(() -> callback.onNetworkUnneeded(request));
- }
- }
-
- @GuardedBy("mProxies")
- @NonNull private final ArrayList<NetworkOfferCallbackProxy> mProxies = new ArrayList<>();
-
- // Returns the proxy associated with this callback, or null if none.
- @Nullable
- private NetworkOfferCallbackProxy findProxyForCallback(@NonNull final NetworkOfferCallback cb) {
- synchronized (mProxies) {
- for (final NetworkOfferCallbackProxy p : mProxies) {
- if (p.callback == cb) return p;
- }
- }
- return null;
- }
-
- /**
- * Register or update an offer for network with the passed capabilities and score.
- *
- * A NetworkProvider's role is to provide networks. This method is how a provider tells the
- * connectivity stack what kind of network it may provide. The score and caps arguments act
- * as filters that the connectivity stack uses to tell when the offer is valuable. When an
- * offer might be preferred over existing networks, the provider will receive a call to
- * the associated callback's {@link NetworkOfferCallback#onNetworkNeeded} method. The provider
- * should then try to bring up this network. When an offer is no longer useful, the stack
- * will inform the provider by calling {@link NetworkOfferCallback#onNetworkUnneeded}. The
- * provider should stop trying to bring up such a network, or disconnect it if it already has
- * one.
- *
- * The stack determines what offers are valuable according to what networks are currently
- * available to the system, and what networking requests are made by applications. If an
- * offer looks like it could connect a better network than any existing network for any
- * particular request, that's when the stack decides the network is needed. If the current
- * networking requests are all satisfied by networks that this offer couldn't possibly be a
- * better match for, that's when the offer is no longer valuable. An offer starts out as
- * unneeded ; the provider should not try to bring up the network until
- * {@link NetworkOfferCallback#onNetworkNeeded} is called.
- *
- * Note that the offers are non-binding to the providers, in particular because providers
- * often don't know if they will be able to bring up such a network at any given time. For
- * example, no wireless network may be in range when the offer would be valuable. This is fine
- * and expected ; the provider should simply continue to try to bring up the network and do so
- * if/when it becomes possible. In the mean time, the stack will continue to satisfy requests
- * with the best network currently available, or if none, keep the apps informed that no
- * network can currently satisfy this request. When/if the provider can bring up the network,
- * the connectivity stack will match it against requests, and inform interested apps of the
- * availability of this network. This may, in turn, render the offer of some other provider
- * low-value if all requests it used to satisfy are now better served by this network.
- *
- * A network can become unneeded for a reason like the above : whether the provider managed
- * to bring up the offered network after it became needed or not, some other provider may
- * bring up a better network than this one, making this network unneeded. A network may also
- * become unneeded if the application making the request withdrew it (for example, after it
- * is done transferring data, or if the user canceled an operation).
- *
- * The capabilities and score act as filters as to what requests the provider will see.
- * They are not promises, but for best performance, the providers should strive to put
- * as much known information as possible in the offer. For the score, it should put as
- * strong a score as the networks will have, since this will filter what requests the
- * provider sees – it's not a promise, it only serves to avoid sending requests that
- * the provider can't ever hope to satisfy better than any current network. For capabilities,
- * it should put all NetworkAgent-managed capabilities a network may have, even if it doesn't
- * have them at first. This applies to INTERNET, for example ; if a provider thinks the
- * network it can bring up for this offer may offer Internet access it should include the
- * INTERNET bit. It's fine if the brought up network ends up not actually having INTERNET.
- *
- * TODO : in the future, to avoid possible infinite loops, there should be constraints on
- * what can be put in capabilities of networks brought up for an offer. If a provider might
- * bring up a network with or without INTERNET, then it should file two offers : this will
- * let it know precisely what networks are needed, so it can avoid bringing up networks that
- * won't actually satisfy requests and remove the risk for bring-up-bring-down loops.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
- public void registerNetworkOffer(@NonNull final NetworkScore score,
- @NonNull final NetworkCapabilities caps, @NonNull final Executor executor,
- @NonNull final NetworkOfferCallback callback) {
- // Can't offer a network with a provider that is not yet registered or already unregistered.
- final int providerId = mProviderId;
- if (providerId == ID_NONE) return;
- NetworkOfferCallbackProxy proxy = null;
- synchronized (mProxies) {
- for (final NetworkOfferCallbackProxy existingProxy : mProxies) {
- if (existingProxy.callback == callback) {
- proxy = existingProxy;
- break;
- }
- }
- if (null == proxy) {
- proxy = new NetworkOfferCallbackProxy(callback, executor);
- mProxies.add(proxy);
- }
- }
- mContext.getSystemService(ConnectivityManager.class)
- .offerNetwork(providerId, score, caps, proxy);
- }
-
- /**
- * Withdraw a network offer previously made to the networking stack.
- *
- * If a provider can no longer provide a network they offered, it should call this method.
- * An example of usage could be if the hardware necessary to bring up the network was turned
- * off in UI by the user. Note that because offers are never binding, the provider might
- * alternatively decide not to withdraw this offer and simply refuse to bring up the network
- * even when it's needed. However, withdrawing the request is slightly more resource-efficient
- * because the networking stack won't have to compare this offer to exiting networks to see
- * if it could beat any of them, and may be advantageous to the provider's implementation that
- * can rely on no longer receiving callbacks for a network that they can't bring up anyways.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
- public void unregisterNetworkOffer(final @NonNull NetworkOfferCallback callback) {
- final NetworkOfferCallbackProxy proxy = findProxyForCallback(callback);
- if (null == proxy) return;
- mProxies.remove(proxy);
- mContext.getSystemService(ConnectivityManager.class).unofferNetwork(proxy);
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkReleasedException.java b/packages/Connectivity/framework/src/android/net/NetworkReleasedException.java
deleted file mode 100644
index 0629b75..0000000
--- a/packages/Connectivity/framework/src/android/net/NetworkReleasedException.java
+++ /dev/null
@@ -1,32 +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.annotation.SystemApi;
-
-/**
- * Indicates that the {@link Network} was released and is no longer available.
- *
- * @hide
- */
-@SystemApi
-public class NetworkReleasedException extends Exception {
- /** @hide */
- public NetworkReleasedException() {
- super("The network was released and is no longer available");
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
deleted file mode 100644
index afc76d6..0000000
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ /dev/null
@@ -1,753 +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 android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-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_PARTIAL_CONNECTIVITY;
-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.TRANSPORT_TEST;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.NetworkCapabilities.NetCapability;
-import android.net.NetworkCapabilities.Transport;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.Process;
-import android.text.TextUtils;
-import android.util.Range;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Defines a request for a network, made through {@link NetworkRequest.Builder} and used
- * to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes
- * via {@link ConnectivityManager#registerNetworkCallback}.
- */
-public class NetworkRequest implements Parcelable {
- /**
- * The first requestId value that will be allocated.
- * @hide only used by ConnectivityService.
- */
- public static final int FIRST_REQUEST_ID = 1;
-
- /**
- * The requestId value that represents the absence of a request.
- * @hide only used by ConnectivityService.
- */
- public static final int REQUEST_ID_NONE = -1;
-
- /**
- * The {@link NetworkCapabilities} that define this request.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public final @NonNull NetworkCapabilities networkCapabilities;
-
- /**
- * Identifies the request. NetworkRequests should only be constructed by
- * the Framework and given out to applications as tokens to be used to identify
- * the request.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public final int requestId;
-
- /**
- * Set for legacy requests and the default. Set to TYPE_NONE for none.
- * Causes CONNECTIVITY_ACTION broadcasts to be sent.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public final int legacyType;
-
- /**
- * A NetworkRequest as used by the system can be one of the following types:
- *
- * - LISTEN, for which the framework will issue callbacks about any
- * and all networks that match the specified NetworkCapabilities,
- *
- * - REQUEST, capable of causing a specific network to be created
- * first (e.g. a telephony DUN request), the framework will issue
- * callbacks about the single, highest scoring current network
- * (if any) that matches the specified NetworkCapabilities, or
- *
- * - TRACK_DEFAULT, which causes the framework to issue callbacks for
- * the single, highest scoring current network (if any) that will
- * be chosen for an app, but which cannot cause the framework to
- * either create or retain the existence of any specific network.
- *
- * - TRACK_SYSTEM_DEFAULT, which causes the framework to send callbacks
- * for the network (if any) that satisfies the default Internet
- * request.
- *
- * - TRACK_BEST, which causes the framework to send callbacks about
- * the single, highest scoring current network (if any) that matches
- * the specified NetworkCapabilities.
- *
- * - BACKGROUND_REQUEST, like REQUEST but does not cause any networks
- * to retain the NET_CAPABILITY_FOREGROUND capability. A network with
- * no foreground requests is in the background. A network that has
- * one or more background requests and loses its last foreground
- * request to a higher-scoring network will not go into the
- * background immediately, but will linger and go into the background
- * after the linger timeout.
- *
- * - The value NONE is used only by applications. When an application
- * creates a NetworkRequest, it does not have a type; the type is set
- * by the system depending on the method used to file the request
- * (requestNetwork, registerNetworkCallback, etc.).
- *
- * @hide
- */
- public static enum Type {
- NONE,
- LISTEN,
- TRACK_DEFAULT,
- REQUEST,
- BACKGROUND_REQUEST,
- TRACK_SYSTEM_DEFAULT,
- LISTEN_FOR_BEST,
- };
-
- /**
- * The type of the request. This is only used by the system and is always NONE elsewhere.
- *
- * @hide
- */
- public final Type type;
-
- /**
- * @hide
- */
- public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId, Type type) {
- if (nc == null) {
- throw new NullPointerException();
- }
- requestId = rId;
- networkCapabilities = nc;
- this.legacyType = legacyType;
- this.type = type;
- }
-
- /**
- * @hide
- */
- public NetworkRequest(NetworkRequest that) {
- networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
- requestId = that.requestId;
- this.legacyType = that.legacyType;
- this.type = that.type;
- }
-
- /**
- * Builder used to create {@link NetworkRequest} objects. Specify the Network features
- * needed in terms of {@link NetworkCapabilities} features
- */
- public static class Builder {
- /**
- * Capabilities that are currently compatible with VCN networks.
- */
- private static final List<Integer> VCN_SUPPORTED_CAPABILITIES = Arrays.asList(
- NET_CAPABILITY_CAPTIVE_PORTAL,
- NET_CAPABILITY_DUN,
- NET_CAPABILITY_FOREGROUND,
- NET_CAPABILITY_INTERNET,
- NET_CAPABILITY_NOT_CONGESTED,
- NET_CAPABILITY_NOT_METERED,
- NET_CAPABILITY_NOT_RESTRICTED,
- NET_CAPABILITY_NOT_ROAMING,
- NET_CAPABILITY_NOT_SUSPENDED,
- NET_CAPABILITY_NOT_VPN,
- NET_CAPABILITY_PARTIAL_CONNECTIVITY,
- NET_CAPABILITY_TEMPORARILY_NOT_METERED,
- NET_CAPABILITY_TRUSTED,
- NET_CAPABILITY_VALIDATED);
-
- private final NetworkCapabilities mNetworkCapabilities;
-
- // A boolean that represents whether the NOT_VCN_MANAGED capability should be deduced when
- // the NetworkRequest object is built.
- private boolean mShouldDeduceNotVcnManaged = true;
-
- /**
- * Default constructor for Builder.
- */
- public Builder() {
- // By default, restrict this request to networks available to this app.
- // Apps can rescind this restriction, but ConnectivityService will enforce
- // it for apps that do not have the NETWORK_SETTINGS permission.
- mNetworkCapabilities = new NetworkCapabilities();
- mNetworkCapabilities.setSingleUid(Process.myUid());
- }
-
- /**
- * Creates a new Builder of NetworkRequest from an existing instance.
- */
- public Builder(@NonNull final NetworkRequest request) {
- Objects.requireNonNull(request);
- mNetworkCapabilities = request.networkCapabilities;
- // If the caller constructed the builder from a request, it means the user
- // might explicitly want the capabilities from the request. Thus, the NOT_VCN_MANAGED
- // capabilities should not be touched later.
- mShouldDeduceNotVcnManaged = false;
- }
-
- /**
- * Build {@link NetworkRequest} give the current set of capabilities.
- */
- public NetworkRequest build() {
- // Make a copy of mNetworkCapabilities so we don't inadvertently remove NOT_RESTRICTED
- // when later an unrestricted capability could be added to mNetworkCapabilities, in
- // which case NOT_RESTRICTED should be returned to mNetworkCapabilities, which
- // maybeMarkCapabilitiesRestricted() doesn't add back.
- final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities);
- nc.maybeMarkCapabilitiesRestricted();
- deduceNotVcnManagedCapability(nc);
- return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE,
- ConnectivityManager.REQUEST_ID_UNSET, Type.NONE);
- }
-
- /**
- * Add the given capability requirement to this builder. These represent
- * the requested network's required capabilities. Note that when searching
- * for a network to satisfy a request, all capabilities requested must be
- * satisfied.
- *
- * @param capability The capability to add.
- * @return The builder to facilitate chaining
- * {@code builder.addCapability(...).addCapability();}.
- */
- public Builder addCapability(@NetworkCapabilities.NetCapability int capability) {
- mNetworkCapabilities.addCapability(capability);
- if (capability == NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) {
- mShouldDeduceNotVcnManaged = false;
- }
- return this;
- }
-
- /**
- * Removes (if found) the given capability from this builder instance.
- *
- * @param capability The capability to remove.
- * @return The builder to facilitate chaining.
- */
- public Builder removeCapability(@NetworkCapabilities.NetCapability int capability) {
- mNetworkCapabilities.removeCapability(capability);
- if (capability == NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) {
- mShouldDeduceNotVcnManaged = false;
- }
- return this;
- }
-
- /**
- * Set the {@code NetworkCapabilities} for this builder instance,
- * overriding any capabilities that had been previously set.
- *
- * @param nc The superseding {@code NetworkCapabilities} instance.
- * @return The builder to facilitate chaining.
- * @hide
- */
- public Builder setCapabilities(NetworkCapabilities nc) {
- mNetworkCapabilities.set(nc);
- return this;
- }
-
- /**
- * Sets this request to match only networks that apply to the specified UIDs.
- *
- * By default, the set of UIDs is the UID of the calling app, and this request will match
- * any network that applies to the app. Setting it to {@code null} will observe any
- * network on the system, even if it does not apply to this app. In this case, any
- * {@link NetworkSpecifier} set on this request will be redacted or removed to prevent the
- * application deducing restricted information such as location.
- *
- * @param uids The UIDs as a set of {@code Range<Integer>}, or null for everything.
- * @return The builder to facilitate chaining.
- * @hide
- */
- @NonNull
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- @SuppressLint("MissingGetterMatchingBuilder")
- public Builder setUids(@Nullable Set<Range<Integer>> uids) {
- mNetworkCapabilities.setUids(uids);
- return this;
- }
-
- /**
- * Add a capability that must not exist in the requested network.
- * <p>
- * If the capability was previously added to the list of required capabilities (for
- * example, it was there by default or added using {@link #addCapability(int)} method), then
- * it will be removed from the list of required capabilities as well.
- *
- * @see #addCapability(int)
- *
- * @param capability The capability to add to forbidden capability list.
- * @return The builder to facilitate chaining.
- *
- * @hide
- */
- @NonNull
- @SuppressLint("MissingGetterMatchingBuilder")
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public Builder addForbiddenCapability(@NetworkCapabilities.NetCapability int capability) {
- mNetworkCapabilities.addForbiddenCapability(capability);
- return this;
- }
-
- /**
- * Removes (if found) the given forbidden capability from this builder instance.
- *
- * @param capability The forbidden capability to remove.
- * @return The builder to facilitate chaining.
- *
- * @hide
- */
- @NonNull
- @SuppressLint("BuilderSetStyle")
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public Builder removeForbiddenCapability(
- @NetworkCapabilities.NetCapability int capability) {
- mNetworkCapabilities.removeForbiddenCapability(capability);
- return this;
- }
-
- /**
- * Completely clears all the {@code NetworkCapabilities} from this builder instance,
- * removing even the capabilities that are set by default when the object is constructed.
- *
- * @return The builder to facilitate chaining.
- */
- @NonNull
- public Builder clearCapabilities() {
- mNetworkCapabilities.clearAll();
- // If the caller explicitly clear all capabilities, the NOT_VCN_MANAGED capabilities
- // should not be add back later.
- mShouldDeduceNotVcnManaged = false;
- return this;
- }
-
- /**
- * Adds the given transport requirement to this builder. These represent
- * the set of allowed transports for the request. Only networks using one
- * of these transports will satisfy the request. If no particular transports
- * are required, none should be specified here.
- *
- * @param transportType The transport type to add.
- * @return The builder to facilitate chaining.
- */
- public Builder addTransportType(@NetworkCapabilities.Transport int transportType) {
- mNetworkCapabilities.addTransportType(transportType);
- return this;
- }
-
- /**
- * Removes (if found) the given transport from this builder instance.
- *
- * @param transportType The transport type to remove.
- * @return The builder to facilitate chaining.
- */
- public Builder removeTransportType(@NetworkCapabilities.Transport int transportType) {
- mNetworkCapabilities.removeTransportType(transportType);
- return this;
- }
-
- /**
- * @hide
- */
- public Builder setLinkUpstreamBandwidthKbps(int upKbps) {
- mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps);
- return this;
- }
- /**
- * @hide
- */
- public Builder setLinkDownstreamBandwidthKbps(int downKbps) {
- mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps);
- return this;
- }
-
- /**
- * Sets the optional bearer specific network specifier.
- * This has no meaning if a single transport is also not specified, so calling
- * this without a single transport set will generate an exception, as will
- * subsequently adding or removing transports after this is set.
- * </p>
- * If the {@code networkSpecifier} is provided, it shall be interpreted as follows:
- * <ul>
- * <li>If the specifier can be parsed as an integer, it will be treated as a
- * {@link android.net TelephonyNetworkSpecifier}, and the provided integer will be
- * interpreted as a SubscriptionId.
- * <li>If the value is an ethernet interface name, it will be treated as such.
- * <li>For all other cases, the behavior is undefined.
- * </ul>
- *
- * @param networkSpecifier A {@code String} of either a SubscriptionId in cellular
- * network request or an ethernet interface name in ethernet
- * network request.
- *
- * @deprecated Use {@link #setNetworkSpecifier(NetworkSpecifier)} instead.
- */
- @Deprecated
- public Builder setNetworkSpecifier(String networkSpecifier) {
- try {
- int subId = Integer.parseInt(networkSpecifier);
- return setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
- .setSubscriptionId(subId).build());
- } catch (NumberFormatException nfe) {
- // An EthernetNetworkSpecifier or TestNetworkSpecifier does not accept null or empty
- // ("") strings. When network specifiers were strings a null string and an empty
- // string were considered equivalent. Hence no meaning is attached to a null or
- // empty ("") string.
- if (TextUtils.isEmpty(networkSpecifier)) {
- return setNetworkSpecifier((NetworkSpecifier) null);
- } else if (mNetworkCapabilities.hasTransport(TRANSPORT_TEST)) {
- return setNetworkSpecifier(new TestNetworkSpecifier(networkSpecifier));
- } else {
- return setNetworkSpecifier(new EthernetNetworkSpecifier(networkSpecifier));
- }
- }
- }
-
- /**
- * Sets the optional bearer specific network specifier.
- * This has no meaning if a single transport is also not specified, so calling
- * this without a single transport set will generate an exception, as will
- * subsequently adding or removing transports after this is set.
- * </p>
- *
- * @param networkSpecifier A concrete, parcelable framework class that extends
- * NetworkSpecifier.
- */
- public Builder setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
- if (networkSpecifier instanceof MatchAllNetworkSpecifier) {
- throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted");
- }
- mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
- // Do not touch NOT_VCN_MANAGED if the caller needs to access to a very specific
- // Network.
- mShouldDeduceNotVcnManaged = false;
- return this;
- }
-
- /**
- * Sets the signal strength. This is a signed integer, with higher values indicating a
- * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same
- * RSSI units reported by WifiManager.
- * <p>
- * Note that when used to register a network callback, this specifies the minimum acceptable
- * signal strength. When received as the state of an existing network it specifies the
- * current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when
- * received and has no effect when requesting a callback.
- *
- * <p>This method requires the caller to hold the
- * {@link android.Manifest.permission#NETWORK_SIGNAL_STRENGTH_WAKEUP} permission
- *
- * @param signalStrength the bearer-specific signal strength.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP)
- public @NonNull Builder setSignalStrength(int signalStrength) {
- mNetworkCapabilities.setSignalStrength(signalStrength);
- return this;
- }
-
- /**
- * Deduce the NET_CAPABILITY_NOT_VCN_MANAGED capability from other capabilities
- * and user intention, which includes:
- * 1. For the requests that don't have anything besides
- * {@link #VCN_SUPPORTED_CAPABILITIES}, add the NET_CAPABILITY_NOT_VCN_MANAGED to
- * allow the callers automatically utilize VCN networks if available.
- * 2. For the requests that explicitly add or remove NET_CAPABILITY_NOT_VCN_MANAGED,
- * or has clear intention of tracking specific network,
- * do not alter them to allow user fire request that suits their need.
- *
- * @hide
- */
- private void deduceNotVcnManagedCapability(final NetworkCapabilities nc) {
- if (!mShouldDeduceNotVcnManaged) return;
- for (final int cap : nc.getCapabilities()) {
- if (!VCN_SUPPORTED_CAPABILITIES.contains(cap)) return;
- }
- nc.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
- }
-
- /**
- * Sets the optional subscription ID set.
- * <p>
- * This specify the subscription IDs requirement.
- * A network will satisfy this request only if it matches one of the subIds in this set.
- * An empty set matches all networks, including those without a subId.
- *
- * <p>Registering a NetworkRequest with a non-empty set of subIds requires the
- * NETWORK_FACTORY permission.
- *
- * @param subIds A {@code Set} that represents subscription IDs.
- * @hide
- */
- @NonNull
- @SystemApi
- public Builder setSubscriptionIds(@NonNull Set<Integer> subIds) {
- mNetworkCapabilities.setSubscriptionIds(subIds);
- return this;
- }
-
- /**
- * Specifies whether the built request should also match networks that do not apply to the
- * calling UID.
- *
- * By default, the built request will only match networks that apply to the calling UID.
- * If this method is called with {@code true}, the built request will match any network on
- * the system that matches the other parameters of the request. In this case, any
- * information in the built request that is subject to redaction for security or privacy
- * purposes, such as a {@link NetworkSpecifier}, will be redacted or removed to prevent the
- * application deducing sensitive information.
- *
- * @param include Whether to match networks that do not apply to the calling UID.
- * @return The builder to facilitate chaining.
- */
- @NonNull
- public Builder setIncludeOtherUidNetworks(boolean include) {
- if (include) {
- mNetworkCapabilities.setUids(null);
- } else {
- mNetworkCapabilities.setSingleUid(Process.myUid());
- }
- return this;
- }
- }
-
- // implement the Parcelable interface
- public int describeContents() {
- return 0;
- }
- public void writeToParcel(Parcel dest, int flags) {
- networkCapabilities.writeToParcel(dest, flags);
- dest.writeInt(legacyType);
- dest.writeInt(requestId);
- dest.writeString(type.name());
- }
-
- public static final @android.annotation.NonNull Creator<NetworkRequest> CREATOR =
- new Creator<NetworkRequest>() {
- public NetworkRequest createFromParcel(Parcel in) {
- NetworkCapabilities nc = NetworkCapabilities.CREATOR.createFromParcel(in);
- int legacyType = in.readInt();
- int requestId = in.readInt();
- Type type = Type.valueOf(in.readString()); // IllegalArgumentException if invalid.
- NetworkRequest result = new NetworkRequest(nc, legacyType, requestId, type);
- return result;
- }
- public NetworkRequest[] newArray(int size) {
- return new NetworkRequest[size];
- }
- };
-
- /**
- * Returns true iff. this NetworkRequest is of type LISTEN.
- *
- * @hide
- */
- public boolean isListen() {
- return type == Type.LISTEN;
- }
-
- /**
- * Returns true iff. this NetworkRequest is of type LISTEN_FOR_BEST.
- *
- * @hide
- */
- public boolean isListenForBest() {
- return type == Type.LISTEN_FOR_BEST;
- }
-
- /**
- * Returns true iff. the contained NetworkRequest is one that:
- *
- * - should be associated with at most one satisfying network
- * at a time;
- *
- * - should cause a network to be kept up, but not necessarily in
- * the foreground, if it is the best network which can satisfy the
- * NetworkRequest.
- *
- * For full detail of how isRequest() is used for pairing Networks with
- * NetworkRequests read rematchNetworkAndRequests().
- *
- * @hide
- */
- public boolean isRequest() {
- return type == Type.REQUEST || type == Type.BACKGROUND_REQUEST;
- }
-
- /**
- * Returns true iff. this NetworkRequest is of type BACKGROUND_REQUEST.
- *
- * @hide
- */
- public boolean isBackgroundRequest() {
- return type == Type.BACKGROUND_REQUEST;
- }
-
- /**
- * @see Builder#addCapability(int)
- */
- public boolean hasCapability(@NetCapability int capability) {
- return networkCapabilities.hasCapability(capability);
- }
-
- /**
- * @see Builder#addForbiddenCapability(int)
- *
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public boolean hasForbiddenCapability(@NetCapability int capability) {
- return networkCapabilities.hasForbiddenCapability(capability);
- }
-
- /**
- * Returns true if and only if the capabilities requested in this NetworkRequest are satisfied
- * by the provided {@link NetworkCapabilities}.
- *
- * @param nc Capabilities that should satisfy this NetworkRequest. null capabilities do not
- * satisfy any request.
- */
- public boolean canBeSatisfiedBy(@Nullable NetworkCapabilities nc) {
- return networkCapabilities.satisfiedByNetworkCapabilities(nc);
- }
-
- /**
- * @see Builder#addTransportType(int)
- */
- public boolean hasTransport(@Transport int transportType) {
- return networkCapabilities.hasTransport(transportType);
- }
-
- /**
- * @see Builder#setNetworkSpecifier(NetworkSpecifier)
- */
- @Nullable
- public NetworkSpecifier getNetworkSpecifier() {
- return networkCapabilities.getNetworkSpecifier();
- }
-
- /**
- * @return the uid of the app making the request.
- *
- * Note: This could return {@link Process#INVALID_UID} if the {@link NetworkRequest} object was
- * not obtained from {@link ConnectivityManager}.
- * @hide
- */
- @SystemApi
- public int getRequestorUid() {
- return networkCapabilities.getRequestorUid();
- }
-
- /**
- * @return the package name of the app making the request.
- *
- * Note: This could return {@code null} if the {@link NetworkRequest} object was not obtained
- * from {@link ConnectivityManager}.
- * @hide
- */
- @SystemApi
- @Nullable
- public String getRequestorPackageName() {
- return networkCapabilities.getRequestorPackageName();
- }
-
- public String toString() {
- return "NetworkRequest [ " + type + " id=" + requestId +
- (legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") +
- ", " + networkCapabilities.toString() + " ]";
- }
-
- public boolean equals(@Nullable Object obj) {
- if (obj instanceof NetworkRequest == false) return false;
- NetworkRequest that = (NetworkRequest)obj;
- return (that.legacyType == this.legacyType &&
- that.requestId == this.requestId &&
- that.type == this.type &&
- Objects.equals(that.networkCapabilities, this.networkCapabilities));
- }
-
- public int hashCode() {
- return Objects.hash(requestId, legacyType, networkCapabilities, type);
- }
-
- /**
- * Gets all the capabilities set on this {@code NetworkRequest} instance.
- *
- * @return an array of capability values for this instance.
- */
- @NonNull
- public @NetCapability int[] getCapabilities() {
- // No need to make a defensive copy here as NC#getCapabilities() already returns
- // a new array.
- return networkCapabilities.getCapabilities();
- }
-
- /**
- * Gets all the forbidden capabilities set on this {@code NetworkRequest} instance.
- *
- * @return an array of forbidden capability values for this instance.
- *
- * @hide
- */
- @NonNull
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public @NetCapability int[] getForbiddenCapabilities() {
- // No need to make a defensive copy here as NC#getForbiddenCapabilities() already returns
- // a new array.
- return networkCapabilities.getForbiddenCapabilities();
- }
-
- /**
- * Gets all the transports set on this {@code NetworkRequest} instance.
- *
- * @return an array of transport type values for this instance.
- */
- @NonNull
- public @Transport int[] getTransportTypes() {
- // No need to make a defensive copy here as NC#getTransportTypes() already returns
- // a new array.
- return networkCapabilities.getTransportTypes();
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkScore.java b/packages/Connectivity/framework/src/android/net/NetworkScore.java
deleted file mode 100644
index 7be7deb..0000000
--- a/packages/Connectivity/framework/src/android/net/NetworkScore.java
+++ /dev/null
@@ -1,328 +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.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Object representing the quality of a network as perceived by the user.
- *
- * A NetworkScore object represents the characteristics of a network that affects how good the
- * network is considered for a particular use.
- * @hide
- */
-@SystemApi
-public final class NetworkScore implements Parcelable {
- // This will be removed soon. Do *NOT* depend on it for any new code that is not part of
- // a migration.
- private final int mLegacyInt;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- KEEP_CONNECTED_NONE,
- KEEP_CONNECTED_FOR_HANDOVER
- })
- public @interface KeepConnectedReason { }
-
- /**
- * Do not keep this network connected if there is no outstanding request for it.
- */
- public static final int KEEP_CONNECTED_NONE = 0;
- /**
- * Keep this network connected even if there is no outstanding request for it, because it
- * is being considered for handover.
- */
- public static final int KEEP_CONNECTED_FOR_HANDOVER = 1;
-
- // Agent-managed policies
- // This network should lose to a wifi that has ever been validated
- // NOTE : temporarily this policy is managed by ConnectivityService, because of legacy. The
- // legacy design has this bit global to the system and tacked on WiFi which means it will affect
- // networks from carriers who don't want it and non-carrier networks, which is bad for users.
- // The S design has this on mobile networks only, so this can be fixed eventually ; as CS
- // doesn't know what carriers need this bit, the initial S implementation will continue to
- // affect other carriers but will at least leave non-mobile networks alone. Eventually Telephony
- // should set this on networks from carriers that require it.
- /** @hide */
- public static final int POLICY_YIELD_TO_BAD_WIFI = 1;
- // This network is primary for this transport.
- /** @hide */
- public static final int POLICY_TRANSPORT_PRIMARY = 2;
- // This network is exiting : it will likely disconnect in a few seconds.
- /** @hide */
- public static final int POLICY_EXITING = 3;
-
- /** @hide */
- public static final int MIN_AGENT_MANAGED_POLICY = POLICY_YIELD_TO_BAD_WIFI;
- /** @hide */
- public static final int MAX_AGENT_MANAGED_POLICY = POLICY_EXITING;
-
- // Bitmask of all the policies applied to this score.
- private final long mPolicies;
-
- private final int mKeepConnectedReason;
-
- /** @hide */
- NetworkScore(final int legacyInt, final long policies,
- @KeepConnectedReason final int keepConnectedReason) {
- mLegacyInt = legacyInt;
- mPolicies = policies;
- mKeepConnectedReason = keepConnectedReason;
- }
-
- private NetworkScore(@NonNull final Parcel in) {
- mLegacyInt = in.readInt();
- mPolicies = in.readLong();
- mKeepConnectedReason = in.readInt();
- }
-
- /**
- * Get the legacy int score embedded in this NetworkScore.
- * @see Builder#setLegacyInt(int)
- */
- public int getLegacyInt() {
- return mLegacyInt;
- }
-
- /**
- * Returns the keep-connected reason, or KEEP_CONNECTED_NONE.
- */
- public int getKeepConnectedReason() {
- return mKeepConnectedReason;
- }
-
- /**
- * @return whether this score has a particular policy.
- *
- * @hide
- */
- @VisibleForTesting
- public boolean hasPolicy(final int policy) {
- return 0 != (mPolicies & (1L << policy));
- }
-
- /**
- * To the exclusive usage of FullScore
- * @hide
- */
- public long getPolicies() {
- return mPolicies;
- }
-
- /**
- * Whether this network should yield to a previously validated wifi gone bad.
- *
- * If this policy is set, other things being equal, the device will prefer a previously
- * validated WiFi even if this network is validated and the WiFi is not.
- * If this policy is not set, the device prefers the validated network.
- *
- * @hide
- */
- // TODO : Unhide this for telephony and have telephony call it on the relevant carriers.
- // In the mean time this is handled by Connectivity in a backward-compatible manner.
- public boolean shouldYieldToBadWifi() {
- return hasPolicy(POLICY_YIELD_TO_BAD_WIFI);
- }
-
- /**
- * Whether this network is primary for this transport.
- *
- * When multiple networks of the same transport are active, the device prefers the ones that
- * are primary. This is meant in particular for DS-DA devices with a user setting to choose the
- * default SIM card, or for WiFi STA+STA and make-before-break cases.
- *
- * @hide
- */
- @SystemApi
- public boolean isTransportPrimary() {
- return hasPolicy(POLICY_TRANSPORT_PRIMARY);
- }
-
- /**
- * Whether this network is exiting.
- *
- * If this policy is set, the device will expect this network to disconnect within seconds.
- * It will try to migrate to some other network if any is available, policy permitting, to
- * avoid service disruption.
- * This is useful in particular when a good cellular network is available and WiFi is getting
- * weak and risks disconnecting soon. The WiFi network should be marked as exiting so that
- * the device will prefer the reliable mobile network over this soon-to-be-lost WiFi.
- *
- * @hide
- */
- @SystemApi
- public boolean isExiting() {
- return hasPolicy(POLICY_EXITING);
- }
-
- @Override
- public String toString() {
- return "Score(" + mLegacyInt + " ; Policies : " + mPolicies + ")";
- }
-
- @Override
- public void writeToParcel(@NonNull final Parcel dest, final int flags) {
- dest.writeInt(mLegacyInt);
- dest.writeLong(mPolicies);
- dest.writeInt(mKeepConnectedReason);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @NonNull public static final Creator<NetworkScore> CREATOR = new Creator<>() {
- @Override
- @NonNull
- public NetworkScore createFromParcel(@NonNull final Parcel in) {
- return new NetworkScore(in);
- }
-
- @Override
- @NonNull
- public NetworkScore[] newArray(int size) {
- return new NetworkScore[size];
- }
- };
-
- /**
- * A builder for NetworkScore.
- */
- public static final class Builder {
- private static final long POLICY_NONE = 0L;
- private static final int INVALID_LEGACY_INT = Integer.MIN_VALUE;
- private int mLegacyInt = INVALID_LEGACY_INT;
- private int mKeepConnectedReason = KEEP_CONNECTED_NONE;
- private int mPolicies = 0;
-
- /**
- * Sets the legacy int for this score.
- *
- * This will be used for measurements and logs, but will no longer be used for ranking
- * networks against each other. Callers that existed before Android S should send what
- * they used to send as the int score.
- *
- * @param score the legacy int
- * @return this
- */
- @NonNull
- public Builder setLegacyInt(final int score) {
- mLegacyInt = score;
- return this;
- }
-
-
- /**
- * Set for a network that should never be preferred to a wifi that has ever been validated
- *
- * If this policy is set, other things being equal, the device will prefer a previously
- * validated WiFi even if this network is validated and the WiFi is not.
- * If this policy is not set, the device prefers the validated network.
- *
- * @return this builder
- * @hide
- */
- // TODO : Unhide this for telephony and have telephony call it on the relevant carriers.
- // In the mean time this is handled by Connectivity in a backward-compatible manner.
- @NonNull
- public Builder setShouldYieldToBadWifi(final boolean val) {
- if (val) {
- mPolicies |= (1L << POLICY_YIELD_TO_BAD_WIFI);
- } else {
- mPolicies &= ~(1L << POLICY_YIELD_TO_BAD_WIFI);
- }
- return this;
- }
-
- /**
- * Set for a network that is primary for this transport.
- *
- * When multiple networks of the same transport are active, the device prefers the ones that
- * are primary. This is meant in particular for DS-DA devices with a user setting to choose
- * the default SIM card, or for WiFi STA+STA and make-before-break cases.
- *
- * @return this builder
- * @hide
- */
- @SystemApi
- @NonNull
- public Builder setTransportPrimary(final boolean val) {
- if (val) {
- mPolicies |= (1L << POLICY_TRANSPORT_PRIMARY);
- } else {
- mPolicies &= ~(1L << POLICY_TRANSPORT_PRIMARY);
- }
- return this;
- }
-
- /**
- * Set for a network that will likely disconnect in a few seconds.
- *
- * If this policy is set, the device will expect this network to disconnect within seconds.
- * It will try to migrate to some other network if any is available, policy permitting, to
- * avoid service disruption.
- * This is useful in particular when a good cellular network is available and WiFi is
- * getting weak and risks disconnecting soon. The WiFi network should be marked as exiting
- * so that the device will prefer the reliable mobile network over this soon-to-be-lost
- * WiFi.
- *
- * @return this builder
- * @hide
- */
- @SystemApi
- @NonNull
- public Builder setExiting(final boolean val) {
- if (val) {
- mPolicies |= (1L << POLICY_EXITING);
- } else {
- mPolicies &= ~(1L << POLICY_EXITING);
- }
- return this;
- }
-
- /**
- * Set the keep-connected reason.
- *
- * This can be reset by calling it again with {@link KEEP_CONNECTED_NONE}.
- */
- @NonNull
- public Builder setKeepConnectedReason(@KeepConnectedReason final int reason) {
- mKeepConnectedReason = reason;
- return this;
- }
-
- /**
- * Builds this NetworkScore.
- * @return The built NetworkScore object.
- */
- @NonNull
- public NetworkScore build() {
- return new NetworkScore(mLegacyInt, mPolicies, mKeepConnectedReason);
- }
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkState.java b/packages/Connectivity/framework/src/android/net/NetworkState.java
deleted file mode 100644
index 9b69674..0000000
--- a/packages/Connectivity/framework/src/android/net/NetworkState.java
+++ /dev/null
@@ -1,130 +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 android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-/**
- * Snapshot of network state.
- *
- * @hide
- */
-public class NetworkState implements Parcelable {
- private static final boolean VALIDATE_ROAMING_STATE = false;
-
- // TODO: remove and make members @NonNull.
- public static final NetworkState EMPTY = new NetworkState();
-
- public final NetworkInfo networkInfo;
- public final LinkProperties linkProperties;
- public final NetworkCapabilities networkCapabilities;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public final Network network;
- public final String subscriberId;
- public final int legacyNetworkType;
-
- private NetworkState() {
- networkInfo = null;
- linkProperties = null;
- networkCapabilities = null;
- network = null;
- subscriberId = null;
- legacyNetworkType = 0;
- }
-
- public NetworkState(int legacyNetworkType, @NonNull LinkProperties linkProperties,
- @NonNull NetworkCapabilities networkCapabilities, @NonNull Network network,
- @Nullable String subscriberId) {
- this(legacyNetworkType, new NetworkInfo(legacyNetworkType, 0, null, null), linkProperties,
- networkCapabilities, network, subscriberId);
- }
-
- // Constructor that used internally in ConnectivityService mainline module.
- public NetworkState(@NonNull NetworkInfo networkInfo, @NonNull LinkProperties linkProperties,
- @NonNull NetworkCapabilities networkCapabilities, @NonNull Network network,
- @Nullable String subscriberId) {
- this(networkInfo.getType(), networkInfo, linkProperties,
- networkCapabilities, network, subscriberId);
- }
-
- public NetworkState(int legacyNetworkType, @NonNull NetworkInfo networkInfo,
- @NonNull LinkProperties linkProperties,
- @NonNull NetworkCapabilities networkCapabilities, @NonNull Network network,
- @Nullable String subscriberId) {
- this.networkInfo = networkInfo;
- this.linkProperties = linkProperties;
- this.networkCapabilities = networkCapabilities;
- this.network = network;
- this.subscriberId = subscriberId;
- this.legacyNetworkType = legacyNetworkType;
-
- // This object is an atomic view of a network, so the various components
- // should always agree on roaming state.
- if (VALIDATE_ROAMING_STATE && networkInfo != null && networkCapabilities != null) {
- if (networkInfo.isRoaming() == networkCapabilities
- .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)) {
- Log.wtf("NetworkState", "Roaming state disagreement between " + networkInfo
- + " and " + networkCapabilities);
- }
- }
- }
-
- @UnsupportedAppUsage
- public NetworkState(Parcel in) {
- networkInfo = in.readParcelable(null);
- linkProperties = in.readParcelable(null);
- networkCapabilities = in.readParcelable(null);
- network = in.readParcelable(null);
- subscriberId = in.readString();
- legacyNetworkType = in.readInt();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeParcelable(networkInfo, flags);
- out.writeParcelable(linkProperties, flags);
- out.writeParcelable(networkCapabilities, flags);
- out.writeParcelable(network, flags);
- out.writeString(subscriberId);
- out.writeInt(legacyNetworkType);
- }
-
- @UnsupportedAppUsage
- @NonNull
- public static final Creator<NetworkState> CREATOR = new Creator<NetworkState>() {
- @Override
- public NetworkState createFromParcel(Parcel in) {
- return new NetworkState(in);
- }
-
- @Override
- public NetworkState[] newArray(int size) {
- return new NetworkState[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkUtils.java b/packages/Connectivity/framework/src/android/net/NetworkUtils.java
deleted file mode 100644
index 2679b62..0000000
--- a/packages/Connectivity/framework/src/android/net/NetworkUtils.java
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * Copyright (C) 2008 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.NETID_UNSET;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.system.ErrnoException;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.net.module.util.Inet4AddressUtils;
-
-import java.io.FileDescriptor;
-import java.math.BigInteger;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.Locale;
-import java.util.TreeSet;
-
-/**
- * Native methods for managing network interfaces.
- *
- * {@hide}
- */
-public class NetworkUtils {
- static {
- System.loadLibrary("framework-connectivity-jni");
- }
-
- private static final String TAG = "NetworkUtils";
-
- /**
- * Attaches a socket filter that drops all of incoming packets.
- * @param fd the socket's {@link FileDescriptor}.
- */
- public static native void attachDropAllBPFFilter(FileDescriptor fd) throws SocketException;
-
- /**
- * Detaches a socket filter.
- * @param fd the socket's {@link FileDescriptor}.
- */
- public static native void detachBPFFilter(FileDescriptor fd) throws SocketException;
-
- private static native boolean bindProcessToNetworkHandle(long netHandle);
-
- /**
- * Binds the current process to the network designated by {@code netId}. All sockets created
- * in the future (and not explicitly bound via a bound {@link SocketFactory} (see
- * {@link Network#getSocketFactory}) will be bound to this network. Note that if this
- * {@code Network} ever disconnects all sockets created in this way will cease to work. This
- * is by design so an application doesn't accidentally use sockets it thinks are still bound to
- * a particular {@code Network}. Passing NETID_UNSET clears the binding.
- */
- public static boolean bindProcessToNetwork(int netId) {
- return bindProcessToNetworkHandle(new Network(netId).getNetworkHandle());
- }
-
- private static native long getBoundNetworkHandleForProcess();
-
- /**
- * Return the netId last passed to {@link #bindProcessToNetwork}, or NETID_UNSET if
- * {@link #unbindProcessToNetwork} has been called since {@link #bindProcessToNetwork}.
- */
- public static int getBoundNetworkForProcess() {
- final long netHandle = getBoundNetworkHandleForProcess();
- return netHandle == 0L ? NETID_UNSET : Network.fromNetworkHandle(netHandle).getNetId();
- }
-
- /**
- * Binds host resolutions performed by this process to the network designated by {@code netId}.
- * {@link #bindProcessToNetwork} takes precedence over this setting. Passing NETID_UNSET clears
- * the binding.
- *
- * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
- */
- @Deprecated
- public native static boolean bindProcessToNetworkForHostResolution(int netId);
-
- private static native int bindSocketToNetworkHandle(FileDescriptor fd, long netHandle);
-
- /**
- * Explicitly binds {@code fd} to the network designated by {@code netId}. This
- * overrides any binding via {@link #bindProcessToNetwork}.
- * @return 0 on success or negative errno on failure.
- */
- public static int bindSocketToNetwork(FileDescriptor fd, int netId) {
- return bindSocketToNetworkHandle(fd, new Network(netId).getNetworkHandle());
- }
-
- /**
- * Determine if {@code uid} can access network designated by {@code netId}.
- * @return {@code true} if {@code uid} can access network, {@code false} otherwise.
- */
- public static boolean queryUserAccess(int uid, int netId) {
- // TODO (b/183485986): remove this method
- return false;
- }
-
- private static native FileDescriptor resNetworkSend(
- long netHandle, byte[] msg, int msglen, int flags) throws ErrnoException;
-
- /**
- * DNS resolver series jni method.
- * Issue the query {@code msg} on the network designated by {@code netId}.
- * {@code flags} is an additional config to control actual querying behavior.
- * @return a file descriptor to watch for read events
- */
- public static FileDescriptor resNetworkSend(
- int netId, byte[] msg, int msglen, int flags) throws ErrnoException {
- return resNetworkSend(new Network(netId).getNetworkHandle(), msg, msglen, flags);
- }
-
- private static native FileDescriptor resNetworkQuery(
- long netHandle, String dname, int nsClass, int nsType, int flags) throws ErrnoException;
-
- /**
- * DNS resolver series jni method.
- * Look up the {@code nsClass} {@code nsType} Resource Record (RR) associated
- * with Domain Name {@code dname} on the network designated by {@code netId}.
- * {@code flags} is an additional config to control actual querying behavior.
- * @return a file descriptor to watch for read events
- */
- public static FileDescriptor resNetworkQuery(
- int netId, String dname, int nsClass, int nsType, int flags) throws ErrnoException {
- return resNetworkQuery(new Network(netId).getNetworkHandle(), dname, nsClass, nsType,
- flags);
- }
-
- /**
- * DNS resolver series jni method.
- * Read a result for the query associated with the {@code fd}.
- * @return DnsResponse containing blob answer and rcode
- */
- public static native DnsResolver.DnsResponse resNetworkResult(FileDescriptor fd)
- throws ErrnoException;
-
- /**
- * DNS resolver series jni method.
- * Attempts to cancel the in-progress query associated with the {@code fd}.
- */
- public static native void resNetworkCancel(FileDescriptor fd);
-
- /**
- * DNS resolver series jni method.
- * Attempts to get network which resolver will use if no network is explicitly selected.
- */
- public static native Network getDnsNetwork() throws ErrnoException;
-
- /**
- * Get the tcp repair window associated with the {@code fd}.
- *
- * @param fd the tcp socket's {@link FileDescriptor}.
- * @return a {@link TcpRepairWindow} object indicates tcp window size.
- */
- public static native TcpRepairWindow getTcpRepairWindow(FileDescriptor fd)
- throws ErrnoException;
-
- /**
- * @see Inet4AddressUtils#intToInet4AddressHTL(int)
- * @deprecated Use either {@link Inet4AddressUtils#intToInet4AddressHTH(int)}
- * or {@link Inet4AddressUtils#intToInet4AddressHTL(int)}
- */
- @Deprecated
- @UnsupportedAppUsage
- public static InetAddress intToInetAddress(int hostAddress) {
- return Inet4AddressUtils.intToInet4AddressHTL(hostAddress);
- }
-
- /**
- * @see Inet4AddressUtils#inet4AddressToIntHTL(Inet4Address)
- * @deprecated Use either {@link Inet4AddressUtils#inet4AddressToIntHTH(Inet4Address)}
- * or {@link Inet4AddressUtils#inet4AddressToIntHTL(Inet4Address)}
- */
- @Deprecated
- public static int inetAddressToInt(Inet4Address inetAddr)
- throws IllegalArgumentException {
- return Inet4AddressUtils.inet4AddressToIntHTL(inetAddr);
- }
-
- /**
- * @see Inet4AddressUtils#prefixLengthToV4NetmaskIntHTL(int)
- * @deprecated Use either {@link Inet4AddressUtils#prefixLengthToV4NetmaskIntHTH(int)}
- * or {@link Inet4AddressUtils#prefixLengthToV4NetmaskIntHTL(int)}
- */
- @Deprecated
- @UnsupportedAppUsage
- public static int prefixLengthToNetmaskInt(int prefixLength)
- throws IllegalArgumentException {
- return Inet4AddressUtils.prefixLengthToV4NetmaskIntHTL(prefixLength);
- }
-
- /**
- * Convert a IPv4 netmask integer to a prefix length
- * @param netmask as an integer (0xff000000 for a /8 subnet)
- * @return the network prefix length
- */
- public static int netmaskIntToPrefixLength(int netmask) {
- return Integer.bitCount(netmask);
- }
-
- /**
- * Convert an IPv4 netmask to a prefix length, checking that the netmask is contiguous.
- * @param netmask as a {@code Inet4Address}.
- * @return the network prefix length
- * @throws IllegalArgumentException the specified netmask was not contiguous.
- * @hide
- * @deprecated use {@link Inet4AddressUtils#netmaskToPrefixLength(Inet4Address)}
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @Deprecated
- public static int netmaskToPrefixLength(Inet4Address netmask) {
- // This is only here because some apps seem to be using it (@UnsupportedAppUsage).
- return Inet4AddressUtils.netmaskToPrefixLength(netmask);
- }
-
-
- /**
- * Create an InetAddress from a string where the string must be a standard
- * representation of a V4 or V6 address. Avoids doing a DNS lookup on failure
- * but it will throw an IllegalArgumentException in that case.
- * @param addrString
- * @return the InetAddress
- * @hide
- * @deprecated Use {@link InetAddresses#parseNumericAddress(String)}, if possible.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
- @Deprecated
- public static InetAddress numericToInetAddress(String addrString)
- throws IllegalArgumentException {
- return InetAddresses.parseNumericAddress(addrString);
- }
-
- /**
- * Returns the implicit netmask of an IPv4 address, as was the custom before 1993.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static int getImplicitNetmask(Inet4Address address) {
- // Only here because it seems to be used by apps
- return Inet4AddressUtils.getImplicitNetmask(address);
- }
-
- /**
- * Utility method to parse strings such as "192.0.2.5/24" or "2001:db8::cafe:d00d/64".
- * @hide
- */
- public static Pair<InetAddress, Integer> parseIpAndMask(String ipAndMaskString) {
- InetAddress address = null;
- int prefixLength = -1;
- try {
- String[] pieces = ipAndMaskString.split("/", 2);
- prefixLength = Integer.parseInt(pieces[1]);
- address = InetAddresses.parseNumericAddress(pieces[0]);
- } catch (NullPointerException e) { // Null string.
- } catch (ArrayIndexOutOfBoundsException e) { // No prefix length.
- } catch (NumberFormatException e) { // Non-numeric prefix.
- } catch (IllegalArgumentException e) { // Invalid IP address.
- }
-
- if (address == null || prefixLength == -1) {
- throw new IllegalArgumentException("Invalid IP address and mask " + ipAndMaskString);
- }
-
- return new Pair<InetAddress, Integer>(address, prefixLength);
- }
-
- /**
- * Utility method to parse strings such as "192.0.2.5/24" or "2001:db8::cafe:d00d/64".
- * @hide
- *
- * @deprecated This method is used only for IpPrefix and LinkAddress. Since Android S, use
- * {@link #parseIpAndMask(String)}, if possible.
- */
- @Deprecated
- public static Pair<InetAddress, Integer> legacyParseIpAndMask(String ipAndMaskString) {
- InetAddress address = null;
- int prefixLength = -1;
- try {
- String[] pieces = ipAndMaskString.split("/", 2);
- prefixLength = Integer.parseInt(pieces[1]);
- if (pieces[0] == null || pieces[0].isEmpty()) {
- final byte[] bytes = new byte[16];
- bytes[15] = 1;
- return new Pair<InetAddress, Integer>(Inet6Address.getByAddress(
- "ip6-localhost"/* host */, bytes, 0 /* scope_id */), prefixLength);
- }
-
- if (pieces[0].startsWith("[")
- && pieces[0].endsWith("]")
- && pieces[0].indexOf(':') != -1) {
- pieces[0] = pieces[0].substring(1, pieces[0].length() - 1);
- }
- address = InetAddresses.parseNumericAddress(pieces[0]);
- } catch (NullPointerException e) { // Null string.
- } catch (ArrayIndexOutOfBoundsException e) { // No prefix length.
- } catch (NumberFormatException e) { // Non-numeric prefix.
- } catch (IllegalArgumentException e) { // Invalid IP address.
- } catch (UnknownHostException e) { // IP address length is illegal
- }
-
- if (address == null || prefixLength == -1) {
- throw new IllegalArgumentException("Invalid IP address and mask " + ipAndMaskString);
- }
-
- return new Pair<InetAddress, Integer>(address, prefixLength);
- }
-
- /**
- * Convert a 32 char hex string into a Inet6Address.
- * throws a runtime exception if the string isn't 32 chars, isn't hex or can't be
- * made into an Inet6Address
- * @param addrHexString a 32 character hex string representing an IPv6 addr
- * @return addr an InetAddress representation for the string
- */
- public static InetAddress hexToInet6Address(String addrHexString)
- throws IllegalArgumentException {
- try {
- return numericToInetAddress(String.format(Locale.US, "%s:%s:%s:%s:%s:%s:%s:%s",
- addrHexString.substring(0,4), addrHexString.substring(4,8),
- addrHexString.substring(8,12), addrHexString.substring(12,16),
- addrHexString.substring(16,20), addrHexString.substring(20,24),
- addrHexString.substring(24,28), addrHexString.substring(28,32)));
- } catch (Exception e) {
- Log.e("NetworkUtils", "error in hexToInet6Address(" + addrHexString + "): " + e);
- throw new IllegalArgumentException(e);
- }
- }
-
- /**
- * Trim leading zeros from IPv4 address strings
- * Our base libraries will interpret that as octel..
- * Must leave non v4 addresses and host names alone.
- * For example, 192.168.000.010 -> 192.168.0.10
- * TODO - fix base libraries and remove this function
- * @param addr a string representing an ip addr
- * @return a string propertly trimmed
- */
- @UnsupportedAppUsage
- public static String trimV4AddrZeros(String addr) {
- return Inet4AddressUtils.trimAddressZeros(addr);
- }
-
- /**
- * Returns a prefix set without overlaps.
- *
- * This expects the src set to be sorted from shorter to longer. Results are undefined
- * failing this condition. The returned prefix set is sorted in the same order as the
- * passed set, with the same comparator.
- */
- private static TreeSet<IpPrefix> deduplicatePrefixSet(final TreeSet<IpPrefix> src) {
- final TreeSet<IpPrefix> dst = new TreeSet<>(src.comparator());
- // Prefixes match addresses that share their upper part up to their length, therefore
- // the only kind of possible overlap in two prefixes is strict inclusion of the longer
- // (more restrictive) in the shorter (including equivalence if they have the same
- // length).
- // Because prefixes in the src set are sorted from shorter to longer, deduplicating
- // is done by simply iterating in order, and not adding any longer prefix that is
- // already covered by a shorter one.
- newPrefixes:
- for (IpPrefix newPrefix : src) {
- for (IpPrefix existingPrefix : dst) {
- if (existingPrefix.containsPrefix(newPrefix)) {
- continue newPrefixes;
- }
- }
- dst.add(newPrefix);
- }
- return dst;
- }
-
- /**
- * Returns how many IPv4 addresses match any of the prefixes in the passed ordered set.
- *
- * Obviously this returns an integral value between 0 and 2**32.
- * The behavior is undefined if any of the prefixes is not an IPv4 prefix or if the
- * set is not ordered smallest prefix to longer prefix.
- *
- * @param prefixes the set of prefixes, ordered by length
- */
- public static long routedIPv4AddressCount(final TreeSet<IpPrefix> prefixes) {
- long routedIPCount = 0;
- for (final IpPrefix prefix : deduplicatePrefixSet(prefixes)) {
- if (!prefix.isIPv4()) {
- Log.wtf(TAG, "Non-IPv4 prefix in routedIPv4AddressCount");
- }
- int rank = 32 - prefix.getPrefixLength();
- routedIPCount += 1L << rank;
- }
- return routedIPCount;
- }
-
- /**
- * Returns how many IPv6 addresses match any of the prefixes in the passed ordered set.
- *
- * This returns a BigInteger between 0 and 2**128.
- * The behavior is undefined if any of the prefixes is not an IPv6 prefix or if the
- * set is not ordered smallest prefix to longer prefix.
- */
- public static BigInteger routedIPv6AddressCount(final TreeSet<IpPrefix> prefixes) {
- BigInteger routedIPCount = BigInteger.ZERO;
- for (final IpPrefix prefix : deduplicatePrefixSet(prefixes)) {
- if (!prefix.isIPv6()) {
- Log.wtf(TAG, "Non-IPv6 prefix in routedIPv6AddressCount");
- }
- int rank = 128 - prefix.getPrefixLength();
- routedIPCount = routedIPCount.add(BigInteger.ONE.shiftLeft(rank));
- }
- return routedIPCount;
- }
-
-}
diff --git a/packages/Connectivity/framework/src/android/net/OemNetworkPreferences.java b/packages/Connectivity/framework/src/android/net/OemNetworkPreferences.java
deleted file mode 100644
index 2bb006d..0000000
--- a/packages/Connectivity/framework/src/android/net/OemNetworkPreferences.java
+++ /dev/null
@@ -1,276 +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.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Bundle;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Network preferences to set the default active network on a per-application basis as per a given
- * {@link OemNetworkPreference}. An example of this would be to set an application's network
- * preference to {@link #OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK} which would have the default
- * network for that application set to an unmetered network first if available and if not, it then
- * set that application's default network to an OEM managed network if available.
- *
- * @hide
- */
-@SystemApi
-public final class OemNetworkPreferences implements Parcelable {
- // Valid production preferences must be > 0, negative values reserved for testing
- /**
- * This preference is only to be used for testing and nothing else.
- * Use only TRANSPORT_TEST transport networks.
- * @hide
- */
- public static final int OEM_NETWORK_PREFERENCE_TEST_ONLY = -2;
-
- /**
- * This preference is only to be used for testing and nothing else.
- * If an unmetered network is available, use it.
- * Otherwise, if a network with the TRANSPORT_TEST transport is available, use it.
- * Otherwise, use the general default network.
- * @hide
- */
- public static final int OEM_NETWORK_PREFERENCE_TEST = -1;
-
- /**
- * Default in case this value is not set. Using it will result in an error.
- */
- public static final int OEM_NETWORK_PREFERENCE_UNINITIALIZED = 0;
-
- /**
- * If an unmetered network is available, use it.
- * Otherwise, if a network with the OEM_PAID capability is available, use it.
- * Otherwise, use the general default network.
- */
- public static final int OEM_NETWORK_PREFERENCE_OEM_PAID = 1;
-
- /**
- * If an unmetered network is available, use it.
- * Otherwise, if a network with the OEM_PAID capability is available, use it.
- * Otherwise, the app doesn't get a default network.
- */
- public static final int OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK = 2;
-
- /**
- * Use only NET_CAPABILITY_OEM_PAID networks.
- */
- public static final int OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY = 3;
-
- /**
- * Use only NET_CAPABILITY_OEM_PRIVATE networks.
- */
- public static final int OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY = 4;
-
- /**
- * The max allowed value for an OEM network preference.
- * @hide
- */
- public static final int OEM_NETWORK_PREFERENCE_MAX = OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
-
- @NonNull
- private final Bundle mNetworkMappings;
-
- /**
- * Return whether this object is empty.
- * @hide
- */
- public boolean isEmpty() {
- return mNetworkMappings.keySet().size() == 0;
- }
-
- /**
- * Return the currently built application package name to {@link OemNetworkPreference} mappings.
- * @return the current network preferences map.
- */
- @NonNull
- public Map<String, Integer> getNetworkPreferences() {
- return convertToUnmodifiableMap(mNetworkMappings);
- }
-
- private OemNetworkPreferences(@NonNull final Bundle networkMappings) {
- Objects.requireNonNull(networkMappings);
- mNetworkMappings = (Bundle) networkMappings.clone();
- }
-
- @Override
- public String toString() {
- return "OemNetworkPreferences{" + "mNetworkMappings=" + getNetworkPreferences() + '}';
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- OemNetworkPreferences that = (OemNetworkPreferences) o;
-
- return mNetworkMappings.size() == that.mNetworkMappings.size()
- && mNetworkMappings.toString().equals(that.mNetworkMappings.toString());
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mNetworkMappings);
- }
-
- /**
- * Builder used to create {@link OemNetworkPreferences} objects. Specify the preferred Network
- * to package name mappings.
- */
- public static final class Builder {
- private final Bundle mNetworkMappings;
-
- public Builder() {
- mNetworkMappings = new Bundle();
- }
-
- /**
- * Constructor to populate the builder's values with an already built
- * {@link OemNetworkPreferences}.
- * @param preferences the {@link OemNetworkPreferences} to populate with.
- */
- public Builder(@NonNull final OemNetworkPreferences preferences) {
- Objects.requireNonNull(preferences);
- mNetworkMappings = (Bundle) preferences.mNetworkMappings.clone();
- }
-
- /**
- * Add a network preference for a given package. Previously stored values for the given
- * package will be overwritten.
- *
- * @param packageName full package name (e.g.: "com.google.apps.contacts") of the app
- * to use the given preference
- * @param preference the desired network preference to use
- * @return The builder to facilitate chaining.
- */
- @NonNull
- public Builder addNetworkPreference(@NonNull final String packageName,
- @OemNetworkPreference final int preference) {
- Objects.requireNonNull(packageName);
- mNetworkMappings.putInt(packageName, preference);
- return this;
- }
-
- /**
- * Remove a network preference for a given package.
- *
- * @param packageName full package name (e.g.: "com.google.apps.contacts") of the app to
- * remove a preference for.
- * @return The builder to facilitate chaining.
- */
- @NonNull
- public Builder clearNetworkPreference(@NonNull final String packageName) {
- Objects.requireNonNull(packageName);
- mNetworkMappings.remove(packageName);
- return this;
- }
-
- /**
- * Build {@link OemNetworkPreferences} return the current OEM network preferences.
- */
- @NonNull
- public OemNetworkPreferences build() {
- return new OemNetworkPreferences(mNetworkMappings);
- }
- }
-
- private static Map<String, Integer> convertToUnmodifiableMap(@NonNull final Bundle bundle) {
- final Map<String, Integer> networkPreferences = new HashMap<>();
- for (final String key : bundle.keySet()) {
- networkPreferences.put(key, bundle.getInt(key));
- }
- return Collections.unmodifiableMap(networkPreferences);
- }
-
- /** @hide */
- @IntDef(prefix = "OEM_NETWORK_PREFERENCE_", value = {
- OEM_NETWORK_PREFERENCE_TEST_ONLY,
- OEM_NETWORK_PREFERENCE_TEST,
- OEM_NETWORK_PREFERENCE_UNINITIALIZED,
- OEM_NETWORK_PREFERENCE_OEM_PAID,
- OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK,
- OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY,
- OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface OemNetworkPreference {}
-
- /**
- * Return the string value for OemNetworkPreference
- *
- * @param value int value of OemNetworkPreference
- * @return string version of OemNetworkPreference
- *
- * @hide
- */
- @NonNull
- public static String oemNetworkPreferenceToString(@OemNetworkPreference int value) {
- switch (value) {
- case OEM_NETWORK_PREFERENCE_TEST_ONLY:
- return "OEM_NETWORK_PREFERENCE_TEST_ONLY";
- case OEM_NETWORK_PREFERENCE_TEST:
- return "OEM_NETWORK_PREFERENCE_TEST";
- case OEM_NETWORK_PREFERENCE_UNINITIALIZED:
- return "OEM_NETWORK_PREFERENCE_UNINITIALIZED";
- case OEM_NETWORK_PREFERENCE_OEM_PAID:
- return "OEM_NETWORK_PREFERENCE_OEM_PAID";
- case OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK:
- return "OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK";
- case OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY:
- return "OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY";
- case OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY:
- return "OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY";
- default:
- return Integer.toHexString(value);
- }
- }
-
- @Override
- public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
- dest.writeBundle(mNetworkMappings);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @NonNull
- public static final Parcelable.Creator<OemNetworkPreferences> CREATOR =
- new Parcelable.Creator<OemNetworkPreferences>() {
- @Override
- public OemNetworkPreferences[] newArray(int size) {
- return new OemNetworkPreferences[size];
- }
-
- @Override
- public OemNetworkPreferences createFromParcel(@NonNull android.os.Parcel in) {
- return new OemNetworkPreferences(
- in.readBundle(getClass().getClassLoader()));
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/ParseException.java b/packages/Connectivity/framework/src/android/net/ParseException.java
deleted file mode 100644
index 9d4727a..0000000
--- a/packages/Connectivity/framework/src/android/net/ParseException.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2006 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.annotation.NonNull;
-
-/**
- * Thrown when parsing failed.
- */
-// See non-public class {@link WebAddress}.
-public class ParseException extends RuntimeException {
- public String response;
-
- public ParseException(@NonNull String response) {
- super(response);
- this.response = response;
- }
-
- public ParseException(@NonNull String response, @NonNull Throwable cause) {
- super(response, cause);
- this.response = response;
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/ProxyInfo.java b/packages/Connectivity/framework/src/android/net/ProxyInfo.java
deleted file mode 100644
index 0deda37..0000000
--- a/packages/Connectivity/framework/src/android/net/ProxyInfo.java
+++ /dev/null
@@ -1,370 +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 android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import com.android.net.module.util.ProxyUtils;
-
-import java.net.InetSocketAddress;
-import java.net.URLConnection;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Describes a proxy configuration.
- *
- * Proxy configurations are already integrated within the {@code java.net} and
- * Apache HTTP stack. So {@link URLConnection} and Apache's {@code HttpClient} will use
- * them automatically.
- *
- * Other HTTP stacks will need to obtain the proxy info by watching for the
- * {@link Proxy#PROXY_CHANGE_ACTION} broadcast and calling methods such as
- * {@link android.net.ConnectivityManager#getDefaultProxy}.
- */
-public class ProxyInfo implements Parcelable {
-
- private final String mHost;
- private final int mPort;
- private final String mExclusionList;
- private final String[] mParsedExclusionList;
- private final Uri mPacFileUrl;
-
- /**
- *@hide
- */
- public static final String LOCAL_EXCL_LIST = "";
- /**
- *@hide
- */
- public static final int LOCAL_PORT = -1;
- /**
- *@hide
- */
- public static final String LOCAL_HOST = "localhost";
-
- /**
- * Constructs a {@link ProxyInfo} object that points at a Direct proxy
- * on the specified host and port.
- */
- public static ProxyInfo buildDirectProxy(String host, int port) {
- return new ProxyInfo(host, port, null);
- }
-
- /**
- * Constructs a {@link ProxyInfo} object that points at a Direct proxy
- * on the specified host and port.
- *
- * The proxy will not be used to access any host in exclusion list, exclList.
- *
- * @param exclList Hosts to exclude using the proxy on connections for. These
- * hosts can use wildcards such as *.example.com.
- */
- public static ProxyInfo buildDirectProxy(String host, int port, List<String> exclList) {
- String[] array = exclList.toArray(new String[exclList.size()]);
- return new ProxyInfo(host, port, TextUtils.join(",", array), array);
- }
-
- /**
- * Construct a {@link ProxyInfo} that will download and run the PAC script
- * at the specified URL.
- */
- public static ProxyInfo buildPacProxy(Uri pacUri) {
- return new ProxyInfo(pacUri);
- }
-
- /**
- * Construct a {@link ProxyInfo} object that will download and run the PAC script at the
- * specified URL and port.
- */
- @NonNull
- public static ProxyInfo buildPacProxy(@NonNull Uri pacUrl, int port) {
- return new ProxyInfo(pacUrl, port);
- }
-
- /**
- * Create a ProxyProperties that points at a HTTP Proxy.
- * @hide
- */
- @UnsupportedAppUsage
- public ProxyInfo(String host, int port, String exclList) {
- mHost = host;
- mPort = port;
- mExclusionList = exclList;
- mParsedExclusionList = parseExclusionList(mExclusionList);
- mPacFileUrl = Uri.EMPTY;
- }
-
- /**
- * Create a ProxyProperties that points at a PAC URL.
- * @hide
- */
- public ProxyInfo(@NonNull Uri pacFileUrl) {
- mHost = LOCAL_HOST;
- mPort = LOCAL_PORT;
- mExclusionList = LOCAL_EXCL_LIST;
- mParsedExclusionList = parseExclusionList(mExclusionList);
- if (pacFileUrl == null) {
- throw new NullPointerException();
- }
- mPacFileUrl = pacFileUrl;
- }
-
- /**
- * Only used in PacProxyService after Local Proxy is bound.
- * @hide
- */
- public ProxyInfo(@NonNull Uri pacFileUrl, int localProxyPort) {
- mHost = LOCAL_HOST;
- mPort = localProxyPort;
- mExclusionList = LOCAL_EXCL_LIST;
- mParsedExclusionList = parseExclusionList(mExclusionList);
- if (pacFileUrl == null) {
- throw new NullPointerException();
- }
- mPacFileUrl = pacFileUrl;
- }
-
- private static String[] parseExclusionList(String exclusionList) {
- if (exclusionList == null) {
- return new String[0];
- } else {
- return exclusionList.toLowerCase(Locale.ROOT).split(",");
- }
- }
-
- private ProxyInfo(String host, int port, String exclList, String[] parsedExclList) {
- mHost = host;
- mPort = port;
- mExclusionList = exclList;
- mParsedExclusionList = parsedExclList;
- mPacFileUrl = Uri.EMPTY;
- }
-
- /**
- * A copy constructor to hold proxy properties.
- */
- public ProxyInfo(@Nullable ProxyInfo source) {
- if (source != null) {
- mHost = source.getHost();
- mPort = source.getPort();
- mPacFileUrl = source.mPacFileUrl;
- mExclusionList = source.getExclusionListAsString();
- mParsedExclusionList = source.mParsedExclusionList;
- } else {
- mHost = null;
- mPort = 0;
- mExclusionList = null;
- mParsedExclusionList = null;
- mPacFileUrl = Uri.EMPTY;
- }
- }
-
- /**
- * @hide
- */
- public InetSocketAddress getSocketAddress() {
- InetSocketAddress inetSocketAddress = null;
- try {
- inetSocketAddress = new InetSocketAddress(mHost, mPort);
- } catch (IllegalArgumentException e) { }
- return inetSocketAddress;
- }
-
- /**
- * Returns the URL of the current PAC script or null if there is
- * no PAC script.
- */
- public Uri getPacFileUrl() {
- return mPacFileUrl;
- }
-
- /**
- * When configured to use a Direct Proxy this returns the host
- * of the proxy.
- */
- public String getHost() {
- return mHost;
- }
-
- /**
- * When configured to use a Direct Proxy this returns the port
- * of the proxy
- */
- public int getPort() {
- return mPort;
- }
-
- /**
- * When configured to use a Direct Proxy this returns the list
- * of hosts for which the proxy is ignored.
- */
- public String[] getExclusionList() {
- return mParsedExclusionList;
- }
-
- /**
- * comma separated
- * @hide
- */
- @Nullable
- public String getExclusionListAsString() {
- return mExclusionList;
- }
-
- /**
- * Return true if the pattern of proxy is valid, otherwise return false.
- */
- public boolean isValid() {
- if (!Uri.EMPTY.equals(mPacFileUrl)) return true;
- return ProxyUtils.PROXY_VALID == ProxyUtils.validate(mHost == null ? "" : mHost,
- mPort == 0 ? "" : Integer.toString(mPort),
- mExclusionList == null ? "" : mExclusionList);
- }
-
- /**
- * @hide
- */
- public java.net.Proxy makeProxy() {
- java.net.Proxy proxy = java.net.Proxy.NO_PROXY;
- if (mHost != null) {
- try {
- InetSocketAddress inetSocketAddress = new InetSocketAddress(mHost, mPort);
- proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, inetSocketAddress);
- } catch (IllegalArgumentException e) {
- }
- }
- return proxy;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- if (!Uri.EMPTY.equals(mPacFileUrl)) {
- sb.append("PAC Script: ");
- sb.append(mPacFileUrl);
- }
- if (mHost != null) {
- sb.append("[");
- sb.append(mHost);
- sb.append("] ");
- sb.append(Integer.toString(mPort));
- if (mExclusionList != null) {
- sb.append(" xl=").append(mExclusionList);
- }
- } else {
- sb.append("[ProxyProperties.mHost == null]");
- }
- return sb.toString();
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (!(o instanceof ProxyInfo)) return false;
- ProxyInfo p = (ProxyInfo)o;
- // If PAC URL is present in either then they must be equal.
- // Other parameters will only be for fall back.
- if (!Uri.EMPTY.equals(mPacFileUrl)) {
- return mPacFileUrl.equals(p.getPacFileUrl()) && mPort == p.mPort;
- }
- if (!Uri.EMPTY.equals(p.mPacFileUrl)) {
- return false;
- }
- if (mExclusionList != null && !mExclusionList.equals(p.getExclusionListAsString())) {
- return false;
- }
- if (mHost != null && p.getHost() != null && mHost.equals(p.getHost()) == false) {
- return false;
- }
- if (mHost != null && p.mHost == null) return false;
- if (mHost == null && p.mHost != null) return false;
- if (mPort != p.mPort) return false;
- return true;
- }
-
- /**
- * Implement the Parcelable interface
- * @hide
- */
- public int describeContents() {
- return 0;
- }
-
- @Override
- /*
- * generate hashcode based on significant fields
- */
- public int hashCode() {
- return ((null == mHost) ? 0 : mHost.hashCode())
- + ((null == mExclusionList) ? 0 : mExclusionList.hashCode())
- + mPort;
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public void writeToParcel(Parcel dest, int flags) {
- if (!Uri.EMPTY.equals(mPacFileUrl)) {
- dest.writeByte((byte)1);
- mPacFileUrl.writeToParcel(dest, 0);
- dest.writeInt(mPort);
- return;
- } else {
- dest.writeByte((byte)0);
- }
- if (mHost != null) {
- dest.writeByte((byte)1);
- dest.writeString(mHost);
- dest.writeInt(mPort);
- } else {
- dest.writeByte((byte)0);
- }
- dest.writeString(mExclusionList);
- dest.writeStringArray(mParsedExclusionList);
- }
-
- public static final @android.annotation.NonNull Creator<ProxyInfo> CREATOR =
- new Creator<ProxyInfo>() {
- public ProxyInfo createFromParcel(Parcel in) {
- String host = null;
- int port = 0;
- if (in.readByte() != 0) {
- Uri url = Uri.CREATOR.createFromParcel(in);
- int localPort = in.readInt();
- return new ProxyInfo(url, localPort);
- }
- if (in.readByte() != 0) {
- host = in.readString();
- port = in.readInt();
- }
- String exclList = in.readString();
- String[] parsedExclList = in.createStringArray();
- ProxyInfo proxyProperties = new ProxyInfo(host, port, exclList, parsedExclList);
- return proxyProperties;
- }
-
- public ProxyInfo[] newArray(int size) {
- return new ProxyInfo[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/QosCallback.java b/packages/Connectivity/framework/src/android/net/QosCallback.java
deleted file mode 100644
index 22f06bc..0000000
--- a/packages/Connectivity/framework/src/android/net/QosCallback.java
+++ /dev/null
@@ -1,91 +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.annotation.NonNull;
-import android.annotation.SystemApi;
-
-import java.util.concurrent.Executor;
-
-/**
- * Receives Qos information given a {@link Network}. The callback is registered with
- * {@link ConnectivityManager#registerQosCallback}.
- *
- * <p>
- * <br/>
- * The callback will no longer receive calls if any of the following takes place:
- * <ol>
- * <li>{@link ConnectivityManager#unregisterQosCallback(QosCallback)} is called with the same
- * callback instance.</li>
- * <li>{@link QosCallback#onError(QosCallbackException)} is called.</li>
- * <li>A network specific issue occurs. eg. Congestion on a carrier network.</li>
- * <li>The network registered with the callback has no associated QoS providers</li>
- * </ul>
- * {@hide}
- */
-@SystemApi
-public abstract class QosCallback {
- /**
- * Invoked after an error occurs on a registered callback. Once called, the callback is
- * automatically unregistered and the callback will no longer receive calls.
- *
- * <p>The underlying exception can either be a runtime exception or a custom exception made for
- * {@link QosCallback}. see: {@link QosCallbackException}.
- *
- * @param exception wraps the underlying cause
- */
- public void onError(@NonNull final QosCallbackException exception) {
- }
-
- /**
- * Called when a Qos Session first becomes available to the callback or if its attributes have
- * changed.
- * <p>
- * Note: The callback may be called multiple times with the same attributes.
- *
- * @param session the available session
- * @param sessionAttributes the attributes of the session
- */
- public void onQosSessionAvailable(@NonNull final QosSession session,
- @NonNull final QosSessionAttributes sessionAttributes) {
- }
-
- /**
- * Called after a Qos Session is lost.
- * <p>
- * At least one call to
- * {@link QosCallback#onQosSessionAvailable(QosSession, QosSessionAttributes)}
- * with the same {@link QosSession} will precede a call to lost.
- *
- * @param session the lost session
- */
- public void onQosSessionLost(@NonNull final QosSession session) {
- }
-
- /**
- * Thrown when there is a problem registering {@link QosCallback} with
- * {@link ConnectivityManager#registerQosCallback(QosSocketInfo, QosCallback, Executor)}.
- */
- public static class QosCallbackRegistrationException extends RuntimeException {
- /**
- * @hide
- */
- public QosCallbackRegistrationException() {
- super();
- }
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/QosCallbackConnection.java b/packages/Connectivity/framework/src/android/net/QosCallbackConnection.java
deleted file mode 100644
index de0fc24..0000000
--- a/packages/Connectivity/framework/src/android/net/QosCallbackConnection.java
+++ /dev/null
@@ -1,148 +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.annotation.NonNull;
-import android.annotation.Nullable;
-import android.telephony.data.EpsBearerQosSessionAttributes;
-import android.telephony.data.NrQosSessionAttributes;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-/**
- * Sends messages from {@link com.android.server.ConnectivityService} to the registered
- * {@link QosCallback}.
- * <p/>
- * This is a satellite class of {@link ConnectivityManager} and not meant
- * to be used in other contexts.
- *
- * @hide
- */
-class QosCallbackConnection extends android.net.IQosCallback.Stub {
-
- @NonNull private final ConnectivityManager mConnectivityManager;
- @Nullable private volatile QosCallback mCallback;
- @NonNull private final Executor mExecutor;
-
- @VisibleForTesting
- @Nullable
- public QosCallback getCallback() {
- return mCallback;
- }
-
- /**
- * The constructor for the connection
- *
- * @param connectivityManager the mgr that created this connection
- * @param callback the callback to send messages back to
- * @param executor The executor on which the callback will be invoked. The provided
- * {@link Executor} must run callback sequentially, otherwise the order of
- * callbacks cannot be guaranteed.
- */
- QosCallbackConnection(@NonNull final ConnectivityManager connectivityManager,
- @NonNull final QosCallback callback,
- @NonNull final Executor executor) {
- mConnectivityManager = Objects.requireNonNull(connectivityManager,
- "connectivityManager must be non-null");
- mCallback = Objects.requireNonNull(callback, "callback must be non-null");
- mExecutor = Objects.requireNonNull(executor, "executor must be non-null");
- }
-
- /**
- * Called when either the {@link EpsBearerQosSessionAttributes} has changed or on the first time
- * the attributes have become available.
- *
- * @param session the session that is now available
- * @param attributes the corresponding attributes of session
- */
- @Override
- public void onQosEpsBearerSessionAvailable(@NonNull final QosSession session,
- @NonNull final EpsBearerQosSessionAttributes attributes) {
-
- mExecutor.execute(() -> {
- final QosCallback callback = mCallback;
- if (callback != null) {
- callback.onQosSessionAvailable(session, attributes);
- }
- });
- }
-
- /**
- * Called when either the {@link NrQosSessionAttributes} has changed or on the first time
- * the attributes have become available.
- *
- * @param session the session that is now available
- * @param attributes the corresponding attributes of session
- */
- @Override
- public void onNrQosSessionAvailable(@NonNull final QosSession session,
- @NonNull final NrQosSessionAttributes attributes) {
-
- mExecutor.execute(() -> {
- final QosCallback callback = mCallback;
- if (callback != null) {
- callback.onQosSessionAvailable(session, attributes);
- }
- });
- }
-
- /**
- * Called when the session is lost.
- *
- * @param session the session that was lost
- */
- @Override
- public void onQosSessionLost(@NonNull final QosSession session) {
- mExecutor.execute(() -> {
- final QosCallback callback = mCallback;
- if (callback != null) {
- callback.onQosSessionLost(session);
- }
- });
- }
-
- /**
- * Called when there is an error on the registered callback.
- *
- * @param errorType the type of error
- */
- @Override
- public void onError(@QosCallbackException.ExceptionType final int errorType) {
- mExecutor.execute(() -> {
- final QosCallback callback = mCallback;
- if (callback != null) {
- // Messages no longer need to be received since there was an error.
- stopReceivingMessages();
- mConnectivityManager.unregisterQosCallback(callback);
- callback.onError(QosCallbackException.createException(errorType));
- }
- });
- }
-
- /**
- * The callback will stop receiving messages.
- * <p/>
- * There are no synchronization guarantees on exactly when the callback will stop receiving
- * messages.
- */
- void stopReceivingMessages() {
- mCallback = null;
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/QosCallbackException.java b/packages/Connectivity/framework/src/android/net/QosCallbackException.java
deleted file mode 100644
index 7fd9a527e..0000000
--- a/packages/Connectivity/framework/src/android/net/QosCallbackException.java
+++ /dev/null
@@ -1,110 +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.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This is the exception type passed back through the onError method on {@link QosCallback}.
- * {@link QosCallbackException#getCause()} contains the actual error that caused this exception.
- *
- * The possible exception types as causes are:
- * 1. {@link NetworkReleasedException}
- * 2. {@link SocketNotBoundException}
- * 3. {@link UnsupportedOperationException}
- * 4. {@link SocketLocalAddressChangedException}
- *
- * @hide
- */
-@SystemApi
-public final class QosCallbackException extends Exception {
-
- /** @hide */
- @IntDef(prefix = {"EX_TYPE_"}, value = {
- EX_TYPE_FILTER_NONE,
- EX_TYPE_FILTER_NETWORK_RELEASED,
- EX_TYPE_FILTER_SOCKET_NOT_BOUND,
- EX_TYPE_FILTER_NOT_SUPPORTED,
- EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ExceptionType {}
-
- private static final String TAG = "QosCallbackException";
-
- // Types of exceptions supported //
- /** {@hide} */
- public static final int EX_TYPE_FILTER_NONE = 0;
-
- /** {@hide} */
- public static final int EX_TYPE_FILTER_NETWORK_RELEASED = 1;
-
- /** {@hide} */
- public static final int EX_TYPE_FILTER_SOCKET_NOT_BOUND = 2;
-
- /** {@hide} */
- public static final int EX_TYPE_FILTER_NOT_SUPPORTED = 3;
-
- /** {@hide} */
- public static final int EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED = 4;
-
- /**
- * Creates exception based off of a type and message. Not all types of exceptions accept a
- * custom message.
- *
- * {@hide}
- */
- @NonNull
- static QosCallbackException createException(@ExceptionType final int type) {
- switch (type) {
- case EX_TYPE_FILTER_NETWORK_RELEASED:
- return new QosCallbackException(new NetworkReleasedException());
- case EX_TYPE_FILTER_SOCKET_NOT_BOUND:
- return new QosCallbackException(new SocketNotBoundException());
- case EX_TYPE_FILTER_NOT_SUPPORTED:
- return new QosCallbackException(new UnsupportedOperationException(
- "This device does not support the specified filter"));
- case EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED:
- return new QosCallbackException(
- new SocketLocalAddressChangedException());
- default:
- Log.wtf(TAG, "create: No case setup for exception type: '" + type + "'");
- return new QosCallbackException(
- new RuntimeException("Unknown exception code: " + type));
- }
- }
-
- /**
- * @hide
- */
- public QosCallbackException(@NonNull final String message) {
- super(message);
- }
-
- /**
- * @hide
- */
- public QosCallbackException(@NonNull final Throwable cause) {
- super(cause);
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/QosFilter.java b/packages/Connectivity/framework/src/android/net/QosFilter.java
deleted file mode 100644
index 957c867..0000000
--- a/packages/Connectivity/framework/src/android/net/QosFilter.java
+++ /dev/null
@@ -1,86 +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.annotation.NonNull;
-import android.annotation.SystemApi;
-
-import java.net.InetAddress;
-
-/**
- * Provides the related filtering logic to the {@link NetworkAgent} to match {@link QosSession}s
- * to their related {@link QosCallback}.
- *
- * Used by the {@link com.android.server.ConnectivityService} to validate a {@link QosCallback}
- * is still able to receive a {@link QosSession}.
- *
- * @hide
- */
-@SystemApi
-public abstract class QosFilter {
-
- /**
- * The constructor is kept hidden from outside this package to ensure that all derived types
- * are known and properly handled when being passed to and from {@link NetworkAgent}.
- *
- * @hide
- */
- QosFilter() {
- }
-
- /**
- * The network used with this filter.
- *
- * @return the registered {@link Network}
- */
- @NonNull
- public abstract Network getNetwork();
-
- /**
- * Validates that conditions have not changed such that no further {@link QosSession}s should
- * be passed back to the {@link QosCallback} associated to this filter.
- *
- * @return the error code when present, otherwise the filter is valid
- *
- * @hide
- */
- @QosCallbackException.ExceptionType
- public abstract int validate();
-
- /**
- * Determines whether or not the parameters is a match for the filter.
- *
- * @param address the local address
- * @param startPort the start of the port range
- * @param endPort the end of the port range
- * @return whether the parameters match the local address of the filter
- */
- public abstract boolean matchesLocalAddress(@NonNull InetAddress address,
- int startPort, int endPort);
-
- /**
- * Determines whether or not the parameters is a match for the filter.
- *
- * @param address the remote address
- * @param startPort the start of the port range
- * @param endPort the end of the port range
- * @return whether the parameters match the remote address of the filter
- */
- public abstract boolean matchesRemoteAddress(@NonNull InetAddress address,
- int startPort, int endPort);
-}
-
diff --git a/packages/Connectivity/framework/src/android/net/QosFilterParcelable.java b/packages/Connectivity/framework/src/android/net/QosFilterParcelable.java
deleted file mode 100644
index da3b2cf..0000000
--- a/packages/Connectivity/framework/src/android/net/QosFilterParcelable.java
+++ /dev/null
@@ -1,113 +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.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.util.Objects;
-
-/**
- * Aware of how to parcel different types of {@link QosFilter}s. Any new type of qos filter must
- * have a specialized case written here.
- * <p/>
- * Specifically leveraged when transferring {@link QosFilter} from
- * {@link com.android.server.ConnectivityService} to {@link NetworkAgent} when the filter is first
- * registered.
- * <p/>
- * This is not meant to be used in other contexts.
- *
- * @hide
- */
-public final class QosFilterParcelable implements Parcelable {
-
- private static final String LOG_TAG = QosFilterParcelable.class.getSimpleName();
-
- // Indicates that the filter was not successfully written to the parcel.
- private static final int NO_FILTER_PRESENT = 0;
-
- // The parcel is of type qos socket filter.
- private static final int QOS_SOCKET_FILTER = 1;
-
- private final QosFilter mQosFilter;
-
- /**
- * The underlying qos filter.
- * <p/>
- * Null only in the case parceling failed.
- */
- @Nullable
- public QosFilter getQosFilter() {
- return mQosFilter;
- }
-
- public QosFilterParcelable(@NonNull final QosFilter qosFilter) {
- Objects.requireNonNull(qosFilter, "qosFilter must be non-null");
-
- // NOTE: Normally a type check would belong here, but doing so breaks unit tests that rely
- // on mocking qos filter.
- mQosFilter = qosFilter;
- }
-
- private QosFilterParcelable(final Parcel in) {
- final int filterParcelType = in.readInt();
-
- switch (filterParcelType) {
- case QOS_SOCKET_FILTER: {
- mQosFilter = new QosSocketFilter(QosSocketInfo.CREATOR.createFromParcel(in));
- break;
- }
-
- case NO_FILTER_PRESENT:
- default: {
- mQosFilter = null;
- }
- }
- }
-
- public static final Creator<QosFilterParcelable> CREATOR = new Creator<QosFilterParcelable>() {
- @Override
- public QosFilterParcelable createFromParcel(final Parcel in) {
- return new QosFilterParcelable(in);
- }
-
- @Override
- public QosFilterParcelable[] newArray(final int size) {
- return new QosFilterParcelable[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(final Parcel dest, final int flags) {
- if (mQosFilter instanceof QosSocketFilter) {
- dest.writeInt(QOS_SOCKET_FILTER);
- final QosSocketFilter qosSocketFilter = (QosSocketFilter) mQosFilter;
- qosSocketFilter.getQosSocketInfo().writeToParcel(dest, 0);
- return;
- }
- dest.writeInt(NO_FILTER_PRESENT);
- Log.e(LOG_TAG, "Parceling failed, unknown type of filter present: " + mQosFilter);
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/QosSession.java b/packages/Connectivity/framework/src/android/net/QosSession.java
deleted file mode 100644
index 93f2ff2..0000000
--- a/packages/Connectivity/framework/src/android/net/QosSession.java
+++ /dev/null
@@ -1,142 +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.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Provides identifying information of a QoS session. Sent to an application through
- * {@link QosCallback}.
- *
- * @hide
- */
-@SystemApi
-public final class QosSession implements Parcelable {
-
- /**
- * The {@link QosSession} is a LTE EPS Session.
- */
- public static final int TYPE_EPS_BEARER = 1;
-
- /**
- * The {@link QosSession} is a NR Session.
- */
- public static final int TYPE_NR_BEARER = 2;
-
- private final int mSessionId;
-
- private final int mSessionType;
-
- /**
- * Gets the unique id of the session that is used to differentiate sessions across different
- * types.
- * <p/>
- * Note: Different qos sessions can be provided by different actors.
- *
- * @return the unique id
- */
- public long getUniqueId() {
- return (long) mSessionType << 32 | mSessionId;
- }
-
- /**
- * Gets the session id that is unique within that type.
- * <p/>
- * Note: The session id is set by the actor providing the qos. It can be either manufactured by
- * the actor, but also may have a particular meaning within that type. For example, using the
- * bearer id as the session id for {@link android.telephony.data.EpsBearerQosSessionAttributes}
- * is a straight forward way to keep the sessions unique from one another within that type.
- *
- * @return the id of the session
- */
- public int getSessionId() {
- return mSessionId;
- }
-
- /**
- * Gets the type of session.
- */
- @QosSessionType
- public int getSessionType() {
- return mSessionType;
- }
-
- /**
- * Creates a {@link QosSession}.
- *
- * @param sessionId uniquely identifies the session across all sessions of the same type
- * @param sessionType the type of session
- */
- public QosSession(final int sessionId, @QosSessionType final int sessionType) {
- //Ensures the session id is unique across types of sessions
- mSessionId = sessionId;
- mSessionType = sessionType;
- }
-
-
- @Override
- public String toString() {
- return "QosSession{"
- + "mSessionId=" + mSessionId
- + ", mSessionType=" + mSessionType
- + '}';
- }
-
- /**
- * Annotations for types of qos sessions.
- */
- @IntDef(value = {
- TYPE_EPS_BEARER,
- TYPE_NR_BEARER,
- })
- @interface QosSessionType {}
-
- private QosSession(final Parcel in) {
- mSessionId = in.readInt();
- mSessionType = in.readInt();
- }
-
- @NonNull
- public static final Creator<QosSession> CREATOR = new Creator<QosSession>() {
- @NonNull
- @Override
- public QosSession createFromParcel(@NonNull final Parcel in) {
- return new QosSession(in);
- }
-
- @NonNull
- @Override
- public QosSession[] newArray(final int size) {
- return new QosSession[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull final Parcel dest, final int flags) {
- dest.writeInt(mSessionId);
- dest.writeInt(mSessionType);
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/QosSessionAttributes.java b/packages/Connectivity/framework/src/android/net/QosSessionAttributes.java
deleted file mode 100644
index 7a88594..0000000
--- a/packages/Connectivity/framework/src/android/net/QosSessionAttributes.java
+++ /dev/null
@@ -1,30 +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.annotation.SystemApi;
-
-/**
- * Implemented by classes that encapsulate Qos related attributes that describe a Qos Session.
- *
- * Use the instanceof keyword to determine the underlying type.
- *
- * @hide
- */
-@SystemApi
-public interface QosSessionAttributes {
-}
diff --git a/packages/Connectivity/framework/src/android/net/QosSocketFilter.java b/packages/Connectivity/framework/src/android/net/QosSocketFilter.java
deleted file mode 100644
index 69da7f4..0000000
--- a/packages/Connectivity/framework/src/android/net/QosSocketFilter.java
+++ /dev/null
@@ -1,179 +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.QosCallbackException.EX_TYPE_FILTER_NONE;
-import static android.net.QosCallbackException.EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.ParcelFileDescriptor;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.FileDescriptor;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.util.Objects;
-
-/**
- * Filters a {@link QosSession} according to the binding on the provided {@link Socket}.
- *
- * @hide
- */
-public class QosSocketFilter extends QosFilter {
-
- private static final String TAG = QosSocketFilter.class.getSimpleName();
-
- @NonNull
- private final QosSocketInfo mQosSocketInfo;
-
- /**
- * Creates a {@link QosSocketFilter} based off of {@link QosSocketInfo}.
- *
- * @param qosSocketInfo the information required to filter and validate
- */
- public QosSocketFilter(@NonNull final QosSocketInfo qosSocketInfo) {
- Objects.requireNonNull(qosSocketInfo, "qosSocketInfo must be non-null");
- mQosSocketInfo = qosSocketInfo;
- }
-
- /**
- * Gets the parcelable qos socket info that was used to create the filter.
- */
- @NonNull
- public QosSocketInfo getQosSocketInfo() {
- return mQosSocketInfo;
- }
-
- /**
- * Performs two validations:
- * 1. If the socket is not bound, then return
- * {@link QosCallbackException.EX_TYPE_FILTER_SOCKET_NOT_BOUND}. This is detected
- * by checking the local address on the filter which becomes null when the socket is no
- * longer bound.
- * 2. In the scenario that the socket is now bound to a different local address, which can
- * happen in the case of UDP, then
- * {@link QosCallbackException.EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED} is returned.
- * @return validation error code
- */
- @Override
- public int validate() {
- final InetSocketAddress sa = getAddressFromFileDescriptor();
- if (sa == null) {
- return QosCallbackException.EX_TYPE_FILTER_SOCKET_NOT_BOUND;
- }
-
- if (!sa.equals(mQosSocketInfo.getLocalSocketAddress())) {
- return EX_TYPE_FILTER_SOCKET_LOCAL_ADDRESS_CHANGED;
- }
-
- return EX_TYPE_FILTER_NONE;
- }
-
- /**
- * The local address of the socket's binding.
- *
- * Note: If the socket is no longer bound, null is returned.
- *
- * @return the local address
- */
- @Nullable
- private InetSocketAddress getAddressFromFileDescriptor() {
- final ParcelFileDescriptor parcelFileDescriptor = mQosSocketInfo.getParcelFileDescriptor();
- if (parcelFileDescriptor == null) return null;
-
- final FileDescriptor fd = parcelFileDescriptor.getFileDescriptor();
- if (fd == null) return null;
-
- final SocketAddress address;
- try {
- address = Os.getsockname(fd);
- } catch (final ErrnoException e) {
- Log.e(TAG, "getAddressFromFileDescriptor: getLocalAddress exception", e);
- return null;
- }
- if (address instanceof InetSocketAddress) {
- return (InetSocketAddress) address;
- }
- return null;
- }
-
- /**
- * The network used with this filter.
- *
- * @return the registered {@link Network}
- */
- @NonNull
- @Override
- public Network getNetwork() {
- return mQosSocketInfo.getNetwork();
- }
-
- /**
- * @inheritDoc
- */
- @Override
- public boolean matchesLocalAddress(@NonNull final InetAddress address, final int startPort,
- final int endPort) {
- if (mQosSocketInfo.getLocalSocketAddress() == null) {
- return false;
- }
- return matchesAddress(mQosSocketInfo.getLocalSocketAddress(), address, startPort,
- endPort);
- }
-
- /**
- * @inheritDoc
- */
- @Override
- public boolean matchesRemoteAddress(@NonNull final InetAddress address, final int startPort,
- final int endPort) {
- if (mQosSocketInfo.getRemoteSocketAddress() == null) {
- return false;
- }
- return matchesAddress(mQosSocketInfo.getRemoteSocketAddress(), address, startPort,
- endPort);
- }
-
- /**
- * Called from {@link QosSocketFilter#matchesLocalAddress(InetAddress, int, int)}
- * and {@link QosSocketFilter#matchesRemoteAddress(InetAddress, int, int)} with the
- * filterSocketAddress coming from {@link QosSocketInfo#getLocalSocketAddress()}.
- * <p>
- * This method exists for testing purposes since {@link QosSocketInfo} couldn't be mocked
- * due to being final.
- *
- * @param filterSocketAddress the socket address of the filter
- * @param address the address to compare the filterSocketAddressWith
- * @param startPort the start of the port range to check
- * @param endPort the end of the port range to check
- */
- @VisibleForTesting
- public static boolean matchesAddress(@NonNull final InetSocketAddress filterSocketAddress,
- @NonNull final InetAddress address,
- final int startPort, final int endPort) {
- return startPort <= filterSocketAddress.getPort()
- && endPort >= filterSocketAddress.getPort()
- && filterSocketAddress.getAddress().equals(address);
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/QosSocketInfo.java b/packages/Connectivity/framework/src/android/net/QosSocketInfo.java
deleted file mode 100644
index a45d507..0000000
--- a/packages/Connectivity/framework/src/android/net/QosSocketInfo.java
+++ /dev/null
@@ -1,190 +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.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.util.Objects;
-
-/**
- * Used in conjunction with
- * {@link ConnectivityManager#registerQosCallback}
- * in order to receive Qos Sessions related to the local address and port of a bound {@link Socket}
- * and/or remote address and port of a connected {@link Socket}.
- *
- * @hide
- */
-@SystemApi
-public final class QosSocketInfo implements Parcelable {
-
- @NonNull
- private final Network mNetwork;
-
- @NonNull
- private final ParcelFileDescriptor mParcelFileDescriptor;
-
- @NonNull
- private final InetSocketAddress mLocalSocketAddress;
-
- @Nullable
- private final InetSocketAddress mRemoteSocketAddress;
-
- /**
- * The {@link Network} the socket is on.
- *
- * @return the registered {@link Network}
- */
- @NonNull
- public Network getNetwork() {
- return mNetwork;
- }
-
- /**
- * The parcel file descriptor wrapped around the socket's file descriptor.
- *
- * @return the parcel file descriptor of the socket
- */
- @NonNull
- ParcelFileDescriptor getParcelFileDescriptor() {
- return mParcelFileDescriptor;
- }
-
- /**
- * The local address of the socket passed into {@link QosSocketInfo(Network, Socket)}.
- * The value does not reflect any changes that occur to the socket after it is first set
- * in the constructor.
- *
- * @return the local address of the socket
- */
- @NonNull
- public InetSocketAddress getLocalSocketAddress() {
- return mLocalSocketAddress;
- }
-
- /**
- * The remote address of the socket passed into {@link QosSocketInfo(Network, Socket)}.
- * The value does not reflect any changes that occur to the socket after it is first set
- * in the constructor.
- *
- * @return the remote address of the socket if socket is connected, null otherwise
- */
- @Nullable
- public InetSocketAddress getRemoteSocketAddress() {
- return mRemoteSocketAddress;
- }
-
- /**
- * Creates a {@link QosSocketInfo} given a {@link Network} and bound {@link Socket}. The
- * {@link Socket} must remain bound in order to receive {@link QosSession}s.
- *
- * @param network the network
- * @param socket the bound {@link Socket}
- */
- public QosSocketInfo(@NonNull final Network network, @NonNull final Socket socket)
- throws IOException {
- Objects.requireNonNull(socket, "socket cannot be null");
-
- mNetwork = Objects.requireNonNull(network, "network cannot be null");
- mParcelFileDescriptor = ParcelFileDescriptor.fromSocket(socket);
- mLocalSocketAddress =
- new InetSocketAddress(socket.getLocalAddress(), socket.getLocalPort());
-
- if (socket.isConnected()) {
- mRemoteSocketAddress = (InetSocketAddress) socket.getRemoteSocketAddress();
- } else {
- mRemoteSocketAddress = null;
- }
- }
-
- /* Parcelable methods */
- private QosSocketInfo(final Parcel in) {
- mNetwork = Objects.requireNonNull(Network.CREATOR.createFromParcel(in));
- mParcelFileDescriptor = ParcelFileDescriptor.CREATOR.createFromParcel(in);
-
- final int localAddressLength = in.readInt();
- mLocalSocketAddress = readSocketAddress(in, localAddressLength);
-
- final int remoteAddressLength = in.readInt();
- mRemoteSocketAddress = remoteAddressLength == 0 ? null
- : readSocketAddress(in, remoteAddressLength);
- }
-
- private @NonNull InetSocketAddress readSocketAddress(final Parcel in, final int addressLength) {
- final byte[] address = new byte[addressLength];
- in.readByteArray(address);
- final int port = in.readInt();
-
- try {
- return new InetSocketAddress(InetAddress.getByAddress(address), port);
- } catch (final UnknownHostException e) {
- /* This can never happen. UnknownHostException will never be thrown
- since the address provided is numeric and non-null. */
- throw new RuntimeException("UnknownHostException on numeric address", e);
- }
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull final Parcel dest, final int flags) {
- mNetwork.writeToParcel(dest, 0);
- mParcelFileDescriptor.writeToParcel(dest, 0);
-
- final byte[] localAddress = mLocalSocketAddress.getAddress().getAddress();
- dest.writeInt(localAddress.length);
- dest.writeByteArray(localAddress);
- dest.writeInt(mLocalSocketAddress.getPort());
-
- if (mRemoteSocketAddress == null) {
- dest.writeInt(0);
- } else {
- final byte[] remoteAddress = mRemoteSocketAddress.getAddress().getAddress();
- dest.writeInt(remoteAddress.length);
- dest.writeByteArray(remoteAddress);
- dest.writeInt(mRemoteSocketAddress.getPort());
- }
- }
-
- @NonNull
- public static final Parcelable.Creator<QosSocketInfo> CREATOR =
- new Parcelable.Creator<QosSocketInfo>() {
- @NonNull
- @Override
- public QosSocketInfo createFromParcel(final Parcel in) {
- return new QosSocketInfo(in);
- }
-
- @NonNull
- @Override
- public QosSocketInfo[] newArray(final int size) {
- return new QosSocketInfo[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/RouteInfo.java b/packages/Connectivity/framework/src/android/net/RouteInfo.java
deleted file mode 100644
index fad3144..0000000
--- a/packages/Connectivity/framework/src/android/net/RouteInfo.java
+++ /dev/null
@@ -1,659 +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 android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.net.module.util.NetUtils;
-import com.android.net.module.util.NetworkStackConstants;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Collection;
-import java.util.Objects;
-
-/**
- * Represents a network route.
- * <p>
- * This is used both to describe static network configuration and live network
- * configuration information.
- *
- * A route contains three pieces of information:
- * <ul>
- * <li>a destination {@link IpPrefix} specifying the network destinations covered by this route.
- * If this is {@code null} it indicates a default route of the address family (IPv4 or IPv6)
- * implied by the gateway IP address.
- * <li>a gateway {@link InetAddress} indicating the next hop to use. If this is {@code null} it
- * indicates a directly-connected route.
- * <li>an interface (which may be unspecified).
- * </ul>
- * Either the destination or the gateway may be {@code null}, but not both. If the
- * destination and gateway are both specified, they must be of the same address family
- * (IPv4 or IPv6).
- */
-public final class RouteInfo implements Parcelable {
- /** @hide */
- @IntDef(value = {
- RTN_UNICAST,
- RTN_UNREACHABLE,
- RTN_THROW,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface RouteType {}
-
- /**
- * The IP destination address for this route.
- */
- @NonNull
- private final IpPrefix mDestination;
-
- /**
- * The gateway address for this route.
- */
- @UnsupportedAppUsage
- @Nullable
- private final InetAddress mGateway;
-
- /**
- * The interface for this route.
- */
- @Nullable
- private final String mInterface;
-
-
- /** Unicast route. @hide */
- @SystemApi
- public static final int RTN_UNICAST = 1;
-
- /** Unreachable route. @hide */
- @SystemApi
- public static final int RTN_UNREACHABLE = 7;
-
- /** Throw route. @hide */
- @SystemApi
- public static final int RTN_THROW = 9;
-
- /**
- * The type of this route; one of the RTN_xxx constants above.
- */
- private final int mType;
-
- /**
- * The maximum transmission unit size for this route.
- */
- private final int mMtu;
-
- // Derived data members.
- // TODO: remove these.
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- private final boolean mIsHost;
- private final boolean mHasGateway;
-
- /**
- * Constructs a RouteInfo object.
- *
- * If destination is null, then gateway must be specified and the
- * constructed route is either the IPv4 default route <code>0.0.0.0</code>
- * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
- * route <code>::/0</code> if gateway is an instance of
- * {@link Inet6Address}.
- * <p>
- * destination and gateway may not both be null.
- *
- * @param destination the destination prefix
- * @param gateway the IP address to route packets through
- * @param iface the interface name to send packets on
- * @param type the type of this route
- *
- * @hide
- */
- @SystemApi
- public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway,
- @Nullable String iface, @RouteType int type) {
- this(destination, gateway, iface, type, 0);
- }
-
- /**
- * Constructs a RouteInfo object.
- *
- * If destination is null, then gateway must be specified and the
- * constructed route is either the IPv4 default route <code>0.0.0.0</code>
- * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
- * route <code>::/0</code> if gateway is an instance of
- * {@link Inet6Address}.
- * <p>
- * destination and gateway may not both be null.
- *
- * @param destination the destination prefix
- * @param gateway the IP address to route packets through
- * @param iface the interface name to send packets on
- * @param type the type of this route
- * @param mtu the maximum transmission unit size for this route
- *
- * @hide
- */
- @SystemApi
- public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway,
- @Nullable String iface, @RouteType int type, int mtu) {
- switch (type) {
- case RTN_UNICAST:
- case RTN_UNREACHABLE:
- case RTN_THROW:
- // TODO: It would be nice to ensure that route types that don't have nexthops or
- // interfaces, such as unreachable or throw, can't be created if an interface or
- // a gateway is specified. This is a bit too complicated to do at the moment
- // because:
- //
- // - LinkProperties sets the interface on routes added to it, and modifies the
- // interfaces of all the routes when its interface name changes.
- // - Even when the gateway is null, we store a non-null gateway here.
- //
- // For now, we just rely on the code that sets routes to do things properly.
- break;
- default:
- throw new IllegalArgumentException("Unknown route type " + type);
- }
-
- if (destination == null) {
- if (gateway != null) {
- if (gateway instanceof Inet4Address) {
- destination = new IpPrefix(NetworkStackConstants.IPV4_ADDR_ANY, 0);
- } else {
- destination = new IpPrefix(NetworkStackConstants.IPV6_ADDR_ANY, 0);
- }
- } else {
- // no destination, no gateway. invalid.
- throw new IllegalArgumentException("Invalid arguments passed in: " + gateway + "," +
- destination);
- }
- }
- // TODO: set mGateway to null if there is no gateway. This is more correct, saves space, and
- // matches the documented behaviour. Before we can do this we need to fix all callers (e.g.,
- // ConnectivityService) to stop doing things like r.getGateway().equals(), ... .
- if (gateway == null) {
- if (destination.getAddress() instanceof Inet4Address) {
- gateway = NetworkStackConstants.IPV4_ADDR_ANY;
- } else {
- gateway = NetworkStackConstants.IPV6_ADDR_ANY;
- }
- }
- mHasGateway = (!gateway.isAnyLocalAddress());
-
- if ((destination.getAddress() instanceof Inet4Address
- && !(gateway instanceof Inet4Address))
- || (destination.getAddress() instanceof Inet6Address
- && !(gateway instanceof Inet6Address))) {
- throw new IllegalArgumentException("address family mismatch in RouteInfo constructor");
- }
- mDestination = destination; // IpPrefix objects are immutable.
- mGateway = gateway; // InetAddress objects are immutable.
- mInterface = iface; // Strings are immutable.
- mType = type;
- mIsHost = isHost();
- mMtu = mtu;
- }
-
- /**
- * Constructs a {@code RouteInfo} object.
- *
- * If destination is null, then gateway must be specified and the
- * constructed route is either the IPv4 default route <code>0.0.0.0</code>
- * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
- * route <code>::/0</code> if gateway is an instance of {@link Inet6Address}.
- * <p>
- * Destination and gateway may not both be null.
- *
- * @param destination the destination address and prefix in an {@link IpPrefix}
- * @param gateway the {@link InetAddress} to route packets through
- * @param iface the interface name to send packets on
- *
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway,
- @Nullable String iface) {
- this(destination, gateway, iface, RTN_UNICAST);
- }
-
- /**
- * @hide
- */
- @UnsupportedAppUsage
- public RouteInfo(@Nullable LinkAddress destination, @Nullable InetAddress gateway,
- @Nullable String iface) {
- this(destination == null ? null :
- new IpPrefix(destination.getAddress(), destination.getPrefixLength()),
- gateway, iface);
- }
-
- /**
- * Constructs a {@code RouteInfo} object.
- *
- * If destination is null, then gateway must be specified and the
- * constructed route is either the IPv4 default route <code>0.0.0.0</code>
- * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
- * route <code>::/0</code> if gateway is an instance of {@link Inet6Address}.
- * <p>
- * Destination and gateway may not both be null.
- *
- * @param destination the destination address and prefix in an {@link IpPrefix}
- * @param gateway the {@link InetAddress} to route packets through
- *
- * @hide
- */
- public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway) {
- this(destination, gateway, null);
- }
-
- /**
- * @hide
- *
- * TODO: Remove this.
- */
- @UnsupportedAppUsage
- public RouteInfo(@Nullable LinkAddress destination, @Nullable InetAddress gateway) {
- this(destination, gateway, null);
- }
-
- /**
- * Constructs a default {@code RouteInfo} object.
- *
- * @param gateway the {@link InetAddress} to route packets through
- *
- * @hide
- */
- @UnsupportedAppUsage
- public RouteInfo(@NonNull InetAddress gateway) {
- this((IpPrefix) null, gateway, null);
- }
-
- /**
- * Constructs a {@code RouteInfo} object representing a direct connected subnet.
- *
- * @param destination the {@link IpPrefix} describing the address and prefix
- * length of the subnet.
- *
- * @hide
- */
- public RouteInfo(@NonNull IpPrefix destination) {
- this(destination, null, null);
- }
-
- /**
- * @hide
- */
- public RouteInfo(@NonNull LinkAddress destination) {
- this(destination, null, null);
- }
-
- /**
- * @hide
- */
- public RouteInfo(@NonNull IpPrefix destination, @RouteType int type) {
- this(destination, null, null, type);
- }
-
- /**
- * @hide
- */
- public static RouteInfo makeHostRoute(@NonNull InetAddress host, @Nullable String iface) {
- return makeHostRoute(host, null, iface);
- }
-
- /**
- * @hide
- */
- public static RouteInfo makeHostRoute(@Nullable InetAddress host, @Nullable InetAddress gateway,
- @Nullable String iface) {
- if (host == null) return null;
-
- if (host instanceof Inet4Address) {
- return new RouteInfo(new IpPrefix(host, 32), gateway, iface);
- } else {
- return new RouteInfo(new IpPrefix(host, 128), gateway, iface);
- }
- }
-
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- private boolean isHost() {
- return (mDestination.getAddress() instanceof Inet4Address &&
- mDestination.getPrefixLength() == 32) ||
- (mDestination.getAddress() instanceof Inet6Address &&
- mDestination.getPrefixLength() == 128);
- }
-
- /**
- * Retrieves the destination address and prefix length in the form of an {@link IpPrefix}.
- *
- * @return {@link IpPrefix} specifying the destination. This is never {@code null}.
- */
- @NonNull
- public IpPrefix getDestination() {
- return mDestination;
- }
-
- /**
- * TODO: Convert callers to use IpPrefix and then remove.
- * @hide
- */
- @NonNull
- public LinkAddress getDestinationLinkAddress() {
- return new LinkAddress(mDestination.getAddress(), mDestination.getPrefixLength());
- }
-
- /**
- * Retrieves the gateway or next hop {@link InetAddress} for this route.
- *
- * @return {@link InetAddress} specifying the gateway or next hop. This may be
- * {@code null} for a directly-connected route."
- */
- @Nullable
- public InetAddress getGateway() {
- return mGateway;
- }
-
- /**
- * Retrieves the interface used for this route if specified, else {@code null}.
- *
- * @return The name of the interface used for this route.
- */
- @Nullable
- public String getInterface() {
- return mInterface;
- }
-
- /**
- * Retrieves the type of this route.
- *
- * @return The type of this route; one of the {@code RTN_xxx} constants defined in this class.
- *
- * @hide
- */
- @SystemApi
- @RouteType
- public int getType() {
- return mType;
- }
-
- /**
- * Retrieves the MTU size for this route.
- *
- * @return The MTU size, or 0 if it has not been set.
- * @hide
- */
- @SystemApi
- public int getMtu() {
- return mMtu;
- }
-
- /**
- * Indicates if this route is a default route (ie, has no destination specified).
- *
- * @return {@code true} if the destination has a prefix length of 0.
- */
- public boolean isDefaultRoute() {
- return mType == RTN_UNICAST && mDestination.getPrefixLength() == 0;
- }
-
- /**
- * Indicates if this route is an unreachable default route.
- *
- * @return {@code true} if it's an unreachable route with prefix length of 0.
- * @hide
- */
- private boolean isUnreachableDefaultRoute() {
- return mType == RTN_UNREACHABLE && mDestination.getPrefixLength() == 0;
- }
-
- /**
- * Indicates if this route is an IPv4 default route.
- * @hide
- */
- public boolean isIPv4Default() {
- return isDefaultRoute() && mDestination.getAddress() instanceof Inet4Address;
- }
-
- /**
- * Indicates if this route is an IPv4 unreachable default route.
- * @hide
- */
- public boolean isIPv4UnreachableDefault() {
- return isUnreachableDefaultRoute() && mDestination.getAddress() instanceof Inet4Address;
- }
-
- /**
- * Indicates if this route is an IPv6 default route.
- * @hide
- */
- public boolean isIPv6Default() {
- return isDefaultRoute() && mDestination.getAddress() instanceof Inet6Address;
- }
-
- /**
- * Indicates if this route is an IPv6 unreachable default route.
- * @hide
- */
- public boolean isIPv6UnreachableDefault() {
- return isUnreachableDefaultRoute() && mDestination.getAddress() instanceof Inet6Address;
- }
-
- /**
- * Indicates if this route is a host route (ie, matches only a single host address).
- *
- * @return {@code true} if the destination has a prefix length of 32 or 128 for IPv4 or IPv6,
- * respectively.
- * @hide
- */
- public boolean isHostRoute() {
- return mIsHost;
- }
-
- /**
- * Indicates if this route has a next hop ({@code true}) or is directly-connected
- * ({@code false}).
- *
- * @return {@code true} if a gateway is specified
- */
- public boolean hasGateway() {
- return mHasGateway;
- }
-
- /**
- * Determines whether the destination and prefix of this route includes the specified
- * address.
- *
- * @param destination A {@link InetAddress} to test to see if it would match this route.
- * @return {@code true} if the destination and prefix length cover the given address.
- */
- public boolean matches(InetAddress destination) {
- return mDestination.contains(destination);
- }
-
- /**
- * Find the route from a Collection of routes that best matches a given address.
- * May return null if no routes are applicable.
- * @param routes a Collection of RouteInfos to chose from
- * @param dest the InetAddress your trying to get to
- * @return the RouteInfo from the Collection that best fits the given address
- *
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @Nullable
- public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) {
- return NetUtils.selectBestRoute(routes, dest);
- }
-
- /**
- * Returns a human-readable description of this object.
- */
- public String toString() {
- String val = "";
- if (mDestination != null) val = mDestination.toString();
- if (mType == RTN_UNREACHABLE) {
- val += " unreachable";
- } else if (mType == RTN_THROW) {
- val += " throw";
- } else {
- val += " ->";
- if (mGateway != null) val += " " + mGateway.getHostAddress();
- if (mInterface != null) val += " " + mInterface;
- if (mType != RTN_UNICAST) {
- val += " unknown type " + mType;
- }
- }
- val += " mtu " + mMtu;
- return val;
- }
-
- /**
- * Compares this RouteInfo object against the specified object and indicates if they are equal.
- * @return {@code true} if the objects are equal, {@code false} otherwise.
- */
- public boolean equals(@Nullable Object obj) {
- if (this == obj) return true;
-
- if (!(obj instanceof RouteInfo)) return false;
-
- RouteInfo target = (RouteInfo) obj;
-
- return Objects.equals(mDestination, target.getDestination()) &&
- Objects.equals(mGateway, target.getGateway()) &&
- Objects.equals(mInterface, target.getInterface()) &&
- mType == target.getType() && mMtu == target.getMtu();
- }
-
- /**
- * A helper class that contains the destination, the gateway and the interface in a
- * {@code RouteInfo}, used by {@link ConnectivityService#updateRoutes} or
- * {@link LinkProperties#addRoute} to calculate the list to be updated.
- * {@code RouteInfo} objects with different interfaces are treated as different routes because
- * *usually* on Android different interfaces use different routing tables, and moving a route
- * to a new routing table never constitutes an update, but is always a remove and an add.
- *
- * @hide
- */
- public static class RouteKey {
- @NonNull private final IpPrefix mDestination;
- @Nullable private final InetAddress mGateway;
- @Nullable private final String mInterface;
-
- RouteKey(@NonNull IpPrefix destination, @Nullable InetAddress gateway,
- @Nullable String iface) {
- mDestination = destination;
- mGateway = gateway;
- mInterface = iface;
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (!(o instanceof RouteKey)) {
- return false;
- }
- RouteKey p = (RouteKey) o;
- // No need to do anything special for scoped addresses. Inet6Address#equals does not
- // consider the scope ID, but the netd route IPCs (e.g., INetd#networkAddRouteParcel)
- // and the kernel ignore scoped addresses both in the prefix and in the nexthop and only
- // look at RTA_OIF.
- return Objects.equals(p.mDestination, mDestination)
- && Objects.equals(p.mGateway, mGateway)
- && Objects.equals(p.mInterface, mInterface);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mDestination, mGateway, mInterface);
- }
- }
-
- /**
- * Get {@code RouteKey} of this {@code RouteInfo}.
- * @return a {@code RouteKey} object.
- *
- * @hide
- */
- @NonNull
- public RouteKey getRouteKey() {
- return new RouteKey(mDestination, mGateway, mInterface);
- }
-
- /**
- * Returns a hashcode for this <code>RouteInfo</code> object.
- */
- public int hashCode() {
- return (mDestination.hashCode() * 41)
- + (mGateway == null ? 0 :mGateway.hashCode() * 47)
- + (mInterface == null ? 0 :mInterface.hashCode() * 67)
- + (mType * 71) + (mMtu * 89);
- }
-
- /**
- * Implement the Parcelable interface
- */
- public int describeContents() {
- return 0;
- }
-
- /**
- * Implement the Parcelable interface
- */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(mDestination, flags);
- byte[] gatewayBytes = (mGateway == null) ? null : mGateway.getAddress();
- dest.writeByteArray(gatewayBytes);
- dest.writeString(mInterface);
- dest.writeInt(mType);
- dest.writeInt(mMtu);
- }
-
- /**
- * Implement the Parcelable interface.
- */
- public static final @android.annotation.NonNull Creator<RouteInfo> CREATOR =
- new Creator<RouteInfo>() {
- public RouteInfo createFromParcel(Parcel in) {
- IpPrefix dest = in.readParcelable(null);
-
- InetAddress gateway = null;
- byte[] addr = in.createByteArray();
- try {
- gateway = InetAddress.getByAddress(addr);
- } catch (UnknownHostException e) {}
-
- String iface = in.readString();
- int type = in.readInt();
- int mtu = in.readInt();
-
- return new RouteInfo(dest, gateway, iface, type, mtu);
- }
-
- public RouteInfo[] newArray(int size) {
- return new RouteInfo[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/SocketKeepalive.java b/packages/Connectivity/framework/src/android/net/SocketKeepalive.java
deleted file mode 100644
index f6cae72..0000000
--- a/packages/Connectivity/framework/src/android/net/SocketKeepalive.java
+++ /dev/null
@@ -1,347 +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.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Binder;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.concurrent.Executor;
-
-/**
- * Allows applications to request that the system periodically send specific packets on their
- * behalf, using hardware offload to save battery power.
- *
- * To request that the system send keepalives, call one of the methods that return a
- * {@link SocketKeepalive} object, such as {@link ConnectivityManager#createSocketKeepalive},
- * passing in a non-null callback. If the {@link SocketKeepalive} is successfully
- * started, the callback's {@code onStarted} method will be called. If an error occurs,
- * {@code onError} will be called, specifying one of the {@code ERROR_*} constants in this
- * class.
- *
- * To stop an existing keepalive, call {@link SocketKeepalive#stop}. The system will call
- * {@link SocketKeepalive.Callback#onStopped} if the operation was successful or
- * {@link SocketKeepalive.Callback#onError} if an error occurred.
- *
- * For cellular, the device MUST support at least 1 keepalive slot.
- *
- * For WiFi, the device SHOULD support keepalive offload. If it does not, it MUST reply with
- * {@link SocketKeepalive.Callback#onError} with {@code ERROR_UNSUPPORTED} to any keepalive offload
- * request. If it does, it MUST support at least 3 concurrent keepalive slots.
- */
-public abstract class SocketKeepalive implements AutoCloseable {
- static final String TAG = "SocketKeepalive";
-
- /**
- * Success. It indicates there is no error.
- * @hide
- */
- @SystemApi
- public static final int SUCCESS = 0;
-
- /**
- * No keepalive. This should only be internally as it indicates There is no keepalive.
- * It should not propagate to applications.
- * @hide
- */
- public static final int NO_KEEPALIVE = -1;
-
- /**
- * Data received.
- * @hide
- */
- public static final int DATA_RECEIVED = -2;
-
- /**
- * The binder died.
- * @hide
- */
- public static final int BINDER_DIED = -10;
-
- /**
- * The invalid network. It indicates the specified {@code Network} is not connected.
- */
- public static final int ERROR_INVALID_NETWORK = -20;
-
- /**
- * The invalid IP addresses. Indicates the specified IP addresses are invalid.
- * For example, the specified source IP address is not configured on the
- * specified {@code Network}.
- */
- public static final int ERROR_INVALID_IP_ADDRESS = -21;
-
- /**
- * The port is invalid.
- */
- public static final int ERROR_INVALID_PORT = -22;
-
- /**
- * The length is invalid (e.g. too long).
- */
- public static final int ERROR_INVALID_LENGTH = -23;
-
- /**
- * The interval is invalid (e.g. too short).
- */
- public static final int ERROR_INVALID_INTERVAL = -24;
-
- /**
- * The socket is invalid.
- */
- public static final int ERROR_INVALID_SOCKET = -25;
-
- /**
- * The socket is not idle.
- */
- public static final int ERROR_SOCKET_NOT_IDLE = -26;
-
- /**
- * The stop reason is uninitialized. This should only be internally used as initial state
- * of stop reason, instead of propagating to application.
- * @hide
- */
- public static final int ERROR_STOP_REASON_UNINITIALIZED = -27;
-
- /**
- * The request is unsupported.
- */
- public static final int ERROR_UNSUPPORTED = -30;
-
- /**
- * There was a hardware error.
- */
- public static final int ERROR_HARDWARE_ERROR = -31;
-
- /**
- * Resources are insufficient (e.g. all hardware slots are in use).
- */
- public static final int ERROR_INSUFFICIENT_RESOURCES = -32;
-
- /**
- * There was no such slot. This should only be internally as it indicates
- * a programming error in the system server. It should not propagate to
- * applications.
- * @hide
- */
- @SystemApi
- public static final int ERROR_NO_SUCH_SLOT = -33;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "ERROR_" }, value = {
- ERROR_INVALID_NETWORK,
- ERROR_INVALID_IP_ADDRESS,
- ERROR_INVALID_PORT,
- ERROR_INVALID_LENGTH,
- ERROR_INVALID_INTERVAL,
- ERROR_INVALID_SOCKET,
- ERROR_SOCKET_NOT_IDLE,
- ERROR_NO_SUCH_SLOT
- })
- public @interface ErrorCode {}
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- SUCCESS,
- ERROR_INVALID_LENGTH,
- ERROR_UNSUPPORTED,
- ERROR_INSUFFICIENT_RESOURCES,
- })
- public @interface KeepaliveEvent {}
-
- /**
- * The minimum interval in seconds between keepalive packet transmissions.
- *
- * @hide
- **/
- public static final int MIN_INTERVAL_SEC = 10;
-
- /**
- * The maximum interval in seconds between keepalive packet transmissions.
- *
- * @hide
- **/
- public static final int MAX_INTERVAL_SEC = 3600;
-
- /**
- * An exception that embarks an error code.
- * @hide
- */
- public static class ErrorCodeException extends Exception {
- public final int error;
- public ErrorCodeException(final int error, final Throwable e) {
- super(e);
- this.error = error;
- }
- public ErrorCodeException(final int error) {
- this.error = error;
- }
- }
-
- /**
- * This socket is invalid.
- * See the error code for details, and the optional cause.
- * @hide
- */
- public static class InvalidSocketException extends ErrorCodeException {
- public InvalidSocketException(final int error, final Throwable e) {
- super(error, e);
- }
- public InvalidSocketException(final int error) {
- super(error);
- }
- }
-
- @NonNull final IConnectivityManager mService;
- @NonNull final Network mNetwork;
- @NonNull final ParcelFileDescriptor mPfd;
- @NonNull final Executor mExecutor;
- @NonNull final ISocketKeepaliveCallback mCallback;
- // TODO: remove slot since mCallback could be used to identify which keepalive to stop.
- @Nullable Integer mSlot;
-
- SocketKeepalive(@NonNull IConnectivityManager service, @NonNull Network network,
- @NonNull ParcelFileDescriptor pfd,
- @NonNull Executor executor, @NonNull Callback callback) {
- mService = service;
- mNetwork = network;
- mPfd = pfd;
- mExecutor = executor;
- mCallback = new ISocketKeepaliveCallback.Stub() {
- @Override
- public void onStarted(int slot) {
- final long token = Binder.clearCallingIdentity();
- try {
- mExecutor.execute(() -> {
- mSlot = slot;
- callback.onStarted();
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void onStopped() {
- final long token = Binder.clearCallingIdentity();
- try {
- executor.execute(() -> {
- mSlot = null;
- callback.onStopped();
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void onError(int error) {
- final long token = Binder.clearCallingIdentity();
- try {
- executor.execute(() -> {
- mSlot = null;
- callback.onError(error);
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public void onDataReceived() {
- final long token = Binder.clearCallingIdentity();
- try {
- executor.execute(() -> {
- mSlot = null;
- callback.onDataReceived();
- });
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- };
- }
-
- /**
- * Request that keepalive be started with the given {@code intervalSec}. See
- * {@link SocketKeepalive}. If the remote binder dies, or the binder call throws an exception
- * when invoking start or stop of the {@link SocketKeepalive}, a {@link RemoteException} will be
- * thrown into the {@code executor}. This is typically not important to catch because the remote
- * party is the system, so if it is not in shape to communicate through binder the system is
- * probably going down anyway. If the caller cares regardless, it can use a custom
- * {@link Executor} to catch the {@link RemoteException}.
- *
- * @param intervalSec The target interval in seconds between keepalive packet transmissions.
- * The interval should be between 10 seconds and 3600 seconds, otherwise
- * {@link #ERROR_INVALID_INTERVAL} will be returned.
- */
- public final void start(@IntRange(from = MIN_INTERVAL_SEC, to = MAX_INTERVAL_SEC)
- int intervalSec) {
- startImpl(intervalSec);
- }
-
- abstract void startImpl(int intervalSec);
-
- /**
- * Requests that keepalive be stopped. The application must wait for {@link Callback#onStopped}
- * before using the object. See {@link SocketKeepalive}.
- */
- public final void stop() {
- stopImpl();
- }
-
- abstract void stopImpl();
-
- /**
- * Deactivate this {@link SocketKeepalive} and free allocated resources. The instance won't be
- * usable again if {@code close()} is called.
- */
- @Override
- public final void close() {
- stop();
- try {
- mPfd.close();
- } catch (IOException e) {
- // Nothing much can be done.
- }
- }
-
- /**
- * The callback which app can use to learn the status changes of {@link SocketKeepalive}. See
- * {@link SocketKeepalive}.
- */
- public static class Callback {
- /** The requested keepalive was successfully started. */
- public void onStarted() {}
- /** The keepalive was successfully stopped. */
- public void onStopped() {}
- /** An error occurred. */
- public void onError(@ErrorCode int error) {}
- /** The keepalive on a TCP socket was stopped because the socket received data. This is
- * never called for UDP sockets. */
- public void onDataReceived() {}
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/SocketLocalAddressChangedException.java b/packages/Connectivity/framework/src/android/net/SocketLocalAddressChangedException.java
deleted file mode 100644
index 9daad83..0000000
--- a/packages/Connectivity/framework/src/android/net/SocketLocalAddressChangedException.java
+++ /dev/null
@@ -1,32 +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.annotation.SystemApi;
-
-/**
- * Thrown when the local address of the socket has changed.
- *
- * @hide
- */
-@SystemApi
-public class SocketLocalAddressChangedException extends Exception {
- /** @hide */
- public SocketLocalAddressChangedException() {
- super("The local address of the socket changed");
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/SocketNotBoundException.java b/packages/Connectivity/framework/src/android/net/SocketNotBoundException.java
deleted file mode 100644
index b1d7026..0000000
--- a/packages/Connectivity/framework/src/android/net/SocketNotBoundException.java
+++ /dev/null
@@ -1,32 +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.annotation.SystemApi;
-
-/**
- * Thrown when a previously bound socket becomes unbound.
- *
- * @hide
- */
-@SystemApi
-public class SocketNotBoundException extends Exception {
- /** @hide */
- public SocketNotBoundException() {
- super("The socket is unbound");
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.java b/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.java
deleted file mode 100644
index 7904f7a..0000000
--- a/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.java
+++ /dev/null
@@ -1,331 +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 android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.net.module.util.InetAddressUtils;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Class that describes static IP configuration.
- *
- * <p>This class is different from {@link LinkProperties} because it represents
- * configuration intent. The general contract is that if we can represent
- * a configuration here, then we should be able to configure it on a network.
- * The intent is that it closely match the UI we have for configuring networks.
- *
- * <p>In contrast, {@link LinkProperties} represents current state. It is much more
- * expressive. For example, it supports multiple IP addresses, multiple routes,
- * stacked interfaces, and so on. Because LinkProperties is so expressive,
- * using it to represent configuration intent as well as current state causes
- * problems. For example, we could unknowingly save a configuration that we are
- * not in fact capable of applying, or we could save a configuration that the
- * UI cannot display, which has the potential for malicious code to hide
- * hostile or unexpected configuration from the user.
- *
- * @hide
- */
-@SystemApi
-public final class StaticIpConfiguration implements Parcelable {
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @Nullable
- public LinkAddress ipAddress;
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @Nullable
- public InetAddress gateway;
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @NonNull
- public final ArrayList<InetAddress> dnsServers;
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @Nullable
- public String domains;
-
- public StaticIpConfiguration() {
- dnsServers = new ArrayList<>();
- }
-
- public StaticIpConfiguration(@Nullable StaticIpConfiguration source) {
- this();
- if (source != null) {
- // All of these except dnsServers are immutable, so no need to make copies.
- ipAddress = source.ipAddress;
- gateway = source.gateway;
- dnsServers.addAll(source.dnsServers);
- domains = source.domains;
- }
- }
-
- public void clear() {
- ipAddress = null;
- gateway = null;
- dnsServers.clear();
- domains = null;
- }
-
- /**
- * Get the static IP address included in the configuration.
- */
- public @Nullable LinkAddress getIpAddress() {
- return ipAddress;
- }
-
- /**
- * Get the gateway included in the configuration.
- */
- public @Nullable InetAddress getGateway() {
- return gateway;
- }
-
- /**
- * Get the DNS servers included in the configuration.
- */
- public @NonNull List<InetAddress> getDnsServers() {
- return dnsServers;
- }
-
- /**
- * Get a {@link String} containing the comma separated domains to search when resolving host
- * names on this link, in priority order.
- */
- public @Nullable String getDomains() {
- return domains;
- }
-
- /**
- * Helper class to build a new instance of {@link StaticIpConfiguration}.
- */
- public static final class Builder {
- private LinkAddress mIpAddress;
- private InetAddress mGateway;
- private Iterable<InetAddress> mDnsServers;
- private String mDomains;
-
- /**
- * Set the IP address to be included in the configuration; null by default.
- * @return The {@link Builder} for chaining.
- */
- public @NonNull Builder setIpAddress(@Nullable LinkAddress ipAddress) {
- mIpAddress = ipAddress;
- return this;
- }
-
- /**
- * Set the address of the gateway to be included in the configuration; null by default.
- * @return The {@link Builder} for chaining.
- */
- public @NonNull Builder setGateway(@Nullable InetAddress gateway) {
- mGateway = gateway;
- return this;
- }
-
- /**
- * Set the addresses of the DNS servers included in the configuration; empty by default.
- * @return The {@link Builder} for chaining.
- */
- public @NonNull Builder setDnsServers(@NonNull Iterable<InetAddress> dnsServers) {
- Objects.requireNonNull(dnsServers);
- mDnsServers = dnsServers;
- return this;
- }
-
- /**
- * Sets the DNS domain search path to be used on the link; null by default.
- * @param newDomains A {@link String} containing the comma separated domains to search when
- * resolving host names on this link, in priority order.
- * @return The {@link Builder} for chaining.
- */
- public @NonNull Builder setDomains(@Nullable String newDomains) {
- mDomains = newDomains;
- return this;
- }
-
- /**
- * Create a {@link StaticIpConfiguration} from the parameters in this {@link Builder}.
- * @return The newly created StaticIpConfiguration.
- */
- public @NonNull StaticIpConfiguration build() {
- final StaticIpConfiguration config = new StaticIpConfiguration();
- config.ipAddress = mIpAddress;
- config.gateway = mGateway;
- if (mDnsServers != null) {
- for (InetAddress server : mDnsServers) {
- config.dnsServers.add(server);
- }
- }
- config.domains = mDomains;
- return config;
- }
- }
-
- /**
- * Add a DNS server to this configuration.
- */
- public void addDnsServer(@NonNull InetAddress server) {
- dnsServers.add(server);
- }
-
- /**
- * Returns the network routes specified by this object. Will typically include a
- * directly-connected route for the IP address's local subnet and a default route.
- * @param iface Interface to include in the routes.
- */
- public @NonNull List<RouteInfo> getRoutes(@Nullable String iface) {
- List<RouteInfo> routes = new ArrayList<RouteInfo>(3);
- if (ipAddress != null) {
- RouteInfo connectedRoute = new RouteInfo(ipAddress, null, iface);
- routes.add(connectedRoute);
- // If the default gateway is not covered by the directly-connected route, also add a
- // host route to the gateway as well. This configuration is arguably invalid, but it
- // used to work in K and earlier, and other OSes appear to accept it.
- if (gateway != null && !connectedRoute.matches(gateway)) {
- routes.add(RouteInfo.makeHostRoute(gateway, iface));
- }
- }
- if (gateway != null) {
- routes.add(new RouteInfo((IpPrefix) null, gateway, iface));
- }
- return routes;
- }
-
- /**
- * Returns a LinkProperties object expressing the data in this object. Note that the information
- * contained in the LinkProperties will not be a complete picture of the link's configuration,
- * because any configuration information that is obtained dynamically by the network (e.g.,
- * IPv6 configuration) will not be included.
- * @hide
- */
- public @NonNull LinkProperties toLinkProperties(String iface) {
- LinkProperties lp = new LinkProperties();
- lp.setInterfaceName(iface);
- if (ipAddress != null) {
- lp.addLinkAddress(ipAddress);
- }
- for (RouteInfo route : getRoutes(iface)) {
- lp.addRoute(route);
- }
- for (InetAddress dns : dnsServers) {
- lp.addDnsServer(dns);
- }
- lp.setDomains(domains);
- return lp;
- }
-
- @NonNull
- @Override
- public String toString() {
- StringBuffer str = new StringBuffer();
-
- str.append("IP address ");
- if (ipAddress != null ) str.append(ipAddress).append(" ");
-
- str.append("Gateway ");
- if (gateway != null) str.append(gateway.getHostAddress()).append(" ");
-
- str.append(" DNS servers: [");
- for (InetAddress dnsServer : dnsServers) {
- str.append(" ").append(dnsServer.getHostAddress());
- }
-
- str.append(" ] Domains ");
- if (domains != null) str.append(domains);
- return str.toString();
- }
-
- @Override
- public int hashCode() {
- int result = 13;
- result = 47 * result + (ipAddress == null ? 0 : ipAddress.hashCode());
- result = 47 * result + (gateway == null ? 0 : gateway.hashCode());
- result = 47 * result + (domains == null ? 0 : domains.hashCode());
- result = 47 * result + dnsServers.hashCode();
- return result;
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (this == obj) return true;
-
- if (!(obj instanceof StaticIpConfiguration)) return false;
-
- StaticIpConfiguration other = (StaticIpConfiguration) obj;
-
- return other != null &&
- Objects.equals(ipAddress, other.ipAddress) &&
- Objects.equals(gateway, other.gateway) &&
- dnsServers.equals(other.dnsServers) &&
- Objects.equals(domains, other.domains);
- }
-
- /** Implement the Parcelable interface */
- public static final @android.annotation.NonNull Creator<StaticIpConfiguration> CREATOR =
- new Creator<StaticIpConfiguration>() {
- public StaticIpConfiguration createFromParcel(Parcel in) {
- return readFromParcel(in);
- }
-
- public StaticIpConfiguration[] newArray(int size) {
- return new StaticIpConfiguration[size];
- }
- };
-
- /** Implement the Parcelable interface */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(ipAddress, flags);
- InetAddressUtils.parcelInetAddress(dest, gateway, flags);
- dest.writeInt(dnsServers.size());
- for (InetAddress dnsServer : dnsServers) {
- InetAddressUtils.parcelInetAddress(dest, dnsServer, flags);
- }
- dest.writeString(domains);
- }
-
- /** @hide */
- public static StaticIpConfiguration readFromParcel(Parcel in) {
- final StaticIpConfiguration s = new StaticIpConfiguration();
- s.ipAddress = in.readParcelable(null);
- s.gateway = InetAddressUtils.unparcelInetAddress(in);
- s.dnsServers.clear();
- int size = in.readInt();
- for (int i = 0; i < size; i++) {
- s.dnsServers.add(InetAddressUtils.unparcelInetAddress(in));
- }
- s.domains = in.readString();
- return s;
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java b/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java
deleted file mode 100644
index c2c4f32..0000000
--- a/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java
+++ /dev/null
@@ -1,230 +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.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.net.InetAddress;
-import java.util.Objects;
-
-/**
- * Represents the actual tcp keep alive packets which will be used for hardware offload.
- * @hide
- */
-@SystemApi
-public final class TcpKeepalivePacketData extends KeepalivePacketData implements Parcelable {
- private static final String TAG = "TcpKeepalivePacketData";
-
- /**
- * TCP sequence number.
- * @hide
- */
- public final int tcpSeq;
-
- /**
- * TCP ACK number.
- * @hide
- */
- public final int tcpAck;
-
- /**
- * TCP RCV window.
- * @hide
- */
- public final int tcpWindow;
-
- /** TCP RCV window scale.
- * @hide
- */
- public final int tcpWindowScale;
-
- /**
- * IP TOS.
- * @hide
- */
- public final int ipTos;
-
- /**
- * IP TTL.
- * @hide
- */
- public final int ipTtl;
-
- public TcpKeepalivePacketData(@NonNull final InetAddress srcAddress, int srcPort,
- @NonNull final InetAddress dstAddress, int dstPort, @NonNull final byte[] data,
- int tcpSeq, int tcpAck, int tcpWindow, int tcpWindowScale, int ipTos, int ipTtl)
- throws InvalidPacketException {
- super(srcAddress, srcPort, dstAddress, dstPort, data);
- this.tcpSeq = tcpSeq;
- this.tcpAck = tcpAck;
- this.tcpWindow = tcpWindow;
- this.tcpWindowScale = tcpWindowScale;
- this.ipTos = ipTos;
- this.ipTtl = ipTtl;
- }
-
- /**
- * Get the TCP sequence number.
- *
- * See https://tools.ietf.org/html/rfc793#page-15.
- */
- public int getTcpSeq() {
- return tcpSeq;
- }
-
- /**
- * Get the TCP ACK number.
- *
- * See https://tools.ietf.org/html/rfc793#page-15.
- */
- public int getTcpAck() {
- return tcpAck;
- }
-
- /**
- * Get the TCP RCV window.
- *
- * See https://tools.ietf.org/html/rfc793#page-15.
- */
- public int getTcpWindow() {
- return tcpWindow;
- }
-
- /**
- * Get the TCP RCV window scale.
- *
- * See https://tools.ietf.org/html/rfc793#page-15.
- */
- public int getTcpWindowScale() {
- return tcpWindowScale;
- }
-
- /**
- * Get the IP type of service.
- */
- public int getIpTos() {
- return ipTos;
- }
-
- /**
- * Get the IP TTL.
- */
- public int getIpTtl() {
- return ipTtl;
- }
-
- @Override
- public boolean equals(@Nullable final Object o) {
- if (!(o instanceof TcpKeepalivePacketData)) return false;
- final TcpKeepalivePacketData other = (TcpKeepalivePacketData) o;
- final InetAddress srcAddress = getSrcAddress();
- final InetAddress dstAddress = getDstAddress();
- return srcAddress.equals(other.getSrcAddress())
- && dstAddress.equals(other.getDstAddress())
- && getSrcPort() == other.getSrcPort()
- && getDstPort() == other.getDstPort()
- && this.tcpAck == other.tcpAck
- && this.tcpSeq == other.tcpSeq
- && this.tcpWindow == other.tcpWindow
- && this.tcpWindowScale == other.tcpWindowScale
- && this.ipTos == other.ipTos
- && this.ipTtl == other.ipTtl;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(getSrcAddress(), getDstAddress(), getSrcPort(), getDstPort(),
- tcpAck, tcpSeq, tcpWindow, tcpWindowScale, ipTos, ipTtl);
- }
-
- /**
- * Parcelable Implementation.
- * Note that this object implements parcelable (and needs to keep doing this as it inherits
- * from a class that does), but should usually be parceled as a stable parcelable using
- * the toStableParcelable() and fromStableParcelable() methods.
- */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** Write to parcel. */
- @Override
- public void writeToParcel(@NonNull Parcel out, int flags) {
- out.writeString(getSrcAddress().getHostAddress());
- out.writeString(getDstAddress().getHostAddress());
- out.writeInt(getSrcPort());
- out.writeInt(getDstPort());
- out.writeByteArray(getPacket());
- out.writeInt(tcpSeq);
- out.writeInt(tcpAck);
- out.writeInt(tcpWindow);
- out.writeInt(tcpWindowScale);
- out.writeInt(ipTos);
- out.writeInt(ipTtl);
- }
-
- private static TcpKeepalivePacketData readFromParcel(Parcel in) throws InvalidPacketException {
- InetAddress srcAddress = InetAddresses.parseNumericAddress(in.readString());
- InetAddress dstAddress = InetAddresses.parseNumericAddress(in.readString());
- int srcPort = in.readInt();
- int dstPort = in.readInt();
- byte[] packet = in.createByteArray();
- int tcpSeq = in.readInt();
- int tcpAck = in.readInt();
- int tcpWnd = in.readInt();
- int tcpWndScale = in.readInt();
- int ipTos = in.readInt();
- int ipTtl = in.readInt();
- return new TcpKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, packet, tcpSeq,
- tcpAck, tcpWnd, tcpWndScale, ipTos, ipTtl);
- }
-
- /** Parcelable Creator. */
- public static final @NonNull Parcelable.Creator<TcpKeepalivePacketData> CREATOR =
- new Parcelable.Creator<TcpKeepalivePacketData>() {
- public TcpKeepalivePacketData createFromParcel(Parcel in) {
- try {
- return readFromParcel(in);
- } catch (InvalidPacketException e) {
- throw new IllegalArgumentException(
- "Invalid TCP keepalive data: " + e.getError());
- }
- }
-
- public TcpKeepalivePacketData[] newArray(int size) {
- return new TcpKeepalivePacketData[size];
- }
- };
-
- @Override
- public String toString() {
- return "saddr: " + getSrcAddress()
- + " daddr: " + getDstAddress()
- + " sport: " + getSrcPort()
- + " dport: " + getDstPort()
- + " seq: " + tcpSeq
- + " ack: " + tcpAck
- + " window: " + tcpWindow
- + " windowScale: " + tcpWindowScale
- + " tos: " + ipTos
- + " ttl: " + ipTtl;
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/TcpRepairWindow.java b/packages/Connectivity/framework/src/android/net/TcpRepairWindow.java
deleted file mode 100644
index 86034f0..0000000
--- a/packages/Connectivity/framework/src/android/net/TcpRepairWindow.java
+++ /dev/null
@@ -1,45 +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;
-
-/**
- * Corresponds to C's {@code struct tcp_repair_window} from
- * include/uapi/linux/tcp.h
- *
- * @hide
- */
-public final class TcpRepairWindow {
- public final int sndWl1;
- public final int sndWnd;
- public final int maxWindow;
- public final int rcvWnd;
- public final int rcvWup;
- public final int rcvWndScale;
-
- /**
- * Constructs an instance with the given field values.
- */
- public TcpRepairWindow(final int sndWl1, final int sndWnd, final int maxWindow,
- final int rcvWnd, final int rcvWup, final int rcvWndScale) {
- this.sndWl1 = sndWl1;
- this.sndWnd = sndWnd;
- this.maxWindow = maxWindow;
- this.rcvWnd = rcvWnd;
- this.rcvWup = rcvWup;
- this.rcvWndScale = rcvWndScale;
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/TcpSocketKeepalive.java b/packages/Connectivity/framework/src/android/net/TcpSocketKeepalive.java
deleted file mode 100644
index d89814d..0000000
--- a/packages/Connectivity/framework/src/android/net/TcpSocketKeepalive.java
+++ /dev/null
@@ -1,77 +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.annotation.NonNull;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.concurrent.Executor;
-
-/** @hide */
-final class TcpSocketKeepalive extends SocketKeepalive {
-
- TcpSocketKeepalive(@NonNull IConnectivityManager service,
- @NonNull Network network,
- @NonNull ParcelFileDescriptor pfd,
- @NonNull Executor executor,
- @NonNull Callback callback) {
- super(service, network, pfd, executor, callback);
- }
-
- /**
- * Starts keepalives. {@code mSocket} must be a connected TCP socket.
- *
- * - The application must not write to or read from the socket after calling this method, until
- * onDataReceived, onStopped, or onError are called. If it does, the keepalive will fail
- * with {@link #ERROR_SOCKET_NOT_IDLE}, or {@code #ERROR_INVALID_SOCKET} if the socket
- * experienced an error (as in poll(2) returned POLLERR or POLLHUP); if this happens, the data
- * received from the socket may be invalid, and the socket can't be recovered.
- * - If the socket has data in the send or receive buffer, then this call will fail with
- * {@link #ERROR_SOCKET_NOT_IDLE} and can be retried after the data has been processed.
- * An app could ensure this by using an application-layer protocol to receive acknowledgement
- * that indicates all data has been delivered to server, e.g. HTTP 200 OK.
- * Then the app could go into keepalive mode after reading all remaining data within the
- * acknowledgement.
- */
- @Override
- void startImpl(int intervalSec) {
- mExecutor.execute(() -> {
- try {
- mService.startTcpKeepalive(mNetwork, mPfd, intervalSec, mCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "Error starting packet keepalive: ", e);
- throw e.rethrowFromSystemServer();
- }
- });
- }
-
- @Override
- void stopImpl() {
- mExecutor.execute(() -> {
- try {
- if (mSlot != null) {
- mService.stopKeepalive(mNetwork, mSlot);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Error stopping packet keepalive: ", e);
- throw e.rethrowFromSystemServer();
- }
- });
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/TestNetworkInterface.java b/packages/Connectivity/framework/src/android/net/TestNetworkInterface.java
deleted file mode 100644
index 4449ff8..0000000
--- a/packages/Connectivity/framework/src/android/net/TestNetworkInterface.java
+++ /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 android.net;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
-
-/**
- * This class is used to return the interface name and fd of the test interface
- *
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public final class TestNetworkInterface implements Parcelable {
- @NonNull
- private final ParcelFileDescriptor mFileDescriptor;
- @NonNull
- private final String mInterfaceName;
-
- @Override
- public int describeContents() {
- return (mFileDescriptor != null) ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel out, int flags) {
- out.writeParcelable(mFileDescriptor, PARCELABLE_WRITE_RETURN_VALUE);
- out.writeString(mInterfaceName);
- }
-
- public TestNetworkInterface(@NonNull ParcelFileDescriptor pfd, @NonNull String intf) {
- mFileDescriptor = pfd;
- mInterfaceName = intf;
- }
-
- private TestNetworkInterface(@NonNull Parcel in) {
- mFileDescriptor = in.readParcelable(ParcelFileDescriptor.class.getClassLoader());
- mInterfaceName = in.readString();
- }
-
- @NonNull
- public ParcelFileDescriptor getFileDescriptor() {
- return mFileDescriptor;
- }
-
- @NonNull
- public String getInterfaceName() {
- return mInterfaceName;
- }
-
- @NonNull
- public static final Parcelable.Creator<TestNetworkInterface> CREATOR =
- new Parcelable.Creator<TestNetworkInterface>() {
- public TestNetworkInterface createFromParcel(Parcel in) {
- return new TestNetworkInterface(in);
- }
-
- public TestNetworkInterface[] newArray(int size) {
- return new TestNetworkInterface[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/TestNetworkManager.java b/packages/Connectivity/framework/src/android/net/TestNetworkManager.java
deleted file mode 100644
index 9ddd2f5..0000000
--- a/packages/Connectivity/framework/src/android/net/TestNetworkManager.java
+++ /dev/null
@@ -1,182 +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 android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.os.IBinder;
-import android.os.RemoteException;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Objects;
-
-/**
- * Class that allows creation and management of per-app, test-only networks
- *
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public class TestNetworkManager {
- /**
- * Prefix for tun interfaces created by this class.
- * @hide
- */
- public static final String TEST_TUN_PREFIX = "testtun";
-
- /**
- * Prefix for tap interfaces created by this class.
- */
- public static final String TEST_TAP_PREFIX = "testtap";
-
- @NonNull private static final String TAG = TestNetworkManager.class.getSimpleName();
-
- @NonNull private final ITestNetworkManager mService;
-
- /** @hide */
- public TestNetworkManager(@NonNull ITestNetworkManager service) {
- mService = Objects.requireNonNull(service, "missing ITestNetworkManager");
- }
-
- /**
- * Teardown the capability-limited, testing-only network for a given interface
- *
- * @param network The test network that should be torn down
- * @hide
- */
- @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public void teardownTestNetwork(@NonNull Network network) {
- try {
- mService.teardownTestNetwork(network.netId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- private void setupTestNetwork(
- @NonNull String iface,
- @Nullable LinkProperties lp,
- boolean isMetered,
- @NonNull int[] administratorUids,
- @NonNull IBinder binder) {
- try {
- mService.setupTestNetwork(iface, lp, isMetered, administratorUids, binder);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Sets up a capability-limited, testing-only network for a given interface
- *
- * @param lp The LinkProperties for the TestNetworkService to use for this test network. Note
- * that the interface name and link addresses will be overwritten, and the passed-in values
- * discarded.
- * @param isMetered Whether or not the network should be considered metered.
- * @param binder A binder object guarding the lifecycle of this test network.
- * @hide
- */
- public void setupTestNetwork(
- @NonNull LinkProperties lp, boolean isMetered, @NonNull IBinder binder) {
- Objects.requireNonNull(lp, "Invalid LinkProperties");
- setupTestNetwork(lp.getInterfaceName(), lp, isMetered, new int[0], binder);
- }
-
- /**
- * Sets up a capability-limited, testing-only network for a given interface
- *
- * @param iface the name of the interface to be used for the Network LinkProperties.
- * @param binder A binder object guarding the lifecycle of this test network.
- * @hide
- */
- @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public void setupTestNetwork(@NonNull String iface, @NonNull IBinder binder) {
- setupTestNetwork(iface, null, true, new int[0], binder);
- }
-
- /**
- * Sets up a capability-limited, testing-only network for a given interface with the given
- * administrator UIDs.
- *
- * @param iface the name of the interface to be used for the Network LinkProperties.
- * @param administratorUids The administrator UIDs to be used for the test-only network
- * @param binder A binder object guarding the lifecycle of this test network.
- * @hide
- */
- public void setupTestNetwork(
- @NonNull String iface, @NonNull int[] administratorUids, @NonNull IBinder binder) {
- setupTestNetwork(iface, null, true, administratorUids, binder);
- }
-
- /**
- * Create a tun interface for testing purposes
- *
- * @param linkAddrs an array of LinkAddresses to assign to the TUN interface
- * @return A ParcelFileDescriptor of the underlying TUN interface. Close this to tear down the
- * TUN interface.
- * @deprecated Use {@link #createTunInterface(Collection)} instead.
- * @hide
- */
- @Deprecated
- @NonNull
- public TestNetworkInterface createTunInterface(@NonNull LinkAddress[] linkAddrs) {
- return createTunInterface(Arrays.asList(linkAddrs));
- }
-
- /**
- * Create a tun interface for testing purposes
- *
- * @param linkAddrs an array of LinkAddresses to assign to the TUN interface
- * @return A ParcelFileDescriptor of the underlying TUN interface. Close this to tear down the
- * TUN interface.
- * @hide
- */
- @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- @NonNull
- public TestNetworkInterface createTunInterface(@NonNull Collection<LinkAddress> linkAddrs) {
- try {
- final LinkAddress[] arr = new LinkAddress[linkAddrs.size()];
- return mService.createTunInterface(linkAddrs.toArray(arr));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Create a tap interface for testing purposes
- *
- * @return A ParcelFileDescriptor of the underlying TAP interface. Close this to tear down the
- * TAP interface.
- * @hide
- */
- @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- @NonNull
- public TestNetworkInterface createTapInterface() {
- try {
- return mService.createTapInterface();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
-}
diff --git a/packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java b/packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java
deleted file mode 100644
index 117457d..0000000
--- a/packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java
+++ /dev/null
@@ -1,97 +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.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.util.Objects;
-
-/**
- * A {@link NetworkSpecifier} used to identify test interfaces.
- *
- * @see TestNetworkManager
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public final class TestNetworkSpecifier extends NetworkSpecifier implements Parcelable {
-
- /**
- * Name of the network interface.
- */
- @NonNull
- private final String mInterfaceName;
-
- public TestNetworkSpecifier(@NonNull String interfaceName) {
- if (TextUtils.isEmpty(interfaceName)) {
- throw new IllegalArgumentException("Empty interfaceName");
- }
- mInterfaceName = interfaceName;
- }
-
- // This may be null in the future to support specifiers based on data other than the interface
- // name.
- @Nullable
- public String getInterfaceName() {
- return mInterfaceName;
- }
-
- @Override
- public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) {
- return equals(other);
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof TestNetworkSpecifier)) return false;
- return TextUtils.equals(mInterfaceName, ((TestNetworkSpecifier) o).mInterfaceName);
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(mInterfaceName);
- }
-
- @Override
- public String toString() {
- return "TestNetworkSpecifier (" + mInterfaceName + ")";
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeString(mInterfaceName);
- }
-
- public static final @NonNull Creator<TestNetworkSpecifier> CREATOR =
- new Creator<TestNetworkSpecifier>() {
- public TestNetworkSpecifier createFromParcel(Parcel in) {
- return new TestNetworkSpecifier(in.readString());
- }
- public TestNetworkSpecifier[] newArray(int size) {
- return new TestNetworkSpecifier[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/TransportInfo.java b/packages/Connectivity/framework/src/android/net/TransportInfo.java
deleted file mode 100644
index fa889ea..0000000
--- a/packages/Connectivity/framework/src/android/net/TransportInfo.java
+++ /dev/null
@@ -1,75 +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 android.annotation.NonNull;
-import android.annotation.SystemApi;
-
-/**
- * A container for transport-specific capabilities which is returned by
- * {@link NetworkCapabilities#getTransportInfo()}. Specific networks
- * may provide concrete implementations of this interface.
- * @see android.net.wifi.aware.WifiAwareNetworkInfo
- * @see android.net.wifi.WifiInfo
- */
-public interface TransportInfo {
-
- /**
- * Create a copy of a {@link TransportInfo} with some fields redacted based on the permissions
- * held by the receiving app.
- *
- * <p>
- * Usage by connectivity stack:
- * <ul>
- * <li> Connectivity stack will invoke {@link #getApplicableRedactions()} to find the list
- * of redactions that are required by this {@link TransportInfo} instance.</li>
- * <li> Connectivity stack then loops through each bit in the bitmask returned and checks if the
- * receiving app holds the corresponding permission.
- * <ul>
- * <li> If the app holds the corresponding permission, the bit is cleared from the
- * |redactions| bitmask. </li>
- * <li> If the app does not hold the corresponding permission, the bit is retained in the
- * |redactions| bitmask. </li>
- * </ul>
- * <li> Connectivity stack then invokes {@link #makeCopy(long)} with the necessary |redactions|
- * to create a copy to send to the corresponding app. </li>
- * </ul>
- * </p>
- *
- * @param redactions bitmask of redactions that needs to be performed on this instance.
- * @return Copy of this instance with the necessary redactions.
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- @NonNull
- default TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) {
- return this;
- }
-
- /**
- * Returns a bitmask of all the applicable redactions (based on the permissions held by the
- * receiving app) to be performed on this TransportInfo.
- *
- * @return bitmask of redactions applicable on this instance.
- * @see #makeCopy(long)
- * @hide
- */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- default @NetworkCapabilities.RedactionType long getApplicableRedactions() {
- return NetworkCapabilities.REDACT_NONE;
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/UidRange.aidl b/packages/Connectivity/framework/src/android/net/UidRange.aidl
deleted file mode 100644
index f70fc8e..0000000
--- a/packages/Connectivity/framework/src/android/net/UidRange.aidl
+++ /dev/null
@@ -1,24 +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;
-
-/**
- * An inclusive range of UIDs.
- *
- * {@hide}
- */
-parcelable UidRange;
\ No newline at end of file
diff --git a/packages/Connectivity/framework/src/android/net/UidRange.java b/packages/Connectivity/framework/src/android/net/UidRange.java
deleted file mode 100644
index bd33292..0000000
--- a/packages/Connectivity/framework/src/android/net/UidRange.java
+++ /dev/null
@@ -1,183 +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 android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.UserHandle;
-import android.util.ArraySet;
-import android.util.Range;
-
-import java.util.Collection;
-import java.util.Set;
-
-/**
- * An inclusive range of UIDs.
- *
- * @hide
- */
-public final class UidRange implements Parcelable {
- public final int start;
- public final int stop;
-
- public UidRange(int startUid, int stopUid) {
- if (startUid < 0) throw new IllegalArgumentException("Invalid start UID.");
- if (stopUid < 0) throw new IllegalArgumentException("Invalid stop UID.");
- if (startUid > stopUid) throw new IllegalArgumentException("Invalid UID range.");
- start = startUid;
- stop = stopUid;
- }
-
- /** Creates a UidRange for the specified user. */
- public static UidRange createForUser(UserHandle user) {
- final UserHandle nextUser = UserHandle.of(user.getIdentifier() + 1);
- final int start = user.getUid(0 /* appId */);
- final int end = nextUser.getUid(0 /* appId */) - 1;
- return new UidRange(start, end);
- }
-
- /** Returns the smallest user Id which is contained in this UidRange */
- public int getStartUser() {
- return UserHandle.getUserHandleForUid(start).getIdentifier();
- }
-
- /** Returns the largest user Id which is contained in this UidRange */
- public int getEndUser() {
- return UserHandle.getUserHandleForUid(stop).getIdentifier();
- }
-
- /** Returns whether the UidRange contains the specified UID. */
- public boolean contains(int uid) {
- return start <= uid && uid <= stop;
- }
-
- /**
- * Returns the count of UIDs in this range.
- */
- public int count() {
- return 1 + stop - start;
- }
-
- /**
- * @return {@code true} if this range contains every UID contained by the {@code other} range.
- */
- public boolean containsRange(UidRange other) {
- return start <= other.start && other.stop <= stop;
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- result = 31 * result + start;
- result = 31 * result + stop;
- return result;
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) {
- return true;
- }
- if (o instanceof UidRange) {
- UidRange other = (UidRange) o;
- return start == other.start && stop == other.stop;
- }
- return false;
- }
-
- @Override
- public String toString() {
- return start + "-" + stop;
- }
-
- // Implement the Parcelable interface
- // TODO: Consider making this class no longer parcelable, since all users are likely in the
- // system server.
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(start);
- dest.writeInt(stop);
- }
-
- public static final @android.annotation.NonNull Creator<UidRange> CREATOR =
- new Creator<UidRange>() {
- @Override
- public UidRange createFromParcel(Parcel in) {
- int start = in.readInt();
- int stop = in.readInt();
-
- return new UidRange(start, stop);
- }
- @Override
- public UidRange[] newArray(int size) {
- return new UidRange[size];
- }
- };
-
- /**
- * Returns whether any of the UidRange in the collection contains the specified uid
- *
- * @param ranges The collection of UidRange to check
- * @param uid the uid in question
- * @return {@code true} if the uid is contained within the ranges, {@code false} otherwise
- *
- * @see UidRange#contains(int)
- */
- public static boolean containsUid(Collection<UidRange> ranges, int uid) {
- if (ranges == null) return false;
- for (UidRange range : ranges) {
- if (range.contains(uid)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Convert a set of {@code Range<Integer>} to a set of {@link UidRange}.
- */
- @Nullable
- public static ArraySet<UidRange> fromIntRanges(@Nullable Set<Range<Integer>> ranges) {
- if (null == ranges) return null;
-
- final ArraySet<UidRange> uids = new ArraySet<>();
- for (Range<Integer> range : ranges) {
- uids.add(new UidRange(range.getLower(), range.getUpper()));
- }
- return uids;
- }
-
- /**
- * Convert a set of {@link UidRange} to a set of {@code Range<Integer>}.
- */
- @Nullable
- public static ArraySet<Range<Integer>> toIntRanges(@Nullable Set<UidRange> ranges) {
- if (null == ranges) return null;
-
- final ArraySet<Range<Integer>> uids = new ArraySet<>();
- for (UidRange range : ranges) {
- uids.add(new Range<Integer>(range.start, range.stop));
- }
- return uids;
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
deleted file mode 100644
index 4071c9a..0000000
--- a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
+++ /dev/null
@@ -1,120 +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.annotation.SystemApi.Client.MODULE_LIBRARIES;
-import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.NetworkCapabilities.RedactionType;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.util.Objects;
-
-/**
- * Container for VPN-specific transport information.
- *
- * @see android.net.TransportInfo
- * @see NetworkCapabilities#getTransportInfo()
- *
- * @hide
- */
-@SystemApi(client = MODULE_LIBRARIES)
-public final class VpnTransportInfo implements TransportInfo, Parcelable {
- /** Type of this VPN. */
- private final int mType;
-
- @Nullable
- private final String mSessionId;
-
- @Override
- public @RedactionType long getApplicableRedactions() {
- return REDACT_FOR_NETWORK_SETTINGS;
- }
-
- /**
- * Create a copy of a {@link VpnTransportInfo} with the sessionId redacted if necessary.
- */
- @NonNull
- public VpnTransportInfo makeCopy(@RedactionType long redactions) {
- return new VpnTransportInfo(mType,
- ((redactions & REDACT_FOR_NETWORK_SETTINGS) != 0) ? null : mSessionId);
- }
-
- public VpnTransportInfo(int type, @Nullable String sessionId) {
- this.mType = type;
- this.mSessionId = sessionId;
- }
-
- /**
- * Returns the session Id of this VpnTransportInfo.
- */
- @Nullable
- public String getSessionId() {
- return mSessionId;
- }
-
- /**
- * Returns the type of this VPN.
- */
- public int getType() {
- return mType;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof VpnTransportInfo)) return false;
-
- VpnTransportInfo that = (VpnTransportInfo) o;
- return (this.mType == that.mType) && TextUtils.equals(this.mSessionId, that.mSessionId);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mType, mSessionId);
- }
-
- @Override
- public String toString() {
- return String.format("VpnTransportInfo{type=%d, sessionId=%s}", mType, mSessionId);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mType);
- dest.writeString(mSessionId);
- }
-
- public static final @NonNull Creator<VpnTransportInfo> CREATOR =
- new Creator<VpnTransportInfo>() {
- public VpnTransportInfo createFromParcel(Parcel in) {
- return new VpnTransportInfo(in.readInt(), in.readString());
- }
- public VpnTransportInfo[] newArray(int size) {
- return new VpnTransportInfo[size];
- }
- };
-}
diff --git a/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.java b/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.java
deleted file mode 100644
index 663c1b3..0000000
--- a/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.java
+++ /dev/null
@@ -1,151 +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.apf;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.content.res.Resources;
-import android.net.ConnectivityResources;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * APF program support capabilities. APF stands for Android Packet Filtering and it is a flexible
- * way to drop unwanted network packets to save power.
- *
- * See documentation at hardware/google/apf/apf.h
- *
- * This class is immutable.
- * @hide
- */
-@SystemApi
-public final class ApfCapabilities implements Parcelable {
- private static ConnectivityResources sResources;
-
- /**
- * Version of APF instruction set supported for packet filtering. 0 indicates no support for
- * packet filtering using APF programs.
- */
- public final int apfVersionSupported;
-
- /**
- * Maximum size of APF program allowed.
- */
- public final int maximumApfProgramSize;
-
- /**
- * Format of packets passed to APF filter. Should be one of ARPHRD_*
- */
- public final int apfPacketFormat;
-
- public ApfCapabilities(
- int apfVersionSupported, int maximumApfProgramSize, int apfPacketFormat) {
- this.apfVersionSupported = apfVersionSupported;
- this.maximumApfProgramSize = maximumApfProgramSize;
- this.apfPacketFormat = apfPacketFormat;
- }
-
- private ApfCapabilities(Parcel in) {
- apfVersionSupported = in.readInt();
- maximumApfProgramSize = in.readInt();
- apfPacketFormat = in.readInt();
- }
-
- @NonNull
- private static synchronized ConnectivityResources getResources(@NonNull Context ctx) {
- if (sResources == null) {
- sResources = new ConnectivityResources(ctx);
- }
- return sResources;
- }
-
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(apfVersionSupported);
- dest.writeInt(maximumApfProgramSize);
- dest.writeInt(apfPacketFormat);
- }
-
- public static final Creator<ApfCapabilities> CREATOR = new Creator<ApfCapabilities>() {
- @Override
- public ApfCapabilities createFromParcel(Parcel in) {
- return new ApfCapabilities(in);
- }
-
- @Override
- public ApfCapabilities[] newArray(int size) {
- return new ApfCapabilities[size];
- }
- };
-
- @NonNull
- @Override
- public String toString() {
- return String.format("%s{version: %d, maxSize: %d, format: %d}", getClass().getSimpleName(),
- apfVersionSupported, maximumApfProgramSize, apfPacketFormat);
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (!(obj instanceof ApfCapabilities)) return false;
- final ApfCapabilities other = (ApfCapabilities) obj;
- return apfVersionSupported == other.apfVersionSupported
- && maximumApfProgramSize == other.maximumApfProgramSize
- && apfPacketFormat == other.apfPacketFormat;
- }
-
- /**
- * Determines whether the APF interpreter advertises support for the data buffer access opcodes
- * LDDW (LoaD Data Word) and STDW (STore Data Word). Full LDDW (LoaD Data Word) and
- * STDW (STore Data Word) support is present from APFv4 on.
- *
- * @return {@code true} if the IWifiStaIface#readApfPacketFilterData is supported.
- */
- public boolean hasDataAccess() {
- return apfVersionSupported >= 4;
- }
-
- /**
- * @return Whether the APF Filter in the device should filter out IEEE 802.3 Frames.
- */
- public static boolean getApfDrop8023Frames() {
- // TODO: deprecate/remove this method (now unused in the platform), as the resource was
- // moved to NetworkStack.
- final Resources systemRes = Resources.getSystem();
- final int id = systemRes.getIdentifier("config_apfDrop802_3Frames", "bool", "android");
- return systemRes.getBoolean(id);
- }
-
- /**
- * @return An array of denylisted EtherType, packets with EtherTypes within it will be dropped.
- */
- public static @NonNull int[] getApfEtherTypeBlackList() {
- // TODO: deprecate/remove this method (now unused in the platform), as the resource was
- // moved to NetworkStack.
- final Resources systemRes = Resources.getSystem();
- final int id = systemRes.getIdentifier("config_apfEthTypeBlackList", "array", "android");
- return systemRes.getIntArray(id);
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/util/DnsUtils.java b/packages/Connectivity/framework/src/android/net/util/DnsUtils.java
deleted file mode 100644
index 3fe245e..0000000
--- a/packages/Connectivity/framework/src/android/net/util/DnsUtils.java
+++ /dev/null
@@ -1,377 +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.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_DGRAM;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.InetAddresses;
-import android.net.Network;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.util.Log;
-
-import libcore.io.IoUtils;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * @hide
- */
-public class DnsUtils {
- private static final String TAG = "DnsUtils";
- private static final int CHAR_BIT = 8;
- public static final int IPV6_ADDR_SCOPE_NODELOCAL = 0x01;
- public static final int IPV6_ADDR_SCOPE_LINKLOCAL = 0x02;
- public static final int IPV6_ADDR_SCOPE_SITELOCAL = 0x05;
- public static final int IPV6_ADDR_SCOPE_GLOBAL = 0x0e;
- private static final Comparator<SortableAddress> sRfc6724Comparator = new Rfc6724Comparator();
-
- /**
- * Comparator to sort SortableAddress in Rfc6724 style.
- */
- public static class Rfc6724Comparator implements Comparator<SortableAddress> {
- // This function matches the behaviour of _rfc6724_compare in the native resolver.
- @Override
- public int compare(SortableAddress span1, SortableAddress span2) {
- // Rule 1: Avoid unusable destinations.
- if (span1.hasSrcAddr != span2.hasSrcAddr) {
- return span2.hasSrcAddr - span1.hasSrcAddr;
- }
-
- // Rule 2: Prefer matching scope.
- if (span1.scopeMatch != span2.scopeMatch) {
- return span2.scopeMatch - span1.scopeMatch;
- }
-
- // TODO: Implement rule 3: Avoid deprecated addresses.
- // TODO: Implement rule 4: Prefer home addresses.
-
- // Rule 5: Prefer matching label.
- if (span1.labelMatch != span2.labelMatch) {
- return span2.labelMatch - span1.labelMatch;
- }
-
- // Rule 6: Prefer higher precedence.
- if (span1.precedence != span2.precedence) {
- return span2.precedence - span1.precedence;
- }
-
- // TODO: Implement rule 7: Prefer native transport.
-
- // Rule 8: Prefer smaller scope.
- if (span1.scope != span2.scope) {
- return span1.scope - span2.scope;
- }
-
- // Rule 9: Use longest matching prefix. IPv6 only.
- if (span1.prefixMatchLen != span2.prefixMatchLen) {
- return span2.prefixMatchLen - span1.prefixMatchLen;
- }
-
- // Rule 10: Leave the order unchanged. Collections.sort is a stable sort.
- return 0;
- }
- }
-
- /**
- * Class used to sort with RFC 6724
- */
- public static class SortableAddress {
- public final int label;
- public final int labelMatch;
- public final int scope;
- public final int scopeMatch;
- public final int precedence;
- public final int prefixMatchLen;
- public final int hasSrcAddr;
- public final InetAddress address;
-
- public SortableAddress(@NonNull InetAddress addr, @Nullable InetAddress srcAddr) {
- address = addr;
- hasSrcAddr = (srcAddr != null) ? 1 : 0;
- label = findLabel(addr);
- scope = findScope(addr);
- precedence = findPrecedence(addr);
- labelMatch = ((srcAddr != null) && (label == findLabel(srcAddr))) ? 1 : 0;
- scopeMatch = ((srcAddr != null) && (scope == findScope(srcAddr))) ? 1 : 0;
- if (isIpv6Address(addr) && isIpv6Address(srcAddr)) {
- prefixMatchLen = compareIpv6PrefixMatchLen(srcAddr, addr);
- } else {
- prefixMatchLen = 0;
- }
- }
- }
-
- /**
- * Sort the given address list in RFC6724 order.
- * Will leave the list unchanged if an error occurs.
- *
- * This function matches the behaviour of _rfc6724_sort in the native resolver.
- */
- public static @NonNull List<InetAddress> rfc6724Sort(@Nullable Network network,
- @NonNull List<InetAddress> answers) {
- final ArrayList<SortableAddress> sortableAnswerList = new ArrayList<>();
- for (InetAddress addr : answers) {
- sortableAnswerList.add(new SortableAddress(addr, findSrcAddress(network, addr)));
- }
-
- Collections.sort(sortableAnswerList, sRfc6724Comparator);
-
- final List<InetAddress> sortedAnswers = new ArrayList<>();
- for (SortableAddress ans : sortableAnswerList) {
- sortedAnswers.add(ans.address);
- }
-
- return sortedAnswers;
- }
-
- private static @Nullable InetAddress findSrcAddress(@Nullable Network network,
- @NonNull InetAddress addr) {
- final int domain;
- if (isIpv4Address(addr)) {
- domain = AF_INET;
- } else if (isIpv6Address(addr)) {
- domain = AF_INET6;
- } else {
- return null;
- }
- final FileDescriptor socket;
- try {
- socket = Os.socket(domain, SOCK_DGRAM, IPPROTO_UDP);
- } catch (ErrnoException e) {
- Log.e(TAG, "findSrcAddress:" + e.toString());
- return null;
- }
- try {
- if (network != null) network.bindSocket(socket);
- Os.connect(socket, new InetSocketAddress(addr, 0));
- return ((InetSocketAddress) Os.getsockname(socket)).getAddress();
- } catch (IOException | ErrnoException e) {
- return null;
- } finally {
- IoUtils.closeQuietly(socket);
- }
- }
-
- /**
- * Get the label for a given IPv4/IPv6 address.
- * RFC 6724, section 2.1.
- *
- * Note that Java will return an IPv4-mapped address as an IPv4 address.
- */
- private static int findLabel(@NonNull InetAddress addr) {
- if (isIpv4Address(addr)) {
- return 4;
- } else if (isIpv6Address(addr)) {
- if (addr.isLoopbackAddress()) {
- return 0;
- } else if (isIpv6Address6To4(addr)) {
- return 2;
- } else if (isIpv6AddressTeredo(addr)) {
- return 5;
- } else if (isIpv6AddressULA(addr)) {
- return 13;
- } else if (((Inet6Address) addr).isIPv4CompatibleAddress()) {
- return 3;
- } else if (addr.isSiteLocalAddress()) {
- return 11;
- } else if (isIpv6Address6Bone(addr)) {
- return 12;
- } else {
- // All other IPv6 addresses, including global unicast addresses.
- return 1;
- }
- } else {
- // This should never happen.
- return 1;
- }
- }
-
- private static boolean isIpv6Address(@Nullable InetAddress addr) {
- return addr instanceof Inet6Address;
- }
-
- private static boolean isIpv4Address(@Nullable InetAddress addr) {
- return addr instanceof Inet4Address;
- }
-
- private static boolean isIpv6Address6To4(@NonNull InetAddress addr) {
- if (!isIpv6Address(addr)) return false;
- final byte[] byteAddr = addr.getAddress();
- return byteAddr[0] == 0x20 && byteAddr[1] == 0x02;
- }
-
- private static boolean isIpv6AddressTeredo(@NonNull InetAddress addr) {
- if (!isIpv6Address(addr)) return false;
- final byte[] byteAddr = addr.getAddress();
- return byteAddr[0] == 0x20 && byteAddr[1] == 0x01 && byteAddr[2] == 0x00
- && byteAddr[3] == 0x00;
- }
-
- private static boolean isIpv6AddressULA(@NonNull InetAddress addr) {
- return isIpv6Address(addr) && (addr.getAddress()[0] & 0xfe) == 0xfc;
- }
-
- private static boolean isIpv6Address6Bone(@NonNull InetAddress addr) {
- if (!isIpv6Address(addr)) return false;
- final byte[] byteAddr = addr.getAddress();
- return byteAddr[0] == 0x3f && byteAddr[1] == (byte) 0xfe;
- }
-
- private static int getIpv6MulticastScope(@NonNull InetAddress addr) {
- return !isIpv6Address(addr) ? 0 : (addr.getAddress()[1] & 0x0f);
- }
-
- private static int findScope(@NonNull InetAddress addr) {
- if (isIpv6Address(addr)) {
- if (addr.isMulticastAddress()) {
- return getIpv6MulticastScope(addr);
- } else if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()) {
- /**
- * RFC 4291 section 2.5.3 says loopback is to be treated as having
- * link-local scope.
- */
- return IPV6_ADDR_SCOPE_LINKLOCAL;
- } else if (addr.isSiteLocalAddress()) {
- return IPV6_ADDR_SCOPE_SITELOCAL;
- } else {
- return IPV6_ADDR_SCOPE_GLOBAL;
- }
- } else if (isIpv4Address(addr)) {
- if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()) {
- return IPV6_ADDR_SCOPE_LINKLOCAL;
- } else {
- /**
- * RFC 6724 section 3.2. Other IPv4 addresses, including private addresses
- * and shared addresses (100.64.0.0/10), are assigned global scope.
- */
- return IPV6_ADDR_SCOPE_GLOBAL;
- }
- } else {
- /**
- * This should never happen.
- * Return a scope with low priority as a last resort.
- */
- return IPV6_ADDR_SCOPE_NODELOCAL;
- }
- }
-
- /**
- * Get the precedence for a given IPv4/IPv6 address.
- * RFC 6724, section 2.1.
- *
- * Note that Java will return an IPv4-mapped address as an IPv4 address.
- */
- private static int findPrecedence(@NonNull InetAddress addr) {
- if (isIpv4Address(addr)) {
- return 35;
- } else if (isIpv6Address(addr)) {
- if (addr.isLoopbackAddress()) {
- return 50;
- } else if (isIpv6Address6To4(addr)) {
- return 30;
- } else if (isIpv6AddressTeredo(addr)) {
- return 5;
- } else if (isIpv6AddressULA(addr)) {
- return 3;
- } else if (((Inet6Address) addr).isIPv4CompatibleAddress() || addr.isSiteLocalAddress()
- || isIpv6Address6Bone(addr)) {
- return 1;
- } else {
- // All other IPv6 addresses, including global unicast addresses.
- return 40;
- }
- } else {
- return 1;
- }
- }
-
- /**
- * Find number of matching initial bits between the two addresses.
- */
- private static int compareIpv6PrefixMatchLen(@NonNull InetAddress srcAddr,
- @NonNull InetAddress dstAddr) {
- final byte[] srcByte = srcAddr.getAddress();
- final byte[] dstByte = dstAddr.getAddress();
-
- // This should never happen.
- if (srcByte.length != dstByte.length) return 0;
-
- for (int i = 0; i < dstByte.length; ++i) {
- if (srcByte[i] == dstByte[i]) {
- continue;
- }
- int x = (srcByte[i] & 0xff) ^ (dstByte[i] & 0xff);
- return i * CHAR_BIT + (Integer.numberOfLeadingZeros(x) - 24); // Java ints are 32 bits
- }
- return dstByte.length * CHAR_BIT;
- }
-
- /**
- * Check if given network has Ipv4 capability
- * This function matches the behaviour of have_ipv4 in the native resolver.
- */
- public static boolean haveIpv4(@Nullable Network network) {
- final SocketAddress addrIpv4 =
- new InetSocketAddress(InetAddresses.parseNumericAddress("8.8.8.8"), 0);
- return checkConnectivity(network, AF_INET, addrIpv4);
- }
-
- /**
- * Check if given network has Ipv6 capability
- * This function matches the behaviour of have_ipv6 in the native resolver.
- */
- public static boolean haveIpv6(@Nullable Network network) {
- final SocketAddress addrIpv6 =
- new InetSocketAddress(InetAddresses.parseNumericAddress("2000::"), 0);
- return checkConnectivity(network, AF_INET6, addrIpv6);
- }
-
- private static boolean checkConnectivity(@Nullable Network network,
- int domain, @NonNull SocketAddress addr) {
- final FileDescriptor socket;
- try {
- socket = Os.socket(domain, SOCK_DGRAM, IPPROTO_UDP);
- } catch (ErrnoException e) {
- return false;
- }
- try {
- if (network != null) network.bindSocket(socket);
- Os.connect(socket, addr);
- } catch (IOException | ErrnoException e) {
- return false;
- } finally {
- IoUtils.closeQuietly(socket);
- }
- return true;
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/util/KeepaliveUtils.java b/packages/Connectivity/framework/src/android/net/util/KeepaliveUtils.java
deleted file mode 100644
index 8d7a0b3..0000000
--- a/packages/Connectivity/framework/src/android/net/util/KeepaliveUtils.java
+++ /dev/null
@@ -1,117 +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.annotation.NonNull;
-import android.content.Context;
-import android.content.res.Resources;
-import android.net.ConnectivityResources;
-import android.net.NetworkCapabilities;
-import android.text.TextUtils;
-import android.util.AndroidRuntimeException;
-
-/**
- * Collection of utilities for socket keepalive offload.
- *
- * @hide
- */
-public final class KeepaliveUtils {
-
- public static final String TAG = "KeepaliveUtils";
-
- public static class KeepaliveDeviceConfigurationException extends AndroidRuntimeException {
- public KeepaliveDeviceConfigurationException(final String msg) {
- super(msg);
- }
- }
-
- /**
- * Read supported keepalive count for each transport type from overlay resource. This should be
- * used to create a local variable store of resource customization, and use it as the input for
- * {@link getSupportedKeepalivesForNetworkCapabilities}.
- *
- * @param context The context to read resource from.
- * @return An array of supported keepalive count for each transport type.
- */
- @NonNull
- public static int[] getSupportedKeepalives(@NonNull Context context) {
- String[] res = null;
- try {
- final ConnectivityResources connRes = new ConnectivityResources(context);
- // TODO: use R.id.config_networkSupportedKeepaliveCount directly
- final int id = connRes.get().getIdentifier("config_networkSupportedKeepaliveCount",
- "array", connRes.getResourcesContext().getPackageName());
- res = new ConnectivityResources(context).get().getStringArray(id);
- } catch (Resources.NotFoundException unused) {
- }
- if (res == null) throw new KeepaliveDeviceConfigurationException("invalid resource");
-
- final int[] ret = new int[NetworkCapabilities.MAX_TRANSPORT + 1];
- for (final String row : res) {
- if (TextUtils.isEmpty(row)) {
- throw new KeepaliveDeviceConfigurationException("Empty string");
- }
- final String[] arr = row.split(",");
- if (arr.length != 2) {
- throw new KeepaliveDeviceConfigurationException("Invalid parameter length");
- }
-
- int transport;
- int supported;
- try {
- transport = Integer.parseInt(arr[0]);
- supported = Integer.parseInt(arr[1]);
- } catch (NumberFormatException e) {
- throw new KeepaliveDeviceConfigurationException("Invalid number format");
- }
-
- if (!NetworkCapabilities.isValidTransport(transport)) {
- throw new KeepaliveDeviceConfigurationException("Invalid transport " + transport);
- }
-
- if (supported < 0) {
- throw new KeepaliveDeviceConfigurationException(
- "Invalid supported count " + supported + " for "
- + NetworkCapabilities.transportNameOf(transport));
- }
- ret[transport] = supported;
- }
- return ret;
- }
-
- /**
- * Get supported keepalive count for the given {@link NetworkCapabilities}.
- *
- * @param supportedKeepalives An array of supported keepalive count for each transport type.
- * @param nc The {@link NetworkCapabilities} of the network the socket keepalive is on.
- *
- * @return Supported keepalive count for the given {@link NetworkCapabilities}.
- */
- public static int getSupportedKeepalivesForNetworkCapabilities(
- @NonNull int[] supportedKeepalives, @NonNull NetworkCapabilities nc) {
- final int[] transports = nc.getTransportTypes();
- if (transports.length == 0) return 0;
- int supportedCount = supportedKeepalives[transports[0]];
- // Iterate through transports and return minimum supported value.
- for (final int transport : transports) {
- if (supportedCount > supportedKeepalives[transport]) {
- supportedCount = supportedKeepalives[transport];
- }
- }
- return supportedCount;
- }
-}
diff --git a/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java b/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java
deleted file mode 100644
index 0b42a00..0000000
--- a/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java
+++ /dev/null
@@ -1,247 +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.util;
-
-import static android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI;
-import static android.net.ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE;
-
-import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.net.ConnectivityResources;
-import android.net.Uri;
-import android.os.Handler;
-import android.provider.Settings;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyCallback;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Executor;
-import java.util.concurrent.RejectedExecutionException;
-
-/**
- * A class to encapsulate management of the "Smart Networking" capability of
- * avoiding bad Wi-Fi when, for example upstream connectivity is lost or
- * certain critical link failures occur.
- *
- * This enables the device to switch to another form of connectivity, like
- * mobile, if it's available and working.
- *
- * The Runnable |avoidBadWifiCallback|, if given, is posted to the supplied
- * Handler' whenever the computed "avoid bad wifi" value changes.
- *
- * Disabling this reverts the device to a level of networking sophistication
- * circa 2012-13 by disabling disparate code paths each of which contribute to
- * maintaining continuous, working Internet connectivity.
- *
- * @hide
- */
-public class MultinetworkPolicyTracker {
- private static String TAG = MultinetworkPolicyTracker.class.getSimpleName();
-
- private final Context mContext;
- private final ConnectivityResources mResources;
- private final Handler mHandler;
- private final Runnable mAvoidBadWifiCallback;
- private final List<Uri> mSettingsUris;
- private final ContentResolver mResolver;
- private final SettingObserver mSettingObserver;
- private final BroadcastReceiver mBroadcastReceiver;
-
- private volatile boolean mAvoidBadWifi = true;
- private volatile int mMeteredMultipathPreference;
- private int mActiveSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
- // Mainline module can't use internal HandlerExecutor, so add an identical executor here.
- private static class HandlerExecutor implements Executor {
- @NonNull
- private final Handler mHandler;
-
- HandlerExecutor(@NonNull Handler handler) {
- mHandler = handler;
- }
- @Override
- public void execute(Runnable command) {
- if (!mHandler.post(command)) {
- throw new RejectedExecutionException(mHandler + " is shutting down");
- }
- }
- }
-
- @VisibleForTesting
- protected class ActiveDataSubscriptionIdListener extends TelephonyCallback
- implements TelephonyCallback.ActiveDataSubscriptionIdListener {
- @Override
- public void onActiveDataSubscriptionIdChanged(int subId) {
- mActiveSubId = subId;
- reevaluateInternal();
- }
- }
-
- public MultinetworkPolicyTracker(Context ctx, Handler handler) {
- this(ctx, handler, null);
- }
-
- public MultinetworkPolicyTracker(Context ctx, Handler handler, Runnable avoidBadWifiCallback) {
- mContext = ctx;
- mResources = new ConnectivityResources(ctx);
- mHandler = handler;
- mAvoidBadWifiCallback = avoidBadWifiCallback;
- mSettingsUris = Arrays.asList(
- Settings.Global.getUriFor(NETWORK_AVOID_BAD_WIFI),
- Settings.Global.getUriFor(NETWORK_METERED_MULTIPATH_PREFERENCE));
- mResolver = mContext.getContentResolver();
- mSettingObserver = new SettingObserver();
- mBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- reevaluateInternal();
- }
- };
-
- ctx.getSystemService(TelephonyManager.class).registerTelephonyCallback(
- new HandlerExecutor(handler), new ActiveDataSubscriptionIdListener());
-
- updateAvoidBadWifi();
- updateMeteredMultipathPreference();
- }
-
- public void start() {
- for (Uri uri : mSettingsUris) {
- mResolver.registerContentObserver(uri, false, mSettingObserver);
- }
-
- final IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
- mContext.registerReceiverForAllUsers(mBroadcastReceiver, intentFilter,
- null /* broadcastPermission */, mHandler);
-
- reevaluate();
- }
-
- public void shutdown() {
- mResolver.unregisterContentObserver(mSettingObserver);
-
- mContext.unregisterReceiver(mBroadcastReceiver);
- }
-
- public boolean getAvoidBadWifi() {
- return mAvoidBadWifi;
- }
-
- // TODO: move this to MultipathPolicyTracker.
- public int getMeteredMultipathPreference() {
- return mMeteredMultipathPreference;
- }
-
- /**
- * Whether the device or carrier configuration disables avoiding bad wifi by default.
- */
- public boolean configRestrictsAvoidBadWifi() {
- // TODO: use R.integer.config_networkAvoidBadWifi directly
- final int id = mResources.get().getIdentifier("config_networkAvoidBadWifi",
- "integer", mResources.getResourcesContext().getPackageName());
- return (getResourcesForActiveSubId().getInteger(id) == 0);
- }
-
- @NonNull
- private Resources getResourcesForActiveSubId() {
- return SubscriptionManager.getResourcesForSubId(
- mResources.getResourcesContext(), mActiveSubId);
- }
-
- /**
- * Whether we should display a notification when wifi becomes unvalidated.
- */
- public boolean shouldNotifyWifiUnvalidated() {
- return configRestrictsAvoidBadWifi() && getAvoidBadWifiSetting() == null;
- }
-
- public String getAvoidBadWifiSetting() {
- return Settings.Global.getString(mResolver, NETWORK_AVOID_BAD_WIFI);
- }
-
- @VisibleForTesting
- public void reevaluate() {
- mHandler.post(this::reevaluateInternal);
- }
-
- /**
- * Reevaluate the settings. Must be called on the handler thread.
- */
- private void reevaluateInternal() {
- if (updateAvoidBadWifi() && mAvoidBadWifiCallback != null) {
- mAvoidBadWifiCallback.run();
- }
- updateMeteredMultipathPreference();
- }
-
- public boolean updateAvoidBadWifi() {
- final boolean settingAvoidBadWifi = "1".equals(getAvoidBadWifiSetting());
- final boolean prev = mAvoidBadWifi;
- mAvoidBadWifi = settingAvoidBadWifi || !configRestrictsAvoidBadWifi();
- return mAvoidBadWifi != prev;
- }
-
- /**
- * The default (device and carrier-dependent) value for metered multipath preference.
- */
- public int configMeteredMultipathPreference() {
- // TODO: use R.integer.config_networkMeteredMultipathPreference directly
- final int id = mResources.get().getIdentifier("config_networkMeteredMultipathPreference",
- "integer", mResources.getResourcesContext().getPackageName());
- return mResources.get().getInteger(id);
- }
-
- public void updateMeteredMultipathPreference() {
- String setting = Settings.Global.getString(mResolver, NETWORK_METERED_MULTIPATH_PREFERENCE);
- try {
- mMeteredMultipathPreference = Integer.parseInt(setting);
- } catch (NumberFormatException e) {
- mMeteredMultipathPreference = configMeteredMultipathPreference();
- }
- }
-
- private class SettingObserver extends ContentObserver {
- public SettingObserver() {
- super(null);
- }
-
- @Override
- public void onChange(boolean selfChange) {
- Log.wtf(TAG, "Should never be reached.");
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- if (!mSettingsUris.contains(uri)) {
- Log.wtf(TAG, "Unexpected settings observation: " + uri);
- }
- reevaluate();
- }
- }
-}
diff --git a/packages/Connectivity/service/Android.bp b/packages/Connectivity/service/Android.bp
deleted file mode 100644
index 7265426..0000000
--- a/packages/Connectivity/service/Android.bp
+++ /dev/null
@@ -1,119 +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 {
- // 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: "libservice-connectivity",
- min_sdk_version: "30",
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- "-Wthread-safety",
- ],
- srcs: [
- "jni/com_android_server_TestNetworkService.cpp",
- "jni/onload.cpp",
- ],
- stl: "libc++_static",
- header_libs: [
- "libbase_headers",
- ],
- shared_libs: [
- "liblog",
- "libnativehelper",
- ],
- apex_available: [
- "com.android.tethering",
- ],
-}
-
-java_library {
- name: "service-connectivity-pre-jarjar",
- sdk_version: "system_server_current",
- min_sdk_version: "30",
- srcs: [
- "src/**/*.java",
- ":framework-connectivity-shared-srcs",
- ":services-connectivity-shared-srcs",
- // TODO: move to net-utils-device-common, enable shrink optimization to avoid extra classes
- ":net-module-utils-srcs",
- ],
- libs: [
- // TODO (b/183097033) remove once system_server_current includes core_current
- "stable.core.platform.api.stubs",
- "android_system_server_stubs_current",
- "framework-annotations-lib",
- "framework-connectivity-annotations",
- "framework-connectivity.impl",
- "framework-tethering.stubs.module_lib",
- "framework-wifi.stubs.module_lib",
- "unsupportedappusage",
- "ServiceConnectivityResources",
- ],
- static_libs: [
- "dnsresolver_aidl_interface-V8-java",
- "modules-utils-os",
- "net-utils-device-common",
- "net-utils-framework-common",
- "netd-client",
- "netlink-client",
- "networkstack-client",
- "PlatformProperties",
- "service-connectivity-protos",
- ],
- apex_available: [
- "com.android.tethering",
- ],
-}
-
-java_library {
- name: "service-connectivity-protos",
- sdk_version: "system_current",
- min_sdk_version: "30",
- proto: {
- type: "nano",
- },
- srcs: [
- ":system-messages-proto-src",
- ],
- libs: ["libprotobuf-java-nano"],
- apex_available: [
- "com.android.tethering",
- ],
-}
-
-java_library {
- name: "service-connectivity",
- sdk_version: "system_server_current",
- min_sdk_version: "30",
- installable: true,
- static_libs: [
- "service-connectivity-pre-jarjar",
- ],
- jarjar_rules: "jarjar-rules.txt",
- apex_available: [
- "com.android.tethering",
- ],
-}
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/Android.bp b/packages/Connectivity/service/ServiceConnectivityResources/Android.bp
deleted file mode 100644
index f491cc7..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/Android.bp
+++ /dev/null
@@ -1,40 +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.
-//
-
-// APK to hold all the wifi overlayable resources.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_app {
- name: "ServiceConnectivityResources",
- sdk_version: "module_30",
- min_sdk_version: "30",
- resource_dirs: [
- "res",
- ],
- privileged: true,
- export_package_resources: true,
- apex_available: [
- "com.android.tethering",
- ],
- certificate: ":com.android.connectivity.resources.certificate",
-}
-
-android_app_certificate {
- name: "com.android.connectivity.resources.certificate",
- certificate: "resources-certs/com.android.connectivity.resources",
-}
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/AndroidManifest.xml b/packages/Connectivity/service/ServiceConnectivityResources/AndroidManifest.xml
deleted file mode 100644
index 2c30302..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/AndroidManifest.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * 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.
- */
--->
-<!-- Manifest for connectivity resources APK -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.connectivity.resources"
- coreApp="true"
- android:versionCode="1"
- android:versionName="S-initial">
- <application
- android:label="@string/connectivityResourcesAppLabel"
- android:defaultToDeviceProtectedStorage="true"
- android:directBootAware="true">
- <!-- This is only used to identify this app by resolving the action.
- The activity is never actually triggered. -->
- <activity android:name="android.app.Activity" android:exported="true" android:enabled="true">
- <intent-filter>
- <action android:name="com.android.server.connectivity.intent.action.SERVICE_CONNECTIVITY_RESOURCES_APK" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-hdpi/stat_notify_rssi_in_range.png b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-hdpi/stat_notify_rssi_in_range.png
deleted file mode 100644
index 74977e6..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-hdpi/stat_notify_rssi_in_range.png
+++ /dev/null
Binary files differ
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-mdpi/stat_notify_rssi_in_range.png b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-mdpi/stat_notify_rssi_in_range.png
deleted file mode 100644
index 62e4fe9..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-mdpi/stat_notify_rssi_in_range.png
+++ /dev/null
Binary files differ
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-xhdpi/stat_notify_rssi_in_range.png b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-xhdpi/stat_notify_rssi_in_range.png
deleted file mode 100644
index c0586d8..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-xhdpi/stat_notify_rssi_in_range.png
+++ /dev/null
Binary files differ
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-xxhdpi/stat_notify_rssi_in_range.png b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-xxhdpi/stat_notify_rssi_in_range.png
deleted file mode 100644
index 86c34ed..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-xxhdpi/stat_notify_rssi_in_range.png
+++ /dev/null
Binary files differ
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable/stat_notify_wifi_in_range.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable/stat_notify_wifi_in_range.xml
deleted file mode 100644
index a271ca5..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable/stat_notify_wifi_in_range.xml
+++ /dev/null
@@ -1,27 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="26.0dp"
- android:height="24.0dp"
- android:viewportWidth="26.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#4DFFFFFF"
- android:pathData="M19.1,14l-3.4,0l0,-1.5c0,-1.8 0.8,-2.8 1.5,-3.4C18.1,8.3 19.200001,8 20.6,8c1.2,0 2.3,0.3 3.1,0.8l1.9,-2.3C25.1,6.1 20.299999,2.1 13,2.1S0.9,6.1 0.4,6.5L13,22l0,0l0,0l0,0l0,0l6.5,-8.1L19.1,14z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M19.5,17.799999c0,-0.8 0.1,-1.3 0.2,-1.6c0.2,-0.3 0.5,-0.7 1.1,-1.2c0.4,-0.4 0.7,-0.8 1,-1.1s0.4,-0.8 0.4,-1.2c0,-0.5 -0.1,-0.9 -0.4,-1.2c-0.3,-0.3 -0.7,-0.4 -1.2,-0.4c-0.4,0 -0.8,0.1 -1.1,0.3c-0.3,0.2 -0.4,0.6 -0.4,1.1l-1.9,0c0,-1 0.3,-1.7 1,-2.2c0.6,-0.5 1.5,-0.8 2.5,-0.8c1.1,0 2,0.3 2.6,0.8c0.6,0.5 0.9,1.3 0.9,2.3c0,0.7 -0.2,1.3 -0.6,1.8c-0.4,0.6 -0.9,1.1 -1.5,1.6c-0.3,0.3 -0.5,0.5 -0.6,0.7c-0.1,0.2 -0.1,0.6 -0.1,1L19.5,17.700001zM21.4,21l-1.9,0l0,-1.8l1.9,0L21.4,21z"/>
-</vector>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-af/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-af/strings.xml
deleted file mode 100644
index 550ab8a..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-af/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Stelselkonnektiwiteithulpbronne"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Meld aan by Wi-Fi-netwerk"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Meld by netwerk aan"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> het geen internettoegang nie"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tik vir opsies"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Selnetwerk het nie internettoegang nie"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Netwerk het nie internettoegang nie"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Daar kan nie by private DNS-bediener ingegaan word nie"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> het beperkte konnektiwiteit"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tik om in elk geval te koppel"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Het oorgeskakel na <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Toestel gebruik <xliff:g id="NEW_NETWORK">%1$s</xliff:g> wanneer <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> geen internettoegang het nie. Heffings kan geld."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Het oorgeskakel van <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobiele data"</item>
- <item msgid="6341719431034774569">"Wi-fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"\'n onbekende netwerktipe"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-am/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-am/strings.xml
deleted file mode 100644
index 7f1a9db..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-am/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"የስርዓት ግንኙነት መርጃዎች"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"ወደ Wi-Fi አውታረ መረብ በመለያ ግባ"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"ወደ አውታረ መረብ በመለያ ይግቡ"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ምንም የበይነ መረብ መዳረሻ የለም"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ለአማራጮች መታ ያድርጉ"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"የተንቀሳቃሽ ስልክ አውታረ መረብ የበይነመረብ መዳረሻ የለውም"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"አውታረ መረብ የበይነመረብ መዳረሻ የለውም"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"የግል ዲኤንኤስ አገልጋይ ሊደረስበት አይችልም"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> የተገደበ ግንኙነት አለው"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ለማንኛውም ለማገናኘት መታ ያድርጉ"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"ወደ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ተቀይሯል"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ምንም ዓይነት የበይነመረብ ግንኙነት በማይኖረው ጊዜ መሣሪያዎች <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ን ይጠቀማሉ። ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ።"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"ከ<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ወደ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ተቀይሯል"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"የተንቀሳቃሽ ስልክ ውሂብ"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"ብሉቱዝ"</item>
- <item msgid="1160736166977503463">"ኢተርኔት"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"አንድ ያልታወቀ አውታረ መረብ ዓይነት"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ar/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ar/strings.xml
deleted file mode 100644
index b7a62c5..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ar/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"مصادر إمكانية اتصال الخادم"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"تسجيل الدخول إلى شبكة Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"تسجيل الدخول إلى الشبكة"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"لا يتوفّر في <xliff:g id="NETWORK_SSID">%1$s</xliff:g> إمكانية الاتصال بالإنترنت."</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"انقر للحصول على الخيارات."</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"شبكة الجوّال هذه غير متصلة بالإنترنت"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"الشبكة غير متصلة بالإنترنت"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"لا يمكن الوصول إلى خادم أسماء نظام نطاقات خاص"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"إمكانية اتصال <xliff:g id="NETWORK_SSID">%1$s</xliff:g> محدودة."</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"يمكنك النقر للاتصال على أي حال."</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"تم التبديل إلى <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"يستخدم الجهاز <xliff:g id="NEW_NETWORK">%1$s</xliff:g> عندما لا يتوفر اتصال بالإنترنت في شبكة <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>، ويمكن أن يتم فرض رسوم مقابل ذلك."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"تم التبديل من <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> إلى <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"بيانات الجوّال"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"بلوتوث"</item>
- <item msgid="1160736166977503463">"إيثرنت"</item>
- <item msgid="7347618872551558605">"شبكة افتراضية خاصة (VPN)"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"نوع شبكة غير معروف"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-as/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-as/strings.xml
deleted file mode 100644
index cf8e6ac..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-as/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ছিষ্টেম সংযোগৰ উৎস"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"ৱাই-ফাই নেটৱৰ্কত ছাইন ইন কৰক"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"নেটৱৰ্কত ছাইন ইন কৰক"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ৰ ইণ্টাৰনেটৰ এক্সেছ নাই"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"অধিক বিকল্পৰ বাবে টিপক"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"ম’বাইল নেটৱৰ্কৰ কোনো ইণ্টাৰনেটৰ এক্সেছ নাই"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"নেটৱৰ্কৰ কোনো ইণ্টাৰনেটৰ এক্সেছ নাই"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ব্যক্তিগত DNS ছাৰ্ভাৰ এক্সেছ কৰিব নোৱাৰি"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ৰ সকলো সেৱাৰ এক্সেছ নাই"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"যিকোনো প্ৰকাৰে সংযোগ কৰিবলৈ টিপক"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>লৈ সলনি কৰা হ’ল"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"যেতিয়া <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>ত ইণ্টাৰনেট নাথাকে, তেতিয়া ডিভাইচে <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ক ব্যৱহাৰ কৰে। মাচুল প্ৰযোজ্য হ\'ব পাৰে।"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>ৰ পৰা <xliff:g id="NEW_NETWORK">%2$s</xliff:g> লৈ সলনি কৰা হ’ল"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"ম’বাইল ডেটা"</item>
- <item msgid="6341719431034774569">"ৱাই-ফাই"</item>
- <item msgid="5081440868800877512">"ব্লুটুথ"</item>
- <item msgid="1160736166977503463">"ইথাৰনেট"</item>
- <item msgid="7347618872551558605">"ভিপিএন"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"অজ্ঞাত প্ৰকাৰৰ নেটৱৰ্ক"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-az/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-az/strings.xml
deleted file mode 100644
index 7e927ed..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-az/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Sistem Bağlantı Resursları"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi şəbəkəsinə daxil ol"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Şəbəkəyə daxil olun"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> üçün internet girişi əlçatan deyil"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Seçimlər üçün tıklayın"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobil şəbəkənin internetə girişi yoxdur"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Şəbəkənin internetə girişi yoxdur"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Özəl DNS serverinə giriş mümkün deyil"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> bağlantını məhdudlaşdırdı"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"İstənilən halda klikləyin"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> şəbəkə növünə keçirildi"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> şəbəkəsinin internetə girişi olmadıqda, cihaz <xliff:g id="NEW_NETWORK">%1$s</xliff:g> şəbəkəsini istifadə edir. Xidmət haqqı tutula bilər."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> şəbəkəsindən <xliff:g id="NEW_NETWORK">%2$s</xliff:g> şəbəkəsinə keçirildi"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobil data"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"naməlum şəbəkə növü"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-b+sr+Latn/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 3f1b976..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Resursi za povezivanje sa sistemom"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Prijavljivanje na WiFi mrežu"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Prijavite se na mrežu"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Dodirnite za opcije"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilna mreža nema pristup internetu"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Mreža nema pristup internetu"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Pristup privatnom DNS serveru nije uspeo"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu vezu"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Dodirnite da biste se ipak povezali"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Prešli ste na tip mreže <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Uređaj koristi tip mreže <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kada tip mreže <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu. Možda će se naplaćivati troškovi."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Prešli ste sa tipa mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na tip mreže <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobilni podaci"</item>
- <item msgid="6341719431034774569">"WiFi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Eternet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nepoznat tip mreže"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-be/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-be/strings.xml
deleted file mode 100644
index 21edf24..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-be/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Рэсурсы для падключэння да сістэмы"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Уваход у сетку Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Увайдзіце ў сетку"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> не мае доступу ў інтэрнэт"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Дакраніцеся, каб убачыць параметры"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Мабільная сетка не мае доступу ў інтэрнэт"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Сетка не мае доступу ў інтэрнэт"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Не ўдалося атрымаць доступ да прыватнага DNS-сервера"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> мае абмежаваную магчымасць падключэння"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Націсніце, каб падключыцца"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Выкананы пераход да <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Прылада выкарыстоўвае сетку <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, калі ў сетцы <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> няма доступу да інтэрнэту. Можа спаганяцца плата."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Выкананы пераход з <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> да <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"мабільная перадача даных"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"невядомы тып сеткі"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bg/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bg/strings.xml
deleted file mode 100644
index c3c2d72..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bg/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Ресурси за свързаността на системата"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Влизане в Wi-Fi мрежа"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Вход в мрежата"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> няма достъп до интернет"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Докоснете за опции"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Мобилната мрежа няма достъп до интернет"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Мрежата няма достъп до интернет"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Не може да се осъществи достъп до частния DNS сървър"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничена свързаност"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Докоснете, за да се свържете въпреки това"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Превключи се към <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Устройството използва <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, когато <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> няма достъп до интернет. Възможно е да бъдете таксувани."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Превключи се от <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> към <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"мобилни данни"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"неизвестен тип мрежа"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bn/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bn/strings.xml
deleted file mode 100644
index 0f693bd..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bn/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"সিস্টেম কানেক্টিভিটি রিসোর্সেস"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"ওয়াই-ফাই নেটওয়ার্কে সাইন-ইন করুন"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"নেটওয়ার্কে সাইন-ইন করুন"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-এর ইন্টারনেটে অ্যাক্সেস নেই"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"বিকল্পগুলির জন্য আলতো চাপুন"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"মোবাইল নেটওয়ার্কে কোনও ইন্টারনেট অ্যাক্সেস নেই"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"নেটওয়ার্কে কোনও ইন্টারনেট অ্যাক্সেস নেই"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ব্যক্তিগত ডিএনএস সার্ভার অ্যাক্সেস করা যাবে না"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-এর সীমিত কানেক্টিভিটি আছে"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"তবুও কানেক্ট করতে ট্যাপ করুন"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> এ পাল্টানো হয়েছে"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> এ ইন্টারনেট অ্যাক্সেস না থাকলে <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ব্যবহার করা হয়৷ ডেটা চার্জ প্রযোজ্য৷"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> থেকে <xliff:g id="NEW_NETWORK">%2$s</xliff:g> এ পাল্টানো হয়েছে"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"মোবাইল ডেটা"</item>
- <item msgid="6341719431034774569">"ওয়াই-ফাই"</item>
- <item msgid="5081440868800877512">"ব্লুটুথ"</item>
- <item msgid="1160736166977503463">"ইথারনেট"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"এই নেটওয়ার্কের ধরন অজানা"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bs/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bs/strings.xml
deleted file mode 100644
index 33d6ed9..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bs/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Izvori povezivosti sistema"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Prijavljivanje na WiFi mrežu"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Prijava na mrežu"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"Mreža <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Dodirnite za opcije"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilna mreža nema pristup internetu"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Mreža nema pristup internetu"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Nije moguće pristupiti privatnom DNS serveru"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"Mreža <xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu povezivost"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Dodirnite da se ipak povežete"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Prebačeno na: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Kada <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu, uređaj koristi mrežu <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Moguća je naplata usluge."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Prebačeno iz mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> u <xliff:g id="NEW_NETWORK">%2$s</xliff:g> mrežu"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"prijenos podataka na mobilnoj mreži"</item>
- <item msgid="6341719431034774569">"WiFi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nepoznata vrsta mreže"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ca/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ca/strings.xml
deleted file mode 100644
index 04f6bd2..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ca/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de connectivitat del sistema"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Inicia la sessió a la xarxa Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Inicia la sessió a la xarxa"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> no té accés a Internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Toca per veure les opcions"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"La xarxa mòbil no té accés a Internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"La xarxa no té accés a Internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"No es pot accedir al servidor DNS privat"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> té una connectivitat limitada"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Toca per connectar igualment"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Actualment en ús: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"El dispositiu utilitza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> en cas que <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tingui accés a Internet. És possible que s\'hi apliquin càrrecs."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Abans es feia servir la xarxa <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>; ara s\'utilitza <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"dades mòbils"</item>
- <item msgid="6341719431034774569">"Wi‑Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"un tipus de xarxa desconegut"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-cs/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-cs/strings.xml
deleted file mode 100644
index 6309e78..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-cs/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Zdroje pro připojení systému"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Přihlásit se k síti Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Přihlásit se k síti"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"Síť <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nemá přístup k internetu"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Klepnutím zobrazíte možnosti"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilní síť nemá přístup k internetu"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Síť nemá přístup k internetu"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Nelze získat přístup k soukromému serveru DNS"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"Síť <xliff:g id="NETWORK_SSID">%1$s</xliff:g> umožňuje jen omezené připojení"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Klepnutím se i přesto připojíte"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Přechod na síť <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Když síť <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nebude mít přístup k internetu, zařízení použije síť <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Mohou být účtovány poplatky."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Přechod ze sítě <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na síť <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobilní data"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"neznámý typ sítě"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-da/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-da/strings.xml
deleted file mode 100644
index 57c58af..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-da/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Systemets forbindelsesressourcer"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Log ind på Wi-Fi-netværk"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Log ind på netværk"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har ingen internetforbindelse"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tryk for at se valgmuligheder"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilnetværket har ingen internetadgang"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Netværket har ingen internetadgang"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Der er ikke adgang til den private DNS-server"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har begrænset forbindelse"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tryk for at oprette forbindelse alligevel"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Der blev skiftet til <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Enheden benytter <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, når der ikke er internetadgang via <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>. Der opkræves muligvis betaling."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Der blev skiftet fra <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> til <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobildata"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"en ukendt netværkstype"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-de/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-de/strings.xml
deleted file mode 100644
index d0c2551..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-de/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Systemverbindungsressourcen"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"In WLAN anmelden"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Im Netzwerk anmelden"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> hat keinen Internetzugriff"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Für Optionen tippen"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobiles Netzwerk hat keinen Internetzugriff"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Netzwerk hat keinen Internetzugriff"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Auf den privaten DNS-Server kann nicht zugegriffen werden"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"Schlechte Verbindung mit <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tippen, um die Verbindung trotzdem herzustellen"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Zu <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> gewechselt"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Auf dem Gerät werden <xliff:g id="NEW_NETWORK">%1$s</xliff:g> genutzt, wenn über <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> kein Internet verfügbar ist. Eventuell fallen Gebühren an."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Von \"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>\" zu \"<xliff:g id="NEW_NETWORK">%2$s</xliff:g>\" gewechselt"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"Mobile Daten"</item>
- <item msgid="6341719431034774569">"WLAN"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ein unbekannter Netzwerktyp"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-el/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-el/strings.xml
deleted file mode 100644
index 1c2838d..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-el/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Πόροι συνδεσιμότητας συστήματος"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Συνδεθείτε στο δίκτυο Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Σύνδεση στο δίκτυο"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"Η εφαρμογή <xliff:g id="NETWORK_SSID">%1$s</xliff:g> δεν έχει πρόσβαση στο διαδίκτυο"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Πατήστε για να δείτε τις επιλογές"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Το δίκτυο κινητής τηλεφωνίας δεν έχει πρόσβαση στο διαδίκτυο."</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Το δίκτυο δεν έχει πρόσβαση στο διαδίκτυο."</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Δεν είναι δυνατή η πρόσβαση στον ιδιωτικό διακομιστή DNS."</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"Το δίκτυο <xliff:g id="NETWORK_SSID">%1$s</xliff:g> έχει περιορισμένη συνδεσιμότητα"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Πατήστε για σύνδεση ούτως ή άλλως"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Μετάβαση σε δίκτυο <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Η συσκευή χρησιμοποιεί το δίκτυο <xliff:g id="NEW_NETWORK">%1$s</xliff:g> όταν το δίκτυο <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> δεν έχει πρόσβαση στο διαδίκτυο. Μπορεί να ισχύουν χρεώσεις."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Μετάβαση από το δίκτυο <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> στο δίκτυο <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"δεδομένα κινητής τηλεφωνίας"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"άγνωστος τύπος δικτύου"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rAU/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rAU/strings.xml
deleted file mode 100644
index db5ad70..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System connectivity resources"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Sign in to a Wi-Fi network"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Sign in to network"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tap for options"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobile network has no Internet access"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Network has no Internet access"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Private DNS server cannot be accessed"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tap to connect anyway"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobile data"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"an unknown network type"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml
deleted file mode 100644
index db5ad70..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System connectivity resources"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Sign in to a Wi-Fi network"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Sign in to network"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tap for options"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobile network has no Internet access"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Network has no Internet access"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Private DNS server cannot be accessed"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tap to connect anyway"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobile data"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"an unknown network type"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rGB/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rGB/strings.xml
deleted file mode 100644
index db5ad70..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System connectivity resources"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Sign in to a Wi-Fi network"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Sign in to network"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tap for options"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobile network has no Internet access"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Network has no Internet access"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Private DNS server cannot be accessed"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tap to connect anyway"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobile data"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"an unknown network type"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rIN/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rIN/strings.xml
deleted file mode 100644
index db5ad70..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System connectivity resources"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Sign in to a Wi-Fi network"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Sign in to network"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tap for options"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobile network has no Internet access"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Network has no Internet access"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Private DNS server cannot be accessed"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tap to connect anyway"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobile data"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"an unknown network type"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rXC/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rXC/strings.xml
deleted file mode 100644
index 2602bfa..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System Connectivity Resources"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Sign in to Wi-Fi network"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Sign in to network"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no internet access"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tap for options"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobile network has no internet access"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Network has no internet access"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Private DNS server cannot be accessed"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tap to connect anyway"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no internet access. Charges may apply."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobile data"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"an unknown network type"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml
deleted file mode 100644
index e5f1833..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de conectividad del sistema"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Accede a una red Wi-Fi."</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Acceder a la red"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>no tiene acceso a Internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Presiona para ver opciones"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"La red móvil no tiene acceso a Internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"La red no tiene acceso a Internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"No se puede acceder al servidor DNS privado"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tiene conectividad limitada"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Presiona para conectarte de todas formas"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Se cambió a <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"El dispositivo usa <xliff:g id="NEW_NETWORK">%1$s</xliff:g> cuando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tiene acceso a Internet. Es posible que se apliquen cargos."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Se cambió de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"Datos móviles"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"un tipo de red desconocido"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-es/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-es/strings.xml
deleted file mode 100644
index e4f4307..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-es/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de conectividad del sistema"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Iniciar sesión en red Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Iniciar sesión en la red"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> no tiene acceso a Internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Toca para ver opciones"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"La red móvil no tiene acceso a Internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"La red no tiene acceso a Internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"No se ha podido acceder al servidor DNS privado"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tiene una conectividad limitada"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Toca para conectarte de todas formas"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Se ha cambiado a <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"El dispositivo utiliza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> cuando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tiene acceso a Internet. Es posible que se apliquen cargos."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Se ha cambiado de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"datos móviles"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"un tipo de red desconocido"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-et/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-et/strings.xml
deleted file mode 100644
index cec408f..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-et/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Süsteemi ühenduvuse allikad"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Logi sisse WiFi-võrku"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Võrku sisselogimine"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"Võrgul <xliff:g id="NETWORK_SSID">%1$s</xliff:g> puudub Interneti-ühendus"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Puudutage valikute nägemiseks"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobiilsidevõrgul puudub Interneti-ühendus"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Võrgul puudub Interneti-ühendus"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Privaatsele DNS-serverile ei pääse juurde"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"Võrgu <xliff:g id="NETWORK_SSID">%1$s</xliff:g> ühendus on piiratud"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Puudutage, kui soovite siiski ühenduse luua"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Lülitati võrgule <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Seade kasutab võrku <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, kui võrgul <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> puudub juurdepääs Internetile. Rakenduda võivad tasud."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Lülitati võrgult <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> võrgule <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobiilne andmeside"</item>
- <item msgid="6341719431034774569">"WiFi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"tundmatu võrgutüüp"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-eu/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-eu/strings.xml
deleted file mode 100644
index f3ee9b1..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-eu/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Sistemaren konexio-baliabideak"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Hasi saioa Wi-Fi sarean"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Hasi saioa sarean"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"Ezin da konektatu Internetera <xliff:g id="NETWORK_SSID">%1$s</xliff:g> sarearen bidez"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Sakatu aukerak ikusteko"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Sare mugikorra ezin da konektatu Internetera"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Sarea ezin da konektatu Internetera"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Ezin da atzitu DNS zerbitzari pribatua"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> sareak konektagarritasun murriztua du"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Sakatu hala ere konektatzeko"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> erabiltzen ari zara orain"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> Internetera konektatzeko gauza ez denean, <xliff:g id="NEW_NETWORK">%1$s</xliff:g> erabiltzen du gailuak. Agian kostuak ordaindu beharko dituzu."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> erabiltzen ari zinen, baina <xliff:g id="NEW_NETWORK">%2$s</xliff:g> erabiltzen ari zara orain"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"datu-konexioa"</item>
- <item msgid="6341719431034774569">"Wifia"</item>
- <item msgid="5081440868800877512">"Bluetooth-a"</item>
- <item msgid="1160736166977503463">"Ethernet-a"</item>
- <item msgid="7347618872551558605">"VPNa"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"sare mota ezezaguna"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fa/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fa/strings.xml
deleted file mode 100644
index 0c5b147..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fa/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"منابع اتصال سیستم"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"ورود به شبکه Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"ورود به سیستم شبکه"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> به اینترنت دسترسی ندارد"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"برای گزینهها ضربه بزنید"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"شبکه تلفن همراه به اینترنت دسترسی ندارد"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"شبکه به اینترنت دسترسی ندارد"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"سرور DNS خصوصی قابل دسترسی نیست"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> اتصال محدودی دارد"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"بههرصورت، برای اتصال ضربه بزنید"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"به <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> تغییر کرد"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"وقتی <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> به اینترنت دسترسی نداشته باشد، دستگاه از <xliff:g id="NEW_NETWORK">%1$s</xliff:g> استفاده میکند. ممکن است هزینههایی اعمال شود."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"از <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> به <xliff:g id="NEW_NETWORK">%2$s</xliff:g> تغییر کرد"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"داده تلفن همراه"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"بلوتوث"</item>
- <item msgid="1160736166977503463">"اترنت"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"نوع شبکه نامشخص"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fi/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fi/strings.xml
deleted file mode 100644
index 84c0034..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fi/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Järjestelmän yhteysresurssit"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Kirjaudu Wi-Fi-verkkoon"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Kirjaudu verkkoon"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ei ole yhteydessä internetiin"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Näytä vaihtoehdot napauttamalla."</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobiiliverkko ei ole yhteydessä internetiin"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Verkko ei ole yhteydessä internetiin"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Ei pääsyä yksityiselle DNS-palvelimelle"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> toimii rajoitetulla yhteydellä"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Yhdistä napauttamalla"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> otettiin käyttöön"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="NEW_NETWORK">%1$s</xliff:g> otetaan käyttöön, kun <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ei voi muodostaa yhteyttä internetiin. Veloitukset ovat mahdollisia."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> poistettiin käytöstä ja <xliff:g id="NEW_NETWORK">%2$s</xliff:g> otettiin käyttöön."</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobiilidata"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"tuntematon verkon tyyppi"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr-rCA/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr-rCA/strings.xml
deleted file mode 100644
index 0badf1b..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Ressources de connectivité système"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Connectez-vous au réseau Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Connectez-vous au réseau"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"Le réseau <xliff:g id="NETWORK_SSID">%1$s</xliff:g> n\'offre aucun accès à Internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Touchez pour afficher les options"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Le réseau cellulaire n\'offre aucun accès à Internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Le réseau n\'offre aucun accès à Internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Impossible d\'accéder au serveur DNS privé"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"Le réseau <xliff:g id="NETWORK_SSID">%1$s</xliff:g> offre une connectivité limitée"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Touchez pour vous connecter quand même"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Passé au réseau <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"L\'appareil utilise <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quand <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> n\'a pas d\'accès à Internet. Des frais peuvent s\'appliquer."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Passé du réseau <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> au <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"données cellulaires"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"RPV"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"un type de réseau inconnu"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr/strings.xml
deleted file mode 100644
index b483525..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Ressources de connectivité système"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Connectez-vous au réseau Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Se connecter au réseau"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"Aucune connexion à Internet pour <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Appuyez ici pour afficher des options."</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Le réseau mobile ne dispose d\'aucun accès à Internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Le réseau ne dispose d\'aucun accès à Internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Impossible d\'accéder au serveur DNS privé"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"La connectivité de <xliff:g id="NETWORK_SSID">%1$s</xliff:g> est limitée"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Appuyer pour se connecter quand même"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Nouveau réseau : <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"L\'appareil utilise <xliff:g id="NEW_NETWORK">%1$s</xliff:g> lorsque <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> n\'a pas de connexion Internet. Des frais peuvent s\'appliquer."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Ancien réseau : <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>. Nouveau réseau : <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"données mobiles"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"type de réseau inconnu"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-gl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-gl/strings.xml
deleted file mode 100644
index dfe8137..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-gl/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de conectividade do sistema"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Inicia sesión na rede wifi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Inicia sesión na rede"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> non ten acceso a Internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Toca para ver opcións."</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"A rede de telefonía móbil non ten acceso a Internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"A rede non ten acceso a Internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Non se puido acceder ao servidor DNS privado"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"A conectividade de <xliff:g id="NETWORK_SSID">%1$s</xliff:g> é limitada"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Toca para conectarte de todas formas"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Cambiouse a: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"O dispositivo utiliza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> cando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> non ten acceso a Internet. Pódense aplicar cargos."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Cambiouse de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"datos móbiles"</item>
- <item msgid="6341719431034774569">"wifi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"un tipo de rede descoñecido"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-gu/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-gu/strings.xml
deleted file mode 100644
index e49b11d..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-gu/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"સિસ્ટમની કનેક્ટિવિટીનાં સાધનો"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"વાઇ-ફાઇ નેટવર્ક પર સાઇન ઇન કરો"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"નેટવર્ક પર સાઇન ઇન કરો"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ઇન્ટરનેટ ઍક્સેસ ધરાવતું નથી"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"વિકલ્પો માટે ટૅપ કરો"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"મોબાઇલ નેટવર્ક કોઈ ઇન્ટરનેટ ઍક્સેસ ધરાવતું નથી"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"નેટવર્ક કોઈ ઇન્ટરનેટ ઍક્સેસ ધરાવતું નથી"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ખાનગી DNS સર્વર ઍક્સેસ કરી શકાતા નથી"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> મર્યાદિત કનેક્ટિવિટી ધરાવે છે"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"છતાં કનેક્ટ કરવા માટે ટૅપ કરો"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> પર સ્વિચ કર્યું"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"જ્યારે <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> પાસે કોઈ ઇન્ટરનેટ ઍક્સેસ ન હોય ત્યારે ઉપકરણ <xliff:g id="NEW_NETWORK">%1$s</xliff:g>નો ઉપયોગ કરે છે. શુલ્ક લાગુ થઈ શકે છે."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> પરથી <xliff:g id="NEW_NETWORK">%2$s</xliff:g> પર સ્વિચ કર્યું"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"મોબાઇલ ડેટા"</item>
- <item msgid="6341719431034774569">"વાઇ-ફાઇ"</item>
- <item msgid="5081440868800877512">"બ્લૂટૂથ"</item>
- <item msgid="1160736166977503463">"ઇથરનેટ"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"કોઈ અજાણ્યો નેટવર્કનો પ્રકાર"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hi/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hi/strings.xml
deleted file mode 100644
index 80ed699..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hi/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"सिस्टम कनेक्टिविटी के संसाधन"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"वाई-फ़ाई नेटवर्क में साइन इन करें"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"नेटवर्क में साइन इन करें"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> का इंटरनेट नहीं चल रहा है"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"विकल्पों के लिए टैप करें"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"मोबाइल नेटवर्क पर इंटरनेट ऐक्सेस नहीं है"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"इस नेटवर्क पर इंटरनेट ऐक्सेस नहीं है"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"निजी डीएनएस सर्वर को ऐक्सेस नहीं किया जा सकता"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> की कनेक्टिविटी सीमित है"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"फिर भी कनेक्ट करने के लिए टैप करें"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> पर ले जाया गया"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> में इंटरनेट की सुविधा नहीं होने पर डिवाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> का इस्तेमाल करता है. इसके लिए शुल्क लिया जा सकता है."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> से <xliff:g id="NEW_NETWORK">%2$s</xliff:g> पर ले जाया गया"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"मोबाइल डेटा"</item>
- <item msgid="6341719431034774569">"वाई-फ़ाई"</item>
- <item msgid="5081440868800877512">"ब्लूटूथ"</item>
- <item msgid="1160736166977503463">"ईथरनेट"</item>
- <item msgid="7347618872551558605">"वीपीएन"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"अज्ञात नेटवर्क टाइप"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hr/strings.xml
deleted file mode 100644
index 24bb22f..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hr/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Resursi za povezivost sustava"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Prijava na Wi-Fi mrežu"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Prijava na mrežu"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Dodirnite za opcije"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilna mreža nema pristup internetu"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Mreža nema pristup internetu"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Nije moguće pristupiti privatnom DNS poslužitelju"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu povezivost"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Dodirnite da biste se ipak povezali"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Prelazak na drugu mrežu: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Kada <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu, na uređaju se upotrebljava <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Moguća je naplata naknade."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Mreža je promijenjena: <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> > <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobilni podaci"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nepoznata vrsta mreže"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hu/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hu/strings.xml
deleted file mode 100644
index 47a1142..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hu/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Rendszerkapcsolat erőforrásai"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Bejelentkezés Wi-Fi hálózatba"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Bejelentkezés a hálózatba"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"A(z) <xliff:g id="NETWORK_SSID">%1$s</xliff:g> hálózaton nincs internet-hozzáférés"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Koppintson a beállítások megjelenítéséhez"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"A mobilhálózaton nincs internet-hozzáférés"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"A hálózaton nincs internet-hozzáférés"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"A privát DNS-kiszolgálóhoz nem lehet hozzáférni"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"A(z) <xliff:g id="NETWORK_SSID">%1$s</xliff:g> hálózat korlátozott kapcsolatot biztosít"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Koppintson, ha mindenképpen csatlakozni szeretne"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Átváltva erre: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="NEW_NETWORK">%1$s</xliff:g> használata, ha nincs internet-hozzáférés <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>-kapcsolaton keresztül. A szolgáltató díjat számíthat fel."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Átváltva <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>-hálózatról erre: <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobiladatok"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ismeretlen hálózati típus"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hy/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hy/strings.xml
deleted file mode 100644
index dd951e8..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hy/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System Connectivity Resources"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Մուտք գործեք Wi-Fi ցանց"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Մուտք գործեք ցանց"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ցանցը չունի մուտք ինտերնետին"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Հպեք՝ ընտրանքները տեսնելու համար"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Բջջային ցանցը չի ապահովում ինտերնետ կապ"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Ցանցը միացված չէ ինտերնետին"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Մասնավոր DNS սերվերն անհասանելի է"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ցանցի կապը սահմանափակ է"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Հպեք՝ միանալու համար"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Անցել է <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ցանցի"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Երբ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ցանցում ինտերնետ կապ չի լինում, սարքն անցնում է <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ցանցի: Նման դեպքում կարող են վճարներ գանձվել:"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ցանցից անցել է <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ցանցի"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"բջջային ինտերնետ"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ցանցի անհայտ տեսակ"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-in/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-in/strings.xml
deleted file mode 100644
index d559f6b..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-in/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Resource Konektivitas Sistem"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Login ke jaringan Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Login ke jaringan"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tidak memiliki akses internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Ketuk untuk melihat opsi"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Jaringan seluler tidak memiliki akses internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Jaringan tidak memiliki akses internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Server DNS pribadi tidak dapat diakses"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> memiliki konektivitas terbatas"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Ketuk untuk tetap menyambungkan"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Dialihkan ke <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Perangkat menggunakan <xliff:g id="NEW_NETWORK">%1$s</xliff:g> jika <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> tidak memiliki akses internet. Tarif mungkin berlaku."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Dialihkan dari <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ke <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"data seluler"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"jenis jaringan yang tidak dikenal"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-is/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-is/strings.xml
deleted file mode 100644
index 877c85f..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-is/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Tengigögn kerfis"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Skrá inn á Wi-Fi net"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Skrá inn á net"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> er ekki með internetaðgang"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Ýttu til að sjá valkosti"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Farsímakerfið er ekki tengt við internetið"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Netkerfið er ekki tengt við internetið"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Ekki næst í DNS-einkaþjón"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"Tengigeta <xliff:g id="NETWORK_SSID">%1$s</xliff:g> er takmörkuð"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Ýttu til að tengjast samt"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Skipt yfir á <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Tækið notar <xliff:g id="NEW_NETWORK">%1$s</xliff:g> þegar <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> er ekki með internetaðgang. Gjöld kunna að eiga við."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Skipt úr <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> yfir í <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"farsímagögn"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"óþekkt tegund netkerfis"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-it/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-it/strings.xml
deleted file mode 100644
index bcac393..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-it/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Risorse per connettività di sistema"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Accedi a rete Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Accedi alla rete"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> non ha accesso a Internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tocca per le opzioni"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"La rete mobile non ha accesso a Internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"La rete non ha accesso a Internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Non è possibile accedere al server DNS privato"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ha una connettività limitata"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tocca per connettere comunque"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Passato a <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Il dispositivo utilizza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> non ha accesso a Internet. Potrebbero essere applicati costi."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Passato da <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"dati mobili"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"tipo di rete sconosciuto"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-iw/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-iw/strings.xml
deleted file mode 100644
index d6684ce..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-iw/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"משאבי קישוריות מערכת"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"היכנס לרשת Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"היכנס לרשת"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"ל-<xliff:g id="NETWORK_SSID">%1$s</xliff:g> אין גישה לאינטרנט"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"הקש לקבלת אפשרויות"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"לרשת הסלולרית אין גישה לאינטרנט"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"לרשת אין גישה לאינטרנט"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"לא ניתן לגשת לשרת DNS הפרטי"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"הקישוריות של <xliff:g id="NETWORK_SSID">%1$s</xliff:g> מוגבלת"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"כדי להתחבר למרות זאת יש להקיש"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"מעבר אל <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"המכשיר משתמש ברשת <xliff:g id="NEW_NETWORK">%1$s</xliff:g> כשלרשת <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> אין גישה לאינטרנט. עשויים לחול חיובים."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"עבר מרשת <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> לרשת <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"חבילת גלישה"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"אתרנט"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"סוג רשת לא מזוהה"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ja/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ja/strings.xml
deleted file mode 100644
index fa4a30a..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ja/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"システム接続リソース"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fiネットワークにログイン"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"ネットワークにログインしてください"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> はインターネットにアクセスできません"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"タップしてその他のオプションを表示"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"モバイル ネットワークがインターネットに接続されていません"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"ネットワークがインターネットに接続されていません"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"プライベート DNS サーバーにアクセスできません"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> の接続が制限されています"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"接続するにはタップしてください"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"「<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>」に切り替えました"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"デバイスで「<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>」によるインターネット接続ができない場合に「<xliff:g id="NEW_NETWORK">%1$s</xliff:g>」を使用します。通信料が発生することがあります。"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"「<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>」から「<xliff:g id="NEW_NETWORK">%2$s</xliff:g>」に切り替えました"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"モバイルデータ"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"イーサネット"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"不明なネットワーク タイプ"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ka/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ka/strings.xml
deleted file mode 100644
index 4183310..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ka/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"სისტემის კავშირის რესურსები"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi ქსელთან დაკავშირება"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"ქსელში შესვლა"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-ს არ აქვს ინტერნეტზე წვდომა"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"შეეხეთ ვარიანტების სანახავად"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"მობილურ ქსელს არ აქვს ინტერნეტზე წვდომა"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"ქსელს არ აქვს ინტერნეტზე წვდომა"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"პირად DNS სერვერზე წვდომა შეუძლებელია"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-ის კავშირები შეზღუდულია"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"შეეხეთ, თუ მაინც გსურთ დაკავშირება"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"ახლა გამოიყენება <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"თუ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ინტერნეტთან კავშირს დაკარგავს, მოწყობილობის მიერ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> იქნება გამოყენებული, რამაც შეიძლება დამატებითი ხარჯები გამოიწვიოს."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"ახლა გამოიყენება <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> (გამოიყენებოდა <xliff:g id="NEW_NETWORK">%2$s</xliff:g>)"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"მობილური ინტერნეტი"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"უცნობი ტიპის ქსელი"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-kk/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-kk/strings.xml
deleted file mode 100644
index 54d5eb3..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-kk/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Жүйе байланысы ресурстары"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi желісіне кіру"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Желіге кіру"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> желісінің интернетті пайдалану мүмкіндігі шектеулі."</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Опциялар үшін түртіңіз"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Мобильдік желі интернетке қосылмаған."</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Желі интернетке қосылмаған."</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Жеке DNS серверіне кіру мүмкін емес."</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> желісінің қосылу мүмкіндігі шектеулі."</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Бәрібір жалғау үшін түртіңіз."</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> желісіне ауысты"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Құрылғы <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> желісінде интернетпен байланыс жоғалған жағдайда <xliff:g id="NEW_NETWORK">%1$s</xliff:g> желісін пайдаланады. Деректер ақысы алынуы мүмкін."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> желісінен <xliff:g id="NEW_NETWORK">%2$s</xliff:g> желісіне ауысты"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"мобильдік деректер"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"желі түрі белгісіз"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-km/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-km/strings.xml
deleted file mode 100644
index bd778a1..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-km/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ធនធានតភ្ជាប់ប្រព័ន្ធ"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"ចូលបណ្ដាញវ៉ាយហ្វាយ"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"ចូលទៅបណ្តាញ"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> មិនមានការតភ្ជាប់អ៊ីនធឺណិតទេ"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ប៉ះសម្រាប់ជម្រើស"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"បណ្ដាញទូរសព្ទចល័តមិនមានការតភ្ជាប់អ៊ីនធឺណិតទេ"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"បណ្ដាញមិនមានការតភ្ជាប់អ៊ីនធឺណិតទេ"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"មិនអាចចូលប្រើម៉ាស៊ីនមេ DNS ឯកជនបានទេ"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> មានការតភ្ជាប់មានកម្រិត"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"មិនអីទេ ចុចភ្ជាប់ចុះ"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"បានប្តូរទៅ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"ឧបករណ៍ប្រើ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> នៅពេលដែល <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> មិនមានការតភ្ជាប់អ៊ីនធឺណិត។ អាចគិតថ្លៃលើការប្រើប្រាស់ទិន្នន័យ។"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"បានប្តូរពី <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ទៅ <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"ទិន្នន័យទូរសព្ទចល័ត"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"ប៊្លូធូស"</item>
- <item msgid="1160736166977503463">"អ៊ីសឺរណិត"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ប្រភេទបណ្តាញដែលមិនស្គាល់"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-kn/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-kn/strings.xml
deleted file mode 100644
index 7f3a420..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-kn/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ಸಿಸ್ಟಂ ಸಂಪರ್ಕ ಕಲ್ಪಿಸುವಿಕೆ ಮಾಹಿತಿಯ ಮೂಲಗಳು"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"ನೆಟ್ವರ್ಕ್ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕವನ್ನು ಹೊಂದಿಲ್ಲ"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ಆಯ್ಕೆಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"ಮೊಬೈಲ್ ನೆಟ್ವರ್ಕ್ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿಲ್ಲ"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"ನೆಟ್ವರ್ಕ್ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿಲ್ಲ"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ಖಾಸಗಿ DNS ಸರ್ವರ್ ಅನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ಸೀಮಿತ ಸಂಪರ್ಕ ಕಲ್ಪಿಸುವಿಕೆಯನ್ನು ಹೊಂದಿದೆ"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ಹೇಗಾದರೂ ಸಂಪರ್ಕಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶ ಹೊಂದಿಲ್ಲದಿರುವಾಗ, ಸಾಧನವು <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ಬಳಸುತ್ತದೆ. ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ರಿಂದ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"ಮೊಬೈಲ್ ಡೇಟಾ"</item>
- <item msgid="6341719431034774569">"ವೈ-ಫೈ"</item>
- <item msgid="5081440868800877512">"ಬ್ಲೂಟೂತ್"</item>
- <item msgid="1160736166977503463">"ಇಥರ್ನೆಟ್"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ಅಪರಿಚಿತ ನೆಟ್ವರ್ಕ್ ಪ್ರಕಾರ"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ko/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ko/strings.xml
deleted file mode 100644
index a763cc5..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ko/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"시스템 연결 리소스"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi 네트워크에 로그인"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"네트워크에 로그인"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>이(가) 인터넷에 액세스할 수 없습니다."</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"탭하여 옵션 보기"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"모바일 네트워크에 인터넷이 연결되어 있지 않습니다."</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"네트워크에 인터넷이 연결되어 있지 않습니다."</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"비공개 DNS 서버에 액세스할 수 없습니다."</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>에서 연결을 제한했습니다."</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"계속 연결하려면 탭하세요."</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>(으)로 전환"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>(으)로 인터넷에 연결할 수 없는 경우 기기에서 <xliff:g id="NEW_NETWORK">%1$s</xliff:g>이(가) 사용됩니다. 요금이 부과될 수 있습니다."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>에서 <xliff:g id="NEW_NETWORK">%2$s</xliff:g>(으)로 전환"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"모바일 데이터"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"블루투스"</item>
- <item msgid="1160736166977503463">"이더넷"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"알 수 없는 네트워크 유형"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ky/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ky/strings.xml
deleted file mode 100644
index 3550af8..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ky/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Тутумдун байланыш булагы"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi түйүнүнө кирүү"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Тармакка кирүү"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> Интернетке туташуусу жок"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Параметрлерди ачуу үчүн таптап коюңуз"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Мобилдик Интернет жок"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Тармактын Интернет жок"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Жеке DNS сервери жеткиликсиз"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> байланышы чектелген"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Баары бир туташуу үчүн таптаңыз"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> тармагына которуштурулду"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> тармагы Интернетке туташпай турганда, түзмөгүңүз <xliff:g id="NEW_NETWORK">%1$s</xliff:g> тармагын колдонот. Акы алынышы мүмкүн."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> дегенден <xliff:g id="NEW_NETWORK">%2$s</xliff:g> тармагына которуштурулду"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"мобилдик трафик"</item>
- <item msgid="6341719431034774569">"Wi‑Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"белгисиз тармак түрү"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lo/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lo/strings.xml
deleted file mode 100644
index 4b3056f..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lo/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ແຫຼ່ງຂໍ້ມູນການເຊື່ອມຕໍ່ລະບົບ"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍ Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"ລົງຊື່ເຂົ້າເຄືອຂ່າຍ"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ແຕະເພື່ອເບິ່ງຕົວເລືອກ"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"ເຄືອຂ່າຍມືຖືບໍ່ສາມາດເຂົ້າເຖິງອິນເຕີເນັດໄດ້"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"ເຄືອຂ່າຍບໍ່ສາມາດເຂົ້າເຖິງອິນເຕີເນັດໄດ້"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ບໍ່ສາມາດເຂົ້າເຖິງເຊີບເວີ DNS ສ່ວນຕົວໄດ້"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ມີການເຊື່ອມຕໍ່ທີ່ຈຳກັດ"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ແຕະເພື່ອຢືນຢັນການເຊື່ອມຕໍ່"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"ສະຫຼັບໄປໃຊ້ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ແລ້ວ"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"ອຸປະກອນຈະໃຊ້ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ເມື່ອ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ. ອາດມີການຮຽກເກັບຄ່າບໍລິການ."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"ສະຫຼັບຈາກ <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ໄປໃຊ້ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ແລ້ວ"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"ອິນເຕີເນັດມືຖື"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"ອີເທີເນັດ"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ບໍ່ຮູ້ຈັກປະເພດເຄືອຂ່າຍ"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lt/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lt/strings.xml
deleted file mode 100644
index 8eb41f1..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lt/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System Connectivity Resources"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Prisijungti prie „Wi-Fi“ tinklo"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Prisijungti prie tinklo"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"„<xliff:g id="NETWORK_SSID">%1$s</xliff:g>“ negali pasiekti interneto"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Palieskite, kad būtų rodomos parinktys."</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobiliojo ryšio tinkle nėra prieigos prie interneto"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Tinkle nėra prieigos prie interneto"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Privataus DNS serverio negalima pasiekti"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"„<xliff:g id="NETWORK_SSID">%1$s</xliff:g>“ ryšys apribotas"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Palieskite, jei vis tiek norite prisijungti"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Perjungta į tinklą <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Įrenginyje naudojamas kitas tinklas (<xliff:g id="NEW_NETWORK">%1$s</xliff:g>), kai dabartiniame tinkle (<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>) nėra interneto ryšio. Gali būti taikomi mokesčiai."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Perjungta iš tinklo <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> į tinklą <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobiliojo ryšio duomenys"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Eternetas"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nežinomas tinklo tipas"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lv/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lv/strings.xml
deleted file mode 100644
index 0647a4f..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lv/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Sistēmas savienojamības resursi"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Pierakstieties Wi-Fi tīklā"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Pierakstīšanās tīklā"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"Tīklā <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nav piekļuves internetam"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Pieskarieties, lai skatītu iespējas."</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilajā tīklā nav piekļuves internetam."</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Tīklā nav piekļuves internetam."</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Nevar piekļūt privātam DNS serverim."</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"Tīklā <xliff:g id="NETWORK_SSID">%1$s</xliff:g> ir ierobežota savienojamība"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Lai tik un tā izveidotu savienojumu, pieskarieties"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Pārslēdzās uz tīklu <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Kad vienā tīklā (<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>) nav piekļuves internetam, ierīcē tiek izmantots cits tīkls (<xliff:g id="NEW_NETWORK">%1$s</xliff:g>). Var tikt piemērota maksa."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Pārslēdzās no tīkla <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> uz tīklu <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobilie dati"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nezināms tīkla veids"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc204-mnc04/config.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc204-mnc04/config.xml
deleted file mode 100644
index 7e7025f..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc204-mnc04/config.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ 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.
- -->
-
-<!-- Configuration values for ConnectivityService
- DO NOT EDIT THIS FILE for specific device configuration; instead, use a Runtime Resources
- Overlay package following the overlayable.xml configuration in the same directory:
- https://source.android.com/devices/architecture/rros -->
-<resources>
- <!-- Whether the device should automatically switch away from Wi-Fi networks that lose
- Internet access. Actual device behaviour is controlled by
- Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. -->
- <integer translatable="false" name="config_networkAvoidBadWifi">0</integer>
-</resources>
\ No newline at end of file
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc310-mnc004/config.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc310-mnc004/config.xml
deleted file mode 100644
index 7e7025f..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc310-mnc004/config.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ 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.
- -->
-
-<!-- Configuration values for ConnectivityService
- DO NOT EDIT THIS FILE for specific device configuration; instead, use a Runtime Resources
- Overlay package following the overlayable.xml configuration in the same directory:
- https://source.android.com/devices/architecture/rros -->
-<resources>
- <!-- Whether the device should automatically switch away from Wi-Fi networks that lose
- Internet access. Actual device behaviour is controlled by
- Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. -->
- <integer translatable="false" name="config_networkAvoidBadWifi">0</integer>
-</resources>
\ No newline at end of file
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc311-mnc480/config.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc311-mnc480/config.xml
deleted file mode 100644
index 7e7025f..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc311-mnc480/config.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ 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.
- -->
-
-<!-- Configuration values for ConnectivityService
- DO NOT EDIT THIS FILE for specific device configuration; instead, use a Runtime Resources
- Overlay package following the overlayable.xml configuration in the same directory:
- https://source.android.com/devices/architecture/rros -->
-<resources>
- <!-- Whether the device should automatically switch away from Wi-Fi networks that lose
- Internet access. Actual device behaviour is controlled by
- Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. -->
- <integer translatable="false" name="config_networkAvoidBadWifi">0</integer>
-</resources>
\ No newline at end of file
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mk/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mk/strings.xml
deleted file mode 100644
index b0024e2..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mk/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System Connectivity Resources"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Најавете се на мрежа на Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Најавете се на мрежа"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> нема интернет-пристап"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Допрете за опции"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Мобилната мрежа нема интернет-пристап"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Мрежата нема интернет-пристап"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Не може да се пристапи до приватниот DNS-сервер"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничена поврзливост"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Допрете за да се поврзете и покрај тоа"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Префрлено на <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Уредот користи <xliff:g id="NEW_NETWORK">%1$s</xliff:g> кога <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> нема пристап до интернет. Може да се наплатат трошоци."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Префрлено од <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"мобилен интернет"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Етернет"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"непознат тип мрежа"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ml/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ml/strings.xml
deleted file mode 100644
index 8ce7667..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ml/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"സിസ്റ്റം കണക്റ്റിവിറ്റി ഉറവിടങ്ങൾ"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"വൈഫൈ നെറ്റ്വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"നെറ്റ്വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> എന്നതിന് ഇന്റർനെറ്റ് ആക്സസ് ഇല്ല"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ഓപ്ഷനുകൾക്ക് ടാപ്പുചെയ്യുക"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"മൊബെെൽ നെറ്റ്വർക്കിന് ഇന്റർനെറ്റ് ആക്സസ് ഇല്ല"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"നെറ്റ്വർക്കിന് ഇന്റർനെറ്റ് ആക്സസ് ഇല്ല"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"സ്വകാര്യ DNS സെർവർ ആക്സസ് ചെയ്യാനാവില്ല"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> എന്നതിന് പരിമിതമായ കണക്റ്റിവിറ്റി ഉണ്ട്"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ഏതുവിധേനയും കണക്റ്റ് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> എന്നതിലേക്ക് മാറി"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>-ന് ഇന്റർനെറ്റ് ആക്സസ് ഇല്ലാത്തപ്പോൾ ഉപകരണം <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ഉപയോഗിക്കുന്നു. നിരക്കുകൾ ബാധകമായേക്കാം."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> നെറ്റ്വർക്കിൽ നിന്ന് <xliff:g id="NEW_NETWORK">%2$s</xliff:g> നെറ്റ്വർക്കിലേക്ക് മാറി"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"മൊബൈൽ ഡാറ്റ"</item>
- <item msgid="6341719431034774569">"വൈഫൈ"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"ഇതർനെറ്റ്"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"അജ്ഞാതമായ നെറ്റ്വർക്ക് തരം"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mn/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mn/strings.xml
deleted file mode 100644
index be8b592..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mn/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Системийн холболтын нөөцүүд"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi сүлжээнд нэвтэрнэ үү"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Сүлжээнд нэвтэрнэ үү"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-д интернэтийн хандалт алга"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Сонголт хийхийн тулд товшино уу"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Мобайл сүлжээнд интернэт хандалт байхгүй байна"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Сүлжээнд интернэт хандалт байхгүй байна"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Хувийн DNS серверт хандах боломжгүй байна"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> зарим үйлчилгээнд хандах боломжгүй байна"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Ямар ч тохиолдолд холбогдохын тулд товших"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> руу шилжүүлсэн"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> интернет холболтгүй үед төхөөрөмж <xliff:g id="NEW_NETWORK">%1$s</xliff:g>-г ашигладаг. Төлбөр гарч болзошгүй."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>-с <xliff:g id="NEW_NETWORK">%2$s</xliff:g> руу шилжүүлсэн"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"мобайл дата"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Этернэт"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"үл мэдэгдэх сүлжээний төрөл"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mr/strings.xml
deleted file mode 100644
index fe7df84..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mr/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"सिस्टम कनेक्टिव्हिटी चे स्रोत"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"वाय-फाय नेटवर्कमध्ये साइन इन करा"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"नेटवर्कवर साइन इन करा"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ला इंटरनेट अॅक्सेस नाही"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"पर्यायांसाठी टॅप करा"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"मोबाइल नेटवर्कला इंटरनेट ॲक्सेस नाही"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"नेटवर्कला इंटरनेट ॲक्सेस नाही"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"खाजगी DNS सर्व्हर ॲक्सेस करू शकत नाही"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ला मर्यादित कनेक्टिव्हिटी आहे"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"तरीही कनेक्ट करण्यासाठी टॅप करा"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> वर स्विच केले"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> कडे इंटरनेटचा अॅक्सेस नसताना डिव्हाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> वापरते. शुल्क लागू शकते."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> वरून <xliff:g id="NEW_NETWORK">%2$s</xliff:g> वर स्विच केले"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"मोबाइल डेटा"</item>
- <item msgid="6341719431034774569">"वाय-फाय"</item>
- <item msgid="5081440868800877512">"ब्लूटूथ"</item>
- <item msgid="1160736166977503463">"इथरनेट"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"अज्ञात नेटवर्क प्रकार"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ms/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ms/strings.xml
deleted file mode 100644
index 54b49a2..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ms/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Sumber Kesambungan Sistem"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Log masuk ke rangkaian Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Log masuk ke rangkaian"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tiada akses Internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Ketik untuk mendapatkan pilihan"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Rangkaian mudah alih tiada akses Internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Rangkaian tiada akses Internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Pelayan DNS peribadi tidak boleh diakses"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> mempunyai kesambungan terhad"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Ketik untuk menyambung juga"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Beralih kepada <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Peranti menggunakan <xliff:g id="NEW_NETWORK">%1$s</xliff:g> apabila <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> tiada akses Internet. Bayaran mungkin dikenakan."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Beralih daripada <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> kepada <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"data mudah alih"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"jenis rangkaian tidak diketahui"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-my/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-my/strings.xml
deleted file mode 100644
index 15b75f0..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-my/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"စနစ်ချိတ်ဆက်နိုင်မှု ရင်းမြစ်များ"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"ဝိုင်ဖိုင်ကွန်ရက်သို့ လက်မှတ်ထိုးဝင်ပါ"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"ကွန်ယက်သို့ လက်မှတ်ထိုးဝင်ရန်"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> တွင် အင်တာနက်အသုံးပြုခွင့် မရှိပါ"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"အခြားရွေးချယ်စရာများကိုကြည့်ရန် တို့ပါ"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"မိုဘိုင်းကွန်ရက်တွင် အင်တာနက်ချိတ်ဆက်မှု မရှိပါ"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"ကွန်ရက်တွင် အင်တာနက်အသုံးပြုခွင့် မရှိပါ"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"သီးသန့် ဒီအန်အက်စ် (DNS) ဆာဗာကို သုံး၍မရပါ။"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> တွင် ချိတ်ဆက်မှုကို ကန့်သတ်ထားသည်"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"မည်သို့ပင်ဖြစ်စေ ချိတ်ဆက်ရန် တို့ပါ"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> သို့ ပြောင်းလိုက်ပြီ"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ဖြင့် အင်တာနက် အသုံးမပြုနိုင်သည့်အချိန်တွင် စက်ပစ္စည်းသည် <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ကို သုံးပါသည်။ ဒေတာသုံးစွဲခ ကျသင့်နိုင်ပါသည်။"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> မှ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> သို့ ပြောင်းလိုက်ပြီ"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"မိုဘိုင်းဒေတာ"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"ဘလူးတုသ်"</item>
- <item msgid="1160736166977503463">"အီသာနက်"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"အမည်မသိကွန်ရက်အမျိုးအစား"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-nb/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-nb/strings.xml
deleted file mode 100644
index a561def..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-nb/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Ressurser for systemtilkobling"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Logg på Wi-Fi-nettverket"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Logg på nettverk"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har ingen internettilkobling"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Trykk for å få alternativer"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilnettverket har ingen internettilgang"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Nettverket har ingen internettilgang"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Den private DNS-tjeneren kan ikke nås"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har begrenset tilkobling"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Trykk for å koble til likevel"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Byttet til <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Enheten bruker <xliff:g id="NEW_NETWORK">%1$s</xliff:g> når <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ikke har Internett-tilgang. Avgifter kan påløpe."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Byttet fra <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> til <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobildata"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"en ukjent nettverkstype"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ne/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ne/strings.xml
deleted file mode 100644
index f74542d..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ne/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"सिस्टम कनेक्टिभिटीका स्रोतहरू"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi नेटवर्कमा साइन इन गर्नुहोस्"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"सञ्जालमा साइन इन गर्नुहोस्"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> को इन्टरनेटमाथि पहुँच छैन"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"विकल्पहरूका लागि ट्याप गर्नुहोस्"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"मोबाइल नेटवर्कको इन्टरनेटमाथि पहुँच छैन"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"नेटवर्कको इन्टरनेटमाथि पहुँच छैन"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"निजी DNS सर्भरमाथि पहुँच प्राप्त गर्न सकिँदैन"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> को जडान सीमित छ"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"जसरी भए पनि जडान गर्न ट्याप गर्नुहोस्"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> मा बदल्नुहोस्"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> मार्फत इन्टरनेटमाथि पहुँच राख्न नसकेको अवस्थामा यन्त्रले <xliff:g id="NEW_NETWORK">%1$s</xliff:g> प्रयोग गर्दछ। शुल्क लाग्न सक्छ।"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> बाट <xliff:g id="NEW_NETWORK">%2$s</xliff:g> मा परिवर्तन गरियो"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"मोबाइल डेटा"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"ब्लुटुथ"</item>
- <item msgid="1160736166977503463">"इथरनेट"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"नेटवर्कको कुनै अज्ञात प्रकार"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-nl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-nl/strings.xml
deleted file mode 100644
index 0f3203b..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-nl/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Resources voor systeemconnectiviteit"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Inloggen bij wifi-netwerk"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Inloggen bij netwerk"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> heeft geen internettoegang"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tik voor opties"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobiel netwerk heeft geen internettoegang"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Netwerk heeft geen internettoegang"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Geen toegang tot privé-DNS-server"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> heeft beperkte connectiviteit"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tik om toch verbinding te maken"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Overgeschakeld naar <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Apparaat gebruikt <xliff:g id="NEW_NETWORK">%1$s</xliff:g> wanneer <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> geen internetverbinding heeft. Er kunnen kosten in rekening worden gebracht."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Overgeschakeld van <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> naar <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobiele data"</item>
- <item msgid="6341719431034774569">"Wifi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"een onbekend netwerktype"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-or/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-or/strings.xml
deleted file mode 100644
index ecf4d69..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-or/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ସିଷ୍ଟମର ସଂଯୋଗ ସମ୍ବନ୍ଧିତ ରିସୋର୍ସଗୁଡ଼ିକ"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"ୱାଇ-ଫାଇ ନେଟୱର୍କରେ ସାଇନ୍-ଇନ୍ କରନ୍ତୁ"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"ନେଟ୍ୱର୍କରେ ସାଇନ୍ ଇନ୍ କରନ୍ତୁ"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ର ଇଣ୍ଟର୍ନେଟ୍ ଆକ୍ସେସ୍ ନାହିଁ"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ବିକଳ୍ପ ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"ମୋବାଇଲ୍ ନେଟ୍ୱାର୍କରେ ଇଣ୍ଟର୍ନେଟ୍ ଆକ୍ସେସ୍ ନାହିଁ"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"ନେଟ୍ୱାର୍କରେ ଇଣ୍ଟର୍ନେଟ୍ ଆକ୍ସେସ୍ ନାହିଁ"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ବ୍ୟକ୍ତିଗତ DNS ସର୍ଭର୍ ଆକ୍ସେସ୍ କରିହେବ ନାହିଁ"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ର ସୀମିତ ସଂଯୋଗ ଅଛି"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ତଥାପି ଯୋଗାଯୋଗ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>କୁ ବଦଳାଗଲା"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>ର ଇଣ୍ଟରନେଟ୍ ଆକ୍ସେସ୍ ନଥିବାବେଳେ ଡିଭାଇସ୍ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ବ୍ୟବହାର କରିଥାଏ। ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ।"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ରୁ <xliff:g id="NEW_NETWORK">%2$s</xliff:g>କୁ ବଦଳାଗଲା"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"ମୋବାଇଲ ଡାଟା"</item>
- <item msgid="6341719431034774569">"ୱାଇ-ଫାଇ"</item>
- <item msgid="5081440868800877512">"ବ୍ଲୁଟୁଥ୍"</item>
- <item msgid="1160736166977503463">"ଇଥରନେଟ୍"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ଏକ ଅଜଣା ନେଟୱାର୍କ ପ୍ରକାର"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pa/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pa/strings.xml
deleted file mode 100644
index 4328054..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pa/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ਸਿਸਟਮ ਕਨੈਕਟੀਵਿਟੀ ਸਰੋਤ"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ਕੋਲ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਕੋਲ ਇੰਟਰਨੈੱਟ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"ਨੈੱਟਵਰਕ ਕੋਲ ਇੰਟਰਨੈੱਟ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ਨਿੱਜੀ ਡੋਮੇਨ ਨਾਮ ਪ੍ਰਣਾਲੀ (DNS) ਸਰਵਰ \'ਤੇ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ਕੋਲ ਸੀਮਤ ਕਨੈਕਟੀਵਿਟੀ ਹੈ"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ਫਿਰ ਵੀ ਕਨੈਕਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"ਬਦਲਕੇ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ਲਿਆਂਦਾ ਗਿਆ"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ਦੀ ਇੰਟਰਨੈੱਟ \'ਤੇ ਪਹੁੰਚ ਨਾ ਹੋਣ \'ਤੇ ਡੀਵਾਈਸ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ। ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ।"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ਤੋਂ ਬਦਲਕੇ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> \'ਤੇ ਕੀਤਾ ਗਿਆ"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"ਮੋਬਾਈਲ ਡਾਟਾ"</item>
- <item msgid="6341719431034774569">"ਵਾਈ-ਫਾਈ"</item>
- <item msgid="5081440868800877512">"ਬਲੂਟੁੱਥ"</item>
- <item msgid="1160736166977503463">"ਈਥਰਨੈੱਟ"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ਕੋਈ ਅਗਿਆਤ ਨੈੱਟਵਰਕ ਦੀ ਕਿਸਮ"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pl/strings.xml
deleted file mode 100644
index e6b3a0c..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pl/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Zasoby systemowe dotyczące łączności"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Zaloguj się w sieci Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Zaloguj się do sieci"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nie ma dostępu do internetu"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Kliknij, by wyświetlić opcje"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Sieć komórkowa nie ma dostępu do internetu"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Sieć nie ma dostępu do internetu"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Brak dostępu do prywatnego serwera DNS"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ma ograniczoną łączność"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Kliknij, by mimo to nawiązać połączenie"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Zmieniono na połączenie typu <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Urządzenie korzysta z połączenia typu <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, gdy <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nie dostępu do internetu. Mogą zostać naliczone opłaty."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Przełączono z połączenia typu <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na <xliff:g id="NEW_NETWORK">%2$s</xliff:g>."</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobilna transmisja danych"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nieznany typ sieci"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rBR/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rBR/strings.xml
deleted file mode 100644
index f1d0bc0..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de conectividade do sistema"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Fazer login na rede Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Fazer login na rede"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> não tem acesso à Internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Toque para ver opções"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"A rede móvel não tem acesso à Internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"A rede não tem acesso à Internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Não é possível acessar o servidor DNS privado"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tem conectividade limitada"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Toque para conectar mesmo assim"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Alternado para <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"O dispositivo usa <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> não tem acesso à Internet. Esse serviço pode ser cobrado."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Alternado de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> para <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"dados móveis"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"um tipo de rede desconhecido"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rPT/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 163d70b..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de conetividade do sistema"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Iniciar sessão na rede Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Início de sessão na rede"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> não tem acesso à Internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Toque para obter mais opções"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"A rede móvel não tem acesso à Internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"A rede não tem acesso à Internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Não é possível aceder ao servidor DNS."</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tem conetividade limitada."</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Toque para ligar mesmo assim."</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Mudou para <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"O dispositivo utiliza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> não tem acesso à Internet. Podem aplicar-se custos."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Mudou de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> para <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"dados móveis"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"um tipo de rede desconhecido"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt/strings.xml
deleted file mode 100644
index f1d0bc0..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Recursos de conectividade do sistema"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Fazer login na rede Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Fazer login na rede"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> não tem acesso à Internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Toque para ver opções"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"A rede móvel não tem acesso à Internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"A rede não tem acesso à Internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Não é possível acessar o servidor DNS privado"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tem conectividade limitada"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Toque para conectar mesmo assim"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Alternado para <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"O dispositivo usa <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> não tem acesso à Internet. Esse serviço pode ser cobrado."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Alternado de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> para <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"dados móveis"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"um tipo de rede desconhecido"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ro/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ro/strings.xml
deleted file mode 100644
index 221261c..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ro/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Resurse pentru conectivitatea sistemului"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Conectați-vă la rețeaua Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Conectați-vă la rețea"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nu are acces la internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Atingeți pentru opțiuni"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Rețeaua mobilă nu are acces la internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Rețeaua nu are acces la internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Serverul DNS privat nu poate fi accesat"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> are conectivitate limitată"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Atingeți pentru a vă conecta oricum"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"S-a comutat la <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Dispozitivul folosește <xliff:g id="NEW_NETWORK">%1$s</xliff:g> când <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nu are acces la internet. Se pot aplica taxe."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"S-a comutat de la <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> la <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"date mobile"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"un tip de rețea necunoscut"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ru/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ru/strings.xml
deleted file mode 100644
index ba179b7..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ru/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"System Connectivity Resources"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Подключение к Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Регистрация в сети"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"Сеть \"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>\" не подключена к Интернету"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Нажмите, чтобы показать варианты."</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Мобильная сеть не подключена к Интернету"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Сеть не подключена к Интернету"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Доступа к частному DNS-серверу нет."</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"Подключение к сети \"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>\" ограничено"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Нажмите, чтобы подключиться"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Новое подключение: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Устройство использует <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, если подключение к сети <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> недоступно. Может взиматься плата за передачу данных."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Устройство отключено от сети <xliff:g id="NEW_NETWORK">%2$s</xliff:g> и теперь использует <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"мобильный интернет"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"неизвестный тип сети"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-si/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-si/strings.xml
deleted file mode 100644
index 1c493a7..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-si/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"පද්ධති සබැඳුම් හැකියා සම්පත්"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi ජාලයට පුරනය වන්න"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"ජාලයට පුරනය වන්න"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> හට අන්තර්ජාල ප්රවේශය නැත"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"විකල්ප සඳහා තට්ටු කරන්න"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"ජංගම ජාලවලට අන්තර්ජාල ප්රවේශය නැත"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"ජාලයට අන්තර්ජාල ප්රවේශය නැත"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"පුද්ගලික DNS සේවාදායකයට ප්රවේශ වීමට නොහැකිය"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> හට සීමිත සබැඳුම් හැකියාවක් ඇත"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"කෙසේ වෙතත් ඉදිරියට යාමට තට්ටු කරන්න"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> වෙත මාරු විය"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"උපාංගය <xliff:g id="NEW_NETWORK">%1$s</xliff:g> <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> සඳහා අන්තර්ජාල ප්රවේශය නැති විට භාවිත කරයි. ගාස්තු අදාළ විය හැකිය."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> සිට <xliff:g id="NEW_NETWORK">%2$s</xliff:g> වෙත මාරු විය"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"ජංගම දත්ත"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"බ්ලූටූත්"</item>
- <item msgid="1160736166977503463">"ඊතර්නෙට්"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"නොදන්නා ජාල වර්ගයකි"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sk/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sk/strings.xml
deleted file mode 100644
index 1b9313a..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sk/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Zdroje možností pripojenia systému"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Prihlásiť sa do siete Wi‑Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Prihlásenie do siete"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nemá prístup k internetu"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Klepnutím získate možnosti"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilná sieť nemá prístup k internetu"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Sieť nemá prístup k internetu"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"K súkromnému serveru DNS sa nepodarilo získať prístup"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> má obmedzené pripojenie"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Ak sa chcete aj napriek tomu pripojiť, klepnite"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Prepnuté na sieť: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Keď <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nemá prístup k internetu, zariadenie používa <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Môžu sa účtovať poplatky."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Prepnuté zo siete <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na sieť <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobilné dáta"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"neznámy typ siete"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sl/strings.xml
deleted file mode 100644
index 739fb8e..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sl/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Viri povezljivosti sistema"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Prijavite se v omrežje Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Prijava v omrežje"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"Omrežje <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nima dostopa do interneta"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Dotaknite se za možnosti"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilno omrežje nima dostopa do interneta"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Omrežje nima dostopa do interneta"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Do zasebnega strežnika DNS ni mogoče dostopati"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"Povezljivost omrežja <xliff:g id="NETWORK_SSID">%1$s</xliff:g> je omejena"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Dotaknite se, da kljub temu vzpostavite povezavo"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Preklopljeno na omrežje vrste <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Naprava uporabi omrežje vrste <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, ko omrežje vrste <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nima dostopa do interneta. Prenos podatkov se lahko zaračuna."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Preklopljeno z omrežja vrste <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na omrežje vrste <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"prenos podatkov v mobilnem omrežju"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"neznana vrsta omrežja"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sq/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sq/strings.xml
deleted file mode 100644
index cf8cf3b..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sq/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Burimet e lidhshmërisë së sistemit"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Identifikohu në rrjetin Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Identifikohu në rrjet"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nuk ka qasje në internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Trokit për opsionet"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Rrjeti celular nuk ka qasje në internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Rrjeti nuk ka qasje në internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Serveri privat DNS nuk mund të qaset"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ka lidhshmëri të kufizuar"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Trokit për t\'u lidhur gjithsesi"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Kaloi te <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Pajisja përdor <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kur <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nuk ka qasje në internet. Mund të zbatohen tarifa."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Kaloi nga <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> te <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"të dhënat celulare"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Eternet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"një lloj rrjeti i panjohur"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sr/strings.xml
deleted file mode 100644
index 1f7c95c..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sr/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Ресурси за повезивање са системом"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Пријављивање на WiFi мрежу"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Пријавите се на мрежу"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> нема приступ интернету"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Додирните за опције"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Мобилна мрежа нема приступ интернету"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Мрежа нема приступ интернету"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Приступ приватном DNS серверу није успео"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничену везу"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Додирните да бисте се ипак повезали"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Прешли сте на тип мреже <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Уређај користи тип мреже <xliff:g id="NEW_NETWORK">%1$s</xliff:g> када тип мреже <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> нема приступ интернету. Можда ће се наплаћивати трошкови."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Прешли сте са типа мреже <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на тип мреже <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"мобилни подаци"</item>
- <item msgid="6341719431034774569">"WiFi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Етернет"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"непознат тип мреже"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sv/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sv/strings.xml
deleted file mode 100644
index 57e74e9..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sv/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Resurser för systemanslutning"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Logga in på ett wifi-nätverk"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Logga in på nätverket"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har ingen internetanslutning"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Tryck för alternativ"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobilnätverket har ingen internetanslutning"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Nätverket har ingen internetanslutning"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Det går inte att komma åt den privata DNS-servern."</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har begränsad anslutning"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Tryck för att ansluta ändå"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Byte av nätverk till <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="NEW_NETWORK">%1$s</xliff:g> används på enheten när det inte finns internetåtkomst via <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>. Avgifter kan tillkomma."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Byte av nätverk från <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> till <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobildata"</item>
- <item msgid="6341719431034774569">"Wifi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"en okänd nätverkstyp"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sw/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sw/strings.xml
deleted file mode 100644
index 5c4d594..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sw/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Nyenzo za Muunganisho wa Mfumo"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Ingia kwa mtandao wa Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Ingia katika mtandao"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> haina uwezo wa kufikia intaneti"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Gusa ili upate chaguo"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mtandao wa simu hauna uwezo wa kufikia intaneti"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Mtandao hauna uwezo wa kufikia intaneti"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Seva ya faragha ya DNS haiwezi kufikiwa"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ina muunganisho unaofikia huduma chache."</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Gusa ili uunganishe tu"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Sasa inatumia <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Kifaa hutumia <xliff:g id="NEW_NETWORK">%1$s</xliff:g> wakati <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> haina intaneti. Huenda ukalipishwa."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Imebadilisha mtandao kutoka <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na sasa inatumia <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"data ya mtandao wa simu"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethaneti"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"aina ya mtandao isiyojulikana"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ta/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ta/strings.xml
deleted file mode 100644
index 90f89c9..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ta/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"சிஸ்டம் இணைப்பு மூலங்கள்"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"வைஃபை நெட்வொர்க்கில் உள்நுழையவும்"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> நெட்வொர்க்கிற்கு இணைய அணுகல் இல்லை"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"விருப்பங்களுக்கு, தட்டவும்"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"மொபைல் நெட்வொர்க்கிற்கு இணைய அணுகல் இல்லை"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"நெட்வொர்க்கிற்கு இணைய அணுகல் இல்லை"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"தனிப்பட்ட DNS சேவையகத்தை அணுக இயலாது"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> வரம்பிற்கு உட்பட்ட இணைப்புநிலையைக் கொண்டுள்ளது"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"எப்படியேனும் இணைப்பதற்குத் தட்டவும்"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>க்கு மாற்றப்பட்டது"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> நெட்வொர்க்கில் இண்டர்நெட் அணுகல் இல்லாததால், சாதனமானது <xliff:g id="NEW_NETWORK">%1$s</xliff:g> நெட்வொர்க்கைப் பயன்படுத்துகிறது. கட்டணங்கள் விதிக்கப்படலாம்."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> இலிருந்து <xliff:g id="NEW_NETWORK">%2$s</xliff:g>க்கு மாற்றப்பட்டது"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"மொபைல் டேட்டா"</item>
- <item msgid="6341719431034774569">"வைஃபை"</item>
- <item msgid="5081440868800877512">"புளூடூத்"</item>
- <item msgid="1160736166977503463">"ஈதர்நெட்"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"தெரியாத நெட்வொர்க் வகை"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-te/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-te/strings.xml
deleted file mode 100644
index c69b599..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-te/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"సిస్టమ్ కనెక్టివిటీ రిసోర్స్లు"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi నెట్వర్క్కి సైన్ ఇన్ చేయండి"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"నెట్వర్క్కి సైన్ ఇన్ చేయండి"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>కి ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"ఎంపికల కోసం నొక్కండి"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"మొబైల్ నెట్వర్క్కు ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"నెట్వర్క్కు ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"ప్రైవేట్ DNS సర్వర్ను యాక్సెస్ చేయడం సాధ్యపడదు"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> పరిమిత కనెక్టివిటీని కలిగి ఉంది"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"ఏదేమైనా కనెక్ట్ చేయడానికి నొక్కండి"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>కి మార్చబడింది"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"పరికరం <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>కి ఇంటర్నెట్ యాక్సెస్ లేనప్పుడు <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ని ఉపయోగిస్తుంది. ఛార్జీలు వర్తించవచ్చు."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> నుండి <xliff:g id="NEW_NETWORK">%2$s</xliff:g>కి మార్చబడింది"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"మొబైల్ డేటా"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"బ్లూటూత్"</item>
- <item msgid="1160736166977503463">"ఈథర్నెట్"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"తెలియని నెట్వర్క్ రకం"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-th/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-th/strings.xml
deleted file mode 100644
index eee5a35..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-th/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"ทรัพยากรการเชื่อมต่อของระบบ"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"ลงชื่อเข้าใช้เครือข่าย WiFi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"ลงชื่อเข้าใช้เครือข่าย"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> เข้าถึงอินเทอร์เน็ตไม่ได้"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"แตะเพื่อดูตัวเลือก"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"เครือข่ายมือถือไม่มีการเข้าถึงอินเทอร์เน็ต"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"เครือข่ายไม่มีการเข้าถึงอินเทอร์เน็ต"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"เข้าถึงเซิร์ฟเวอร์ DNS ไม่ได้"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> มีการเชื่อมต่อจำกัด"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"แตะเพื่อเชื่อมต่อ"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"เปลี่ยนเป็น <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"อุปกรณ์จะใช้ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> เมื่อ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> เข้าถึงอินเทอร์เน็ตไม่ได้ โดยอาจมีค่าบริการ"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"เปลี่ยนจาก <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> เป็น <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"อินเทอร์เน็ตมือถือ"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"บลูทูธ"</item>
- <item msgid="1160736166977503463">"อีเทอร์เน็ต"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"ประเภทเครือข่ายที่ไม่รู้จัก"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-tl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-tl/strings.xml
deleted file mode 100644
index 8d665fe..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-tl/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Mga Resource ng Pagkakonekta ng System"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Mag-sign in sa Wi-Fi network"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Mag-sign in sa network"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"Walang access sa internet ang <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"I-tap para sa mga opsyon"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Walang access sa internet ang mobile network"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Walang access sa internet ang network"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Hindi ma-access ang pribadong DNS server"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"Limitado ang koneksyon ng <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"I-tap para kumonekta pa rin"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Lumipat sa <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Ginagamit ng device ang <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kapag walang access sa internet ang <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>. Maaaring may mga malapat na singilin."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Lumipat sa <xliff:g id="NEW_NETWORK">%2$s</xliff:g> mula sa <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobile data"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"isang hindi kilalang uri ng network"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-tr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-tr/strings.xml
deleted file mode 100644
index cfb7632..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-tr/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Sistem Bağlantı Kaynakları"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Kablosuz ağda oturum açın"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Ağda oturum açın"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ağının internet bağlantısı yok"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Seçenekler için dokunun"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobil ağın internet bağlantısı yok"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Ağın internet bağlantısı yok"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Gizli DNS sunucusuna erişilemiyor"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> sınırlı bağlantıya sahip"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Yine de bağlanmak için dokunun"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ağına geçildi"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ağının internet erişimi olmadığında cihaz <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ağını kullanır. Bunun için ödeme alınabilir."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ağından <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ağına geçildi"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobil veri"</item>
- <item msgid="6341719431034774569">"Kablosuz"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"bilinmeyen ağ türü"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-uk/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-uk/strings.xml
deleted file mode 100644
index c5da746..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-uk/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Ресурси для підключення системи"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Вхід у мережу Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Вхід у мережу"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"Мережа <xliff:g id="NETWORK_SSID">%1$s</xliff:g> не має доступу до Інтернету"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Торкніться, щоб відкрити опції"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Мобільна мережа не має доступу до Інтернету"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Мережа не має доступу до Інтернету"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Немає доступу до приватного DNS-сервера"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"Підключення до мережі <xliff:g id="NETWORK_SSID">%1$s</xliff:g> обмежено"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Натисніть, щоб усе одно підключитися"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Пристрій перейшов на мережу <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Коли мережа <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> не має доступу до Інтернету, використовується <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Може стягуватися плата."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Пристрій перейшов з мережі <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на мережу <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"мобільний Інтернет"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"невідомий тип мережі"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ur/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ur/strings.xml
deleted file mode 100644
index bd2a228..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ur/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"سسٹم کنیکٹوٹی کے وسائل"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi نیٹ ورک میں سائن ان کریں"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"نیٹ ورک میں سائن ان کریں"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> کو انٹرنیٹ تک رسائی حاصل نہیں ہے"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"اختیارات کیلئے تھپتھپائیں"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"موبائل نیٹ ورک کو انٹرنیٹ تک رسائی حاصل نہیں ہے"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"نیٹ ورک کو انٹرنیٹ تک رسائی حاصل نہیں ہے"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"نجی DNS سرور تک رسائی حاصل نہیں کی جا سکی"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> کی کنیکٹوٹی محدود ہے"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"بہر حال منسلک کرنے کے لیے تھپتھپائیں"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> پر سوئچ ہو گیا"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"جب <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> کو انٹرنیٹ تک رسائی نہیں ہوتی ہے تو آلہ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> کا استعمال کرتا ہے۔ چارجز لاگو ہو سکتے ہیں۔"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> سے <xliff:g id="NEW_NETWORK">%2$s</xliff:g> پر سوئچ ہو گیا"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"موبائل ڈیٹا"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"بلوٹوتھ"</item>
- <item msgid="1160736166977503463">"ایتھرنیٹ"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"نامعلوم نیٹ ورک کی قسم"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-uz/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-uz/strings.xml
deleted file mode 100644
index 567aa88..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-uz/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Tizim aloqa resurslari"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Wi-Fi tarmoqqa kirish"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Tarmoqqa kirish"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nomli tarmoqda internetga ruxsati yoʻq"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Variantlarni ko‘rsatish uchun bosing"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mobil tarmoq internetga ulanmagan"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Tarmoq internetga ulanmagan"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Xususiy DNS server ishlamayapti"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nomli tarmoqda aloqa cheklangan"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Baribir ulash uchun bosing"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Yangi ulanish: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Agar <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> tarmoqda internet uzilsa, qurilma <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ga ulanadi. Sarflangan trafik uchun haq olinishi mumkin."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> tarmog‘idan <xliff:g id="NEW_NETWORK">%2$s</xliff:g> tarmog‘iga o‘tildi"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"mobil internet"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"nomaʼlum tarmoq turi"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-vi/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-vi/strings.xml
deleted file mode 100644
index 590b388..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-vi/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Tài nguyên kết nối hệ thống"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Đăng nhập vào mạng Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Đăng nhập vào mạng"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> không có quyền truy cập Internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Nhấn để biết tùy chọn"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Mạng di động không có quyền truy cập Internet"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Mạng không có quyền truy cập Internet"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Không thể truy cập máy chủ DNS riêng tư"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> có khả năng kết nối giới hạn"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Nhấn để tiếp tục kết nối"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Đã chuyển sang <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Thiết bị sử dụng <xliff:g id="NEW_NETWORK">%1$s</xliff:g> khi <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> không có quyền truy cập Internet. Bạn có thể phải trả phí."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Đã chuyển từ <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> sang <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"dữ liệu di động"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"Bluetooth"</item>
- <item msgid="1160736166977503463">"Ethernet"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"loại mạng không xác định"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rCN/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 9d6cff9..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"系统网络连接资源"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"登录到WLAN网络"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"登录到网络"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 无法访问互联网"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"点按即可查看相关选项"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"此移动网络无法访问互联网"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"此网络无法访问互联网"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"无法访问私人 DNS 服务器"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 的连接受限"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"点按即可继续连接"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"已切换至<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"设备会在<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>无法访问互联网时使用<xliff:g id="NEW_NETWORK">%1$s</xliff:g>(可能需要支付相应的费用)。"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"已从<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>切换至<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"移动数据"</item>
- <item msgid="6341719431034774569">"WLAN"</item>
- <item msgid="5081440868800877512">"蓝牙"</item>
- <item msgid="1160736166977503463">"以太网"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"未知网络类型"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rHK/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rHK/strings.xml
deleted file mode 100644
index c84241c..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"系統連線資源"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"登入 Wi-Fi 網絡"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"登入網絡"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>未有連接至互聯網"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"輕按即可查看選項"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"流動網絡並未連接互聯網"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"網絡並未連接互聯網"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"無法存取私人 DNS 伺服器"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>連線受限"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"仍要輕按以連結至此網絡"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"已切換至<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"裝置會在 <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> 無法連線至互聯網時使用<xliff:g id="NEW_NETWORK">%1$s</xliff:g> (可能需要支付相關費用)。"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"已從<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>切換至<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"流動數據"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"藍牙"</item>
- <item msgid="1160736166977503463">"以太網絡"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"不明網絡類型"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rTW/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 07540d1..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"系統連線資源"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"登入 Wi-Fi 網路"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"登入網路"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 沒有網際網路連線"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"輕觸即可查看選項"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"這個行動網路沒有網際網路連線"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"這個網路沒有網際網路連線"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"無法存取私人 DNS 伺服器"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 的連線能力受限"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"輕觸即可繼續連線"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"已切換至<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"裝置會在無法連上「<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>」時切換至「<xliff:g id="NEW_NETWORK">%1$s</xliff:g>」(可能需要支付相關費用)。"</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"已從 <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> 切換至<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"行動數據"</item>
- <item msgid="6341719431034774569">"Wi-Fi"</item>
- <item msgid="5081440868800877512">"藍牙"</item>
- <item msgid="1160736166977503463">"乙太網路"</item>
- <item msgid="7347618872551558605">"VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"不明的網路類型"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zu/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zu/strings.xml
deleted file mode 100644
index 19f390b..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zu/strings.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="connectivityResourcesAppLabel" msgid="8294935652079168395">"Izinsiza Zokuxhumeka Zesistimu"</string>
- <string name="wifi_available_sign_in" msgid="5254156478006453593">"Ngena ngemvume kunethiwekhi ye-Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="7794369329839408792">"Ngena ngemvume kunethiwekhi"</string>
- <!-- no translation found for network_available_sign_in_detailed (3643910593681893097) -->
- <skip />
- <string name="wifi_no_internet" msgid="3961697321010262514">"I-<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ayinakho ukufinyelela kwe-inthanethi"</string>
- <string name="wifi_no_internet_detailed" msgid="1229067002306296104">"Thepha ukuze uthole izinketho"</string>
- <string name="mobile_no_internet" msgid="2262524005014119639">"Inethiwekhi yeselula ayinakho ukufinyelela kwe-inthanethi"</string>
- <string name="other_networks_no_internet" msgid="8226004998719563755">"Inethiwekhi ayinakho ukufinyelela kwenethiwekhi"</string>
- <string name="private_dns_broken_detailed" msgid="3537567373166991809">"Iseva eyimfihlo ye-DNS ayikwazi ukufinyelelwa"</string>
- <string name="network_partial_connectivity" msgid="5957065286265771273">"I-<xliff:g id="NETWORK_SSID">%1$s</xliff:g> inokuxhumeka okukhawulelwe"</string>
- <string name="network_partial_connectivity_detailed" msgid="6975752539442533034">"Thepha ukuze uxhume noma kunjalo"</string>
- <string name="network_switch_metered" msgid="2814798852883117872">"Kushintshelwe ku-<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="605546931076348229">"Idivayisi isebenzisa i-<xliff:g id="NEW_NETWORK">%1$s</xliff:g> uma i-<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> inganakho ukufinyelela kwe-inthanethi. Kungasebenza izindleko."</string>
- <string name="network_switch_metered_toast" msgid="8831325515040986641">"Kushintshelewe kusuka ku-<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> kuya ku-<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
- <string-array name="network_switch_type_name">
- <item msgid="5454013645032700715">"idatha yeselula"</item>
- <item msgid="6341719431034774569">"I-Wi-Fi"</item>
- <item msgid="5081440868800877512">"I-Bluetooth"</item>
- <item msgid="1160736166977503463">"I-Ethernet"</item>
- <item msgid="7347618872551558605">"I-VPN"</item>
- </string-array>
- <string name="network_switch_type_name_unknown" msgid="7826330274368951740">"uhlobo olungaziwa lwenethiwekhi"</string>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml
deleted file mode 100644
index 70ddb9a..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml
+++ /dev/null
@@ -1,114 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ 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.
- -->
-
-<!-- Configuration values for ConnectivityService
- DO NOT EDIT THIS FILE for specific device configuration; instead, use a Runtime Resources
- Overlay package following the overlayable.xml configuration in the same directory:
- https://source.android.com/devices/architecture/rros -->
-<resources>
-
- <!-- Configuration hook for the URL returned by ConnectivityManager#getCaptivePortalServerUrl.
- If empty, the returned value is controlled by Settings.Global.CAPTIVE_PORTAL_HTTP_URL,
- and if that value is empty, the framework will use a hard-coded default.
- This is *NOT* a URL that will always be used by the system network validation to detect
- captive portals: NetworkMonitor may use different strategies and will not necessarily use
- this URL. NetworkMonitor behaviour should be configured with NetworkStack resource overlays
- instead. -->
- <!--suppress CheckTagEmptyBody -->
- <string translatable="false" name="config_networkCaptivePortalServerUrl"></string>
-
- <!-- The maximum duration (in milliseconds) we expect a network transition to take -->
- <integer name="config_networkTransitionTimeout">60000</integer>
-
- <!-- Configuration of network interfaces that support WakeOnLAN -->
- <string-array translatable="false" name="config_wakeonlan_supported_interfaces">
- <!--
- <item>wlan0</item>
- <item>eth0</item>
- -->
- </string-array>
-
- <string-array translatable="false" name="config_legacy_networktype_restore_timers">
- <item>2,60000</item><!-- mobile_mms -->
- <item>3,60000</item><!-- mobile_supl -->
- <item>4,60000</item><!-- mobile_dun -->
- <item>5,60000</item><!-- mobile_hipri -->
- <item>10,60000</item><!-- mobile_fota -->
- <item>11,60000</item><!-- mobile_ims -->
- <item>12,60000</item><!-- mobile_cbs -->
- </string-array>
-
- <!-- Default supported concurrent socket keepalive slots per transport type, used by
- ConnectivityManager.createSocketKeepalive() for calculating the number of keepalive
- offload slots that should be reserved for privileged access. This string array should be
- overridden by the device to present the capability of creating socket keepalives. -->
- <!-- An Array of "[NetworkCapabilities.TRANSPORT_*],[supported keepalives] -->
- <string-array translatable="false" name="config_networkSupportedKeepaliveCount">
- <item>0,1</item>
- <item>1,3</item>
- </string-array>
-
- <!-- Reserved privileged keepalive slots per transport. -->
- <integer translatable="false" name="config_reservedPrivilegedKeepaliveSlots">2</integer>
-
- <!-- Allowed unprivileged keepalive slots per uid. -->
- <integer translatable="false" name="config_allowedUnprivilegedKeepalivePerUid">2</integer>
-
- <!-- Default value for ConnectivityManager.getMultipathPreference() on metered networks. Actual
- device behaviour is controlled by the metered multipath preference in
- ConnectivitySettingsManager. This is the default value of that setting. -->
- <integer translatable="false" name="config_networkMeteredMultipathPreference">0</integer>
-
- <!-- Whether the device should automatically switch away from Wi-Fi networks that lose
- Internet access. Actual device behaviour is controlled by
- Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. -->
- <integer translatable="false" name="config_networkAvoidBadWifi">1</integer>
-
- <!-- Array of ConnectivityManager.TYPE_xxxx constants for networks that may only
- be controlled by systemOrSignature apps. -->
- <integer-array translatable="false" name="config_protectedNetworks">
- <item>10</item>
- <item>11</item>
- <item>12</item>
- <item>14</item>
- <item>15</item>
- </integer-array>
-
- <!-- Whether the internal vehicle network should remain active even when no
- apps requested it. -->
- <bool name="config_vehicleInternalNetworkAlwaysRequested">false</bool>
-
-
- <!-- If the hardware supports specially marking packets that caused a wakeup of the
- main CPU, set this value to the mark used. -->
- <integer name="config_networkWakeupPacketMark">0</integer>
-
- <!-- Mask to use when checking skb mark defined in config_networkWakeupPacketMark above. -->
- <integer name="config_networkWakeupPacketMask">0</integer>
-
- <!-- Whether/how to notify the user on network switches. See LingerMonitor.java. -->
- <integer translatable="false" name="config_networkNotifySwitchType">0</integer>
-
- <!-- What types of network switches to notify. See LingerMonitor.java. -->
- <string-array translatable="false" name="config_networkNotifySwitches">
- </string-array>
-
- <!-- Whether to use an ongoing notification for signing in to captive portals, instead of a
- notification that can be dismissed. -->
- <bool name="config_ongoingSignInNotification">false</bool>
-
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml
deleted file mode 100644
index fd23566..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <overlayable name="ServiceConnectivityResourcesConfig">
- <policy type="product|system|vendor">
- <!-- Configuration values for ConnectivityService -->
- <item type="array" name="config_legacy_networktype_restore_timers"/>
- <item type="string" name="config_networkCaptivePortalServerUrl"/>
- <item type="integer" name="config_networkTransitionTimeout"/>
- <item type="array" name="config_wakeonlan_supported_interfaces"/>
- <item type="integer" name="config_networkMeteredMultipathPreference"/>
- <item type="array" name="config_networkSupportedKeepaliveCount"/>
- <item type="integer" name="config_networkAvoidBadWifi"/>
- <item type="array" name="config_protectedNetworks"/>
- <item type="bool" name="config_vehicleInternalNetworkAlwaysRequested"/>
- <item type="integer" name="config_networkWakeupPacketMark"/>
- <item type="integer" name="config_networkWakeupPacketMask"/>
- <item type="integer" name="config_networkNotifySwitchType"/>
- <item type="array" name="config_networkNotifySwitches"/>
- <item type="bool" name="config_ongoingSignInNotification"/>
-
- </policy>
- </overlayable>
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/strings.xml
deleted file mode 100644
index b2fa5f5..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values/strings.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ 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.
- -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- The System Connectivity Resources package is an internal system package that provides
- configuration values for system networking that were pre-configured in the device. This
- is the name of the package to display in the list of system apps. [CHAR LIMIT=40] -->
- <string name="connectivityResourcesAppLabel">System Connectivity Resources</string>
-
- <!-- A notification is shown when a wifi captive portal network is detected. This is the notification's title. -->
- <string name="wifi_available_sign_in">Sign in to Wi-Fi network</string>
-
- <!-- A notification is shown when a captive portal network is detected. This is the notification's title. -->
- <string name="network_available_sign_in">Sign in to network</string>
-
- <!-- A notification is shown when a captive portal network is detected. This is the notification's message. -->
- <string name="network_available_sign_in_detailed"><xliff:g id="network_ssid">%1$s</xliff:g></string>
-
- <!-- A notification is shown when the user connects to a Wi-Fi network and the system detects that that network has no Internet access. This is the notification's title. -->
- <string name="wifi_no_internet"><xliff:g id="network_ssid" example="GoogleGuest">%1$s</xliff:g> has no internet access</string>
-
- <!-- A notification is shown when the user connects to a Wi-Fi network and the system detects that that network has no Internet access. This is the notification's message. -->
- <string name="wifi_no_internet_detailed">Tap for options</string>
-
- <!-- A notification is shown when the user connects to a mobile network without internet access. This is the notification's title. -->
- <string name="mobile_no_internet">Mobile network has no internet access</string>
-
- <!-- A notification is shown when the user connects to a non-mobile and non-wifi network without internet access. This is the notification's title. -->
- <string name="other_networks_no_internet">Network has no internet access</string>
-
- <!-- A notification is shown when connected network without internet due to private dns validation failed. This is the notification's message. [CHAR LIMIT=NONE] -->
- <string name="private_dns_broken_detailed">Private DNS server cannot be accessed</string>
-
- <!-- A notification is shown when the user connects to a network that doesn't have access to some services (e.g. Push notifications may not work). This is the notification's title. [CHAR LIMIT=50] -->
- <string name="network_partial_connectivity"><xliff:g id="network_ssid" example="GoogleGuest">%1$s</xliff:g> has limited connectivity</string>
-
- <!-- A notification is shown when the user connects to a network that doesn't have access to some services (e.g. Push notifications may not work). This is the notification's message. [CHAR LIMIT=50] -->
- <string name="network_partial_connectivity_detailed">Tap to connect anyway</string>
-
- <!-- A notification might be shown if the device switches to another network type (e.g., mobile data) because it detects that the network it was using (e.g., Wi-Fi) has lost Internet connectivity. This is the notification's title. %1$s is the network type that the device switched to, e.g., cellular data. It is one of the strings in the network_switch_type_name array. -->
- <string name="network_switch_metered">Switched to <xliff:g id="network_type">%1$s</xliff:g></string>
-
- <!-- A notification might be shown if the device switches to another network type (e.g., mobile data) because it detects that the network it was using (e.g., Wi-Fi) has lost Internet connectivity. This is the notification's message. %1$s is the network that the device switched to, e.g., cellular data. %2$s is the network type the device switched from, e.g., Wi-Fi. Both are strings in the network_switch_type_name array. -->
- <string name="network_switch_metered_detail">Device uses <xliff:g id="new_network">%1$s</xliff:g> when <xliff:g id="previous_network">%2$s</xliff:g> has no internet access. Charges may apply.</string>
-
- <!-- A toast might be shown if the device switches to another network type (e.g., mobile data) because it detects that the network it was using (e.g., Wi-Fi) has lost Internet connectivity. This is the text of the toast. %1$s is the network that the device switched from, e.g., Wi-Fi. %2$s is the network type the device switched from, e.g., cellular data. Both are strings in the network_switch_type_name array. -->
- <string name="network_switch_metered_toast">Switched from <xliff:g id="previous_network">%1$s</xliff:g> to <xliff:g id="new_network">%2$s</xliff:g></string>
-
- <!-- Network type names used in the network_switch_metered and network_switch_metered_detail strings. These must be kept in the sync with the values NetworkCapabilities.TRANSPORT_xxx values, and in the same order. -->
- <string-array name="network_switch_type_name">
- <item>mobile data</item>
- <item>Wi-Fi</item>
- <item>Bluetooth</item>
- <item>Ethernet</item>
- <item>VPN</item>
- </string-array>
-
- <!-- Network type name displayed if one of the types is not found in network_switch_type_name. -->
- <string name="network_switch_type_name_unknown">an unknown network type</string>
-
-</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/resources-certs/com.android.connectivity.resources.pk8 b/packages/Connectivity/service/ServiceConnectivityResources/resources-certs/com.android.connectivity.resources.pk8
deleted file mode 100644
index bfdc28b..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/resources-certs/com.android.connectivity.resources.pk8
+++ /dev/null
Binary files differ
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/resources-certs/com.android.connectivity.resources.x509.pem b/packages/Connectivity/service/ServiceConnectivityResources/resources-certs/com.android.connectivity.resources.x509.pem
deleted file mode 100644
index 70eca1c..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/resources-certs/com.android.connectivity.resources.x509.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGQzCCBCugAwIBAgIUZY8nxBMINp/79sziXU77MLPpEXowDQYJKoZIhvcNAQEL
-BQAwga8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMSswKQYDVQQDDCJjb20uYW5kcm9pZC5jb25uZWN0aXZpdHkucmVzb3VyY2Vz
-MSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29tMCAXDTIxMDQyMjA3
-MjkxMFoYDzQ3NTkwMzE5MDcyOTEwWjCBrzELMAkGA1UEBhMCVVMxEzARBgNVBAgM
-CkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB0Fu
-ZHJvaWQxEDAOBgNVBAsMB0FuZHJvaWQxKzApBgNVBAMMImNvbS5hbmRyb2lkLmNv
-bm5lY3Rpdml0eS5yZXNvdXJjZXMxIjAgBgkqhkiG9w0BCQEWE2FuZHJvaWRAYW5k
-cm9pZC5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC361NT9qSz
-h3uLcLBD67HNE1QX3ykwGyw8u7ExzqpsqLCzZsOCFRJQJY+CnrgNaAz0NXeNtx7D
-Lpr9OCWWbG1KTQ/ANlR8g6xCqlAk4xdixsAnIlBUJB90+RlkcWrliEY7OwcqIu3x
-/qe+5UR3irIFZOApNHOm760PjRl7VWAnYZC/PhkW0iKwnBuE96ddPIJc+KuiqCcP
-KflgF4/jmbHTZ+5uvVV4qkfovc744HnQtQoCDoYR8WpsJv3YL5xrAv78o3WCRzx6
-xxB+eUlJpuyyfIee2lUCG4Ly4jgOsWaupnUglLDORnz/L8fhhnpv83wLal7E0Shx
-sqvzZZbb1QLuwMWy++gfzdDvGWewES3BdSFp5NwYWXQGZWSkEEFbIiorKSurU1On
-9OwB0jT/H2B/CAFKYJQ2V+hQ4I7PG+z9p7ZFNR6GZbZuhEr+Dpq1CwtI3W45izr3
-RJgcc2IP6Oj7/XC2MmKGMqZkybBWcvazdyAMHzk9EZIBT2Oru3dnOl3uVUUPeZRs
-xRzqaA0MAlyj+GJ9uziEr3W1j+U1CFEnNWtlD/jqcTAwmaOsn1GhWyMAo1KOrJ/o
-LcJvwk5P/0XEyeli7/DSUpGjYiAgWMHWCOn9s6aYw3YFb+A/SgX3/+FIDib/vHTX
-i76JZfO0CfoKsbFDCH9KOMupHM9EO3ftQwIDAQABo1MwUTAdBgNVHQ4EFgQU/KGg
-gmMqXD5YOe5+B0W+YezN9LcwHwYDVR0jBBgwFoAU/KGggmMqXD5YOe5+B0W+YezN
-9LcwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAhr+AaNaIlRyM
-WKyJ+2Aa35fH5e44Xr/xPpriM5HHxsj0evjMCODqCQ7kzfwSEmtXh5uZYYNKb/JP
-ZMDHIFcYi1QCvm6E6YOd+Qn9CVxrwaDhigJv7ylhVf8q201GTvHhJIU99yFIrzJQ
-RNhxw+pNo7FYMZr3J7JZPAy60DN1KZvRV4FjZx5qiPUMyu4zVygzDkr0v5Ilncdp
-l9VVjOi7ocHyBKI+7RkXl97xN4SUe3vszwZQHCVyVopBw+YrMbDBCrknrQzUEgie
-BuI+kj5oOeiQ0P1i1K+UCCAjrLwhNyc9H02rKUtBHxa2AVjw7YpAJlBesb49Qvq+
-5L6JjHFVSSOEbIjboNib26zNackjbiefF74meSUbGVGfcJ1OdkZsXZWphmER8V7X
-Wz3Z8JwOXW1RLPgcbjilHUR5g8pEmWBv4KrTCSg5IvOJr4w3pyyMBiiVI9NI5sB7
-g5Mi9v3ifPD1OHA4Y3wYCb26mMEpRb8ogOhMHcGNbdnL3QtIUg4cmXGqGSY/LbpU
-np0sIQDSjc46o79F0boPsLlaN3US5WZIu0nc9SHkjoNhd0CJQ5r9aEn4/wNrZgxs
-s8OEKsqcS7OsWiIE6nG51TMDsCuyRBrGedtSUyFFSVSpivpYIrPVNKKlHsJ/o+Nv
-Udb6dBjCraPvJB8binB1aojwya3MwRs=
------END CERTIFICATE-----
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/resources-certs/key.pem b/packages/Connectivity/service/ServiceConnectivityResources/resources-certs/key.pem
deleted file mode 100644
index 38771c2..0000000
--- a/packages/Connectivity/service/ServiceConnectivityResources/resources-certs/key.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQC361NT9qSzh3uL
-cLBD67HNE1QX3ykwGyw8u7ExzqpsqLCzZsOCFRJQJY+CnrgNaAz0NXeNtx7DLpr9
-OCWWbG1KTQ/ANlR8g6xCqlAk4xdixsAnIlBUJB90+RlkcWrliEY7OwcqIu3x/qe+
-5UR3irIFZOApNHOm760PjRl7VWAnYZC/PhkW0iKwnBuE96ddPIJc+KuiqCcPKflg
-F4/jmbHTZ+5uvVV4qkfovc744HnQtQoCDoYR8WpsJv3YL5xrAv78o3WCRzx6xxB+
-eUlJpuyyfIee2lUCG4Ly4jgOsWaupnUglLDORnz/L8fhhnpv83wLal7E0Shxsqvz
-ZZbb1QLuwMWy++gfzdDvGWewES3BdSFp5NwYWXQGZWSkEEFbIiorKSurU1On9OwB
-0jT/H2B/CAFKYJQ2V+hQ4I7PG+z9p7ZFNR6GZbZuhEr+Dpq1CwtI3W45izr3RJgc
-c2IP6Oj7/XC2MmKGMqZkybBWcvazdyAMHzk9EZIBT2Oru3dnOl3uVUUPeZRsxRzq
-aA0MAlyj+GJ9uziEr3W1j+U1CFEnNWtlD/jqcTAwmaOsn1GhWyMAo1KOrJ/oLcJv
-wk5P/0XEyeli7/DSUpGjYiAgWMHWCOn9s6aYw3YFb+A/SgX3/+FIDib/vHTXi76J
-ZfO0CfoKsbFDCH9KOMupHM9EO3ftQwIDAQABAoICAQCXM/GKqtAXBIBOT/Ops0C2
-n3hYM9BRy1UgDRKNJyG3OSwkIY0ECbzHhUmpkkEwTGWx8675JB43Sr6DBUDpnPRw
-zE/xrvjgcQQSvqAq40PbohhhU/WEZzoxWYVFrXS7hcBve4TVYGgMtlZEO4qBWNYo
-Vxlu5r9Z89tsWI0ldzgYyD5O64eG2nVIit6Y/11p6pAmTQ4WKHYMIm7xUA2siTPH
-4L8F7cQx8pQxxLI+q5WaPuweasBQShA7IAc7T1EiLRFitCOsWlJfgf6Oa7oTwhcA
-Wh7JOyf+Fo4ejlqVwcTwOss6YOPGge7LgQWr5HoORbeqTuXgmy/L4Z85+EABNOs1
-5muHZvsuPXSmW6g1bCi8zvQcjFIX31yBVg8zkdG8WRezFxiVlN8UFAx4rwo03aBs
-rDyU4GCxoUBvF/M9534l1gKOyr0hlQ40nQ4kBabbm2wWOKCVzmLEtFmWX9RV0tjX
-pEtTCqgsGlsIypLy21+uow8SBojhkZ+xORCF2XivGu6SKtvwGvjpYXpXrI6DN4Lw
-kH5J5FwSu1SNY8tnIEJEmj8IMTp+Vw20kwNVTcwdC2nJDDiezJum4PqZRdWIuupm
-BWzXD3fvMXqHmT02sJTQ+FRAgiQLLWDzNAYMJUofzuIwycs4iO9MOPHjkHScvk4N
-FXLrzFBSbdw+wi1DdzzMuQKCAQEA5wx07O5bHBHybs6tpwuZ0TuJ3OIVXh/ocNVR
-gSOCSMirv+K4u3jToXwjfTXUc9lcn+DenZPpGmUWF0sZ83ytZm1eFVgGZpP6941C
-waSeb8zGsgbEyZIQTVILfgtyPDwdtgu0d1Ip+ppj9czXmnxMY/ruHOX1Do1UfZoA
-UA1ytHJSjFKU6saAhHrdk91soTVzc/E3uo7U4Ff0L8/3tT3DAEFYxDXUCH8W2IZZ
-6zVvlqnPH4elxsPYM6rtIwq52reOTLNxC+SFSamK/82zu09Kjj5sQ6HKlvKJFiL5
-bULWu4lenoDfEN0lng+QopJTgZq4/tgOLum43C/Zd0PGC9R6PwKCAQEAy8fvPqwM
-gPbNasni9qGVG+FfiFd/wEMlgKlVVqi+WzF6tCAnXCQXXg3A7FpLQrX8hVKdMznq
-wPgM5AXP4FOguBFNk65chZmPizBIUDPJ4TNHI8FcGgcxbKGvDdVHsUpa/h5rJlvV
-GLJTKV4KjcsTjl5tlRsJ48bSfpBNQHpSKlCswT6jjteiDY6Rln0GFKQIKDHqp3I6
-Zn1E4yfdiIz9VnMPfg1fbjBeR7s1zNzlrR8Dv9oK9tkzI5G1wSbdzksg2O1q2tvg
-WrZrTAA3Uw6sPUMft0vk5Jw6a6CLkrcfayv3xDHwvM/4P3HgP8j9WQ8at8ttHpfD
-oWyt3fZ3pBuj/QKCAQANqxH7tjoTlgg2f+mL+Ua3NwN32rQS5mZUznnM3vHlJmHq
-rxnolURHyFU9IgMYe2JcXuwsfESM+C/vXtUBL33+kje/oX53cQemv2eUlw18ZavX
-ekkH96kZOeJOKZUvdQr46wZZDLZJCfsh3mVe0T2fqIePlBcELl4yM/sSwUjo3d5+
-SKBgpy+RJseW6MF1Y/kZgcqfMbXsM6fRcEciJK41hKggq2KIwiPy2TfWj0mzqwYC
-wn6PHKTcoZ73tLm786Hqba8hWfp8mhgL+/pG+XDaq1yyP48BkQWFFrqUuSCE5aKA
-U/VeRQblq9wNkgR4pVOOV++23MK/2+DMimjb6Ez3AoIBABIXK7wKlgmU32ONjKKM
-capJ9asq6WJuE5Q6dCL/U/bQi64V9KiPY6ur2OailW/UrBhB30a+64I6AxrzESM/
-CVON5a8omXoayc13edP05QUjAjvAXKbK4K5eJCY8OuMYUL+if6ymFmLc4dkYSiOQ
-Vaob4+qKvfQEoIcv1EvXEBhFlTCKmQaDShWeBHqxmqqWbUr0M3qt/1U95bGsxlPr
-AEp+aG+uTDyB+ryvd/U53wHhcPnFJ5gGbC3KL7J3+tTngoD/gq7vOhmTfC8BDehH
-sy61GMmy6R0KaX1IgVuC+j0PaC14qYB5jfZD675930/asWqDmqpOmsVn2n+L888T
-zRkCggEBAIMuNhhfGGY6E4PLUcPM0LZA4tI/wTpeYEahunU1hWIYo/iZB9od2biz
-EeYY4BtkzCoE5ZWYXqTgiMxN4hJ4ufB+5umZ4BO0Gyx4p2/Ik2uv1BXu++GbM+TI
-eeFmaBh00dTtjccpeZEDgNkjAO7Rh9GV2ifl3uhqg0MnFXywPUX2Vm2bmwQXnfV9
-wY2TXgOmBN2epFBOArJwiA5IfV+bSqXCFCx8fgyOWpMNq9+zDRd6KCeHyge54ahm
-jMhCncp1OPDPaV+gnUdgWDGcywYg0KQvu5dLuCFfvucnsWoH2txsVZrXFha5XSM4
-/4Pif3Aj5E9dm1zkUtZJYQbII5SKQ94=
------END PRIVATE KEY-----
diff --git a/packages/Connectivity/service/jarjar-rules.txt b/packages/Connectivity/service/jarjar-rules.txt
deleted file mode 100644
index 5caa11b..0000000
--- a/packages/Connectivity/service/jarjar-rules.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-rule android.sysprop.** com.android.connectivity.sysprop.@1
-rule com.android.net.module.util.** com.android.connectivity.net-utils.@1
-rule com.android.modules.utils.** com.android.connectivity.modules-utils.@1
-
-# internal util classes
-# Exclude AsyncChannel. TODO: remove AsyncChannel usage in ConnectivityService
-rule com.android.internal.util.AsyncChannel* @0
-# Exclude LocationPermissionChecker. This is going to be moved to libs/net
-rule com.android.internal.util.LocationPermissionChecker* @0
-rule android.util.LocalLog* com.android.connectivity.util.LocalLog@1
-# android.util.IndentingPrintWriter* should use a different package name from
-# the one in com.android.internal.util
-rule android.util.IndentingPrintWriter* android.connectivity.util.IndentingPrintWriter@1
-rule com.android.internal.util.** com.android.connectivity.util.@1
-
-rule com.android.internal.messages.** com.android.connectivity.messages.@1
-rule com.google.protobuf.** com.android.connectivity.protobuf.@1
diff --git a/packages/Connectivity/service/jni/com_android_server_TestNetworkService.cpp b/packages/Connectivity/service/jni/com_android_server_TestNetworkService.cpp
deleted file mode 100644
index e7a40e5..0000000
--- a/packages/Connectivity/service/jni/com_android_server_TestNetworkService.cpp
+++ /dev/null
@@ -1,104 +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.
- */
-
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "TestNetworkServiceJni"
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#include <linux/ipv6_route.h>
-#include <linux/route.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <log/log.h>
-
-#include "jni.h"
-#include <android-base/stringprintf.h>
-#include <android-base/unique_fd.h>
-#include <nativehelper/JNIHelp.h>
-#include <nativehelper/ScopedUtfChars.h>
-
-namespace android {
-
-//------------------------------------------------------------------------------
-
-static void throwException(JNIEnv* env, int error, const char* action, const char* iface) {
- const std::string& msg = "Error: " + std::string(action) + " " + std::string(iface) + ": "
- + std::string(strerror(error));
- jniThrowException(env, "java/lang/IllegalStateException", msg.c_str());
-}
-
-static int createTunTapInterface(JNIEnv* env, bool isTun, const char* iface) {
- base::unique_fd tun(open("/dev/tun", O_RDWR | O_NONBLOCK));
- ifreq ifr{};
-
- // Allocate interface.
- ifr.ifr_flags = (isTun ? IFF_TUN : IFF_TAP) | IFF_NO_PI;
- strlcpy(ifr.ifr_name, iface, IFNAMSIZ);
- if (ioctl(tun.get(), TUNSETIFF, &ifr)) {
- throwException(env, errno, "allocating", ifr.ifr_name);
- return -1;
- }
-
- // Activate interface using an unconnected datagram socket.
- base::unique_fd inet6CtrlSock(socket(AF_INET6, SOCK_DGRAM, 0));
- ifr.ifr_flags = IFF_UP;
-
- if (ioctl(inet6CtrlSock.get(), SIOCSIFFLAGS, &ifr)) {
- throwException(env, errno, "activating", ifr.ifr_name);
- return -1;
- }
-
- return tun.release();
-}
-
-//------------------------------------------------------------------------------
-
-static jint create(JNIEnv* env, jobject /* thiz */, jboolean isTun, jstring jIface) {
- ScopedUtfChars iface(env, jIface);
- if (!iface.c_str()) {
- jniThrowNullPointerException(env, "iface");
- return -1;
- }
-
- int tun = createTunTapInterface(env, isTun, iface.c_str());
-
- // Any exceptions will be thrown from the createTunTapInterface call
- return tun;
-}
-
-//------------------------------------------------------------------------------
-
-static const JNINativeMethod gMethods[] = {
- {"jniCreateTunTap", "(ZLjava/lang/String;)I", (void*)create},
-};
-
-int register_android_server_TestNetworkService(JNIEnv* env) {
- return jniRegisterNativeMethods(env, "com/android/server/TestNetworkService", gMethods,
- NELEM(gMethods));
-}
-
-}; // namespace android
diff --git a/packages/Connectivity/service/jni/onload.cpp b/packages/Connectivity/service/jni/onload.cpp
deleted file mode 100644
index 0012879..0000000
--- a/packages/Connectivity/service/jni/onload.cpp
+++ /dev/null
@@ -1,38 +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.
- */
-
-#include <nativehelper/JNIHelp.h>
-#include <log/log.h>
-
-namespace android {
-
-int register_android_server_TestNetworkService(JNIEnv* env);
-
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
- JNIEnv *env;
- if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
- ALOGE("GetEnv failed");
- return JNI_ERR;
- }
-
- if (register_android_server_TestNetworkService(env) < 0) {
- return JNI_ERR;
- }
-
- return JNI_VERSION_1_6;
-}
-
-};
diff --git a/packages/Connectivity/service/lint-baseline.xml b/packages/Connectivity/service/lint-baseline.xml
deleted file mode 100644
index 95c169c..0000000
--- a/packages/Connectivity/service/lint-baseline.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 30): `android.telephony.TelephonyManager#isDataCapable`"
- errorLine1=" if (tm.isDataCapable()) {"
- errorLine2=" ~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/Connectivity/service/src/com/android/server/ConnectivityService.java"
- line="787"
- column="20"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 30): `android.content.Context#sendStickyBroadcast`"
- errorLine1=" mUserAllContext.sendStickyBroadcast(intent, options);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/Connectivity/service/src/com/android/server/ConnectivityService.java"
- line="2681"
- column="33"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 30): `android.content.pm.PackageManager#getTargetSdkVersion`"
- errorLine1=" final int callingVersion = pm.getTargetSdkVersion(callingPackageName);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/packages/Connectivity/service/src/com/android/server/ConnectivityService.java"
- line="5851"
- column="43"/>
- </issue>
-
-</issues>
diff --git a/packages/Connectivity/service/proto/connectivityproto.proto b/packages/Connectivity/service/proto/connectivityproto.proto
deleted file mode 100644
index a992d7c..0000000
--- a/packages/Connectivity/service/proto/connectivityproto.proto
+++ /dev/null
@@ -1,20 +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.
- */
-
-syntax = "proto2";
-
-// Connectivity protos can be created in this directory. Note this file must be included before
-// building system-messages-proto, otherwise it will not build by itself.
diff --git a/packages/Connectivity/service/src/com/android/server/ConnectivityService.java b/packages/Connectivity/service/src/com/android/server/ConnectivityService.java
deleted file mode 100644
index 5c47f27..0000000
--- a/packages/Connectivity/service/src/com/android/server/ConnectivityService.java
+++ /dev/null
@@ -1,10077 +0,0 @@
-/*
- * Copyright (C) 2008 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.RECEIVE_DATA_ACTIVITY_CHANGE;
-import static android.content.pm.PackageManager.FEATURE_BLUETOOTH;
-import static android.content.pm.PackageManager.FEATURE_WATCH;
-import static android.content.pm.PackageManager.FEATURE_WIFI;
-import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK;
-import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_SUCCEEDED_BITMASK;
-import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_VALIDATION_RESULT;
-import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_DNS_EVENTS;
-import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_TCP_METRICS;
-import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS;
-import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
-import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE;
-import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
-import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN;
-import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
-import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
-import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
-import static android.net.ConnectivityManager.TYPE_ETHERNET;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_MOBILE_CBS;
-import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
-import static android.net.ConnectivityManager.TYPE_MOBILE_EMERGENCY;
-import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA;
-import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
-import static android.net.ConnectivityManager.TYPE_MOBILE_IA;
-import static android.net.ConnectivityManager.TYPE_MOBILE_IMS;
-import static android.net.ConnectivityManager.TYPE_MOBILE_MMS;
-import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL;
-import static android.net.ConnectivityManager.TYPE_NONE;
-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.ConnectivityManager.TYPE_WIFI_P2P;
-import static android.net.ConnectivityManager.getNetworkTypeName;
-import static android.net.ConnectivityManager.isNetworkTypeValid;
-import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
-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_CAPTIVE_PORTAL;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-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_VALIDATED;
-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.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_TEST;
-import static android.net.NetworkCapabilities.TRANSPORT_VPN;
-import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
-import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired;
-import static android.os.Process.INVALID_UID;
-import static android.os.Process.VPN_UID;
-import static android.system.OsConstants.IPPROTO_TCP;
-import static android.system.OsConstants.IPPROTO_UDP;
-
-import static java.util.Map.Entry;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.AppOpsManager;
-import android.app.BroadcastOptions;
-import android.app.PendingIntent;
-import android.app.usage.NetworkStatsManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.database.ContentObserver;
-import android.net.CaptivePortal;
-import android.net.CaptivePortalData;
-import android.net.ConnectionInfo;
-import android.net.ConnectivityAnnotations.RestrictBackgroundStatus;
-import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
-import android.net.ConnectivityDiagnosticsManager.DataStallReport;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.BlockedReason;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.ConnectivityResources;
-import android.net.ConnectivitySettingsManager;
-import android.net.DataStallReportParcelable;
-import android.net.DnsResolverServiceManager;
-import android.net.ICaptivePortal;
-import android.net.IConnectivityDiagnosticsCallback;
-import android.net.IConnectivityManager;
-import android.net.IDnsResolver;
-import android.net.INetd;
-import android.net.INetworkActivityListener;
-import android.net.INetworkAgent;
-import android.net.INetworkMonitor;
-import android.net.INetworkMonitorCallbacks;
-import android.net.INetworkOfferCallback;
-import android.net.IOnCompleteListener;
-import android.net.IQosCallback;
-import android.net.ISocketKeepaliveCallback;
-import android.net.InetAddresses;
-import android.net.IpMemoryStore;
-import android.net.IpPrefix;
-import android.net.LinkProperties;
-import android.net.MatchAllNetworkSpecifier;
-import android.net.NativeNetworkConfig;
-import android.net.NativeNetworkType;
-import android.net.NattSocketKeepalive;
-import android.net.Network;
-import android.net.NetworkAgent;
-import android.net.NetworkAgentConfig;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkMonitorManager;
-import android.net.NetworkPolicyManager;
-import android.net.NetworkPolicyManager.NetworkPolicyCallback;
-import android.net.NetworkProvider;
-import android.net.NetworkRequest;
-import android.net.NetworkScore;
-import android.net.NetworkSpecifier;
-import android.net.NetworkStack;
-import android.net.NetworkState;
-import android.net.NetworkStateSnapshot;
-import android.net.NetworkTestResultParcelable;
-import android.net.NetworkUtils;
-import android.net.NetworkWatchlistManager;
-import android.net.OemNetworkPreferences;
-import android.net.PrivateDnsConfigParcel;
-import android.net.ProxyInfo;
-import android.net.QosCallbackException;
-import android.net.QosFilter;
-import android.net.QosSocketFilter;
-import android.net.QosSocketInfo;
-import android.net.RouteInfo;
-import android.net.RouteInfoParcel;
-import android.net.SocketKeepalive;
-import android.net.TetheringManager;
-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.metrics.NetworkEvent;
-import android.net.netlink.InetDiagMessage;
-import android.net.networkstack.ModuleNetworkStackClient;
-import android.net.networkstack.NetworkStackClientBase;
-import android.net.resolv.aidl.DnsHealthEventParcel;
-import android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener;
-import android.net.resolv.aidl.Nat64PrefixEventParcel;
-import android.net.resolv.aidl.PrivateDnsValidationEventParcel;
-import android.net.shared.PrivateDnsConfig;
-import android.net.util.MultinetworkPolicyTracker;
-import android.os.BatteryStatsManager;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-import android.os.PowerManager;
-import android.os.Process;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.sysprop.NetworkProperties;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.LocalLog;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-import android.util.SparseIntArray;
-
-import com.android.connectivity.resources.R;
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.MessageUtils;
-import com.android.modules.utils.BasicShellCommandHandler;
-import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
-import com.android.net.module.util.CollectionUtils;
-import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
-import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
-import com.android.net.module.util.LocationPermissionChecker;
-import com.android.net.module.util.NetworkCapabilitiesUtils;
-import com.android.net.module.util.PermissionUtils;
-import com.android.server.connectivity.AutodestructReference;
-import com.android.server.connectivity.DnsManager;
-import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
-import com.android.server.connectivity.FullScore;
-import com.android.server.connectivity.KeepaliveTracker;
-import com.android.server.connectivity.LingerMonitor;
-import com.android.server.connectivity.MockableSystemProperties;
-import com.android.server.connectivity.NetworkAgentInfo;
-import com.android.server.connectivity.NetworkDiagnostics;
-import com.android.server.connectivity.NetworkNotificationManager;
-import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
-import com.android.server.connectivity.NetworkOffer;
-import com.android.server.connectivity.NetworkRanker;
-import com.android.server.connectivity.PermissionMonitor;
-import com.android.server.connectivity.ProfileNetworkPreferences;
-import com.android.server.connectivity.ProxyTracker;
-import com.android.server.connectivity.QosCallbackTracker;
-
-import libcore.io.IoUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.ConcurrentModificationException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.StringJoiner;
-import java.util.TreeSet;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * @hide
- */
-public class ConnectivityService extends IConnectivityManager.Stub
- implements PendingIntent.OnFinished {
- private static final String TAG = ConnectivityService.class.getSimpleName();
-
- private static final String DIAG_ARG = "--diag";
- public static final String SHORT_ARG = "--short";
- private static final String NETWORK_ARG = "networks";
- private static final String REQUEST_ARG = "requests";
-
- private static final boolean DBG = true;
- private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG);
- private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
-
- private static final boolean LOGD_BLOCKED_NETWORKINFO = true;
-
- /**
- * Default URL to use for {@link #getCaptivePortalServerUrl()}. This should not be changed
- * by OEMs for configuration purposes, as this value is overridden by
- * ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL.
- * R.string.config_networkCaptivePortalServerUrl should be overridden instead for this purpose
- * (preferably via runtime resource overlays).
- */
- private static final String DEFAULT_CAPTIVE_PORTAL_HTTP_URL =
- "http://connectivitycheck.gstatic.com/generate_204";
-
- // TODO: create better separation between radio types and network types
-
- // how long to wait before switching back to a radio's default network
- private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000;
- // system property that can override the above value
- private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
- "android.telephony.apn-restore";
-
- // How long to wait before putting up a "This network doesn't have an Internet connection,
- // connect anyway?" dialog after the user selects a network that doesn't validate.
- private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000;
-
- // Default to 30s linger time-out, and 5s for nascent network. Modifiable only for testing.
- private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger";
- private static final int DEFAULT_LINGER_DELAY_MS = 30_000;
- private static final int DEFAULT_NASCENT_DELAY_MS = 5_000;
-
- // The maximum number of network request allowed per uid before an exception is thrown.
- private static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
-
- // The maximum number of network request allowed for system UIDs before an exception is thrown.
- @VisibleForTesting
- static final int MAX_NETWORK_REQUESTS_PER_SYSTEM_UID = 250;
-
- @VisibleForTesting
- protected int mLingerDelayMs; // Can't be final, or test subclass constructors can't change it.
- @VisibleForTesting
- protected int mNascentDelayMs;
-
- // How long to delay to removal of a pending intent based request.
- // See ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS
- private final int mReleasePendingIntentDelayMs;
-
- private MockableSystemProperties mSystemProperties;
-
- @VisibleForTesting
- protected final PermissionMonitor mPermissionMonitor;
-
- private final PerUidCounter mNetworkRequestCounter;
- @VisibleForTesting
- final PerUidCounter mSystemNetworkRequestCounter;
-
- private volatile boolean mLockdownEnabled;
-
- /**
- * Stale copy of uid blocked reasons provided by NPMS. As long as they are accessed only in
- * internal handler thread, they don't need a lock.
- */
- private SparseIntArray mUidBlockedReasons = new SparseIntArray();
-
- private final Context mContext;
- private final ConnectivityResources mResources;
- // The Context is created for UserHandle.ALL.
- private final Context mUserAllContext;
- private final Dependencies mDeps;
- // 0 is full bad, 100 is full good
- private int mDefaultInetConditionPublished = 0;
-
- @VisibleForTesting
- protected IDnsResolver mDnsResolver;
- @VisibleForTesting
- protected INetd mNetd;
- private NetworkStatsManager mStatsManager;
- private NetworkPolicyManager mPolicyManager;
- private final NetdCallback mNetdCallback;
-
- /**
- * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple
- * instances.
- */
- @GuardedBy("mTNSLock")
- private TestNetworkService mTNS;
-
- private final Object mTNSLock = new Object();
-
- private String mCurrentTcpBufferSizes;
-
- private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(
- new Class[] { ConnectivityService.class, NetworkAgent.class, NetworkAgentInfo.class });
-
- private enum ReapUnvalidatedNetworks {
- // Tear down networks that have no chance (e.g. even if validated) of becoming
- // the highest scoring network satisfying a NetworkRequest. This should be passed when
- // all networks have been rematched against all NetworkRequests.
- REAP,
- // Don't reap networks. This should be passed when some networks have not yet been
- // rematched against all NetworkRequests.
- DONT_REAP
- }
-
- private enum UnneededFor {
- LINGER, // Determine whether this network is unneeded and should be lingered.
- TEARDOWN, // Determine whether this network is unneeded and should be torn down.
- }
-
- /**
- * used internally to clear a wakelock when transitioning
- * from one net to another. Clear happens when we get a new
- * network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens
- * after a timeout if no network is found (typically 1 min).
- */
- private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8;
-
- /**
- * used internally to reload global proxy settings
- */
- private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9;
-
- /**
- * PAC manager has received new port.
- */
- private static final int EVENT_PROXY_HAS_CHANGED = 16;
-
- /**
- * used internally when registering NetworkProviders
- * obj = NetworkProviderInfo
- */
- private static final int EVENT_REGISTER_NETWORK_PROVIDER = 17;
-
- /**
- * used internally when registering NetworkAgents
- * obj = Messenger
- */
- private static final int EVENT_REGISTER_NETWORK_AGENT = 18;
-
- /**
- * used to add a network request
- * includes a NetworkRequestInfo
- */
- private static final int EVENT_REGISTER_NETWORK_REQUEST = 19;
-
- /**
- * indicates a timeout period is over - check if we had a network yet or not
- * and if not, call the timeout callback (but leave the request live until they
- * cancel it.
- * includes a NetworkRequestInfo
- */
- private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20;
-
- /**
- * used to add a network listener - no request
- * includes a NetworkRequestInfo
- */
- private static final int EVENT_REGISTER_NETWORK_LISTENER = 21;
-
- /**
- * used to remove a network request, either a listener or a real request
- * arg1 = UID of caller
- * obj = NetworkRequest
- */
- private static final int EVENT_RELEASE_NETWORK_REQUEST = 22;
-
- /**
- * used internally when registering NetworkProviders
- * obj = Messenger
- */
- private static final int EVENT_UNREGISTER_NETWORK_PROVIDER = 23;
-
- /**
- * used internally to expire a wakelock when transitioning
- * from one net to another. Expire happens when we fail to find
- * a new network (typically after 1 minute) -
- * EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found
- * a replacement network.
- */
- private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24;
-
- /**
- * used to add a network request with a pending intent
- * obj = NetworkRequestInfo
- */
- private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26;
-
- /**
- * used to remove a pending intent and its associated network request.
- * arg1 = UID of caller
- * obj = PendingIntent
- */
- private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27;
-
- /**
- * used to specify whether a network should be used even if unvalidated.
- * arg1 = whether to accept the network if it's unvalidated (1 or 0)
- * arg2 = whether to remember this choice in the future (1 or 0)
- * obj = network
- */
- private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28;
-
- /**
- * used to ask the user to confirm a connection to an unvalidated network.
- * obj = network
- */
- private static final int EVENT_PROMPT_UNVALIDATED = 29;
-
- /**
- * used internally to (re)configure always-on networks.
- */
- private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30;
-
- /**
- * used to add a network listener with a pending intent
- * obj = NetworkRequestInfo
- */
- private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
-
- /**
- * used to specify whether a network should not be penalized when it becomes unvalidated.
- */
- private static final int EVENT_SET_AVOID_UNVALIDATED = 35;
-
- /**
- * used to trigger revalidation of a network.
- */
- private static final int EVENT_REVALIDATE_NETWORK = 36;
-
- // Handle changes in Private DNS settings.
- private static final int EVENT_PRIVATE_DNS_SETTINGS_CHANGED = 37;
-
- // Handle private DNS validation status updates.
- private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
-
- /**
- * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has
- * been tested.
- * obj = {@link NetworkTestedResults} representing information sent from NetworkMonitor.
- * data = PersistableBundle of extras passed from NetworkMonitor. If {@link
- * NetworkMonitorCallbacks#notifyNetworkTested} is called, this will be null.
- */
- private static final int EVENT_NETWORK_TESTED = 41;
-
- /**
- * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the private DNS
- * config was resolved.
- * obj = PrivateDnsConfig
- * arg2 = netid
- */
- private static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42;
-
- /**
- * Request ConnectivityService display provisioning notification.
- * arg1 = Whether to make the notification visible.
- * arg2 = NetID.
- * obj = Intent to be launched when notification selected by user, null if !arg1.
- */
- private static final int EVENT_PROVISIONING_NOTIFICATION = 43;
-
- /**
- * Used to specify whether a network should be used even if connectivity is partial.
- * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for
- * false)
- * arg2 = whether to remember this choice in the future (1 for true or 0 for false)
- * obj = network
- */
- private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 44;
-
- /**
- * Event for NetworkMonitor to inform ConnectivityService that the probe status has changed.
- * Both of the arguments are bitmasks, and the value of bits come from
- * INetworkMonitor.NETWORK_VALIDATION_PROBE_*.
- * arg1 = A bitmask to describe which probes are completed.
- * arg2 = A bitmask to describe which probes are successful.
- */
- public static final int EVENT_PROBE_STATUS_CHANGED = 45;
-
- /**
- * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed.
- * arg1 = unused
- * arg2 = netId
- * obj = captive portal data
- */
- private static final int EVENT_CAPPORT_DATA_CHANGED = 46;
-
- /**
- * Used by setRequireVpnForUids.
- * arg1 = whether the specified UID ranges are required to use a VPN.
- * obj = Array of UidRange objects.
- */
- private static final int EVENT_SET_REQUIRE_VPN_FOR_UIDS = 47;
-
- /**
- * Used internally when setting the default networks for OemNetworkPreferences.
- * obj = Pair<OemNetworkPreferences, listener>
- */
- private static final int EVENT_SET_OEM_NETWORK_PREFERENCE = 48;
-
- /**
- * Used to indicate the system default network becomes active.
- */
- private static final int EVENT_REPORT_NETWORK_ACTIVITY = 49;
-
- /**
- * Used internally when setting a network preference for a user profile.
- * obj = Pair<ProfileNetworkPreference, Listener>
- */
- private static final int EVENT_SET_PROFILE_NETWORK_PREFERENCE = 50;
-
- /**
- * Event to specify that reasons for why an uid is blocked changed.
- * arg1 = uid
- * arg2 = blockedReasons
- */
- private static final int EVENT_UID_BLOCKED_REASON_CHANGED = 51;
-
- /**
- * Event to register a new network offer
- * obj = NetworkOffer
- */
- private static final int EVENT_REGISTER_NETWORK_OFFER = 52;
-
- /**
- * Event to unregister an existing network offer
- * obj = INetworkOfferCallback
- */
- private static final int EVENT_UNREGISTER_NETWORK_OFFER = 53;
-
- /**
- * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
- * should be shown.
- */
- private static final int PROVISIONING_NOTIFICATION_SHOW = 1;
-
- /**
- * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
- * should be hidden.
- */
- private static final int PROVISIONING_NOTIFICATION_HIDE = 0;
-
- private static String eventName(int what) {
- return sMagicDecoderRing.get(what, Integer.toString(what));
- }
-
- private static IDnsResolver getDnsResolver(Context context) {
- final DnsResolverServiceManager dsm = context.getSystemService(
- DnsResolverServiceManager.class);
- return IDnsResolver.Stub.asInterface(dsm.getService());
- }
-
- /** Handler thread used for all of the handlers below. */
- @VisibleForTesting
- protected final HandlerThread mHandlerThread;
- /** Handler used for internal events. */
- final private InternalHandler mHandler;
- /** Handler used for incoming {@link NetworkStateTracker} events. */
- final private NetworkStateTrackerHandler mTrackerHandler;
- /** Handler used for processing {@link android.net.ConnectivityDiagnosticsManager} events */
- @VisibleForTesting
- final ConnectivityDiagnosticsHandler mConnectivityDiagnosticsHandler;
-
- private final DnsManager mDnsManager;
- private final NetworkRanker mNetworkRanker;
-
- private boolean mSystemReady;
- private Intent mInitialBroadcast;
-
- private PowerManager.WakeLock mNetTransitionWakeLock;
- private final PowerManager.WakeLock mPendingIntentWakeLock;
-
- // A helper object to track the current default HTTP proxy. ConnectivityService needs to tell
- // the world when it changes.
- @VisibleForTesting
- protected final ProxyTracker mProxyTracker;
-
- final private SettingsObserver mSettingsObserver;
-
- private UserManager mUserManager;
-
- // the set of network types that can only be enabled by system/sig apps
- private List<Integer> mProtectedNetworks;
-
- private Set<String> mWolSupportedInterfaces;
-
- private final TelephonyManager mTelephonyManager;
- private final AppOpsManager mAppOpsManager;
-
- private final LocationPermissionChecker mLocationPermissionChecker;
-
- private KeepaliveTracker mKeepaliveTracker;
- private QosCallbackTracker mQosCallbackTracker;
- private NetworkNotificationManager mNotifier;
- private LingerMonitor mLingerMonitor;
-
- // sequence number of NetworkRequests
- private int mNextNetworkRequestId = NetworkRequest.FIRST_REQUEST_ID;
-
- // Sequence number for NetworkProvider IDs.
- private final AtomicInteger mNextNetworkProviderId = new AtomicInteger(
- NetworkProvider.FIRST_PROVIDER_ID);
-
- // NetworkRequest activity String log entries.
- private static final int MAX_NETWORK_REQUEST_LOGS = 20;
- private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS);
-
- // NetworkInfo blocked and unblocked String log entries
- private static final int MAX_NETWORK_INFO_LOGS = 40;
- private final LocalLog mNetworkInfoBlockingLogs = new LocalLog(MAX_NETWORK_INFO_LOGS);
-
- private static final int MAX_WAKELOCK_LOGS = 20;
- private final LocalLog mWakelockLogs = new LocalLog(MAX_WAKELOCK_LOGS);
- private int mTotalWakelockAcquisitions = 0;
- private int mTotalWakelockReleases = 0;
- private long mTotalWakelockDurationMs = 0;
- private long mMaxWakelockDurationMs = 0;
- private long mLastWakeLockAcquireTimestamp = 0;
-
- private final IpConnectivityLog mMetricsLog;
-
- @GuardedBy("mBandwidthRequests")
- private final SparseArray<Integer> mBandwidthRequests = new SparseArray(10);
-
- @VisibleForTesting
- final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
-
- @VisibleForTesting
- final Map<IBinder, ConnectivityDiagnosticsCallbackInfo> mConnectivityDiagnosticsCallbacks =
- new HashMap<>();
-
- /**
- * Implements support for the legacy "one network per network type" model.
- *
- * We used to have a static array of NetworkStateTrackers, one for each
- * network type, but that doesn't work any more now that we can have,
- * for example, more that one wifi network. This class stores all the
- * NetworkAgentInfo objects that support a given type, but the legacy
- * API will only see the first one.
- *
- * It serves two main purposes:
- *
- * 1. Provide information about "the network for a given type" (since this
- * API only supports one).
- * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if
- * the first network for a given type changes, or if the default network
- * changes.
- */
- @VisibleForTesting
- static class LegacyTypeTracker {
-
- private static final boolean DBG = true;
- private static final boolean VDBG = false;
-
- /**
- * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS).
- * Each list holds references to all NetworkAgentInfos that are used to
- * satisfy requests for that network type.
- *
- * This array is built out at startup such that an unsupported network
- * doesn't get an ArrayList instance, making this a tristate:
- * unsupported, supported but not active and active.
- *
- * The actual lists are populated when we scan the network types that
- * are supported on this device.
- *
- * Threading model:
- * - addSupportedType() is only called in the constructor
- * - add(), update(), remove() are only called from the ConnectivityService handler thread.
- * They are therefore not thread-safe with respect to each other.
- * - getNetworkForType() can be called at any time on binder threads. It is synchronized
- * on mTypeLists to be thread-safe with respect to a concurrent remove call.
- * - getRestoreTimerForType(type) is also synchronized on mTypeLists.
- * - dump is thread-safe with respect to concurrent add and remove calls.
- */
- private final ArrayList<NetworkAgentInfo> mTypeLists[];
- @NonNull
- private final ConnectivityService mService;
-
- // Restore timers for requestNetworkForFeature (network type -> timer in ms). Types without
- // an entry have no timer (equivalent to -1). Lazily loaded.
- @NonNull
- private ArrayMap<Integer, Integer> mRestoreTimers = new ArrayMap<>();
-
- LegacyTypeTracker(@NonNull ConnectivityService service) {
- mService = service;
- mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
- }
-
- public void loadSupportedTypes(@NonNull Context ctx, @NonNull TelephonyManager tm) {
- final PackageManager pm = ctx.getPackageManager();
- if (pm.hasSystemFeature(FEATURE_WIFI)) {
- addSupportedType(TYPE_WIFI);
- }
- if (pm.hasSystemFeature(FEATURE_WIFI_DIRECT)) {
- addSupportedType(TYPE_WIFI_P2P);
- }
- if (tm.isDataCapable()) {
- // Telephony does not have granular support for these types: they are either all
- // supported, or none is supported
- addSupportedType(TYPE_MOBILE);
- addSupportedType(TYPE_MOBILE_MMS);
- addSupportedType(TYPE_MOBILE_SUPL);
- addSupportedType(TYPE_MOBILE_DUN);
- addSupportedType(TYPE_MOBILE_HIPRI);
- addSupportedType(TYPE_MOBILE_FOTA);
- addSupportedType(TYPE_MOBILE_IMS);
- addSupportedType(TYPE_MOBILE_CBS);
- addSupportedType(TYPE_MOBILE_IA);
- addSupportedType(TYPE_MOBILE_EMERGENCY);
- }
- if (pm.hasSystemFeature(FEATURE_BLUETOOTH)) {
- addSupportedType(TYPE_BLUETOOTH);
- }
- if (pm.hasSystemFeature(FEATURE_WATCH)) {
- // TYPE_PROXY is only used on Wear
- addSupportedType(TYPE_PROXY);
- }
- // Ethernet is often not specified in the configs, although many devices can use it via
- // USB host adapters. Add it as long as the ethernet service is here.
- if (ctx.getSystemService(Context.ETHERNET_SERVICE) != null) {
- addSupportedType(TYPE_ETHERNET);
- }
-
- // Always add TYPE_VPN as a supported type
- addSupportedType(TYPE_VPN);
- }
-
- private void addSupportedType(int type) {
- if (mTypeLists[type] != null) {
- throw new IllegalStateException(
- "legacy list for type " + type + "already initialized");
- }
- mTypeLists[type] = new ArrayList<>();
- }
-
- public boolean isTypeSupported(int type) {
- return isNetworkTypeValid(type) && mTypeLists[type] != null;
- }
-
- public NetworkAgentInfo getNetworkForType(int type) {
- synchronized (mTypeLists) {
- if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) {
- return mTypeLists[type].get(0);
- }
- }
- return null;
- }
-
- public int getRestoreTimerForType(int type) {
- synchronized (mTypeLists) {
- if (mRestoreTimers == null) {
- mRestoreTimers = loadRestoreTimers();
- }
- return mRestoreTimers.getOrDefault(type, -1);
- }
- }
-
- private ArrayMap<Integer, Integer> loadRestoreTimers() {
- final String[] configs = mService.mResources.get().getStringArray(
- R.array.config_legacy_networktype_restore_timers);
- final ArrayMap<Integer, Integer> ret = new ArrayMap<>(configs.length);
- for (final String config : configs) {
- final String[] splits = TextUtils.split(config, ",");
- if (splits.length != 2) {
- logwtf("Invalid restore timer token count: " + config);
- continue;
- }
- try {
- ret.put(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
- } catch (NumberFormatException e) {
- logwtf("Invalid restore timer number format: " + config, e);
- }
- }
- return ret;
- }
-
- private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type,
- boolean isDefaultNetwork) {
- if (DBG) {
- log("Sending " + state
- + " broadcast for type " + type + " " + nai.toShortString()
- + " isDefaultNetwork=" + isDefaultNetwork);
- }
- }
-
- // When a lockdown VPN connects, send another CONNECTED broadcast for the underlying
- // network type, to preserve previous behaviour.
- private void maybeSendLegacyLockdownBroadcast(@NonNull NetworkAgentInfo vpnNai) {
- if (vpnNai != mService.getLegacyLockdownNai()) return;
-
- if (vpnNai.declaredUnderlyingNetworks == null
- || vpnNai.declaredUnderlyingNetworks.length != 1) {
- Log.wtf(TAG, "Legacy lockdown VPN must have exactly one underlying network: "
- + Arrays.toString(vpnNai.declaredUnderlyingNetworks));
- return;
- }
- final NetworkAgentInfo underlyingNai = mService.getNetworkAgentInfoForNetwork(
- vpnNai.declaredUnderlyingNetworks[0]);
- if (underlyingNai == null) return;
-
- final int type = underlyingNai.networkInfo.getType();
- final DetailedState state = DetailedState.CONNECTED;
- maybeLogBroadcast(underlyingNai, state, type, true /* isDefaultNetwork */);
- mService.sendLegacyNetworkBroadcast(underlyingNai, state, type);
- }
-
- /** Adds the given network to the specified legacy type list. */
- public void add(int type, NetworkAgentInfo nai) {
- if (!isTypeSupported(type)) {
- return; // Invalid network type.
- }
- if (VDBG) log("Adding agent " + nai + " for legacy network type " + type);
-
- ArrayList<NetworkAgentInfo> list = mTypeLists[type];
- if (list.contains(nai)) {
- return;
- }
- synchronized (mTypeLists) {
- list.add(nai);
- }
-
- // Send a broadcast if this is the first network of its type or if it's the default.
- final boolean isDefaultNetwork = mService.isDefaultNetwork(nai);
-
- // If a legacy lockdown VPN is active, override the NetworkInfo state in all broadcasts
- // to preserve previous behaviour.
- final DetailedState state = mService.getLegacyLockdownState(DetailedState.CONNECTED);
- if ((list.size() == 1) || isDefaultNetwork) {
- maybeLogBroadcast(nai, state, type, isDefaultNetwork);
- mService.sendLegacyNetworkBroadcast(nai, state, type);
- }
-
- if (type == TYPE_VPN && state == DetailedState.CONNECTED) {
- maybeSendLegacyLockdownBroadcast(nai);
- }
- }
-
- /** Removes the given network from the specified legacy type list. */
- public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) {
- ArrayList<NetworkAgentInfo> list = mTypeLists[type];
- if (list == null || list.isEmpty()) {
- return;
- }
- final boolean wasFirstNetwork = list.get(0).equals(nai);
-
- synchronized (mTypeLists) {
- if (!list.remove(nai)) {
- return;
- }
- }
-
- if (wasFirstNetwork || wasDefault) {
- maybeLogBroadcast(nai, DetailedState.DISCONNECTED, type, wasDefault);
- mService.sendLegacyNetworkBroadcast(nai, DetailedState.DISCONNECTED, type);
- }
-
- if (!list.isEmpty() && wasFirstNetwork) {
- if (DBG) log("Other network available for type " + type +
- ", sending connected broadcast");
- final NetworkAgentInfo replacement = list.get(0);
- maybeLogBroadcast(replacement, DetailedState.CONNECTED, type,
- mService.isDefaultNetwork(replacement));
- mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type);
- }
- }
-
- /** Removes the given network from all legacy type lists. */
- public void remove(NetworkAgentInfo nai, boolean wasDefault) {
- if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault);
- for (int type = 0; type < mTypeLists.length; type++) {
- remove(type, nai, wasDefault);
- }
- }
-
- // send out another legacy broadcast - currently only used for suspend/unsuspend
- // toggle
- public void update(NetworkAgentInfo nai) {
- final boolean isDefault = mService.isDefaultNetwork(nai);
- final DetailedState state = nai.networkInfo.getDetailedState();
- for (int type = 0; type < mTypeLists.length; type++) {
- final ArrayList<NetworkAgentInfo> list = mTypeLists[type];
- final boolean contains = (list != null && list.contains(nai));
- final boolean isFirst = contains && (nai == list.get(0));
- if (isFirst || contains && isDefault) {
- maybeLogBroadcast(nai, state, type, isDefault);
- mService.sendLegacyNetworkBroadcast(nai, state, type);
- }
- }
- }
-
- public void dump(IndentingPrintWriter pw) {
- pw.println("mLegacyTypeTracker:");
- pw.increaseIndent();
- pw.print("Supported types:");
- for (int type = 0; type < mTypeLists.length; type++) {
- if (mTypeLists[type] != null) pw.print(" " + type);
- }
- pw.println();
- pw.println("Current state:");
- pw.increaseIndent();
- synchronized (mTypeLists) {
- for (int type = 0; type < mTypeLists.length; type++) {
- if (mTypeLists[type] == null || mTypeLists[type].isEmpty()) continue;
- for (NetworkAgentInfo nai : mTypeLists[type]) {
- pw.println(type + " " + nai.toShortString());
- }
- }
- }
- pw.decreaseIndent();
- pw.decreaseIndent();
- pw.println();
- }
- }
- private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
-
- final LocalPriorityDump mPriorityDumper = new LocalPriorityDump();
- /**
- * Helper class which parses out priority arguments and dumps sections according to their
- * priority. If priority arguments are omitted, function calls the legacy dump command.
- */
- private class LocalPriorityDump {
- private static final String PRIORITY_ARG = "--dump-priority";
- private static final String PRIORITY_ARG_HIGH = "HIGH";
- private static final String PRIORITY_ARG_NORMAL = "NORMAL";
-
- LocalPriorityDump() {}
-
- private void dumpHigh(FileDescriptor fd, PrintWriter pw) {
- doDump(fd, pw, new String[] {DIAG_ARG});
- doDump(fd, pw, new String[] {SHORT_ARG});
- }
-
- private void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
- doDump(fd, pw, args);
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (args == null) {
- dumpNormal(fd, pw, args);
- return;
- }
-
- String priority = null;
- for (int argIndex = 0; argIndex < args.length; argIndex++) {
- if (args[argIndex].equals(PRIORITY_ARG) && argIndex + 1 < args.length) {
- argIndex++;
- priority = args[argIndex];
- }
- }
-
- if (PRIORITY_ARG_HIGH.equals(priority)) {
- dumpHigh(fd, pw);
- } else if (PRIORITY_ARG_NORMAL.equals(priority)) {
- dumpNormal(fd, pw, args);
- } else {
- // ConnectivityService publishes binder service using publishBinderService() with
- // no priority assigned will be treated as NORMAL priority. Dumpsys does not send
- // "--dump-priority" arguments to the service. Thus, dump NORMAL only to align the
- // legacy output for dumpsys connectivity.
- // TODO: Integrate into signal dump.
- dumpNormal(fd, pw, args);
- }
- }
- }
-
- /**
- * Keeps track of the number of requests made under different uids.
- */
- public static class PerUidCounter {
- private final int mMaxCountPerUid;
-
- // Map from UID to number of NetworkRequests that UID has filed.
- @VisibleForTesting
- @GuardedBy("mUidToNetworkRequestCount")
- final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray();
-
- /**
- * Constructor
- *
- * @param maxCountPerUid the maximum count per uid allowed
- */
- public PerUidCounter(final int maxCountPerUid) {
- mMaxCountPerUid = maxCountPerUid;
- }
-
- /**
- * Increments the request count of the given uid. Throws an exception if the number
- * of open requests for the uid exceeds the value of maxCounterPerUid which is the value
- * passed into the constructor. see: {@link #PerUidCounter(int)}.
- *
- * @throws ServiceSpecificException with
- * {@link ConnectivityManager.Errors.TOO_MANY_REQUESTS} if the number of requests for
- * the uid exceed the allowed number.
- *
- * @param uid the uid that the request was made under
- */
- public void incrementCountOrThrow(final int uid) {
- synchronized (mUidToNetworkRequestCount) {
- incrementCountOrThrow(uid, 1 /* numToIncrement */);
- }
- }
-
- private void incrementCountOrThrow(final int uid, final int numToIncrement) {
- final int newRequestCount =
- mUidToNetworkRequestCount.get(uid, 0) + numToIncrement;
- if (newRequestCount >= mMaxCountPerUid) {
- throw new ServiceSpecificException(
- ConnectivityManager.Errors.TOO_MANY_REQUESTS);
- }
- mUidToNetworkRequestCount.put(uid, newRequestCount);
- }
-
- /**
- * Decrements the request count of the given uid.
- *
- * @param uid the uid that the request was made under
- */
- public void decrementCount(final int uid) {
- synchronized (mUidToNetworkRequestCount) {
- decrementCount(uid, 1 /* numToDecrement */);
- }
- }
-
- private void decrementCount(final int uid, final int numToDecrement) {
- final int newRequestCount =
- mUidToNetworkRequestCount.get(uid, 0) - numToDecrement;
- if (newRequestCount < 0) {
- logwtf("BUG: too small request count " + newRequestCount + " for UID " + uid);
- } else if (newRequestCount == 0) {
- mUidToNetworkRequestCount.delete(uid);
- } else {
- mUidToNetworkRequestCount.put(uid, newRequestCount);
- }
- }
-
- /**
- * Used to adjust the request counter for the per-app API flows. Directly adjusting the
- * counter is not ideal however in the per-app flows, the nris can't be removed until they
- * are used to create the new nris upon set. Therefore the request count limit can be
- * artificially hit. This method is used as a workaround for this particular case so that
- * the request counts are accounted for correctly.
- * @param uid the uid to adjust counts for
- * @param numOfNewRequests the new request count to account for
- * @param r the runnable to execute
- */
- public void transact(final int uid, final int numOfNewRequests, @NonNull final Runnable r) {
- // This should only be used on the handler thread as per all current and foreseen
- // use-cases. ensureRunningOnConnectivityServiceThread() can't be used because there is
- // no ref to the outer ConnectivityService.
- synchronized (mUidToNetworkRequestCount) {
- final int reqCountOverage = getCallingUidRequestCountOverage(uid, numOfNewRequests);
- decrementCount(uid, reqCountOverage);
- r.run();
- incrementCountOrThrow(uid, reqCountOverage);
- }
- }
-
- private int getCallingUidRequestCountOverage(final int uid, final int numOfNewRequests) {
- final int newUidRequestCount = mUidToNetworkRequestCount.get(uid, 0)
- + numOfNewRequests;
- return newUidRequestCount >= MAX_NETWORK_REQUESTS_PER_SYSTEM_UID
- ? newUidRequestCount - (MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1) : 0;
- }
- }
-
- /**
- * Dependencies of ConnectivityService, for injection in tests.
- */
- @VisibleForTesting
- public static class Dependencies {
- public int getCallingUid() {
- return Binder.getCallingUid();
- }
-
- /**
- * Get system properties to use in ConnectivityService.
- */
- public MockableSystemProperties getSystemProperties() {
- return new MockableSystemProperties();
- }
-
- /**
- * Get the {@link ConnectivityResources} to use in ConnectivityService.
- */
- public ConnectivityResources getResources(@NonNull Context ctx) {
- return new ConnectivityResources(ctx);
- }
-
- /**
- * Create a HandlerThread to use in ConnectivityService.
- */
- public HandlerThread makeHandlerThread() {
- return new HandlerThread("ConnectivityServiceThread");
- }
-
- /**
- * Get a reference to the ModuleNetworkStackClient.
- */
- public NetworkStackClientBase getNetworkStack() {
- return ModuleNetworkStackClient.getInstance(null);
- }
-
- /**
- * @see ProxyTracker
- */
- public ProxyTracker makeProxyTracker(@NonNull Context context,
- @NonNull Handler connServiceHandler) {
- return new ProxyTracker(context, connServiceHandler, EVENT_PROXY_HAS_CHANGED);
- }
-
- /**
- * @see NetIdManager
- */
- public NetIdManager makeNetIdManager() {
- return new NetIdManager();
- }
-
- /**
- * @see NetworkUtils#queryUserAccess(int, int)
- */
- public boolean queryUserAccess(int uid, Network network, ConnectivityService cs) {
- return cs.queryUserAccess(uid, network);
- }
-
- /**
- * Gets the UID that owns a socket connection. Needed because opening SOCK_DIAG sockets
- * requires CAP_NET_ADMIN, which the unit tests do not have.
- */
- public int getConnectionOwnerUid(int protocol, InetSocketAddress local,
- InetSocketAddress remote) {
- return InetDiagMessage.getConnectionOwnerUid(protocol, local, remote);
- }
-
- /**
- * @see MultinetworkPolicyTracker
- */
- public MultinetworkPolicyTracker makeMultinetworkPolicyTracker(
- @NonNull Context c, @NonNull Handler h, @NonNull Runnable r) {
- return new MultinetworkPolicyTracker(c, h, r);
- }
-
- /**
- * @see BatteryStatsManager
- */
- public void reportNetworkInterfaceForTransports(Context context, String iface,
- int[] transportTypes) {
- final BatteryStatsManager batteryStats =
- context.getSystemService(BatteryStatsManager.class);
- batteryStats.reportNetworkInterfaceForTransports(iface, transportTypes);
- }
-
- public boolean getCellular464XlatEnabled() {
- return NetworkProperties.isCellular464XlatEnabled().orElse(true);
- }
- }
-
- public ConnectivityService(Context context) {
- this(context, getDnsResolver(context), new IpConnectivityLog(),
- INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)),
- new Dependencies());
- }
-
- @VisibleForTesting
- protected ConnectivityService(Context context, IDnsResolver dnsresolver,
- IpConnectivityLog logger, INetd netd, Dependencies deps) {
- if (DBG) log("ConnectivityService starting up");
-
- mDeps = Objects.requireNonNull(deps, "missing Dependencies");
- mSystemProperties = mDeps.getSystemProperties();
- mNetIdManager = mDeps.makeNetIdManager();
- mContext = Objects.requireNonNull(context, "missing Context");
- mResources = deps.getResources(mContext);
- mNetworkRequestCounter = new PerUidCounter(MAX_NETWORK_REQUESTS_PER_UID);
- mSystemNetworkRequestCounter = new PerUidCounter(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID);
-
- mMetricsLog = logger;
- mNetworkRanker = new NetworkRanker();
- final NetworkRequest defaultInternetRequest = createDefaultRequest();
- mDefaultRequest = new NetworkRequestInfo(
- Process.myUid(), defaultInternetRequest, null,
- new Binder(), NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
- null /* attributionTags */);
- mNetworkRequests.put(defaultInternetRequest, mDefaultRequest);
- mDefaultNetworkRequests.add(mDefaultRequest);
- mNetworkRequestInfoLogs.log("REGISTER " + mDefaultRequest);
-
- mDefaultMobileDataRequest = createDefaultInternetRequestForTransport(
- NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST);
-
- // The default WiFi request is a background request so that apps using WiFi are
- // migrated to a better network (typically ethernet) when one comes up, instead
- // of staying on WiFi forever.
- mDefaultWifiRequest = createDefaultInternetRequestForTransport(
- NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST);
-
- mDefaultVehicleRequest = createAlwaysOnRequestForCapability(
- NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL,
- NetworkRequest.Type.BACKGROUND_REQUEST);
-
- mHandlerThread = mDeps.makeHandlerThread();
- mHandlerThread.start();
- mHandler = new InternalHandler(mHandlerThread.getLooper());
- mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper());
- mConnectivityDiagnosticsHandler =
- new ConnectivityDiagnosticsHandler(mHandlerThread.getLooper());
-
- mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(),
- ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000);
-
- mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
- // TODO: Consider making the timer customizable.
- mNascentDelayMs = DEFAULT_NASCENT_DELAY_MS;
-
- mStatsManager = mContext.getSystemService(NetworkStatsManager.class);
- mPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
- mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver");
- mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
-
- mNetd = netd;
- mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
- mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
- mLocationPermissionChecker = new LocationPermissionChecker(mContext);
-
- // To ensure uid state is synchronized with Network Policy, register for
- // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
- // reading existing policy from disk.
- mPolicyManager.registerNetworkPolicyCallback(null, mPolicyCallback);
-
- final PowerManager powerManager = (PowerManager) context.getSystemService(
- Context.POWER_SERVICE);
- mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
- mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
-
- mLegacyTypeTracker.loadSupportedTypes(mContext, mTelephonyManager);
- mProtectedNetworks = new ArrayList<>();
- int[] protectedNetworks = mResources.get().getIntArray(R.array.config_protectedNetworks);
- for (int p : protectedNetworks) {
- if (mLegacyTypeTracker.isTypeSupported(p) && !mProtectedNetworks.contains(p)) {
- mProtectedNetworks.add(p);
- } else {
- if (DBG) loge("Ignoring protectedNetwork " + p);
- }
- }
-
- mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-
- mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
-
- mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
- // Listen for user add/removes to inform PermissionMonitor.
- // Should run on mHandler to avoid any races.
- final IntentFilter userIntentFilter = new IntentFilter();
- userIntentFilter.addAction(Intent.ACTION_USER_ADDED);
- userIntentFilter.addAction(Intent.ACTION_USER_REMOVED);
- mUserAllContext.registerReceiver(mUserIntentReceiver, userIntentFilter,
- null /* broadcastPermission */, mHandler);
-
- // Listen to package add/removes for netd
- final IntentFilter packageIntentFilter = new IntentFilter();
- packageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
- packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
- packageIntentFilter.addDataScheme("package");
- mUserAllContext.registerReceiver(mPackageIntentReceiver, packageIntentFilter,
- null /* broadcastPermission */, mHandler);
-
- mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNetd);
-
- mNetdCallback = new NetdCallback();
- try {
- mNetd.registerUnsolicitedEventListener(mNetdCallback);
- } catch (RemoteException | ServiceSpecificException e) {
- loge("Error registering event listener :" + e);
- }
-
- mSettingsObserver = new SettingsObserver(mContext, mHandler);
- registerSettingsCallbacks();
-
- mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler);
- mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager);
- mQosCallbackTracker = new QosCallbackTracker(mHandler, mNetworkRequestCounter);
-
- final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(),
- ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT,
- LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT);
- final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(),
- ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS,
- LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS);
- mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit);
-
- mMultinetworkPolicyTracker = mDeps.makeMultinetworkPolicyTracker(
- mContext, mHandler, () -> updateAvoidBadWifi());
- mMultinetworkPolicyTracker.start();
-
- mDnsManager = new DnsManager(mContext, mDnsResolver);
- registerPrivateDnsSettingsCallbacks();
-
- // This NAI is a sentinel used to offer no service to apps that are on a multi-layer
- // request that doesn't allow fallback to the default network. It should never be visible
- // to apps. As such, it's not in the list of NAIs and doesn't need many of the normal
- // arguments like the handler or the DnsResolver.
- // TODO : remove this ; it is probably better handled with a sentinel request.
- mNoServiceNetwork = new NetworkAgentInfo(null,
- new Network(INetd.UNREACHABLE_NET_ID),
- new NetworkInfo(TYPE_NONE, 0, "", ""),
- new LinkProperties(), new NetworkCapabilities(),
- new NetworkScore.Builder().setLegacyInt(0).build(), mContext, null,
- new NetworkAgentConfig(), this, null, null, 0, INVALID_UID,
- mLingerDelayMs, mQosCallbackTracker, mDeps);
- }
-
- private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
- return createDefaultNetworkCapabilitiesForUidRange(new UidRange(uid, uid));
- }
-
- private static NetworkCapabilities createDefaultNetworkCapabilitiesForUidRange(
- @NonNull final UidRange uids) {
- final NetworkCapabilities netCap = new NetworkCapabilities();
- netCap.addCapability(NET_CAPABILITY_INTERNET);
- netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
- netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
- netCap.setUids(UidRange.toIntRanges(Collections.singleton(uids)));
- return netCap;
- }
-
- private NetworkRequest createDefaultRequest() {
- return createDefaultInternetRequestForTransport(
- TYPE_NONE, NetworkRequest.Type.REQUEST);
- }
-
- private NetworkRequest createDefaultInternetRequestForTransport(
- int transportType, NetworkRequest.Type type) {
- final NetworkCapabilities netCap = new NetworkCapabilities();
- netCap.addCapability(NET_CAPABILITY_INTERNET);
- netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
- netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
- if (transportType > TYPE_NONE) {
- netCap.addTransportType(transportType);
- }
- return createNetworkRequest(type, netCap);
- }
-
- private NetworkRequest createNetworkRequest(
- NetworkRequest.Type type, NetworkCapabilities netCap) {
- return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type);
- }
-
- private NetworkRequest createAlwaysOnRequestForCapability(int capability,
- NetworkRequest.Type type) {
- final NetworkCapabilities netCap = new NetworkCapabilities();
- netCap.clearAll();
- netCap.addCapability(capability);
- netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
- return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type);
- }
-
- // Used only for testing.
- // TODO: Delete this and either:
- // 1. Give FakeSettingsProvider the ability to send settings change notifications (requires
- // changing ContentResolver to make registerContentObserver non-final).
- // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it
- // by subclassing SettingsObserver.
- @VisibleForTesting
- void updateAlwaysOnNetworks() {
- mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
- }
-
- // See FakeSettingsProvider comment above.
- @VisibleForTesting
- void updatePrivateDnsSettings() {
- mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
- }
-
- private void handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, int id) {
- final boolean enable = mContext.getResources().getBoolean(id);
- handleAlwaysOnNetworkRequest(networkRequest, enable);
- }
-
- private void handleAlwaysOnNetworkRequest(
- NetworkRequest networkRequest, String settingName, boolean defaultValue) {
- final boolean enable = toBool(Settings.Global.getInt(
- mContext.getContentResolver(), settingName, encodeBool(defaultValue)));
- handleAlwaysOnNetworkRequest(networkRequest, enable);
- }
-
- private void handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, boolean enable) {
- final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null);
- if (enable == isEnabled) {
- return; // Nothing to do.
- }
-
- if (enable) {
- handleRegisterNetworkRequest(new NetworkRequestInfo(
- Process.myUid(), networkRequest, null, new Binder(),
- NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
- null /* attributionTags */));
- } else {
- handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID,
- /* callOnUnavailable */ false);
- }
- }
-
- private void handleConfigureAlwaysOnNetworks() {
- handleAlwaysOnNetworkRequest(mDefaultMobileDataRequest,
- ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, true /* defaultValue */);
- handleAlwaysOnNetworkRequest(mDefaultWifiRequest,
- ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED, false /* defaultValue */);
- final boolean vehicleAlwaysRequested = mResources.get().getBoolean(
- R.bool.config_vehicleInternalNetworkAlwaysRequested);
- handleAlwaysOnNetworkRequest(mDefaultVehicleRequest, vehicleAlwaysRequested);
- }
-
- private void registerSettingsCallbacks() {
- // Watch for global HTTP proxy changes.
- mSettingsObserver.observe(
- Settings.Global.getUriFor(Settings.Global.HTTP_PROXY),
- EVENT_APPLY_GLOBAL_HTTP_PROXY);
-
- // Watch for whether or not to keep mobile data always on.
- mSettingsObserver.observe(
- Settings.Global.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON),
- EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
-
- // Watch for whether or not to keep wifi always on.
- mSettingsObserver.observe(
- Settings.Global.getUriFor(ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED),
- EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
- }
-
- private void registerPrivateDnsSettingsCallbacks() {
- for (Uri uri : DnsManager.getPrivateDnsSettingsUris()) {
- mSettingsObserver.observe(uri, EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
- }
- }
-
- private synchronized int nextNetworkRequestId() {
- // TODO: Consider handle wrapping and exclude {@link NetworkRequest#REQUEST_ID_NONE} if
- // doing that.
- return mNextNetworkRequestId++;
- }
-
- @VisibleForTesting
- protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
- if (network == null) {
- return null;
- }
- return getNetworkAgentInfoForNetId(network.getNetId());
- }
-
- private NetworkAgentInfo getNetworkAgentInfoForNetId(int netId) {
- synchronized (mNetworkForNetId) {
- return mNetworkForNetId.get(netId);
- }
- }
-
- // TODO: determine what to do when more than one VPN applies to |uid|.
- private NetworkAgentInfo getVpnForUid(int uid) {
- synchronized (mNetworkForNetId) {
- for (int i = 0; i < mNetworkForNetId.size(); i++) {
- final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
- if (nai.isVPN() && nai.everConnected && nai.networkCapabilities.appliesToUid(uid)) {
- return nai;
- }
- }
- }
- return null;
- }
-
- private Network[] getVpnUnderlyingNetworks(int uid) {
- if (mLockdownEnabled) return null;
- final NetworkAgentInfo nai = getVpnForUid(uid);
- if (nai != null) return nai.declaredUnderlyingNetworks;
- return null;
- }
-
- private NetworkAgentInfo getNetworkAgentInfoForUid(int uid) {
- NetworkAgentInfo nai = getDefaultNetworkForUid(uid);
-
- final Network[] networks = getVpnUnderlyingNetworks(uid);
- if (networks != null) {
- // getUnderlyingNetworks() returns:
- // null => there was no VPN, or the VPN didn't specify anything, so we use the default.
- // empty array => the VPN explicitly said "no default network".
- // non-empty array => the VPN specified one or more default networks; we use the
- // first one.
- if (networks.length > 0) {
- nai = getNetworkAgentInfoForNetwork(networks[0]);
- } else {
- nai = null;
- }
- }
- return nai;
- }
-
- /**
- * Check if UID should be blocked from using the specified network.
- */
- private boolean isNetworkWithCapabilitiesBlocked(@Nullable final NetworkCapabilities nc,
- final int uid, final boolean ignoreBlocked) {
- // Networks aren't blocked when ignoring blocked status
- if (ignoreBlocked) {
- return false;
- }
- if (isUidBlockedByVpn(uid, mVpnBlockedUidRanges)) return true;
- final long ident = Binder.clearCallingIdentity();
- try {
- final boolean metered = nc == null ? true : nc.isMetered();
- return mPolicyManager.isUidNetworkingBlocked(uid, metered);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) {
- if (ni == null || !LOGD_BLOCKED_NETWORKINFO) {
- return;
- }
- final boolean blocked;
- synchronized (mBlockedAppUids) {
- if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) {
- blocked = true;
- } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) {
- blocked = false;
- } else {
- return;
- }
- }
- String action = blocked ? "BLOCKED" : "UNBLOCKED";
- log(String.format("Returning %s NetworkInfo to uid=%d", action, uid));
- mNetworkInfoBlockingLogs.log(action + " " + uid);
- }
-
- private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, int blocked) {
- if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) {
- return;
- }
- final String action = (blocked != 0) ? "BLOCKED" : "UNBLOCKED";
- final int requestId = nri.getActiveRequest() != null
- ? nri.getActiveRequest().requestId : nri.mRequests.get(0).requestId;
- mNetworkInfoBlockingLogs.log(String.format(
- "%s %d(%d) on netId %d: %s", action, nri.mAsUid, requestId, net.getNetId(),
- Integer.toHexString(blocked)));
- }
-
- /**
- * Apply any relevant filters to the specified {@link NetworkInfo} for the given UID. For
- * example, this may mark the network as {@link DetailedState#BLOCKED} based
- * on {@link #isNetworkWithCapabilitiesBlocked}.
- */
- @NonNull
- private NetworkInfo filterNetworkInfo(@NonNull NetworkInfo networkInfo, int type,
- @NonNull NetworkCapabilities nc, int uid, boolean ignoreBlocked) {
- final NetworkInfo filtered = new NetworkInfo(networkInfo);
- // Many legacy types (e.g,. TYPE_MOBILE_HIPRI) are not actually a property of the network
- // but only exists if an app asks about them or requests them. Ensure the requesting app
- // gets the type it asks for.
- filtered.setType(type);
- if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) {
- filtered.setDetailedState(DetailedState.BLOCKED, null /* reason */,
- null /* extraInfo */);
- }
- filterForLegacyLockdown(filtered);
- return filtered;
- }
-
- private NetworkInfo getFilteredNetworkInfo(NetworkAgentInfo nai, int uid,
- boolean ignoreBlocked) {
- return filterNetworkInfo(nai.networkInfo, nai.networkInfo.getType(),
- nai.networkCapabilities, uid, ignoreBlocked);
- }
-
- /**
- * Return NetworkInfo for the active (i.e., connected) network interface.
- * It is assumed that at most one network is active at a time. If more
- * than one is active, it is indeterminate which will be returned.
- * @return the info for the active network, or {@code null} if none is
- * active
- */
- @Override
- public NetworkInfo getActiveNetworkInfo() {
- enforceAccessPermission();
- final int uid = mDeps.getCallingUid();
- final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
- if (nai == null) return null;
- final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false);
- maybeLogBlockedNetworkInfo(networkInfo, uid);
- return networkInfo;
- }
-
- @Override
- public Network getActiveNetwork() {
- enforceAccessPermission();
- return getActiveNetworkForUidInternal(mDeps.getCallingUid(), false);
- }
-
- @Override
- public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
- PermissionUtils.enforceNetworkStackPermission(mContext);
- return getActiveNetworkForUidInternal(uid, ignoreBlocked);
- }
-
- private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) {
- final NetworkAgentInfo vpnNai = getVpnForUid(uid);
- if (vpnNai != null) {
- final NetworkCapabilities requiredCaps = createDefaultNetworkCapabilitiesForUid(uid);
- if (requiredCaps.satisfiedByNetworkCapabilities(vpnNai.networkCapabilities)) {
- return vpnNai.network;
- }
- }
-
- NetworkAgentInfo nai = getDefaultNetworkForUid(uid);
- if (nai == null || isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid,
- ignoreBlocked)) {
- return null;
- }
- return nai.network;
- }
-
- @Override
- public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
- PermissionUtils.enforceNetworkStackPermission(mContext);
- final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
- if (nai == null) return null;
- return getFilteredNetworkInfo(nai, uid, ignoreBlocked);
- }
-
- /** Returns a NetworkInfo object for a network that doesn't exist. */
- private NetworkInfo makeFakeNetworkInfo(int networkType, int uid) {
- final NetworkInfo info = new NetworkInfo(networkType, 0 /* subtype */,
- getNetworkTypeName(networkType), "" /* subtypeName */);
- info.setIsAvailable(true);
- // For compatibility with legacy code, return BLOCKED instead of DISCONNECTED when
- // background data is restricted.
- final NetworkCapabilities nc = new NetworkCapabilities(); // Metered.
- final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, false)
- ? DetailedState.BLOCKED
- : DetailedState.DISCONNECTED;
- info.setDetailedState(state, null /* reason */, null /* extraInfo */);
- filterForLegacyLockdown(info);
- return info;
- }
-
- private NetworkInfo getFilteredNetworkInfoForType(int networkType, int uid) {
- if (!mLegacyTypeTracker.isTypeSupported(networkType)) {
- return null;
- }
- final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- if (nai == null) {
- return makeFakeNetworkInfo(networkType, uid);
- }
- return filterNetworkInfo(nai.networkInfo, networkType, nai.networkCapabilities, uid,
- false);
- }
-
- @Override
- public NetworkInfo getNetworkInfo(int networkType) {
- enforceAccessPermission();
- final int uid = mDeps.getCallingUid();
- if (getVpnUnderlyingNetworks(uid) != null) {
- // A VPN is active, so we may need to return one of its underlying networks. This
- // information is not available in LegacyTypeTracker, so we have to get it from
- // getNetworkAgentInfoForUid.
- final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
- if (nai == null) return null;
- final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false);
- if (networkInfo.getType() == networkType) {
- return networkInfo;
- }
- }
- return getFilteredNetworkInfoForType(networkType, uid);
- }
-
- @Override
- public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
- enforceAccessPermission();
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
- if (nai == null) return null;
- return getFilteredNetworkInfo(nai, uid, ignoreBlocked);
- }
-
- @Override
- public NetworkInfo[] getAllNetworkInfo() {
- enforceAccessPermission();
- final ArrayList<NetworkInfo> result = new ArrayList<>();
- for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE;
- networkType++) {
- NetworkInfo info = getNetworkInfo(networkType);
- if (info != null) {
- result.add(info);
- }
- }
- return result.toArray(new NetworkInfo[result.size()]);
- }
-
- @Override
- public Network getNetworkForType(int networkType) {
- enforceAccessPermission();
- if (!mLegacyTypeTracker.isTypeSupported(networkType)) {
- return null;
- }
- final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- if (nai == null) {
- return null;
- }
- final int uid = mDeps.getCallingUid();
- if (isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, false)) {
- return null;
- }
- return nai.network;
- }
-
- @Override
- public Network[] getAllNetworks() {
- enforceAccessPermission();
- synchronized (mNetworkForNetId) {
- final Network[] result = new Network[mNetworkForNetId.size()];
- for (int i = 0; i < mNetworkForNetId.size(); i++) {
- result[i] = mNetworkForNetId.valueAt(i).network;
- }
- return result;
- }
- }
-
- @Override
- public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(
- int userId, String callingPackageName, @Nullable String callingAttributionTag) {
- // The basic principle is: if an app's traffic could possibly go over a
- // network, without the app doing anything multinetwork-specific,
- // (hence, by "default"), then include that network's capabilities in
- // the array.
- //
- // In the normal case, app traffic only goes over the system's default
- // network connection, so that's the only network returned.
- //
- // With a VPN in force, some app traffic may go into the VPN, and thus
- // over whatever underlying networks the VPN specifies, while other app
- // traffic may go over the system default network (e.g.: a split-tunnel
- // VPN, or an app disallowed by the VPN), so the set of networks
- // returned includes the VPN's underlying networks and the system
- // default.
- enforceAccessPermission();
-
- HashMap<Network, NetworkCapabilities> result = new HashMap<>();
-
- for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
- if (!nri.isBeingSatisfied()) {
- continue;
- }
- final NetworkAgentInfo nai = nri.getSatisfier();
- final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
- if (null != nc
- && nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
- && !result.containsKey(nai.network)) {
- result.put(
- nai.network,
- createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- nc, false /* includeLocationSensitiveInfo */,
- getCallingPid(), mDeps.getCallingUid(), callingPackageName,
- callingAttributionTag));
- }
- }
-
- // No need to check mLockdownEnabled. If it's true, getVpnUnderlyingNetworks returns null.
- final Network[] networks = getVpnUnderlyingNetworks(mDeps.getCallingUid());
- if (null != networks) {
- for (final Network network : networks) {
- final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
- if (null != nc) {
- result.put(
- network,
- createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- nc,
- false /* includeLocationSensitiveInfo */,
- getCallingPid(), mDeps.getCallingUid(), callingPackageName,
- callingAttributionTag));
- }
- }
- }
-
- NetworkCapabilities[] out = new NetworkCapabilities[result.size()];
- out = result.values().toArray(out);
- return out;
- }
-
- @Override
- public boolean isNetworkSupported(int networkType) {
- enforceAccessPermission();
- return mLegacyTypeTracker.isTypeSupported(networkType);
- }
-
- /**
- * Return LinkProperties for the active (i.e., connected) default
- * network interface for the calling uid.
- * @return the ip properties for the active network, or {@code null} if
- * none is active
- */
- @Override
- public LinkProperties getActiveLinkProperties() {
- enforceAccessPermission();
- final int uid = mDeps.getCallingUid();
- NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
- if (nai == null) return null;
- return linkPropertiesRestrictedForCallerPermissions(nai.linkProperties,
- Binder.getCallingPid(), uid);
- }
-
- @Override
- public LinkProperties getLinkPropertiesForType(int networkType) {
- enforceAccessPermission();
- NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- final LinkProperties lp = getLinkProperties(nai);
- if (lp == null) return null;
- return linkPropertiesRestrictedForCallerPermissions(
- lp, Binder.getCallingPid(), mDeps.getCallingUid());
- }
-
- // TODO - this should be ALL networks
- @Override
- public LinkProperties getLinkProperties(Network network) {
- enforceAccessPermission();
- final LinkProperties lp = getLinkProperties(getNetworkAgentInfoForNetwork(network));
- if (lp == null) return null;
- return linkPropertiesRestrictedForCallerPermissions(
- lp, Binder.getCallingPid(), mDeps.getCallingUid());
- }
-
- @Nullable
- private LinkProperties getLinkProperties(@Nullable NetworkAgentInfo nai) {
- if (nai == null) {
- return null;
- }
- synchronized (nai) {
- return nai.linkProperties;
- }
- }
-
- private NetworkCapabilities getNetworkCapabilitiesInternal(Network network) {
- return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
- }
-
- private NetworkCapabilities getNetworkCapabilitiesInternal(NetworkAgentInfo nai) {
- if (nai == null) return null;
- synchronized (nai) {
- return networkCapabilitiesRestrictedForCallerPermissions(
- nai.networkCapabilities, Binder.getCallingPid(), mDeps.getCallingUid());
- }
- }
-
- @Override
- public NetworkCapabilities getNetworkCapabilities(Network network, String callingPackageName,
- @Nullable String callingAttributionTag) {
- mAppOpsManager.checkPackage(mDeps.getCallingUid(), callingPackageName);
- enforceAccessPermission();
- return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- getNetworkCapabilitiesInternal(network),
- false /* includeLocationSensitiveInfo */,
- getCallingPid(), mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
- }
-
- @VisibleForTesting
- NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
- NetworkCapabilities nc, int callerPid, int callerUid) {
- final NetworkCapabilities newNc = new NetworkCapabilities(nc);
- if (!checkSettingsPermission(callerPid, callerUid)) {
- newNc.setUids(null);
- newNc.setSSID(null);
- }
- if (newNc.getNetworkSpecifier() != null) {
- newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact());
- }
- newNc.setAdministratorUids(new int[0]);
- if (!checkAnyPermissionOf(
- callerPid, callerUid, android.Manifest.permission.NETWORK_FACTORY)) {
- newNc.setSubscriptionIds(Collections.emptySet());
- }
-
- return newNc;
- }
-
- /**
- * Wrapper used to cache the permission check results performed for the corresponding
- * app. This avoid performing multiple permission checks for different fields in
- * NetworkCapabilities.
- * Note: This wrapper does not support any sort of invalidation and thus must not be
- * persistent or long-lived. It may only be used for the time necessary to
- * compute the redactions required by one particular NetworkCallback or
- * synchronous call.
- */
- private class RedactionPermissionChecker {
- private final int mCallingPid;
- private final int mCallingUid;
- @NonNull private final String mCallingPackageName;
- @Nullable private final String mCallingAttributionTag;
-
- private Boolean mHasLocationPermission = null;
- private Boolean mHasLocalMacAddressPermission = null;
- private Boolean mHasSettingsPermission = null;
-
- RedactionPermissionChecker(int callingPid, int callingUid,
- @NonNull String callingPackageName, @Nullable String callingAttributionTag) {
- mCallingPid = callingPid;
- mCallingUid = callingUid;
- mCallingPackageName = callingPackageName;
- mCallingAttributionTag = callingAttributionTag;
- }
-
- private boolean hasLocationPermissionInternal() {
- final long token = Binder.clearCallingIdentity();
- try {
- return mLocationPermissionChecker.checkLocationPermission(
- mCallingPackageName, mCallingAttributionTag, mCallingUid,
- null /* message */);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Returns whether the app holds location permission or not (might return cached result
- * if the permission was already checked before).
- */
- public boolean hasLocationPermission() {
- if (mHasLocationPermission == null) {
- // If there is no cached result, perform the check now.
- mHasLocationPermission = hasLocationPermissionInternal();
- }
- return mHasLocationPermission;
- }
-
- /**
- * Returns whether the app holds local mac address permission or not (might return cached
- * result if the permission was already checked before).
- */
- public boolean hasLocalMacAddressPermission() {
- if (mHasLocalMacAddressPermission == null) {
- // If there is no cached result, perform the check now.
- mHasLocalMacAddressPermission =
- checkLocalMacAddressPermission(mCallingPid, mCallingUid);
- }
- return mHasLocalMacAddressPermission;
- }
-
- /**
- * Returns whether the app holds settings permission or not (might return cached
- * result if the permission was already checked before).
- */
- public boolean hasSettingsPermission() {
- if (mHasSettingsPermission == null) {
- // If there is no cached result, perform the check now.
- mHasSettingsPermission = checkSettingsPermission(mCallingPid, mCallingUid);
- }
- return mHasSettingsPermission;
- }
- }
-
- private static boolean shouldRedact(@NetworkCapabilities.RedactionType long redactions,
- @NetworkCapabilities.NetCapability long redaction) {
- return (redactions & redaction) != 0;
- }
-
- /**
- * Use the provided |applicableRedactions| to check the receiving app's
- * permissions and clear/set the corresponding bit in the returned bitmask. The bitmask
- * returned will be used to ensure the necessary redactions are performed by NetworkCapabilities
- * before being sent to the corresponding app.
- */
- private @NetworkCapabilities.RedactionType long retrieveRequiredRedactions(
- @NetworkCapabilities.RedactionType long applicableRedactions,
- @NonNull RedactionPermissionChecker redactionPermissionChecker,
- boolean includeLocationSensitiveInfo) {
- long redactions = applicableRedactions;
- if (shouldRedact(redactions, REDACT_FOR_ACCESS_FINE_LOCATION)) {
- if (includeLocationSensitiveInfo
- && redactionPermissionChecker.hasLocationPermission()) {
- redactions &= ~REDACT_FOR_ACCESS_FINE_LOCATION;
- }
- }
- if (shouldRedact(redactions, REDACT_FOR_LOCAL_MAC_ADDRESS)) {
- if (redactionPermissionChecker.hasLocalMacAddressPermission()) {
- redactions &= ~REDACT_FOR_LOCAL_MAC_ADDRESS;
- }
- }
- if (shouldRedact(redactions, REDACT_FOR_NETWORK_SETTINGS)) {
- if (redactionPermissionChecker.hasSettingsPermission()) {
- redactions &= ~REDACT_FOR_NETWORK_SETTINGS;
- }
- }
- return redactions;
- }
-
- @VisibleForTesting
- @Nullable
- NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- @Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo,
- int callingPid, int callingUid, @NonNull String callingPkgName,
- @Nullable String callingAttributionTag) {
- if (nc == null) {
- return null;
- }
- // Avoid doing location permission check if the transport info has no location sensitive
- // data.
- final RedactionPermissionChecker redactionPermissionChecker =
- new RedactionPermissionChecker(callingPid, callingUid, callingPkgName,
- callingAttributionTag);
- final long redactions = retrieveRequiredRedactions(
- nc.getApplicableRedactions(), redactionPermissionChecker,
- includeLocationSensitiveInfo);
- final NetworkCapabilities newNc = new NetworkCapabilities(nc, redactions);
- // Reset owner uid if not destined for the owner app.
- if (callingUid != nc.getOwnerUid()) {
- newNc.setOwnerUid(INVALID_UID);
- return newNc;
- }
- // Allow VPNs to see ownership of their own VPN networks - not location sensitive.
- if (nc.hasTransport(TRANSPORT_VPN)) {
- // Owner UIDs already checked above. No need to re-check.
- return newNc;
- }
- // If the calling does not want location sensitive data & target SDK >= S, then mask info.
- // Else include the owner UID iff the calling has location permission to provide backwards
- // compatibility for older apps.
- if (!includeLocationSensitiveInfo
- && isTargetSdkAtleast(
- Build.VERSION_CODES.S, callingUid, callingPkgName)) {
- newNc.setOwnerUid(INVALID_UID);
- return newNc;
- }
- // Reset owner uid if the app has no location permission.
- if (!redactionPermissionChecker.hasLocationPermission()) {
- newNc.setOwnerUid(INVALID_UID);
- }
- return newNc;
- }
-
- private LinkProperties linkPropertiesRestrictedForCallerPermissions(
- LinkProperties lp, int callerPid, int callerUid) {
- if (lp == null) return new LinkProperties();
-
- // Only do a permission check if sanitization is needed, to avoid unnecessary binder calls.
- final boolean needsSanitization =
- (lp.getCaptivePortalApiUrl() != null || lp.getCaptivePortalData() != null);
- if (!needsSanitization) {
- return new LinkProperties(lp);
- }
-
- if (checkSettingsPermission(callerPid, callerUid)) {
- return new LinkProperties(lp, true /* parcelSensitiveFields */);
- }
-
- final LinkProperties newLp = new LinkProperties(lp);
- // Sensitive fields would not be parceled anyway, but sanitize for consistency before the
- // object gets parceled.
- newLp.setCaptivePortalApiUrl(null);
- newLp.setCaptivePortalData(null);
- return newLp;
- }
-
- private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc,
- int callerUid, String callerPackageName) {
- // There is no need to track the effective UID of the request here. If the caller
- // lacks the settings permission, the effective UID is the same as the calling ID.
- if (!checkSettingsPermission()) {
- // Unprivileged apps can only pass in null or their own UID.
- if (nc.getUids() == null) {
- // If the caller passes in null, the callback will also match networks that do not
- // apply to its UID, similarly to what it would see if it called getAllNetworks.
- // In this case, redact everything in the request immediately. This ensures that the
- // app is not able to get any redacted information by filing an unredacted request
- // and observing whether the request matches something.
- if (nc.getNetworkSpecifier() != null) {
- nc.setNetworkSpecifier(nc.getNetworkSpecifier().redact());
- }
- } else {
- nc.setSingleUid(callerUid);
- }
- }
- nc.setRequestorUidAndPackageName(callerUid, callerPackageName);
- nc.setAdministratorUids(new int[0]);
-
- // Clear owner UID; this can never come from an app.
- nc.setOwnerUid(INVALID_UID);
- }
-
- private void restrictBackgroundRequestForCaller(NetworkCapabilities nc) {
- if (!mPermissionMonitor.hasUseBackgroundNetworksPermission(mDeps.getCallingUid())) {
- nc.addCapability(NET_CAPABILITY_FOREGROUND);
- }
- }
-
- @Override
- public @RestrictBackgroundStatus int getRestrictBackgroundStatusByCaller() {
- enforceAccessPermission();
- final int callerUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- return mPolicyManager.getRestrictBackgroundStatus(callerUid);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- // TODO: Consider delete this function or turn it into a no-op method.
- @Override
- public NetworkState[] getAllNetworkState() {
- // This contains IMSI details, so make sure the caller is privileged.
- PermissionUtils.enforceNetworkStackPermission(mContext);
-
- final ArrayList<NetworkState> result = new ArrayList<>();
- for (NetworkStateSnapshot snapshot : getAllNetworkStateSnapshots()) {
- // NetworkStateSnapshot doesn't contain NetworkInfo, so need to fetch it from the
- // NetworkAgentInfo.
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(snapshot.getNetwork());
- if (nai != null && nai.networkInfo.isConnected()) {
- result.add(new NetworkState(new NetworkInfo(nai.networkInfo),
- snapshot.getLinkProperties(), snapshot.getNetworkCapabilities(),
- snapshot.getNetwork(), snapshot.getSubscriberId()));
- }
- }
- return result.toArray(new NetworkState[result.size()]);
- }
-
- @Override
- @NonNull
- public List<NetworkStateSnapshot> getAllNetworkStateSnapshots() {
- // This contains IMSI details, so make sure the caller is privileged.
- enforceNetworkStackOrSettingsPermission();
-
- final ArrayList<NetworkStateSnapshot> result = new ArrayList<>();
- for (Network network : getAllNetworks()) {
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
- // TODO: Consider include SUSPENDED networks, which should be considered as
- // temporary shortage of connectivity of a connected network.
- if (nai != null && nai.networkInfo.isConnected()) {
- // TODO (b/73321673) : NetworkStateSnapshot contains a copy of the
- // NetworkCapabilities, which may contain UIDs of apps to which the
- // network applies. Should the UIDs be cleared so as not to leak or
- // interfere ?
- result.add(nai.getNetworkStateSnapshot());
- }
- }
- return result;
- }
-
- @Override
- public boolean isActiveNetworkMetered() {
- enforceAccessPermission();
-
- final NetworkCapabilities caps = getNetworkCapabilitiesInternal(getActiveNetwork());
- if (caps != null) {
- return !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
- } else {
- // Always return the most conservative value
- return true;
- }
- }
-
- /**
- * Ensures that the system cannot call a particular method.
- */
- private boolean disallowedBecauseSystemCaller() {
- // TODO: start throwing a SecurityException when GnssLocationProvider stops calling
- // requestRouteToHost. In Q, GnssLocationProvider is changed to not call requestRouteToHost
- // for devices launched with Q and above. However, existing devices upgrading to Q and
- // above must continued to be supported for few more releases.
- if (isSystem(mDeps.getCallingUid()) && SystemProperties.getInt(
- "ro.product.first_api_level", 0) > Build.VERSION_CODES.P) {
- log("This method exists only for app backwards compatibility"
- + " and must not be called by system services.");
- return true;
- }
- return false;
- }
-
- /**
- * Ensure that a network route exists to deliver traffic to the specified
- * host via the specified network interface.
- * @param networkType the type of the network over which traffic to the
- * specified host is to be routed
- * @param hostAddress the IP address of the host to which the route is
- * desired
- * @return {@code true} on success, {@code false} on failure
- */
- @Override
- public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress,
- String callingPackageName, String callingAttributionTag) {
- if (disallowedBecauseSystemCaller()) {
- return false;
- }
- enforceChangePermission(callingPackageName, callingAttributionTag);
- if (mProtectedNetworks.contains(networkType)) {
- enforceConnectivityRestrictedNetworksPermission();
- }
-
- InetAddress addr;
- try {
- addr = InetAddress.getByAddress(hostAddress);
- } catch (UnknownHostException e) {
- if (DBG) log("requestRouteToHostAddress got " + e.toString());
- return false;
- }
-
- if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
- if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
- return false;
- }
-
- NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- if (nai == null) {
- if (mLegacyTypeTracker.isTypeSupported(networkType) == false) {
- if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType);
- } else {
- if (DBG) log("requestRouteToHostAddress on down network: " + networkType);
- }
- return false;
- }
-
- DetailedState netState;
- synchronized (nai) {
- netState = nai.networkInfo.getDetailedState();
- }
-
- if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) {
- if (VDBG) {
- log("requestRouteToHostAddress on down network "
- + "(" + networkType + ") - dropped"
- + " netState=" + netState);
- }
- return false;
- }
-
- final int uid = mDeps.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- LinkProperties lp;
- int netId;
- synchronized (nai) {
- lp = nai.linkProperties;
- netId = nai.network.getNetId();
- }
- boolean ok = addLegacyRouteToHost(lp, addr, netId, uid);
- if (DBG) {
- log("requestRouteToHostAddress " + addr + nai.toShortString() + " ok=" + ok);
- }
- return ok;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) {
- RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr);
- if (bestRoute == null) {
- bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName());
- } else {
- String iface = bestRoute.getInterface();
- if (bestRoute.getGateway().equals(addr)) {
- // if there is no better route, add the implied hostroute for our gateway
- bestRoute = RouteInfo.makeHostRoute(addr, iface);
- } else {
- // if we will connect to this through another route, add a direct route
- // to it's gateway
- bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface);
- }
- }
- if (DBG) log("Adding legacy route " + bestRoute +
- " for UID/PID " + uid + "/" + Binder.getCallingPid());
-
- final String dst = bestRoute.getDestinationLinkAddress().toString();
- final String nextHop = bestRoute.hasGateway()
- ? bestRoute.getGateway().getHostAddress() : "";
- try {
- mNetd.networkAddLegacyRoute(netId, bestRoute.getInterface(), dst, nextHop , uid);
- } catch (RemoteException | ServiceSpecificException e) {
- if (DBG) loge("Exception trying to add a route: " + e);
- return false;
- }
- return true;
- }
-
- class DnsResolverUnsolicitedEventCallback extends
- IDnsResolverUnsolicitedEventListener.Stub {
- @Override
- public void onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event) {
- try {
- mHandler.sendMessage(mHandler.obtainMessage(
- EVENT_PRIVATE_DNS_VALIDATION_UPDATE,
- new PrivateDnsValidationUpdate(event.netId,
- InetAddresses.parseNumericAddress(event.ipAddress),
- event.hostname, event.validation)));
- } catch (IllegalArgumentException e) {
- loge("Error parsing ip address in validation event");
- }
- }
-
- @Override
- public void onDnsHealthEvent(final DnsHealthEventParcel event) {
- NetworkAgentInfo nai = getNetworkAgentInfoForNetId(event.netId);
- // Netd event only allow registrants from system. Each NetworkMonitor thread is under
- // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd
- // event callback for certain nai. e.g. cellular. Register here to pass to
- // NetworkMonitor instead.
- // TODO: Move the Dns Event to NetworkMonitor. NetdEventListenerService only allow one
- // callback from each caller type. Need to re-factor NetdEventListenerService to allow
- // multiple NetworkMonitor registrants.
- if (nai != null && nai.satisfies(mDefaultRequest.mRequests.get(0))) {
- nai.networkMonitor().notifyDnsResponse(event.healthResult);
- }
- }
-
- @Override
- public void onNat64PrefixEvent(final Nat64PrefixEventParcel event) {
- mHandler.post(() -> handleNat64PrefixEvent(event.netId, event.prefixOperation,
- event.prefixAddress, event.prefixLength));
- }
-
- @Override
- public int getInterfaceVersion() {
- return this.VERSION;
- }
-
- @Override
- public String getInterfaceHash() {
- return this.HASH;
- }
- }
-
- @VisibleForTesting
- protected final DnsResolverUnsolicitedEventCallback mResolverUnsolEventCallback =
- new DnsResolverUnsolicitedEventCallback();
-
- private void registerDnsResolverUnsolicitedEventListener() {
- try {
- mDnsResolver.registerUnsolicitedEventListener(mResolverUnsolEventCallback);
- } catch (Exception e) {
- loge("Error registering DnsResolver unsolicited event callback: " + e);
- }
- }
-
- private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() {
- @Override
- public void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_BLOCKED_REASON_CHANGED,
- uid, blockedReasons));
- }
- };
-
- private void handleUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {
- maybeNotifyNetworkBlockedForNewState(uid, blockedReasons);
- setUidBlockedReasons(uid, blockedReasons);
- }
-
- private boolean checkAnyPermissionOf(String... permissions) {
- for (String permission : permissions) {
- if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
- return true;
- }
- }
- return false;
- }
-
- private boolean checkAnyPermissionOf(int pid, int uid, String... permissions) {
- for (String permission : permissions) {
- if (mContext.checkPermission(permission, pid, uid) == PERMISSION_GRANTED) {
- return true;
- }
- }
- return false;
- }
-
- private void enforceAnyPermissionOf(String... permissions) {
- if (!checkAnyPermissionOf(permissions)) {
- throw new SecurityException("Requires one of the following permissions: "
- + String.join(", ", permissions) + ".");
- }
- }
-
- private void enforceInternetPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.INTERNET,
- "ConnectivityService");
- }
-
- private void enforceAccessPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_NETWORK_STATE,
- "ConnectivityService");
- }
-
- /**
- * Performs a strict and comprehensive check of whether a calling package is allowed to
- * change the state of network, as the condition differs for pre-M, M+, and
- * privileged/preinstalled apps. The caller is expected to have either the
- * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these
- * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and
- * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal
- * permission and cannot be revoked. See http://b/23597341
- *
- * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation
- * of this app will be updated to the current time.
- */
- private void enforceChangePermission(String callingPkg, String callingAttributionTag) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE)
- == PackageManager.PERMISSION_GRANTED) {
- return;
- }
-
- if (callingPkg == null) {
- throw new SecurityException("Calling package name is null.");
- }
-
- final AppOpsManager appOpsMgr = mContext.getSystemService(AppOpsManager.class);
- final int uid = mDeps.getCallingUid();
- final int mode = appOpsMgr.noteOpNoThrow(AppOpsManager.OPSTR_WRITE_SETTINGS, uid,
- callingPkg, callingAttributionTag, null /* message */);
-
- if (mode == AppOpsManager.MODE_ALLOWED) {
- return;
- }
-
- if ((mode == AppOpsManager.MODE_DEFAULT) && (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED)) {
- return;
- }
-
- throw new SecurityException(callingPkg + " was not granted either of these permissions:"
- + android.Manifest.permission.CHANGE_NETWORK_STATE + ","
- + android.Manifest.permission.WRITE_SETTINGS + ".");
- }
-
- private void enforceSettingsPermission() {
- enforceAnyPermissionOf(
- android.Manifest.permission.NETWORK_SETTINGS,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
- }
-
- private void enforceNetworkFactoryPermission() {
- enforceAnyPermissionOf(
- android.Manifest.permission.NETWORK_FACTORY,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
- }
-
- private void enforceNetworkFactoryOrSettingsPermission() {
- enforceAnyPermissionOf(
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_FACTORY,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
- }
-
- private void enforceNetworkFactoryOrTestNetworksPermission() {
- enforceAnyPermissionOf(
- android.Manifest.permission.MANAGE_TEST_NETWORKS,
- android.Manifest.permission.NETWORK_FACTORY,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
- }
-
- private boolean checkSettingsPermission() {
- return checkAnyPermissionOf(
- android.Manifest.permission.NETWORK_SETTINGS,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
- }
-
- private boolean checkSettingsPermission(int pid, int uid) {
- return PERMISSION_GRANTED == mContext.checkPermission(
- android.Manifest.permission.NETWORK_SETTINGS, pid, uid)
- || PERMISSION_GRANTED == mContext.checkPermission(
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid);
- }
-
- private void enforceNetworkStackOrSettingsPermission() {
- enforceAnyPermissionOf(
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
- }
-
- private void enforceNetworkStackSettingsOrSetup() {
- enforceAnyPermissionOf(
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD,
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
- }
-
- private void enforceAirplaneModePermission() {
- enforceAnyPermissionOf(
- android.Manifest.permission.NETWORK_AIRPLANE_MODE,
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD,
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
- }
-
- private void enforceOemNetworkPreferencesPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE,
- "ConnectivityService");
- }
-
- private boolean checkNetworkStackPermission() {
- return checkAnyPermissionOf(
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
- }
-
- private boolean checkNetworkStackPermission(int pid, int uid) {
- return checkAnyPermissionOf(pid, uid,
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
- }
-
- private boolean checkNetworkSignalStrengthWakeupPermission(int pid, int uid) {
- return checkAnyPermissionOf(pid, uid,
- android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_SETTINGS);
- }
-
- private void enforceConnectivityRestrictedNetworksPermission() {
- try {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS,
- "ConnectivityService");
- return;
- } catch (SecurityException e) { /* fallback to ConnectivityInternalPermission */ }
- // TODO: Remove this fallback check after all apps have declared
- // CONNECTIVITY_USE_RESTRICTED_NETWORKS.
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CONNECTIVITY_INTERNAL,
- "ConnectivityService");
- }
-
- private void enforceKeepalivePermission() {
- mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
- }
-
- private boolean checkLocalMacAddressPermission(int pid, int uid) {
- return PERMISSION_GRANTED == mContext.checkPermission(
- Manifest.permission.LOCAL_MAC_ADDRESS, pid, uid);
- }
-
- private void sendConnectedBroadcast(NetworkInfo info) {
- sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
- }
-
- private void sendInetConditionBroadcast(NetworkInfo info) {
- sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
- }
-
- private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
- Intent intent = new Intent(bcastType);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info));
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
- if (info.isFailover()) {
- intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
- info.setFailover(false);
- }
- if (info.getReason() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
- }
- if (info.getExtraInfo() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
- info.getExtraInfo());
- }
- intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
- return intent;
- }
-
- private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
- sendStickyBroadcast(makeGeneralIntent(info, bcastType));
- }
-
- private void sendStickyBroadcast(Intent intent) {
- synchronized (this) {
- if (!mSystemReady
- && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
- mInitialBroadcast = new Intent(intent);
- }
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- if (VDBG) {
- log("sendStickyBroadcast: action=" + intent.getAction());
- }
-
- Bundle options = null;
- final long ident = Binder.clearCallingIdentity();
- if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
- final NetworkInfo ni = intent.getParcelableExtra(
- ConnectivityManager.EXTRA_NETWORK_INFO);
- final BroadcastOptions opts = BroadcastOptions.makeBasic();
- opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M);
- options = opts.toBundle();
- intent.addFlags(Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
- }
- try {
- mUserAllContext.sendStickyBroadcast(intent, options);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- /**
- * Called by SystemServer through ConnectivityManager when the system is ready.
- */
- @Override
- public void systemReady() {
- if (mDeps.getCallingUid() != Process.SYSTEM_UID) {
- throw new SecurityException("Calling Uid is not system uid.");
- }
- systemReadyInternal();
- }
-
- /**
- * Called when ConnectivityService can initialize remaining components.
- */
- @VisibleForTesting
- public void systemReadyInternal() {
- // Since mApps in PermissionMonitor needs to be populated first to ensure that
- // listening network request which is sent by MultipathPolicyTracker won't be added
- // NET_CAPABILITY_FOREGROUND capability. Thus, MultipathPolicyTracker.start() must
- // be called after PermissionMonitor#startMonitoring().
- // Calling PermissionMonitor#startMonitoring() in systemReadyInternal() and the
- // MultipathPolicyTracker.start() is called in NetworkPolicyManagerService#systemReady()
- // to ensure the tracking will be initialized correctly.
- mPermissionMonitor.startMonitoring();
- mProxyTracker.loadGlobalProxy();
- registerDnsResolverUnsolicitedEventListener();
-
- synchronized (this) {
- mSystemReady = true;
- if (mInitialBroadcast != null) {
- mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL);
- mInitialBroadcast = null;
- }
- }
-
- // Create network requests for always-on networks.
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS));
- }
-
- /**
- * Start listening for default data network activity state changes.
- */
- @Override
- public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
- mNetworkActivityTracker.registerNetworkActivityListener(l);
- }
-
- /**
- * Stop listening for default data network activity state changes.
- */
- @Override
- public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
- mNetworkActivityTracker.unregisterNetworkActivityListener(l);
- }
-
- /**
- * Check whether the default network radio is currently active.
- */
- @Override
- public boolean isDefaultNetworkActive() {
- return mNetworkActivityTracker.isDefaultNetworkActive();
- }
-
- /**
- * Reads the network specific MTU size from resources.
- * and set it on it's iface.
- */
- private void updateMtu(LinkProperties newLp, LinkProperties oldLp) {
- final String iface = newLp.getInterfaceName();
- final int mtu = newLp.getMtu();
- if (oldLp == null && mtu == 0) {
- // Silently ignore unset MTU value.
- return;
- }
- if (oldLp != null && newLp.isIdenticalMtu(oldLp)) {
- if (VDBG) log("identical MTU - not setting");
- return;
- }
- if (!LinkProperties.isValidMtu(mtu, newLp.hasGlobalIpv6Address())) {
- if (mtu != 0) loge("Unexpected mtu value: " + mtu + ", " + iface);
- return;
- }
-
- // Cannot set MTU without interface name
- if (TextUtils.isEmpty(iface)) {
- loge("Setting MTU size with null iface.");
- return;
- }
-
- try {
- if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu);
- mNetd.interfaceSetMtu(iface, mtu);
- } catch (RemoteException | ServiceSpecificException e) {
- loge("exception in interfaceSetMtu()" + e);
- }
- }
-
- @VisibleForTesting
- protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208";
-
- private void updateTcpBufferSizes(String tcpBufferSizes) {
- String[] values = null;
- if (tcpBufferSizes != null) {
- values = tcpBufferSizes.split(",");
- }
-
- if (values == null || values.length != 6) {
- if (DBG) log("Invalid tcpBufferSizes string: " + tcpBufferSizes +", using defaults");
- tcpBufferSizes = DEFAULT_TCP_BUFFER_SIZES;
- values = tcpBufferSizes.split(",");
- }
-
- if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return;
-
- try {
- if (VDBG || DDBG) log("Setting tx/rx TCP buffers to " + tcpBufferSizes);
-
- String rmemValues = String.join(" ", values[0], values[1], values[2]);
- String wmemValues = String.join(" ", values[3], values[4], values[5]);
- mNetd.setTcpRWmemorySize(rmemValues, wmemValues);
- mCurrentTcpBufferSizes = tcpBufferSizes;
- } catch (RemoteException | ServiceSpecificException e) {
- loge("Can't set TCP buffer sizes:" + e);
- }
- }
-
- @Override
- public int getRestoreDefaultNetworkDelay(int networkType) {
- String restoreDefaultNetworkDelayStr = mSystemProperties.get(
- NETWORK_RESTORE_DELAY_PROP_NAME);
- if(restoreDefaultNetworkDelayStr != null &&
- restoreDefaultNetworkDelayStr.length() != 0) {
- try {
- return Integer.parseInt(restoreDefaultNetworkDelayStr);
- } catch (NumberFormatException e) {
- }
- }
- // if the system property isn't set, use the value for the apn type
- int ret = RESTORE_DEFAULT_NETWORK_DELAY;
-
- if (mLegacyTypeTracker.isTypeSupported(networkType)) {
- ret = mLegacyTypeTracker.getRestoreTimerForType(networkType);
- }
- return ret;
- }
-
- private void dumpNetworkDiagnostics(IndentingPrintWriter pw) {
- final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>();
- final long DIAG_TIME_MS = 5000;
- for (NetworkAgentInfo nai : networksSortedById()) {
- PrivateDnsConfig privateDnsCfg = mDnsManager.getPrivateDnsConfig(nai.network);
- // Start gathering diagnostic information.
- netDiags.add(new NetworkDiagnostics(
- nai.network,
- new LinkProperties(nai.linkProperties), // Must be a copy.
- privateDnsCfg,
- DIAG_TIME_MS));
- }
-
- for (NetworkDiagnostics netDiag : netDiags) {
- pw.println();
- netDiag.waitForMeasurements();
- netDiag.dump(pw);
- }
- }
-
- @Override
- protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
- @Nullable String[] args) {
- if (!checkDumpPermission(mContext, TAG, writer)) return;
-
- mPriorityDumper.dump(fd, writer, args);
- }
-
- private boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
- if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump " + tag + " from from pid="
- + Binder.getCallingPid() + ", uid=" + mDeps.getCallingUid()
- + " due to missing android.permission.DUMP permission");
- return false;
- } else {
- return true;
- }
- }
-
- private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) {
- final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
-
- if (CollectionUtils.contains(args, DIAG_ARG)) {
- dumpNetworkDiagnostics(pw);
- return;
- } else if (CollectionUtils.contains(args, NETWORK_ARG)) {
- dumpNetworks(pw);
- return;
- } else if (CollectionUtils.contains(args, REQUEST_ARG)) {
- dumpNetworkRequests(pw);
- return;
- }
-
- pw.print("NetworkProviders for:");
- for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
- pw.print(" " + npi.name);
- }
- pw.println();
- pw.println();
-
- final NetworkAgentInfo defaultNai = getDefaultNetwork();
- pw.print("Active default network: ");
- if (defaultNai == null) {
- pw.println("none");
- } else {
- pw.println(defaultNai.network.getNetId());
- }
- pw.println();
-
- pw.print("Current per-app default networks: ");
- pw.increaseIndent();
- dumpPerAppNetworkPreferences(pw);
- pw.decreaseIndent();
- pw.println();
-
- pw.println("Current Networks:");
- pw.increaseIndent();
- dumpNetworks(pw);
- pw.decreaseIndent();
- pw.println();
-
- pw.println("Status for known UIDs:");
- pw.increaseIndent();
- final int size = mUidBlockedReasons.size();
- for (int i = 0; i < size; i++) {
- // Don't crash if the array is modified while dumping in bugreports.
- try {
- final int uid = mUidBlockedReasons.keyAt(i);
- final int blockedReasons = mUidBlockedReasons.valueAt(i);
- pw.println("UID=" + uid + " blockedReasons="
- + Integer.toHexString(blockedReasons));
- } catch (ArrayIndexOutOfBoundsException e) {
- pw.println(" ArrayIndexOutOfBoundsException");
- } catch (ConcurrentModificationException e) {
- pw.println(" ConcurrentModificationException");
- }
- }
- pw.println();
- pw.decreaseIndent();
-
- pw.println("Network Requests:");
- pw.increaseIndent();
- dumpNetworkRequests(pw);
- pw.decreaseIndent();
- pw.println();
-
- mLegacyTypeTracker.dump(pw);
-
- pw.println();
- mKeepaliveTracker.dump(pw);
-
- pw.println();
- dumpAvoidBadWifiSettings(pw);
-
- pw.println();
-
- if (!CollectionUtils.contains(args, SHORT_ARG)) {
- pw.println();
- pw.println("mNetworkRequestInfoLogs (most recent first):");
- pw.increaseIndent();
- mNetworkRequestInfoLogs.reverseDump(pw);
- pw.decreaseIndent();
-
- pw.println();
- pw.println("mNetworkInfoBlockingLogs (most recent first):");
- pw.increaseIndent();
- mNetworkInfoBlockingLogs.reverseDump(pw);
- pw.decreaseIndent();
-
- pw.println();
- pw.println("NetTransition WakeLock activity (most recent first):");
- pw.increaseIndent();
- pw.println("total acquisitions: " + mTotalWakelockAcquisitions);
- pw.println("total releases: " + mTotalWakelockReleases);
- pw.println("cumulative duration: " + (mTotalWakelockDurationMs / 1000) + "s");
- pw.println("longest duration: " + (mMaxWakelockDurationMs / 1000) + "s");
- if (mTotalWakelockAcquisitions > mTotalWakelockReleases) {
- long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
- pw.println("currently holding WakeLock for: " + (duration / 1000) + "s");
- }
- mWakelockLogs.reverseDump(pw);
-
- pw.println();
- pw.println("bandwidth update requests (by uid):");
- pw.increaseIndent();
- synchronized (mBandwidthRequests) {
- for (int i = 0; i < mBandwidthRequests.size(); i++) {
- pw.println("[" + mBandwidthRequests.keyAt(i)
- + "]: " + mBandwidthRequests.valueAt(i));
- }
- }
- pw.decreaseIndent();
- pw.decreaseIndent();
-
- pw.println();
- pw.println("mOemNetworkPreferencesLogs (most recent first):");
- pw.increaseIndent();
- mOemNetworkPreferencesLogs.reverseDump(pw);
- pw.decreaseIndent();
- }
-
- pw.println();
-
- pw.println();
- pw.println("Permission Monitor:");
- pw.increaseIndent();
- mPermissionMonitor.dump(pw);
- pw.decreaseIndent();
-
- pw.println();
- pw.println("Legacy network activity:");
- pw.increaseIndent();
- mNetworkActivityTracker.dump(pw);
- pw.decreaseIndent();
- }
-
- private void dumpNetworks(IndentingPrintWriter pw) {
- for (NetworkAgentInfo nai : networksSortedById()) {
- pw.println(nai.toString());
- pw.increaseIndent();
- pw.println(String.format(
- "Requests: REQUEST:%d LISTEN:%d BACKGROUND_REQUEST:%d total:%d",
- nai.numForegroundNetworkRequests(),
- nai.numNetworkRequests() - nai.numRequestNetworkRequests(),
- nai.numBackgroundNetworkRequests(),
- nai.numNetworkRequests()));
- pw.increaseIndent();
- for (int i = 0; i < nai.numNetworkRequests(); i++) {
- pw.println(nai.requestAt(i).toString());
- }
- pw.decreaseIndent();
- pw.println("Inactivity Timers:");
- pw.increaseIndent();
- nai.dumpInactivityTimers(pw);
- pw.decreaseIndent();
- pw.decreaseIndent();
- }
- }
-
- private void dumpPerAppNetworkPreferences(IndentingPrintWriter pw) {
- pw.println("Per-App Network Preference:");
- pw.increaseIndent();
- if (0 == mOemNetworkPreferences.getNetworkPreferences().size()) {
- pw.println("none");
- } else {
- pw.println(mOemNetworkPreferences.toString());
- }
- pw.decreaseIndent();
-
- for (final NetworkRequestInfo defaultRequest : mDefaultNetworkRequests) {
- if (mDefaultRequest == defaultRequest) {
- continue;
- }
-
- final boolean isActive = null != defaultRequest.getSatisfier();
- pw.println("Is per-app network active:");
- pw.increaseIndent();
- pw.println(isActive);
- if (isActive) {
- pw.println("Active network: " + defaultRequest.getSatisfier().network.netId);
- }
- pw.println("Tracked UIDs:");
- pw.increaseIndent();
- if (0 == defaultRequest.mRequests.size()) {
- pw.println("none, this should never occur.");
- } else {
- pw.println(defaultRequest.mRequests.get(0).networkCapabilities.getUidRanges());
- }
- pw.decreaseIndent();
- pw.decreaseIndent();
- }
- }
-
- private void dumpNetworkRequests(IndentingPrintWriter pw) {
- for (NetworkRequestInfo nri : requestsSortedById()) {
- pw.println(nri.toString());
- }
- }
-
- /**
- * Return an array of all current NetworkAgentInfos sorted by network id.
- */
- private NetworkAgentInfo[] networksSortedById() {
- NetworkAgentInfo[] networks = new NetworkAgentInfo[0];
- networks = mNetworkAgentInfos.toArray(networks);
- Arrays.sort(networks, Comparator.comparingInt(nai -> nai.network.getNetId()));
- return networks;
- }
-
- /**
- * Return an array of all current NetworkRequest sorted by request id.
- */
- @VisibleForTesting
- NetworkRequestInfo[] requestsSortedById() {
- NetworkRequestInfo[] requests = new NetworkRequestInfo[0];
- requests = getNrisFromGlobalRequests().toArray(requests);
- // Sort the array based off the NRI containing the min requestId in its requests.
- Arrays.sort(requests,
- Comparator.comparingInt(nri -> Collections.min(nri.mRequests,
- Comparator.comparingInt(req -> req.requestId)).requestId
- )
- );
- return requests;
- }
-
- private boolean isLiveNetworkAgent(NetworkAgentInfo nai, int what) {
- final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network);
- if (officialNai != null && officialNai.equals(nai)) return true;
- if (officialNai != null || VDBG) {
- loge(eventName(what) + " - isLiveNetworkAgent found mismatched netId: " + officialNai +
- " - " + nai);
- }
- return false;
- }
-
- // must be stateless - things change under us.
- private class NetworkStateTrackerHandler extends Handler {
- public NetworkStateTrackerHandler(Looper looper) {
- super(looper);
- }
-
- private void maybeHandleNetworkAgentMessage(Message msg) {
- final Pair<NetworkAgentInfo, Object> arg = (Pair<NetworkAgentInfo, Object>) msg.obj;
- final NetworkAgentInfo nai = arg.first;
- if (!mNetworkAgentInfos.contains(nai)) {
- if (VDBG) {
- log(String.format("%s from unknown NetworkAgent", eventName(msg.what)));
- }
- return;
- }
-
- switch (msg.what) {
- case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
- NetworkCapabilities networkCapabilities = (NetworkCapabilities) arg.second;
- if (networkCapabilities.hasConnectivityManagedCapability()) {
- Log.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
- }
- if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
- // Make sure the original object is not mutated. NetworkAgent normally
- // makes a copy of the capabilities when sending the message through
- // the Messenger, but if this ever changes, not making a defensive copy
- // here will give attack vectors to clients using this code path.
- networkCapabilities = new NetworkCapabilities(networkCapabilities);
- networkCapabilities.restrictCapabilitesForTestNetwork(nai.creatorUid);
- }
- processCapabilitiesFromAgent(nai, networkCapabilities);
- updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
- break;
- }
- case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: {
- LinkProperties newLp = (LinkProperties) arg.second;
- processLinkPropertiesFromAgent(nai, newLp);
- handleUpdateLinkProperties(nai, newLp);
- break;
- }
- case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {
- NetworkInfo info = (NetworkInfo) arg.second;
- updateNetworkInfo(nai, info);
- break;
- }
- case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
- updateNetworkScore(nai, (NetworkScore) arg.second);
- break;
- }
- case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
- if (nai.everConnected) {
- loge("ERROR: cannot call explicitlySelected on already-connected network");
- // Note that if the NAI had been connected, this would affect the
- // score, and therefore would require re-mixing the score and performing
- // a rematch.
- }
- nai.networkAgentConfig.explicitlySelected = toBool(msg.arg1);
- nai.networkAgentConfig.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2);
- // Mark the network as temporarily accepting partial connectivity so that it
- // will be validated (and possibly become default) even if it only provides
- // partial internet access. Note that if user connects to partial connectivity
- // and choose "don't ask again", then wifi disconnected by some reasons(maybe
- // out of wifi coverage) and if the same wifi is available again, the device
- // will auto connect to this wifi even though the wifi has "no internet".
- // TODO: Evaluate using a separate setting in IpMemoryStore.
- nai.networkAgentConfig.acceptPartialConnectivity = toBool(msg.arg2);
- break;
- }
- case NetworkAgent.EVENT_SOCKET_KEEPALIVE: {
- mKeepaliveTracker.handleEventSocketKeepalive(nai, msg.arg1, msg.arg2);
- break;
- }
- case NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED: {
- // TODO: prevent loops, e.g., if a network declares itself as underlying.
- if (!nai.supportsUnderlyingNetworks()) {
- Log.wtf(TAG, "Non-virtual networks cannot have underlying networks");
- break;
- }
-
- final List<Network> underlying = (List<Network>) arg.second;
-
- if (isLegacyLockdownNai(nai)
- && (underlying == null || underlying.size() != 1)) {
- Log.wtf(TAG, "Legacy lockdown VPN " + nai.toShortString()
- + " must have exactly one underlying network: " + underlying);
- }
-
- final Network[] oldUnderlying = nai.declaredUnderlyingNetworks;
- nai.declaredUnderlyingNetworks = (underlying != null)
- ? underlying.toArray(new Network[0]) : null;
-
- if (!Arrays.equals(oldUnderlying, nai.declaredUnderlyingNetworks)) {
- if (DBG) {
- log(nai.toShortString() + " changed underlying networks to "
- + Arrays.toString(nai.declaredUnderlyingNetworks));
- }
- updateCapabilitiesForNetwork(nai);
- notifyIfacesChangedForNetworkStats();
- }
- break;
- }
- case NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED: {
- if (msg.arg1 >= 0 && msg.arg1 <= NetworkAgent.MAX_TEARDOWN_DELAY_MS) {
- nai.teardownDelayMs = msg.arg1;
- } else {
- logwtf(nai.toShortString() + " set invalid teardown delay " + msg.arg1);
- }
- break;
- }
- case NetworkAgent.EVENT_LINGER_DURATION_CHANGED: {
- nai.setLingerDuration((int) arg.second);
- break;
- }
- }
- }
-
- private boolean maybeHandleNetworkMonitorMessage(Message msg) {
- switch (msg.what) {
- default:
- return false;
- case EVENT_PROBE_STATUS_CHANGED: {
- final Integer netId = (Integer) msg.obj;
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
- if (nai == null) {
- break;
- }
- final boolean probePrivateDnsCompleted =
- ((msg.arg1 & NETWORK_VALIDATION_PROBE_PRIVDNS) != 0);
- final boolean privateDnsBroken =
- ((msg.arg2 & NETWORK_VALIDATION_PROBE_PRIVDNS) == 0);
- if (probePrivateDnsCompleted) {
- if (nai.networkCapabilities.isPrivateDnsBroken() != privateDnsBroken) {
- nai.networkCapabilities.setPrivateDnsBroken(privateDnsBroken);
- updateCapabilitiesForNetwork(nai);
- }
- // Only show the notification when the private DNS is broken and the
- // PRIVATE_DNS_BROKEN notification hasn't shown since last valid.
- if (privateDnsBroken && !nai.networkAgentConfig.hasShownBroken) {
- showNetworkNotification(nai, NotificationType.PRIVATE_DNS_BROKEN);
- }
- nai.networkAgentConfig.hasShownBroken = privateDnsBroken;
- } else if (nai.networkCapabilities.isPrivateDnsBroken()) {
- // If probePrivateDnsCompleted is false but nai.networkCapabilities says
- // private DNS is broken, it means this network is being reevaluated.
- // Either probing private DNS is not necessary any more or it hasn't been
- // done yet. In either case, the networkCapabilities should be updated to
- // reflect the new status.
- nai.networkCapabilities.setPrivateDnsBroken(false);
- updateCapabilitiesForNetwork(nai);
- nai.networkAgentConfig.hasShownBroken = false;
- }
- break;
- }
- case EVENT_NETWORK_TESTED: {
- final NetworkTestedResults results = (NetworkTestedResults) msg.obj;
-
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(results.mNetId);
- if (nai == null) break;
-
- handleNetworkTested(nai, results.mTestResult,
- (results.mRedirectUrl == null) ? "" : results.mRedirectUrl);
- break;
- }
- case EVENT_PROVISIONING_NOTIFICATION: {
- final int netId = msg.arg2;
- final boolean visible = toBool(msg.arg1);
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
- // If captive portal status has changed, update capabilities or disconnect.
- if (nai != null && (visible != nai.lastCaptivePortalDetected)) {
- nai.lastCaptivePortalDetected = visible;
- nai.everCaptivePortalDetected |= visible;
- if (nai.lastCaptivePortalDetected &&
- ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID
- == getCaptivePortalMode()) {
- if (DBG) log("Avoiding captive portal network: " + nai.toShortString());
- nai.onPreventAutomaticReconnect();
- teardownUnneededNetwork(nai);
- break;
- }
- updateCapabilitiesForNetwork(nai);
- }
- if (!visible) {
- // Only clear SIGN_IN and NETWORK_SWITCH notifications here, or else other
- // notifications belong to the same network may be cleared unexpectedly.
- mNotifier.clearNotification(netId, NotificationType.SIGN_IN);
- mNotifier.clearNotification(netId, NotificationType.NETWORK_SWITCH);
- } else {
- if (nai == null) {
- loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
- break;
- }
- if (!nai.networkAgentConfig.provisioningNotificationDisabled) {
- mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai, null,
- (PendingIntent) msg.obj,
- nai.networkAgentConfig.explicitlySelected);
- }
- }
- break;
- }
- case EVENT_PRIVATE_DNS_CONFIG_RESOLVED: {
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
- if (nai == null) break;
-
- updatePrivateDns(nai, (PrivateDnsConfig) msg.obj);
- break;
- }
- case EVENT_CAPPORT_DATA_CHANGED: {
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
- if (nai == null) break;
- handleCapportApiDataUpdate(nai, (CaptivePortalData) msg.obj);
- break;
- }
- }
- return true;
- }
-
- private void handleNetworkTested(
- @NonNull NetworkAgentInfo nai, int testResult, @NonNull String redirectUrl) {
- final boolean wasPartial = nai.partialConnectivity;
- nai.partialConnectivity = ((testResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0);
- final boolean partialConnectivityChanged =
- (wasPartial != nai.partialConnectivity);
-
- final boolean valid = ((testResult & NETWORK_VALIDATION_RESULT_VALID) != 0);
- final boolean wasValidated = nai.lastValidated;
- final boolean wasDefault = isDefaultNetwork(nai);
-
- if (DBG) {
- final String logMsg = !TextUtils.isEmpty(redirectUrl)
- ? " with redirect to " + redirectUrl
- : "";
- log(nai.toShortString() + " validation " + (valid ? "passed" : "failed") + logMsg);
- }
- if (valid != nai.lastValidated) {
- final int oldScore = nai.getCurrentScore();
- nai.lastValidated = valid;
- nai.everValidated |= valid;
- updateCapabilities(oldScore, nai, nai.networkCapabilities);
- if (valid) {
- handleFreshlyValidatedNetwork(nai);
- // Clear NO_INTERNET, PRIVATE_DNS_BROKEN, PARTIAL_CONNECTIVITY and
- // LOST_INTERNET notifications if network becomes valid.
- mNotifier.clearNotification(nai.network.getNetId(),
- NotificationType.NO_INTERNET);
- mNotifier.clearNotification(nai.network.getNetId(),
- NotificationType.LOST_INTERNET);
- mNotifier.clearNotification(nai.network.getNetId(),
- NotificationType.PARTIAL_CONNECTIVITY);
- mNotifier.clearNotification(nai.network.getNetId(),
- NotificationType.PRIVATE_DNS_BROKEN);
- // If network becomes valid, the hasShownBroken should be reset for
- // that network so that the notification will be fired when the private
- // DNS is broken again.
- nai.networkAgentConfig.hasShownBroken = false;
- }
- } else if (partialConnectivityChanged) {
- updateCapabilitiesForNetwork(nai);
- }
- updateInetCondition(nai);
- // Let the NetworkAgent know the state of its network
- // TODO: Evaluate to update partial connectivity to status to NetworkAgent.
- nai.onValidationStatusChanged(
- valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK,
- redirectUrl);
-
- // If NetworkMonitor detects partial connectivity before
- // EVENT_PROMPT_UNVALIDATED arrives, show the partial connectivity notification
- // immediately. Re-notify partial connectivity silently if no internet
- // notification already there.
- if (!wasPartial && nai.partialConnectivity) {
- // Remove delayed message if there is a pending message.
- mHandler.removeMessages(EVENT_PROMPT_UNVALIDATED, nai.network);
- handlePromptUnvalidated(nai.network);
- }
-
- if (wasValidated && !nai.lastValidated) {
- handleNetworkUnvalidated(nai);
- }
- }
-
- private int getCaptivePortalMode() {
- return Settings.Global.getInt(mContext.getContentResolver(),
- ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE,
- ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT);
- }
-
- private boolean maybeHandleNetworkAgentInfoMessage(Message msg) {
- switch (msg.what) {
- default:
- return false;
- case NetworkAgentInfo.EVENT_NETWORK_LINGER_COMPLETE: {
- NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
- if (nai != null && isLiveNetworkAgent(nai, msg.what)) {
- handleLingerComplete(nai);
- }
- break;
- }
- case NetworkAgentInfo.EVENT_AGENT_REGISTERED: {
- handleNetworkAgentRegistered(msg);
- break;
- }
- case NetworkAgentInfo.EVENT_AGENT_DISCONNECTED: {
- handleNetworkAgentDisconnected(msg);
- break;
- }
- }
- return true;
- }
-
- @Override
- public void handleMessage(Message msg) {
- if (!maybeHandleNetworkMonitorMessage(msg)
- && !maybeHandleNetworkAgentInfoMessage(msg)) {
- maybeHandleNetworkAgentMessage(msg);
- }
- }
- }
-
- private class NetworkMonitorCallbacks extends INetworkMonitorCallbacks.Stub {
- private final int mNetId;
- private final AutodestructReference<NetworkAgentInfo> mNai;
-
- private NetworkMonitorCallbacks(NetworkAgentInfo nai) {
- mNetId = nai.network.getNetId();
- mNai = new AutodestructReference<>(nai);
- }
-
- @Override
- public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) {
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT,
- new Pair<>(mNai.getAndDestroy(), networkMonitor)));
- }
-
- @Override
- public void notifyNetworkTested(int testResult, @Nullable String redirectUrl) {
- // Legacy version of notifyNetworkTestedWithExtras.
- // Would only be called if the system has a NetworkStack module older than the
- // framework, which does not happen in practice.
- Log.wtf(TAG, "Deprecated notifyNetworkTested called: no action taken");
- }
-
- @Override
- public void notifyNetworkTestedWithExtras(NetworkTestResultParcelable p) {
- // Notify mTrackerHandler and mConnectivityDiagnosticsHandler of the event. Both use
- // the same looper so messages will be processed in sequence.
- final Message msg = mTrackerHandler.obtainMessage(
- EVENT_NETWORK_TESTED,
- new NetworkTestedResults(
- mNetId, p.result, p.timestampMillis, p.redirectUrl));
- mTrackerHandler.sendMessage(msg);
-
- // Invoke ConnectivityReport generation for this Network test event.
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(mNetId);
- if (nai == null) return;
-
- final PersistableBundle extras = new PersistableBundle();
- extras.putInt(KEY_NETWORK_VALIDATION_RESULT, p.result);
- extras.putInt(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK, p.probesSucceeded);
- extras.putInt(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK, p.probesAttempted);
-
- ConnectivityReportEvent reportEvent =
- new ConnectivityReportEvent(p.timestampMillis, nai, extras);
- final Message m = mConnectivityDiagnosticsHandler.obtainMessage(
- ConnectivityDiagnosticsHandler.EVENT_NETWORK_TESTED, reportEvent);
- mConnectivityDiagnosticsHandler.sendMessage(m);
- }
-
- @Override
- public void notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config) {
- mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
- EVENT_PRIVATE_DNS_CONFIG_RESOLVED,
- 0, mNetId, PrivateDnsConfig.fromParcel(config)));
- }
-
- @Override
- public void notifyProbeStatusChanged(int probesCompleted, int probesSucceeded) {
- mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
- EVENT_PROBE_STATUS_CHANGED,
- probesCompleted, probesSucceeded, new Integer(mNetId)));
- }
-
- @Override
- public void notifyCaptivePortalDataChanged(CaptivePortalData data) {
- mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
- EVENT_CAPPORT_DATA_CHANGED,
- 0, mNetId, data));
- }
-
- @Override
- public void showProvisioningNotification(String action, String packageName) {
- final Intent intent = new Intent(action);
- intent.setPackage(packageName);
-
- final PendingIntent pendingIntent;
- // Only the system server can register notifications with package "android"
- final long token = Binder.clearCallingIdentity();
- try {
- pendingIntent = PendingIntent.getBroadcast(
- mContext,
- 0 /* requestCode */,
- intent,
- PendingIntent.FLAG_IMMUTABLE);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
- EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_SHOW,
- mNetId, pendingIntent));
- }
-
- @Override
- public void hideProvisioningNotification() {
- mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
- EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId));
- }
-
- @Override
- public void notifyDataStallSuspected(DataStallReportParcelable p) {
- ConnectivityService.this.notifyDataStallSuspected(p, mNetId);
- }
-
- @Override
- public int getInterfaceVersion() {
- return this.VERSION;
- }
-
- @Override
- public String getInterfaceHash() {
- return this.HASH;
- }
- }
-
- private void notifyDataStallSuspected(DataStallReportParcelable p, int netId) {
- log("Data stall detected with methods: " + p.detectionMethod);
-
- final PersistableBundle extras = new PersistableBundle();
- int detectionMethod = 0;
- if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) {
- extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts);
- detectionMethod |= DETECTION_METHOD_DNS_EVENTS;
- }
- if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) {
- extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate);
- extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS,
- p.tcpMetricsCollectionPeriodMillis);
- detectionMethod |= DETECTION_METHOD_TCP_METRICS;
- }
-
- final Message msg = mConnectivityDiagnosticsHandler.obtainMessage(
- ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, detectionMethod, netId,
- new Pair<>(p.timestampMillis, extras));
-
- // NetworkStateTrackerHandler currently doesn't take any actions based on data
- // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid
- // the cost of going through two handlers.
- mConnectivityDiagnosticsHandler.sendMessage(msg);
- }
-
- private boolean hasDataStallDetectionMethod(DataStallReportParcelable p, int detectionMethod) {
- return (p.detectionMethod & detectionMethod) != 0;
- }
-
- private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) {
- return isPrivateDnsValidationRequired(nai.networkCapabilities);
- }
-
- private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) {
- if (nai == null) return;
- // If the Private DNS mode is opportunistic, reprogram the DNS servers
- // in order to restart a validation pass from within netd.
- final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
- if (cfg.useTls && TextUtils.isEmpty(cfg.hostname)) {
- updateDnses(nai.linkProperties, null, nai.network.getNetId());
- }
- }
-
- private void handlePrivateDnsSettingsChanged() {
- final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
-
- for (NetworkAgentInfo nai : mNetworkAgentInfos) {
- handlePerNetworkPrivateDnsConfig(nai, cfg);
- if (networkRequiresPrivateDnsValidation(nai)) {
- handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
- }
- }
- }
-
- private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) {
- // Private DNS only ever applies to networks that might provide
- // Internet access and therefore also require validation.
- if (!networkRequiresPrivateDnsValidation(nai)) return;
-
- // Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or
- // schedule DNS resolutions. If a DNS resolution is required the
- // result will be sent back to us.
- nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel());
-
- // With Private DNS bypass support, we can proceed to update the
- // Private DNS config immediately, even if we're in strict mode
- // and have not yet resolved the provider name into a set of IPs.
- updatePrivateDns(nai, cfg);
- }
-
- private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) {
- mDnsManager.updatePrivateDns(nai.network, newCfg);
- updateDnses(nai.linkProperties, null, nai.network.getNetId());
- }
-
- private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) {
- NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId);
- if (nai == null) {
- return;
- }
- mDnsManager.updatePrivateDnsValidation(update);
- handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
- }
-
- private void handleNat64PrefixEvent(int netId, int operation, String prefixAddress,
- int prefixLength) {
- NetworkAgentInfo nai = mNetworkForNetId.get(netId);
- if (nai == null) return;
-
- log(String.format("NAT64 prefix changed on netId %d: operation=%d, %s/%d",
- netId, operation, prefixAddress, prefixLength));
-
- IpPrefix prefix = null;
- if (operation == IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED) {
- try {
- prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixAddress),
- prefixLength);
- } catch (IllegalArgumentException e) {
- loge("Invalid NAT64 prefix " + prefixAddress + "/" + prefixLength);
- return;
- }
- }
-
- nai.clatd.setNat64PrefixFromDns(prefix);
- handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
- }
-
- private void handleCapportApiDataUpdate(@NonNull final NetworkAgentInfo nai,
- @Nullable final CaptivePortalData data) {
- nai.capportApiData = data;
- // CaptivePortalData will be merged into LinkProperties from NetworkAgentInfo
- handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
- }
-
- /**
- * Updates the inactivity state from the network requests inside the NAI.
- * @param nai the agent info to update
- * @param now the timestamp of the event causing this update
- * @return whether the network was inactive as a result of this update
- */
- private boolean updateInactivityState(@NonNull final NetworkAgentInfo nai, final long now) {
- // 1. Update the inactivity timer. If it's changed, reschedule or cancel the alarm.
- // 2. If the network was inactive and there are now requests, unset inactive.
- // 3. If this network is unneeded (which implies it is not lingering), and there is at least
- // one lingered request, set inactive.
- nai.updateInactivityTimer();
- if (nai.isInactive() && nai.numForegroundNetworkRequests() > 0) {
- if (DBG) log("Unsetting inactive " + nai.toShortString());
- nai.unsetInactive();
- logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER);
- } else if (unneeded(nai, UnneededFor.LINGER) && nai.getInactivityExpiry() > 0) {
- if (DBG) {
- final int lingerTime = (int) (nai.getInactivityExpiry() - now);
- log("Setting inactive " + nai.toShortString() + " for " + lingerTime + "ms");
- }
- nai.setInactive();
- logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER);
- return true;
- }
- return false;
- }
-
- private void handleNetworkAgentRegistered(Message msg) {
- final NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
- if (!mNetworkAgentInfos.contains(nai)) {
- return;
- }
-
- if (msg.arg1 == NetworkAgentInfo.ARG_AGENT_SUCCESS) {
- if (VDBG) log("NetworkAgent registered");
- } else {
- loge("Error connecting NetworkAgent");
- mNetworkAgentInfos.remove(nai);
- if (nai != null) {
- final boolean wasDefault = isDefaultNetwork(nai);
- synchronized (mNetworkForNetId) {
- mNetworkForNetId.remove(nai.network.getNetId());
- }
- mNetIdManager.releaseNetId(nai.network.getNetId());
- // Just in case.
- mLegacyTypeTracker.remove(nai, wasDefault);
- }
- }
- }
-
- private void handleNetworkAgentDisconnected(Message msg) {
- NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
- if (mNetworkAgentInfos.contains(nai)) {
- disconnectAndDestroyNetwork(nai);
- }
- }
-
- // Destroys a network, remove references to it from the internal state managed by
- // ConnectivityService, free its interfaces and clean up.
- // Must be called on the Handler thread.
- private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) {
- ensureRunningOnConnectivityServiceThread();
- if (DBG) {
- log(nai.toShortString() + " disconnected, was satisfying " + nai.numNetworkRequests());
- }
- // Clear all notifications of this network.
- mNotifier.clearNotification(nai.network.getNetId());
- // A network agent has disconnected.
- // TODO - if we move the logic to the network agent (have them disconnect
- // because they lost all their requests or because their score isn't good)
- // then they would disconnect organically, report their new state and then
- // disconnect the channel.
- if (nai.networkInfo.isConnected()) {
- nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
- null, null);
- }
- final boolean wasDefault = isDefaultNetwork(nai);
- if (wasDefault) {
- mDefaultInetConditionPublished = 0;
- }
- notifyIfacesChangedForNetworkStats();
- // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
- // by other networks that are already connected. Perhaps that can be done by
- // sending all CALLBACK_LOST messages (for requests, not listens) at the end
- // of rematchAllNetworksAndRequests
- notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
- mKeepaliveTracker.handleStopAllKeepalives(nai, SocketKeepalive.ERROR_INVALID_NETWORK);
-
- mQosCallbackTracker.handleNetworkReleased(nai.network);
- for (String iface : nai.linkProperties.getAllInterfaceNames()) {
- // Disable wakeup packet monitoring for each interface.
- wakeupModifyInterface(iface, nai.networkCapabilities, false);
- }
- nai.networkMonitor().notifyNetworkDisconnected();
- mNetworkAgentInfos.remove(nai);
- nai.clatd.update();
- synchronized (mNetworkForNetId) {
- // Remove the NetworkAgent, but don't mark the netId as
- // available until we've told netd to delete it below.
- mNetworkForNetId.remove(nai.network.getNetId());
- }
- propagateUnderlyingNetworkCapabilities(nai.network);
- // Remove all previously satisfied requests.
- for (int i = 0; i < nai.numNetworkRequests(); i++) {
- final NetworkRequest request = nai.requestAt(i);
- final NetworkRequestInfo nri = mNetworkRequests.get(request);
- final NetworkAgentInfo currentNetwork = nri.getSatisfier();
- if (currentNetwork != null
- && currentNetwork.network.getNetId() == nai.network.getNetId()) {
- // uid rules for this network will be removed in destroyNativeNetwork(nai).
- // TODO : setting the satisfier is in fact the job of the rematch. Teach the
- // rematch not to keep disconnected agents instead of setting it here ; this
- // will also allow removing updating the offers below.
- nri.setSatisfier(null, null);
- for (final NetworkOfferInfo noi : mNetworkOffers) {
- informOffer(nri, noi.offer, mNetworkRanker);
- }
-
- if (mDefaultRequest == nri) {
- // TODO : make battery stats aware that since 2013 multiple interfaces may be
- // active at the same time. For now keep calling this with the default
- // network, because while incorrect this is the closest to the old (also
- // incorrect) behavior.
- mNetworkActivityTracker.updateDataActivityTracking(
- null /* newNetwork */, nai);
- ensureNetworkTransitionWakelock(nai.toShortString());
- }
- }
- }
- nai.clearInactivityState();
- // TODO: mLegacyTypeTracker.remove seems redundant given there's a full rematch right after.
- // Currently, deleting it breaks tests that check for the default network disconnecting.
- // Find out why, fix the rematch code, and delete this.
- mLegacyTypeTracker.remove(nai, wasDefault);
- rematchAllNetworksAndRequests();
- mLingerMonitor.noteDisconnect(nai);
-
- // Immediate teardown.
- if (nai.teardownDelayMs == 0) {
- destroyNetwork(nai);
- return;
- }
-
- // Delayed teardown.
- try {
- mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM);
- } catch (RemoteException e) {
- Log.d(TAG, "Error marking network restricted during teardown: " + e);
- }
- mHandler.postDelayed(() -> destroyNetwork(nai), nai.teardownDelayMs);
- }
-
- private void destroyNetwork(NetworkAgentInfo nai) {
- if (nai.created) {
- // Tell netd to clean up the configuration for this network
- // (routing rules, DNS, etc).
- // This may be slow as it requires a lot of netd shelling out to ip and
- // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it
- // after we've rematched networks with requests (which might change the default
- // network or service a new request from an app), so network traffic isn't interrupted
- // for an unnecessarily long time.
- destroyNativeNetwork(nai);
- mDnsManager.removeNetwork(nai.network);
- }
- mNetIdManager.releaseNetId(nai.network.getNetId());
- nai.onNetworkDestroyed();
- }
-
- private boolean createNativeNetwork(@NonNull NetworkAgentInfo nai) {
- try {
- // This should never fail. Specifying an already in use NetID will cause failure.
- final NativeNetworkConfig config;
- if (nai.isVPN()) {
- if (getVpnType(nai) == VpnManager.TYPE_VPN_NONE) {
- Log.wtf(TAG, "Unable to get VPN type from network " + nai.toShortString());
- return false;
- }
- config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.VIRTUAL,
- INetd.PERMISSION_NONE,
- (nai.networkAgentConfig == null || !nai.networkAgentConfig.allowBypass),
- getVpnType(nai));
- } else {
- config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.PHYSICAL,
- getNetworkPermission(nai.networkCapabilities), /*secure=*/ false,
- VpnManager.TYPE_VPN_NONE);
- }
- mNetd.networkCreate(config);
- mDnsResolver.createNetworkCache(nai.network.getNetId());
- mDnsManager.updateTransportsForNetwork(nai.network.getNetId(),
- nai.networkCapabilities.getTransportTypes());
- return true;
- } catch (RemoteException | ServiceSpecificException e) {
- loge("Error creating network " + nai.toShortString() + ": " + e.getMessage());
- return false;
- }
- }
-
- private void destroyNativeNetwork(@NonNull NetworkAgentInfo nai) {
- try {
- mNetd.networkDestroy(nai.network.getNetId());
- } catch (RemoteException | ServiceSpecificException e) {
- loge("Exception destroying network(networkDestroy): " + e);
- }
- try {
- mDnsResolver.destroyNetworkCache(nai.network.getNetId());
- } catch (RemoteException | ServiceSpecificException e) {
- loge("Exception destroying network: " + e);
- }
- }
-
- // If this method proves to be too slow then we can maintain a separate
- // pendingIntent => NetworkRequestInfo map.
- // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo.
- private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) {
- for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) {
- PendingIntent existingPendingIntent = entry.getValue().mPendingIntent;
- if (existingPendingIntent != null &&
- existingPendingIntent.intentFilterEquals(pendingIntent)) {
- return entry.getValue();
- }
- }
- return null;
- }
-
- private void handleRegisterNetworkRequestWithIntent(@NonNull final Message msg) {
- final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
- // handleRegisterNetworkRequestWithIntent() doesn't apply to multilayer requests.
- ensureNotMultilayerRequest(nri, "handleRegisterNetworkRequestWithIntent");
- final NetworkRequestInfo existingRequest =
- findExistingNetworkRequestInfo(nri.mPendingIntent);
- if (existingRequest != null) { // remove the existing request.
- if (DBG) {
- log("Replacing " + existingRequest.mRequests.get(0) + " with "
- + nri.mRequests.get(0) + " because their intents matched.");
- }
- handleReleaseNetworkRequest(existingRequest.mRequests.get(0), mDeps.getCallingUid(),
- /* callOnUnavailable */ false);
- }
- handleRegisterNetworkRequest(nri);
- }
-
- private void handleRegisterNetworkRequest(@NonNull final NetworkRequestInfo nri) {
- handleRegisterNetworkRequests(Collections.singleton(nri));
- }
-
- private void handleRegisterNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
- ensureRunningOnConnectivityServiceThread();
- for (final NetworkRequestInfo nri : nris) {
- mNetworkRequestInfoLogs.log("REGISTER " + nri);
- for (final NetworkRequest req : nri.mRequests) {
- mNetworkRequests.put(req, nri);
- // TODO: Consider update signal strength for other types.
- if (req.isListen()) {
- for (final NetworkAgentInfo network : mNetworkAgentInfos) {
- if (req.networkCapabilities.hasSignalStrength()
- && network.satisfiesImmutableCapabilitiesOf(req)) {
- updateSignalStrengthThresholds(network, "REGISTER", req);
- }
- }
- }
- }
- // If this NRI has a satisfier already, it is replacing an older request that
- // has been removed. Track it.
- final NetworkRequest activeRequest = nri.getActiveRequest();
- if (null != activeRequest) {
- // If there is an active request, then for sure there is a satisfier.
- nri.getSatisfier().addRequest(activeRequest);
- }
- }
-
- rematchAllNetworksAndRequests();
-
- // Requests that have not been matched to a network will not have been sent to the
- // providers, because the old satisfier and the new satisfier are the same (null in this
- // case). Send these requests to the providers.
- for (final NetworkRequestInfo nri : nris) {
- for (final NetworkOfferInfo noi : mNetworkOffers) {
- informOffer(nri, noi.offer, mNetworkRanker);
- }
- }
- }
-
- private void handleReleaseNetworkRequestWithIntent(@NonNull final PendingIntent pendingIntent,
- final int callingUid) {
- final NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent);
- if (nri != null) {
- // handleReleaseNetworkRequestWithIntent() paths don't apply to multilayer requests.
- ensureNotMultilayerRequest(nri, "handleReleaseNetworkRequestWithIntent");
- handleReleaseNetworkRequest(
- nri.mRequests.get(0),
- callingUid,
- /* callOnUnavailable */ false);
- }
- }
-
- // Determines whether the network is the best (or could become the best, if it validated), for
- // none of a particular type of NetworkRequests. The type of NetworkRequests considered depends
- // on the value of reason:
- //
- // - UnneededFor.TEARDOWN: non-listen NetworkRequests. If a network is unneeded for this reason,
- // then it should be torn down.
- // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason,
- // then it should be lingered.
- private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
- ensureRunningOnConnectivityServiceThread();
-
- if (!nai.everConnected || nai.isVPN() || nai.isInactive()
- || nai.getScore().getKeepConnectedReason() != NetworkScore.KEEP_CONNECTED_NONE) {
- return false;
- }
-
- final int numRequests;
- switch (reason) {
- case TEARDOWN:
- numRequests = nai.numRequestNetworkRequests();
- break;
- case LINGER:
- numRequests = nai.numForegroundNetworkRequests();
- break;
- default:
- Log.wtf(TAG, "Invalid reason. Cannot happen.");
- return true;
- }
-
- if (numRequests > 0) return false;
-
- for (NetworkRequestInfo nri : mNetworkRequests.values()) {
- if (reason == UnneededFor.LINGER
- && !nri.isMultilayerRequest()
- && nri.mRequests.get(0).isBackgroundRequest()) {
- // Background requests don't affect lingering.
- continue;
- }
-
- if (isNetworkPotentialSatisfier(nai, nri)) {
- return false;
- }
- }
- return true;
- }
-
- private boolean isNetworkPotentialSatisfier(
- @NonNull final NetworkAgentInfo candidate, @NonNull final NetworkRequestInfo nri) {
- // listen requests won't keep up a network satisfying it. If this is not a multilayer
- // request, return immediately. For multilayer requests, check to see if any of the
- // multilayer requests may have a potential satisfier.
- if (!nri.isMultilayerRequest() && (nri.mRequests.get(0).isListen()
- || nri.mRequests.get(0).isListenForBest())) {
- return false;
- }
- for (final NetworkRequest req : nri.mRequests) {
- // This multilayer listen request is satisfied therefore no further requests need to be
- // evaluated deeming this network not a potential satisfier.
- if ((req.isListen() || req.isListenForBest()) && nri.getActiveRequest() == req) {
- return false;
- }
- // As non-multilayer listen requests have already returned, the below would only happen
- // for a multilayer request therefore continue to the next request if available.
- if (req.isListen() || req.isListenForBest()) {
- continue;
- }
- // If this Network is already the highest scoring Network for a request, or if
- // there is hope for it to become one if it validated, then it is needed.
- if (candidate.satisfies(req)) {
- // As soon as a network is found that satisfies a request, return. Specifically for
- // multilayer requests, returning as soon as a NetworkAgentInfo satisfies a request
- // is important so as to not evaluate lower priority requests further in
- // nri.mRequests.
- final NetworkAgentInfo champion = req.equals(nri.getActiveRequest())
- ? nri.getSatisfier() : null;
- // Note that this catches two important cases:
- // 1. Unvalidated cellular will not be reaped when unvalidated WiFi
- // is currently satisfying the request. This is desirable when
- // cellular ends up validating but WiFi does not.
- // 2. Unvalidated WiFi will not be reaped when validated cellular
- // is currently satisfying the request. This is desirable when
- // WiFi ends up validating and out scoring cellular.
- return mNetworkRanker.mightBeat(req, champion, candidate.getValidatedScoreable());
- }
- }
-
- return false;
- }
-
- private NetworkRequestInfo getNriForAppRequest(
- NetworkRequest request, int callingUid, String requestedOperation) {
- // Looking up the app passed param request in mRequests isn't possible since it may return
- // null for a request managed by a per-app default. Therefore use getNriForAppRequest() to
- // do the lookup since that will also find per-app default managed requests.
- // Additionally, this lookup needs to be relatively fast (hence the lookup optimization)
- // to avoid potential race conditions when validating a package->uid mapping when sending
- // the callback on the very low-chance that an application shuts down prior to the callback
- // being sent.
- final NetworkRequestInfo nri = mNetworkRequests.get(request) != null
- ? mNetworkRequests.get(request) : getNriForAppRequest(request);
-
- if (nri != null) {
- if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) {
- log(String.format("UID %d attempted to %s for unowned request %s",
- callingUid, requestedOperation, nri));
- return null;
- }
- }
-
- return nri;
- }
-
- private void ensureNotMultilayerRequest(@NonNull final NetworkRequestInfo nri,
- final String callingMethod) {
- if (nri.isMultilayerRequest()) {
- throw new IllegalStateException(
- callingMethod + " does not support multilayer requests.");
- }
- }
-
- private void handleTimedOutNetworkRequest(@NonNull final NetworkRequestInfo nri) {
- ensureRunningOnConnectivityServiceThread();
- // handleTimedOutNetworkRequest() is part of the requestNetwork() flow which works off of a
- // single NetworkRequest and thus does not apply to multilayer requests.
- ensureNotMultilayerRequest(nri, "handleTimedOutNetworkRequest");
- if (mNetworkRequests.get(nri.mRequests.get(0)) == null) {
- return;
- }
- if (nri.isBeingSatisfied()) {
- return;
- }
- if (VDBG || (DBG && nri.mRequests.get(0).isRequest())) {
- log("releasing " + nri.mRequests.get(0) + " (timeout)");
- }
- handleRemoveNetworkRequest(nri);
- callCallbackForRequest(
- nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
- }
-
- private void handleReleaseNetworkRequest(@NonNull final NetworkRequest request,
- final int callingUid,
- final boolean callOnUnavailable) {
- final NetworkRequestInfo nri =
- getNriForAppRequest(request, callingUid, "release NetworkRequest");
- if (nri == null) {
- return;
- }
- if (VDBG || (DBG && request.isRequest())) {
- log("releasing " + request + " (release request)");
- }
- handleRemoveNetworkRequest(nri);
- if (callOnUnavailable) {
- callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
- }
- }
-
- private void handleRemoveNetworkRequest(@NonNull final NetworkRequestInfo nri) {
- ensureRunningOnConnectivityServiceThread();
- nri.unlinkDeathRecipient();
- for (final NetworkRequest req : nri.mRequests) {
- mNetworkRequests.remove(req);
- if (req.isListen()) {
- removeListenRequestFromNetworks(req);
- }
- }
- if (mDefaultNetworkRequests.remove(nri)) {
- // If this request was one of the defaults, then the UID rules need to be updated
- // WARNING : if the app(s) for which this network request is the default are doing
- // traffic, this will kill their connected sockets, even if an equivalent request
- // is going to be reinstated right away ; unconnected traffic will go on the default
- // until the new default is set, which will happen very soon.
- // TODO : The only way out of this is to diff old defaults and new defaults, and only
- // remove ranges for those requests that won't have a replacement
- final NetworkAgentInfo satisfier = nri.getSatisfier();
- if (null != satisfier) {
- try {
- mNetd.networkRemoveUidRanges(satisfier.network.getNetId(),
- toUidRangeStableParcels(nri.getUids()));
- } catch (RemoteException e) {
- loge("Exception setting network preference default network", e);
- }
- }
- }
- nri.decrementRequestCount();
- mNetworkRequestInfoLogs.log("RELEASE " + nri);
-
- if (null != nri.getActiveRequest()) {
- if (!nri.getActiveRequest().isListen()) {
- removeSatisfiedNetworkRequestFromNetwork(nri);
- } else {
- nri.setSatisfier(null, null);
- }
- }
-
- // For all outstanding offers, cancel any of the layers of this NRI that used to be
- // needed for this offer.
- for (final NetworkOfferInfo noi : mNetworkOffers) {
- for (final NetworkRequest req : nri.mRequests) {
- if (req.isRequest() && noi.offer.neededFor(req)) {
- noi.offer.onNetworkUnneeded(req);
- }
- }
- }
- }
-
- private void handleRemoveNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
- for (final NetworkRequestInfo nri : nris) {
- if (mDefaultRequest == nri) {
- // Make sure we never remove the default request.
- continue;
- }
- handleRemoveNetworkRequest(nri);
- }
- }
-
- private void removeListenRequestFromNetworks(@NonNull final NetworkRequest req) {
- // listens don't have a singular affected Network. Check all networks to see
- // if this listen request applies and remove it.
- for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
- nai.removeRequest(req.requestId);
- if (req.networkCapabilities.hasSignalStrength()
- && nai.satisfiesImmutableCapabilitiesOf(req)) {
- updateSignalStrengthThresholds(nai, "RELEASE", req);
- }
- }
- }
-
- /**
- * Remove a NetworkRequestInfo's satisfied request from its 'satisfier' (NetworkAgentInfo) and
- * manage the necessary upkeep (linger, teardown networks, etc.) when doing so.
- * @param nri the NetworkRequestInfo to disassociate from its current NetworkAgentInfo
- */
- private void removeSatisfiedNetworkRequestFromNetwork(@NonNull final NetworkRequestInfo nri) {
- boolean wasKept = false;
- final NetworkAgentInfo nai = nri.getSatisfier();
- if (nai != null) {
- final int requestLegacyType = nri.getActiveRequest().legacyType;
- final boolean wasBackgroundNetwork = nai.isBackgroundNetwork();
- nai.removeRequest(nri.getActiveRequest().requestId);
- if (VDBG || DDBG) {
- log(" Removing from current network " + nai.toShortString()
- + ", leaving " + nai.numNetworkRequests() + " requests.");
- }
- // If there are still lingered requests on this network, don't tear it down,
- // but resume lingering instead.
- final long now = SystemClock.elapsedRealtime();
- if (updateInactivityState(nai, now)) {
- notifyNetworkLosing(nai, now);
- }
- if (unneeded(nai, UnneededFor.TEARDOWN)) {
- if (DBG) log("no live requests for " + nai.toShortString() + "; disconnecting");
- teardownUnneededNetwork(nai);
- } else {
- wasKept = true;
- }
- nri.setSatisfier(null, null);
- if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) {
- // Went from foreground to background.
- updateCapabilitiesForNetwork(nai);
- }
-
- // Maintain the illusion. When this request arrived, we might have pretended
- // that a network connected to serve it, even though the network was already
- // connected. Now that this request has gone away, we might have to pretend
- // that the network disconnected. LegacyTypeTracker will generate that
- // phantom disconnect for this type.
- if (requestLegacyType != TYPE_NONE) {
- boolean doRemove = true;
- if (wasKept) {
- // check if any of the remaining requests for this network are for the
- // same legacy type - if so, don't remove the nai
- for (int i = 0; i < nai.numNetworkRequests(); i++) {
- NetworkRequest otherRequest = nai.requestAt(i);
- if (otherRequest.legacyType == requestLegacyType
- && otherRequest.isRequest()) {
- if (DBG) log(" still have other legacy request - leaving");
- doRemove = false;
- }
- }
- }
-
- if (doRemove) {
- mLegacyTypeTracker.remove(requestLegacyType, nai, false);
- }
- }
- }
- }
-
- private PerUidCounter getRequestCounter(NetworkRequestInfo nri) {
- return checkAnyPermissionOf(
- nri.mPid, nri.mUid, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
- ? mSystemNetworkRequestCounter : mNetworkRequestCounter;
- }
-
- @Override
- public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
- enforceNetworkStackSettingsOrSetup();
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED,
- encodeBool(accept), encodeBool(always), network));
- }
-
- @Override
- public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) {
- enforceNetworkStackSettingsOrSetup();
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY,
- encodeBool(accept), encodeBool(always), network));
- }
-
- @Override
- public void setAvoidUnvalidated(Network network) {
- enforceNetworkStackSettingsOrSetup();
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network));
- }
-
- private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) {
- if (DBG) log("handleSetAcceptUnvalidated network=" + network +
- " accept=" + accept + " always=" + always);
-
- NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
- if (nai == null) {
- // Nothing to do.
- return;
- }
-
- if (nai.everValidated) {
- // The network validated while the dialog box was up. Take no action.
- return;
- }
-
- if (!nai.networkAgentConfig.explicitlySelected) {
- Log.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network");
- }
-
- if (accept != nai.networkAgentConfig.acceptUnvalidated) {
- nai.networkAgentConfig.acceptUnvalidated = accept;
- // If network becomes partial connectivity and user already accepted to use this
- // network, we should respect the user's option and don't need to popup the
- // PARTIAL_CONNECTIVITY notification to user again.
- nai.networkAgentConfig.acceptPartialConnectivity = accept;
- nai.updateScoreForNetworkAgentUpdate();
- rematchAllNetworksAndRequests();
- }
-
- if (always) {
- nai.onSaveAcceptUnvalidated(accept);
- }
-
- if (!accept) {
- // Tell the NetworkAgent to not automatically reconnect to the network.
- nai.onPreventAutomaticReconnect();
- // Teardown the network.
- teardownUnneededNetwork(nai);
- }
-
- }
-
- private void handleSetAcceptPartialConnectivity(Network network, boolean accept,
- boolean always) {
- if (DBG) {
- log("handleSetAcceptPartialConnectivity network=" + network + " accept=" + accept
- + " always=" + always);
- }
-
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
- if (nai == null) {
- // Nothing to do.
- return;
- }
-
- if (nai.lastValidated) {
- // The network validated while the dialog box was up. Take no action.
- return;
- }
-
- if (accept != nai.networkAgentConfig.acceptPartialConnectivity) {
- nai.networkAgentConfig.acceptPartialConnectivity = accept;
- }
-
- // TODO: Use the current design or save the user choice into IpMemoryStore.
- if (always) {
- nai.onSaveAcceptUnvalidated(accept);
- }
-
- if (!accept) {
- // Tell the NetworkAgent to not automatically reconnect to the network.
- nai.onPreventAutomaticReconnect();
- // Tear down the network.
- teardownUnneededNetwork(nai);
- } else {
- // Inform NetworkMonitor that partial connectivity is acceptable. This will likely
- // result in a partial connectivity result which will be processed by
- // maybeHandleNetworkMonitorMessage.
- //
- // TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored
- // per network. Therefore, NetworkMonitor may still do https probe.
- nai.networkMonitor().setAcceptPartialConnectivity();
- }
- }
-
- private void handleSetAvoidUnvalidated(Network network) {
- NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
- if (nai == null || nai.lastValidated) {
- // Nothing to do. The network either disconnected or revalidated.
- return;
- }
- if (!nai.avoidUnvalidated) {
- nai.avoidUnvalidated = true;
- nai.updateScoreForNetworkAgentUpdate();
- rematchAllNetworksAndRequests();
- }
- }
-
- private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) {
- if (VDBG) log("scheduleUnvalidatedPrompt " + nai.network);
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(EVENT_PROMPT_UNVALIDATED, nai.network),
- PROMPT_UNVALIDATED_DELAY_MS);
- }
-
- @Override
- public void startCaptivePortalApp(Network network) {
- enforceNetworkStackOrSettingsPermission();
- mHandler.post(() -> {
- NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
- if (nai == null) return;
- if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return;
- nai.networkMonitor().launchCaptivePortalApp();
- });
- }
-
- /**
- * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this
- * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself.
- * @param network Network on which the captive portal was detected.
- * @param appExtras Bundle to use as intent extras for the captive portal application.
- * Must be treated as opaque to avoid preventing the captive portal app to
- * update its arguments.
- */
- @Override
- public void startCaptivePortalAppInternal(Network network, Bundle appExtras) {
- mContext.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- "ConnectivityService");
-
- final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
- appIntent.putExtras(appExtras);
- appIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL,
- new CaptivePortal(new CaptivePortalImpl(network).asBinder()));
- appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
-
- final long token = Binder.clearCallingIdentity();
- try {
- mContext.startActivityAsUser(appIntent, UserHandle.CURRENT);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- private class CaptivePortalImpl extends ICaptivePortal.Stub {
- private final Network mNetwork;
-
- private CaptivePortalImpl(Network network) {
- mNetwork = network;
- }
-
- @Override
- public void appResponse(final int response) {
- if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) {
- enforceSettingsPermission();
- }
-
- final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork);
- if (nm == null) return;
- nm.notifyCaptivePortalAppFinished(response);
- }
-
- @Override
- public void appRequest(final int request) {
- final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork);
- if (nm == null) return;
-
- if (request == CaptivePortal.APP_REQUEST_REEVALUATION_REQUIRED) {
- checkNetworkStackPermission();
- nm.forceReevaluation(mDeps.getCallingUid());
- }
- }
-
- @Nullable
- private NetworkMonitorManager getNetworkMonitorManager(final Network network) {
- // getNetworkAgentInfoForNetwork is thread-safe
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
- if (nai == null) return null;
-
- // nai.networkMonitor() is thread-safe
- return nai.networkMonitor();
- }
- }
-
- public boolean avoidBadWifi() {
- return mMultinetworkPolicyTracker.getAvoidBadWifi();
- }
-
- /**
- * Return whether the device should maintain continuous, working connectivity by switching away
- * from WiFi networks having no connectivity.
- * @see MultinetworkPolicyTracker#getAvoidBadWifi()
- */
- public boolean shouldAvoidBadWifi() {
- if (!checkNetworkStackPermission()) {
- throw new SecurityException("avoidBadWifi requires NETWORK_STACK permission");
- }
- return avoidBadWifi();
- }
-
- private void updateAvoidBadWifi() {
- for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
- nai.updateScoreForNetworkAgentUpdate();
- }
- rematchAllNetworksAndRequests();
- }
-
- // TODO: Evaluate whether this is of interest to other consumers of
- // MultinetworkPolicyTracker and worth moving out of here.
- private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) {
- final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi();
- if (!configRestrict) {
- pw.println("Bad Wi-Fi avoidance: unrestricted");
- return;
- }
-
- pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi());
- pw.increaseIndent();
- pw.println("Config restrict: " + configRestrict);
-
- final String value = mMultinetworkPolicyTracker.getAvoidBadWifiSetting();
- String description;
- // Can't use a switch statement because strings are legal case labels, but null is not.
- if ("0".equals(value)) {
- description = "get stuck";
- } else if (value == null) {
- description = "prompt";
- } else if ("1".equals(value)) {
- description = "avoid";
- } else {
- description = value + " (?)";
- }
- pw.println("User setting: " + description);
- pw.println("Network overrides:");
- pw.increaseIndent();
- for (NetworkAgentInfo nai : networksSortedById()) {
- if (nai.avoidUnvalidated) {
- pw.println(nai.toShortString());
- }
- }
- pw.decreaseIndent();
- pw.decreaseIndent();
- }
-
- // TODO: This method is copied from TetheringNotificationUpdater. Should have a utility class to
- // unify the method.
- private static @NonNull String getSettingsPackageName(@NonNull final PackageManager pm) {
- final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
- final ComponentName settingsComponent = settingsIntent.resolveActivity(pm);
- return settingsComponent != null
- ? settingsComponent.getPackageName() : "com.android.settings";
- }
-
- private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) {
- final String action;
- final boolean highPriority;
- switch (type) {
- case NO_INTERNET:
- action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED;
- // High priority because it is only displayed for explicitly selected networks.
- highPriority = true;
- break;
- case PRIVATE_DNS_BROKEN:
- action = Settings.ACTION_WIRELESS_SETTINGS;
- // High priority because we should let user know why there is no internet.
- highPriority = true;
- break;
- case LOST_INTERNET:
- action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION;
- // High priority because it could help the user avoid unexpected data usage.
- highPriority = true;
- break;
- case PARTIAL_CONNECTIVITY:
- action = ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY;
- // Don't bother the user with a high-priority notification if the network was not
- // explicitly selected by the user.
- highPriority = nai.networkAgentConfig.explicitlySelected;
- break;
- default:
- Log.wtf(TAG, "Unknown notification type " + type);
- return;
- }
-
- Intent intent = new Intent(action);
- if (type != NotificationType.PRIVATE_DNS_BROKEN) {
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK, nai.network);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- // Some OEMs have their own Settings package. Thus, need to get the current using
- // Settings package name instead of just use default name "com.android.settings".
- final String settingsPkgName = getSettingsPackageName(mContext.getPackageManager());
- intent.setClassName(settingsPkgName,
- settingsPkgName + ".wifi.WifiNoInternetDialog");
- }
-
- PendingIntent pendingIntent = PendingIntent.getActivity(
- mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */),
- 0 /* requestCode */,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
-
- mNotifier.showNotification(
- nai.network.getNetId(), type, nai, null, pendingIntent, highPriority);
- }
-
- private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) {
- // Don't prompt if the network is validated, and don't prompt on captive portals
- // because we're already prompting the user to sign in.
- if (nai.everValidated || nai.everCaptivePortalDetected) {
- return false;
- }
-
- // If a network has partial connectivity, always prompt unless the user has already accepted
- // partial connectivity and selected don't ask again. This ensures that if the device
- // automatically connects to a network that has partial Internet access, the user will
- // always be able to use it, either because they've already chosen "don't ask again" or
- // because we have prompt them.
- if (nai.partialConnectivity && !nai.networkAgentConfig.acceptPartialConnectivity) {
- return true;
- }
-
- // If a network has no Internet access, only prompt if the network was explicitly selected
- // and if the user has not already told us to use the network regardless of whether it
- // validated or not.
- if (nai.networkAgentConfig.explicitlySelected
- && !nai.networkAgentConfig.acceptUnvalidated) {
- return true;
- }
-
- return false;
- }
-
- private void handlePromptUnvalidated(Network network) {
- if (VDBG || DDBG) log("handlePromptUnvalidated " + network);
- NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
-
- if (nai == null || !shouldPromptUnvalidated(nai)) {
- return;
- }
-
- // Stop automatically reconnecting to this network in the future. Automatically connecting
- // to a network that provides no or limited connectivity is not useful, because the user
- // cannot use that network except through the notification shown by this method, and the
- // notification is only shown if the network is explicitly selected by the user.
- nai.onPreventAutomaticReconnect();
-
- // TODO: Evaluate if it's needed to wait 8 seconds for triggering notification when
- // NetworkMonitor detects the network is partial connectivity. Need to change the design to
- // popup the notification immediately when the network is partial connectivity.
- if (nai.partialConnectivity) {
- showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY);
- } else {
- showNetworkNotification(nai, NotificationType.NO_INTERNET);
- }
- }
-
- private void handleNetworkUnvalidated(NetworkAgentInfo nai) {
- NetworkCapabilities nc = nai.networkCapabilities;
- if (DBG) log("handleNetworkUnvalidated " + nai.toShortString() + " cap=" + nc);
-
- if (!nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
- return;
- }
-
- if (mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) {
- showNetworkNotification(nai, NotificationType.LOST_INTERNET);
- }
- }
-
- @Override
- public int getMultipathPreference(Network network) {
- enforceAccessPermission();
-
- NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
- if (nai != null && nai.networkCapabilities
- .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
- return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
- }
-
- final NetworkPolicyManager netPolicyManager =
- mContext.getSystemService(NetworkPolicyManager.class);
-
- final long token = Binder.clearCallingIdentity();
- final int networkPreference;
- try {
- networkPreference = netPolicyManager.getMultipathPreference(network);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- if (networkPreference != 0) {
- return networkPreference;
- }
- return mMultinetworkPolicyTracker.getMeteredMultipathPreference();
- }
-
- @Override
- public NetworkRequest getDefaultRequest() {
- return mDefaultRequest.mRequests.get(0);
- }
-
- private class InternalHandler extends Handler {
- public InternalHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK:
- case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: {
- handleReleaseNetworkTransitionWakelock(msg.what);
- break;
- }
- case EVENT_APPLY_GLOBAL_HTTP_PROXY: {
- mProxyTracker.loadDeprecatedGlobalHttpProxy();
- break;
- }
- case EVENT_PROXY_HAS_CHANGED: {
- final Pair<Network, ProxyInfo> arg = (Pair<Network, ProxyInfo>) msg.obj;
- handleApplyDefaultProxy(arg.second);
- break;
- }
- case EVENT_REGISTER_NETWORK_PROVIDER: {
- handleRegisterNetworkProvider((NetworkProviderInfo) msg.obj);
- break;
- }
- case EVENT_UNREGISTER_NETWORK_PROVIDER: {
- handleUnregisterNetworkProvider((Messenger) msg.obj);
- break;
- }
- case EVENT_REGISTER_NETWORK_OFFER: {
- handleRegisterNetworkOffer((NetworkOffer) msg.obj);
- break;
- }
- case EVENT_UNREGISTER_NETWORK_OFFER: {
- final NetworkOfferInfo offer =
- findNetworkOfferInfoByCallback((INetworkOfferCallback) msg.obj);
- if (null != offer) {
- handleUnregisterNetworkOffer(offer);
- }
- break;
- }
- case EVENT_REGISTER_NETWORK_AGENT: {
- final Pair<NetworkAgentInfo, INetworkMonitor> arg =
- (Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj;
- handleRegisterNetworkAgent(arg.first, arg.second);
- break;
- }
- case EVENT_REGISTER_NETWORK_REQUEST:
- case EVENT_REGISTER_NETWORK_LISTENER: {
- handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj);
- break;
- }
- case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT:
- case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: {
- handleRegisterNetworkRequestWithIntent(msg);
- break;
- }
- case EVENT_TIMEOUT_NETWORK_REQUEST: {
- NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj;
- handleTimedOutNetworkRequest(nri);
- break;
- }
- case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: {
- handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1);
- break;
- }
- case EVENT_RELEASE_NETWORK_REQUEST: {
- handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1,
- /* callOnUnavailable */ false);
- break;
- }
- case EVENT_SET_ACCEPT_UNVALIDATED: {
- Network network = (Network) msg.obj;
- handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2));
- break;
- }
- case EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY: {
- Network network = (Network) msg.obj;
- handleSetAcceptPartialConnectivity(network, toBool(msg.arg1),
- toBool(msg.arg2));
- break;
- }
- case EVENT_SET_AVOID_UNVALIDATED: {
- handleSetAvoidUnvalidated((Network) msg.obj);
- break;
- }
- case EVENT_PROMPT_UNVALIDATED: {
- handlePromptUnvalidated((Network) msg.obj);
- break;
- }
- case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: {
- handleConfigureAlwaysOnNetworks();
- break;
- }
- // Sent by KeepaliveTracker to process an app request on the state machine thread.
- case NetworkAgent.CMD_START_SOCKET_KEEPALIVE: {
- mKeepaliveTracker.handleStartKeepalive(msg);
- break;
- }
- // Sent by KeepaliveTracker to process an app request on the state machine thread.
- case NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE: {
- NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj);
- int slot = msg.arg1;
- int reason = msg.arg2;
- mKeepaliveTracker.handleStopKeepalive(nai, slot, reason);
- break;
- }
- case EVENT_REVALIDATE_NETWORK: {
- handleReportNetworkConnectivity((Network) msg.obj, msg.arg1, toBool(msg.arg2));
- break;
- }
- case EVENT_PRIVATE_DNS_SETTINGS_CHANGED:
- handlePrivateDnsSettingsChanged();
- break;
- case EVENT_PRIVATE_DNS_VALIDATION_UPDATE:
- handlePrivateDnsValidationUpdate(
- (PrivateDnsValidationUpdate) msg.obj);
- break;
- case EVENT_UID_BLOCKED_REASON_CHANGED:
- handleUidBlockedReasonChanged(msg.arg1, msg.arg2);
- break;
- case EVENT_SET_REQUIRE_VPN_FOR_UIDS:
- handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj);
- break;
- case EVENT_SET_OEM_NETWORK_PREFERENCE: {
- final Pair<OemNetworkPreferences, IOnCompleteListener> arg =
- (Pair<OemNetworkPreferences, IOnCompleteListener>) msg.obj;
- handleSetOemNetworkPreference(arg.first, arg.second);
- break;
- }
- case EVENT_SET_PROFILE_NETWORK_PREFERENCE: {
- final Pair<ProfileNetworkPreferences.Preference, IOnCompleteListener> arg =
- (Pair<ProfileNetworkPreferences.Preference, IOnCompleteListener>)
- msg.obj;
- handleSetProfileNetworkPreference(arg.first, arg.second);
- break;
- }
- case EVENT_REPORT_NETWORK_ACTIVITY:
- mNetworkActivityTracker.handleReportNetworkActivity();
- break;
- }
- }
- }
-
- @Override
- @Deprecated
- public int getLastTetherError(String iface) {
- final TetheringManager tm = (TetheringManager) mContext.getSystemService(
- Context.TETHERING_SERVICE);
- return tm.getLastTetherError(iface);
- }
-
- @Override
- @Deprecated
- public String[] getTetherableIfaces() {
- final TetheringManager tm = (TetheringManager) mContext.getSystemService(
- Context.TETHERING_SERVICE);
- return tm.getTetherableIfaces();
- }
-
- @Override
- @Deprecated
- public String[] getTetheredIfaces() {
- final TetheringManager tm = (TetheringManager) mContext.getSystemService(
- Context.TETHERING_SERVICE);
- return tm.getTetheredIfaces();
- }
-
-
- @Override
- @Deprecated
- public String[] getTetheringErroredIfaces() {
- final TetheringManager tm = (TetheringManager) mContext.getSystemService(
- Context.TETHERING_SERVICE);
-
- return tm.getTetheringErroredIfaces();
- }
-
- @Override
- @Deprecated
- public String[] getTetherableUsbRegexs() {
- final TetheringManager tm = (TetheringManager) mContext.getSystemService(
- Context.TETHERING_SERVICE);
-
- return tm.getTetherableUsbRegexs();
- }
-
- @Override
- @Deprecated
- public String[] getTetherableWifiRegexs() {
- final TetheringManager tm = (TetheringManager) mContext.getSystemService(
- Context.TETHERING_SERVICE);
- return tm.getTetherableWifiRegexs();
- }
-
- // Called when we lose the default network and have no replacement yet.
- // This will automatically be cleared after X seconds or a new default network
- // becomes CONNECTED, whichever happens first. The timer is started by the
- // first caller and not restarted by subsequent callers.
- private void ensureNetworkTransitionWakelock(String forWhom) {
- synchronized (this) {
- if (mNetTransitionWakeLock.isHeld()) {
- return;
- }
- mNetTransitionWakeLock.acquire();
- mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime();
- mTotalWakelockAcquisitions++;
- }
- mWakelockLogs.log("ACQUIRE for " + forWhom);
- Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
- final int lockTimeout = mResources.get().getInteger(
- R.integer.config_networkTransitionTimeout);
- mHandler.sendMessageDelayed(msg, lockTimeout);
- }
-
- // Called when we gain a new default network to release the network transition wakelock in a
- // second, to allow a grace period for apps to reconnect over the new network. Pending expiry
- // message is cancelled.
- private void scheduleReleaseNetworkTransitionWakelock() {
- synchronized (this) {
- if (!mNetTransitionWakeLock.isHeld()) {
- return; // expiry message released the lock first.
- }
- }
- // Cancel self timeout on wakelock hold.
- mHandler.removeMessages(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
- Message msg = mHandler.obtainMessage(EVENT_CLEAR_NET_TRANSITION_WAKELOCK);
- mHandler.sendMessageDelayed(msg, 1000);
- }
-
- // Called when either message of ensureNetworkTransitionWakelock or
- // scheduleReleaseNetworkTransitionWakelock is processed.
- private void handleReleaseNetworkTransitionWakelock(int eventId) {
- String event = eventName(eventId);
- synchronized (this) {
- if (!mNetTransitionWakeLock.isHeld()) {
- mWakelockLogs.log(String.format("RELEASE: already released (%s)", event));
- Log.w(TAG, "expected Net Transition WakeLock to be held");
- return;
- }
- mNetTransitionWakeLock.release();
- long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
- mTotalWakelockDurationMs += lockDuration;
- mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration);
- mTotalWakelockReleases++;
- }
- mWakelockLogs.log(String.format("RELEASE (%s)", event));
- }
-
- // 100 percent is full good, 0 is full bad.
- @Override
- public void reportInetCondition(int networkType, int percentage) {
- NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- if (nai == null) return;
- reportNetworkConnectivity(nai.network, percentage > 50);
- }
-
- @Override
- public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
- enforceAccessPermission();
- enforceInternetPermission();
- final int uid = mDeps.getCallingUid();
- final int connectivityInfo = encodeBool(hasConnectivity);
-
- // Handle ConnectivityDiagnostics event before attempting to revalidate the network. This
- // forces an ordering of ConnectivityDiagnostics events in the case where hasConnectivity
- // does not match the known connectivity of the network - this causes NetworkMonitor to
- // revalidate the network and generate a ConnectivityDiagnostics ConnectivityReport event.
- final NetworkAgentInfo nai;
- if (network == null) {
- nai = getDefaultNetwork();
- } else {
- nai = getNetworkAgentInfoForNetwork(network);
- }
- if (nai != null) {
- mConnectivityDiagnosticsHandler.sendMessage(
- mConnectivityDiagnosticsHandler.obtainMessage(
- ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED,
- connectivityInfo, 0, nai));
- }
-
- mHandler.sendMessage(
- mHandler.obtainMessage(EVENT_REVALIDATE_NETWORK, uid, connectivityInfo, network));
- }
-
- private void handleReportNetworkConnectivity(
- Network network, int uid, boolean hasConnectivity) {
- final NetworkAgentInfo nai;
- if (network == null) {
- nai = getDefaultNetwork();
- } else {
- nai = getNetworkAgentInfoForNetwork(network);
- }
- if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING ||
- nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
- return;
- }
- // Revalidate if the app report does not match our current validated state.
- if (hasConnectivity == nai.lastValidated) {
- return;
- }
- if (DBG) {
- int netid = nai.network.getNetId();
- log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid);
- }
- // Validating a network that has not yet connected could result in a call to
- // rematchNetworkAndRequests() which is not meant to work on such networks.
- if (!nai.everConnected) {
- return;
- }
- final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
- if (isNetworkWithCapabilitiesBlocked(nc, uid, false)) {
- return;
- }
- nai.networkMonitor().forceReevaluation(uid);
- }
-
- // TODO: call into netd.
- private boolean queryUserAccess(int uid, Network network) {
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
- if (nai == null) return false;
-
- // Any UID can use its default network.
- if (nai == getDefaultNetworkForUid(uid)) return true;
-
- // Privileged apps can use any network.
- if (mPermissionMonitor.hasRestrictedNetworksPermission(uid)) {
- return true;
- }
-
- // An unprivileged UID can use a VPN iff the VPN applies to it.
- if (nai.isVPN()) {
- return nai.networkCapabilities.appliesToUid(uid);
- }
-
- // An unprivileged UID can bypass the VPN that applies to it only if it can protect its
- // sockets, i.e., if it is the owner.
- final NetworkAgentInfo vpn = getVpnForUid(uid);
- if (vpn != null && !vpn.networkAgentConfig.allowBypass
- && uid != vpn.networkCapabilities.getOwnerUid()) {
- return false;
- }
-
- // The UID's permission must be at least sufficient for the network. Since the restricted
- // permission was already checked above, that just leaves background networks.
- if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_FOREGROUND)) {
- return mPermissionMonitor.hasUseBackgroundNetworksPermission(uid);
- }
-
- // Unrestricted network. Anyone gets to use it.
- return true;
- }
-
- /**
- * Returns information about the proxy a certain network is using. If given a null network, it
- * it will return the proxy for the bound network for the caller app or the default proxy if
- * none.
- *
- * @param network the network we want to get the proxy information for.
- * @return Proxy information if a network has a proxy configured, or otherwise null.
- */
- @Override
- public ProxyInfo getProxyForNetwork(Network network) {
- final ProxyInfo globalProxy = mProxyTracker.getGlobalProxy();
- if (globalProxy != null) return globalProxy;
- if (network == null) {
- // Get the network associated with the calling UID.
- final Network activeNetwork = getActiveNetworkForUidInternal(mDeps.getCallingUid(),
- true);
- if (activeNetwork == null) {
- return null;
- }
- return getLinkPropertiesProxyInfo(activeNetwork);
- } else if (mDeps.queryUserAccess(mDeps.getCallingUid(), network, this)) {
- // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which
- // caller may not have.
- return getLinkPropertiesProxyInfo(network);
- }
- // No proxy info available if the calling UID does not have network access.
- return null;
- }
-
-
- private ProxyInfo getLinkPropertiesProxyInfo(Network network) {
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
- if (nai == null) return null;
- synchronized (nai) {
- final ProxyInfo linkHttpProxy = nai.linkProperties.getHttpProxy();
- return linkHttpProxy == null ? null : new ProxyInfo(linkHttpProxy);
- }
- }
-
- @Override
- public void setGlobalProxy(@Nullable final ProxyInfo proxyProperties) {
- PermissionUtils.enforceNetworkStackPermission(mContext);
- mProxyTracker.setGlobalProxy(proxyProperties);
- }
-
- @Override
- @Nullable
- public ProxyInfo getGlobalProxy() {
- return mProxyTracker.getGlobalProxy();
- }
-
- private void handleApplyDefaultProxy(ProxyInfo proxy) {
- if (proxy != null && TextUtils.isEmpty(proxy.getHost())
- && Uri.EMPTY.equals(proxy.getPacFileUrl())) {
- proxy = null;
- }
- mProxyTracker.setDefaultProxy(proxy);
- }
-
- // If the proxy has changed from oldLp to newLp, resend proxy broadcast. This method gets called
- // when any network changes proxy.
- // TODO: Remove usage of broadcast extras as they are deprecated and not applicable in a
- // multi-network world where an app might be bound to a non-default network.
- private void updateProxy(LinkProperties newLp, LinkProperties oldLp) {
- ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy();
- ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
-
- if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
- mProxyTracker.sendProxyBroadcast();
- }
- }
-
- private static class SettingsObserver extends ContentObserver {
- final private HashMap<Uri, Integer> mUriEventMap;
- final private Context mContext;
- final private Handler mHandler;
-
- SettingsObserver(Context context, Handler handler) {
- super(null);
- mUriEventMap = new HashMap<>();
- mContext = context;
- mHandler = handler;
- }
-
- void observe(Uri uri, int what) {
- mUriEventMap.put(uri, what);
- final ContentResolver resolver = mContext.getContentResolver();
- resolver.registerContentObserver(uri, false, this);
- }
-
- @Override
- public void onChange(boolean selfChange) {
- Log.wtf(TAG, "Should never be reached.");
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- final Integer what = mUriEventMap.get(uri);
- if (what != null) {
- mHandler.obtainMessage(what).sendToTarget();
- } else {
- loge("No matching event to send for URI=" + uri);
- }
- }
- }
-
- private static void log(String s) {
- Log.d(TAG, s);
- }
-
- private static void logw(String s) {
- Log.w(TAG, s);
- }
-
- private static void logwtf(String s) {
- Log.wtf(TAG, s);
- }
-
- private static void logwtf(String s, Throwable t) {
- Log.wtf(TAG, s, t);
- }
-
- private static void loge(String s) {
- Log.e(TAG, s);
- }
-
- private static void loge(String s, Throwable t) {
- Log.e(TAG, s, t);
- }
-
- /**
- * Return the information of all ongoing VPNs.
- *
- * <p>This method is used to update NetworkStatsService.
- *
- * <p>Must be called on the handler thread.
- */
- private UnderlyingNetworkInfo[] getAllVpnInfo() {
- ensureRunningOnConnectivityServiceThread();
- if (mLockdownEnabled) {
- return new UnderlyingNetworkInfo[0];
- }
- List<UnderlyingNetworkInfo> infoList = new ArrayList<>();
- for (NetworkAgentInfo nai : mNetworkAgentInfos) {
- UnderlyingNetworkInfo info = createVpnInfo(nai);
- if (info != null) {
- infoList.add(info);
- }
- }
- return infoList.toArray(new UnderlyingNetworkInfo[infoList.size()]);
- }
-
- /**
- * @return VPN information for accounting, or null if we can't retrieve all required
- * information, e.g underlying ifaces.
- */
- private UnderlyingNetworkInfo createVpnInfo(NetworkAgentInfo nai) {
- if (!nai.isVPN()) return null;
-
- Network[] underlyingNetworks = nai.declaredUnderlyingNetworks;
- // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret
- // the underlyingNetworks list.
- if (underlyingNetworks == null) {
- final NetworkAgentInfo defaultNai = getDefaultNetworkForUid(
- nai.networkCapabilities.getOwnerUid());
- if (defaultNai != null) {
- underlyingNetworks = new Network[] { defaultNai.network };
- }
- }
-
- if (CollectionUtils.isEmpty(underlyingNetworks)) return null;
-
- List<String> interfaces = new ArrayList<>();
- for (Network network : underlyingNetworks) {
- NetworkAgentInfo underlyingNai = getNetworkAgentInfoForNetwork(network);
- if (underlyingNai == null) continue;
- LinkProperties lp = underlyingNai.linkProperties;
- for (String iface : lp.getAllInterfaceNames()) {
- if (!TextUtils.isEmpty(iface)) {
- interfaces.add(iface);
- }
- }
- }
-
- if (interfaces.isEmpty()) return null;
-
- // Must be non-null or NetworkStatsService will crash.
- // Cannot happen in production code because Vpn only registers the NetworkAgent after the
- // tun or ipsec interface is created.
- // TODO: Remove this check.
- if (nai.linkProperties.getInterfaceName() == null) return null;
-
- return new UnderlyingNetworkInfo(nai.networkCapabilities.getOwnerUid(),
- nai.linkProperties.getInterfaceName(), interfaces);
- }
-
- // TODO This needs to be the default network that applies to the NAI.
- private Network[] underlyingNetworksOrDefault(final int ownerUid,
- Network[] underlyingNetworks) {
- final Network defaultNetwork = getNetwork(getDefaultNetworkForUid(ownerUid));
- if (underlyingNetworks == null && defaultNetwork != null) {
- // null underlying networks means to track the default.
- underlyingNetworks = new Network[] { defaultNetwork };
- }
- return underlyingNetworks;
- }
-
- // Returns true iff |network| is an underlying network of |nai|.
- private boolean hasUnderlyingNetwork(NetworkAgentInfo nai, Network network) {
- // TODO: support more than one level of underlying networks, either via a fixed-depth search
- // (e.g., 2 levels of underlying networks), or via loop detection, or....
- if (!nai.supportsUnderlyingNetworks()) return false;
- final Network[] underlying = underlyingNetworksOrDefault(
- nai.networkCapabilities.getOwnerUid(), nai.declaredUnderlyingNetworks);
- return CollectionUtils.contains(underlying, network);
- }
-
- /**
- * Recompute the capabilities for any networks that had a specific network as underlying.
- *
- * When underlying networks change, such networks may have to update capabilities to reflect
- * things like the metered bit, their transports, and so on. The capabilities are calculated
- * immediately. This method runs on the ConnectivityService thread.
- */
- private void propagateUnderlyingNetworkCapabilities(Network updatedNetwork) {
- ensureRunningOnConnectivityServiceThread();
- for (NetworkAgentInfo nai : mNetworkAgentInfos) {
- if (updatedNetwork == null || hasUnderlyingNetwork(nai, updatedNetwork)) {
- updateCapabilitiesForNetwork(nai);
- }
- }
- }
-
- private boolean isUidBlockedByVpn(int uid, List<UidRange> blockedUidRanges) {
- // Determine whether this UID is blocked because of always-on VPN lockdown. If a VPN applies
- // to the UID, then the UID is not blocked because always-on VPN lockdown applies only when
- // a VPN is not up.
- final NetworkAgentInfo vpnNai = getVpnForUid(uid);
- if (vpnNai != null && !vpnNai.networkAgentConfig.allowBypass) return false;
- for (UidRange range : blockedUidRanges) {
- if (range.contains(uid)) return true;
- }
- return false;
- }
-
- @Override
- public void setRequireVpnForUids(boolean requireVpn, UidRange[] ranges) {
- enforceNetworkStackOrSettingsPermission();
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_REQUIRE_VPN_FOR_UIDS,
- encodeBool(requireVpn), 0 /* arg2 */, ranges));
- }
-
- private void handleSetRequireVpnForUids(boolean requireVpn, UidRange[] ranges) {
- if (DBG) {
- Log.d(TAG, "Setting VPN " + (requireVpn ? "" : "not ") + "required for UIDs: "
- + Arrays.toString(ranges));
- }
- // Cannot use a Set since the list of UID ranges might contain duplicates.
- final List<UidRange> newVpnBlockedUidRanges = new ArrayList(mVpnBlockedUidRanges);
- for (int i = 0; i < ranges.length; i++) {
- if (requireVpn) {
- newVpnBlockedUidRanges.add(ranges[i]);
- } else {
- newVpnBlockedUidRanges.remove(ranges[i]);
- }
- }
-
- try {
- mNetd.networkRejectNonSecureVpn(requireVpn, toUidRangeStableParcels(ranges));
- } catch (RemoteException | ServiceSpecificException e) {
- Log.e(TAG, "setRequireVpnForUids(" + requireVpn + ", "
- + Arrays.toString(ranges) + "): netd command failed: " + e);
- }
-
- for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
- final boolean curMetered = nai.networkCapabilities.isMetered();
- maybeNotifyNetworkBlocked(nai, curMetered, curMetered,
- mVpnBlockedUidRanges, newVpnBlockedUidRanges);
- }
-
- mVpnBlockedUidRanges = newVpnBlockedUidRanges;
- }
-
- @Override
- public void setLegacyLockdownVpnEnabled(boolean enabled) {
- enforceNetworkStackOrSettingsPermission();
- mHandler.post(() -> mLockdownEnabled = enabled);
- }
-
- private boolean isLegacyLockdownNai(NetworkAgentInfo nai) {
- return mLockdownEnabled
- && getVpnType(nai) == VpnManager.TYPE_VPN_LEGACY
- && nai.networkCapabilities.appliesToUid(Process.FIRST_APPLICATION_UID);
- }
-
- private NetworkAgentInfo getLegacyLockdownNai() {
- if (!mLockdownEnabled) {
- return null;
- }
- // The legacy lockdown VPN always only applies to userId 0.
- final NetworkAgentInfo nai = getVpnForUid(Process.FIRST_APPLICATION_UID);
- if (nai == null || !isLegacyLockdownNai(nai)) return null;
-
- // The legacy lockdown VPN must always have exactly one underlying network.
- // This code may run on any thread and declaredUnderlyingNetworks may change, so store it in
- // a local variable. There is no need to make a copy because its contents cannot change.
- final Network[] underlying = nai.declaredUnderlyingNetworks;
- if (underlying == null || underlying.length != 1) {
- return null;
- }
-
- // The legacy lockdown VPN always uses the default network.
- // If the VPN's underlying network is no longer the current default network, it means that
- // the default network has just switched, and the VPN is about to disconnect.
- // Report that the VPN is not connected, so the state of NetworkInfo objects overwritten
- // by filterForLegacyLockdown will be set to CONNECTING and not CONNECTED.
- final NetworkAgentInfo defaultNetwork = getDefaultNetwork();
- if (defaultNetwork == null || !defaultNetwork.network.equals(underlying[0])) {
- return null;
- }
-
- return nai;
- };
-
- // TODO: move all callers to filterForLegacyLockdown and delete this method.
- // This likely requires making sendLegacyNetworkBroadcast take a NetworkInfo object instead of
- // just a DetailedState object.
- private DetailedState getLegacyLockdownState(DetailedState origState) {
- if (origState != DetailedState.CONNECTED) {
- return origState;
- }
- return (mLockdownEnabled && getLegacyLockdownNai() == null)
- ? DetailedState.CONNECTING
- : DetailedState.CONNECTED;
- }
-
- private void filterForLegacyLockdown(NetworkInfo ni) {
- if (!mLockdownEnabled || !ni.isConnected()) return;
- // The legacy lockdown VPN replaces the state of every network in CONNECTED state with the
- // state of its VPN. This is to ensure that when an underlying network connects, apps will
- // not see a CONNECTIVITY_ACTION broadcast for a network in state CONNECTED until the VPN
- // comes up, at which point there is a new CONNECTIVITY_ACTION broadcast for the underlying
- // network, this time with a state of CONNECTED.
- //
- // Now that the legacy lockdown code lives in ConnectivityService, and no longer has access
- // to the internal state of the Vpn object, always replace the state with CONNECTING. This
- // is not too far off the truth, since an always-on VPN, when not connected, is always
- // trying to reconnect.
- if (getLegacyLockdownNai() == null) {
- ni.setDetailedState(DetailedState.CONNECTING, "", null);
- }
- }
-
- @Override
- public void setProvisioningNotificationVisible(boolean visible, int networkType,
- String action) {
- enforceSettingsPermission();
- if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
- return;
- }
- final long ident = Binder.clearCallingIdentity();
- try {
- // Concatenate the range of types onto the range of NetIDs.
- int id = NetIdManager.MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE);
- mNotifier.setProvNotificationVisible(visible, id, action);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public void setAirplaneMode(boolean enable) {
- enforceAirplaneModePermission();
- final long ident = Binder.clearCallingIdentity();
- try {
- final ContentResolver cr = mContext.getContentResolver();
- Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, encodeBool(enable));
- Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- intent.putExtra("state", enable);
- mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- private void onUserAdded(@NonNull final UserHandle user) {
- mPermissionMonitor.onUserAdded(user);
- if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) {
- handleSetOemNetworkPreference(mOemNetworkPreferences, null);
- }
- }
-
- private void onUserRemoved(@NonNull final UserHandle user) {
- mPermissionMonitor.onUserRemoved(user);
- // If there was a network preference for this user, remove it.
- handleSetProfileNetworkPreference(new ProfileNetworkPreferences.Preference(user, null),
- null /* listener */);
- if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) {
- handleSetOemNetworkPreference(mOemNetworkPreferences, null);
- }
- }
-
- private void onPackageChanged(@NonNull final String packageName) {
- // This is necessary in case a package is added or removed, but also when it's replaced to
- // run as a new UID by its manifest rules. Also, if a separate package shares the same UID
- // as one in the preferences, then it should follow the same routing as that other package,
- // which means updating the rules is never to be needed in this case (whether it joins or
- // leaves a UID with a preference).
- if (isMappedInOemNetworkPreference(packageName)) {
- handleSetOemNetworkPreference(mOemNetworkPreferences, null);
- }
- }
-
- private final BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- ensureRunningOnConnectivityServiceThread();
- final String action = intent.getAction();
- final UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
-
- // User should be filled for below intents, check the existence.
- if (user == null) {
- Log.wtf(TAG, intent.getAction() + " broadcast without EXTRA_USER");
- return;
- }
-
- if (Intent.ACTION_USER_ADDED.equals(action)) {
- onUserAdded(user);
- } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
- onUserRemoved(user);
- } else {
- Log.wtf(TAG, "received unexpected intent: " + action);
- }
- }
- };
-
- private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- ensureRunningOnConnectivityServiceThread();
- switch (intent.getAction()) {
- case Intent.ACTION_PACKAGE_ADDED:
- case Intent.ACTION_PACKAGE_REMOVED:
- case Intent.ACTION_PACKAGE_REPLACED:
- onPackageChanged(intent.getData().getSchemeSpecificPart());
- break;
- default:
- Log.wtf(TAG, "received unexpected intent: " + intent.getAction());
- }
- }
- };
-
- private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>();
- private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>();
-
- private static class NetworkProviderInfo {
- public final String name;
- public final Messenger messenger;
- private final IBinder.DeathRecipient mDeathRecipient;
- public final int providerId;
-
- NetworkProviderInfo(String name, Messenger messenger, int providerId,
- @NonNull IBinder.DeathRecipient deathRecipient) {
- this.name = name;
- this.messenger = messenger;
- this.providerId = providerId;
- mDeathRecipient = deathRecipient;
-
- if (mDeathRecipient == null) {
- throw new AssertionError("Must pass a deathRecipient");
- }
- }
-
- void connect(Context context, Handler handler) {
- try {
- messenger.getBinder().linkToDeath(mDeathRecipient, 0);
- } catch (RemoteException e) {
- mDeathRecipient.binderDied();
- }
- }
- }
-
- private void ensureAllNetworkRequestsHaveType(List<NetworkRequest> requests) {
- for (int i = 0; i < requests.size(); i++) {
- ensureNetworkRequestHasType(requests.get(i));
- }
- }
-
- private void ensureNetworkRequestHasType(NetworkRequest request) {
- if (request.type == NetworkRequest.Type.NONE) {
- throw new IllegalArgumentException(
- "All NetworkRequests in ConnectivityService must have a type");
- }
- }
-
- /**
- * Tracks info about the requester.
- * Also used to notice when the calling process dies so as to self-expire
- */
- @VisibleForTesting
- protected class NetworkRequestInfo implements IBinder.DeathRecipient {
- // The requests to be satisfied in priority order. Non-multilayer requests will only have a
- // single NetworkRequest in mRequests.
- final List<NetworkRequest> mRequests;
-
- // mSatisfier and mActiveRequest rely on one another therefore set them together.
- void setSatisfier(
- @Nullable final NetworkAgentInfo satisfier,
- @Nullable final NetworkRequest activeRequest) {
- mSatisfier = satisfier;
- mActiveRequest = activeRequest;
- }
-
- // The network currently satisfying this NRI. Only one request in an NRI can have a
- // satisfier. For non-multilayer requests, only non-listen requests can have a satisfier.
- @Nullable
- private NetworkAgentInfo mSatisfier;
- NetworkAgentInfo getSatisfier() {
- return mSatisfier;
- }
-
- // The request in mRequests assigned to a network agent. This is null if none of the
- // requests in mRequests can be satisfied. This member has the constraint of only being
- // accessible on the handler thread.
- @Nullable
- private NetworkRequest mActiveRequest;
- NetworkRequest getActiveRequest() {
- return mActiveRequest;
- }
-
- final PendingIntent mPendingIntent;
- boolean mPendingIntentSent;
- @Nullable
- final Messenger mMessenger;
-
- // Information about the caller that caused this object to be created.
- @Nullable
- private final IBinder mBinder;
- final int mPid;
- final int mUid;
- final @NetworkCallback.Flag int mCallbackFlags;
- @Nullable
- final String mCallingAttributionTag;
-
- // Counter keeping track of this NRI.
- final PerUidCounter mPerUidCounter;
-
- // Effective UID of this request. This is different from mUid when a privileged process
- // files a request on behalf of another UID. This UID is used to determine blocked status,
- // UID matching, and so on. mUid above is used for permission checks and to enforce the
- // maximum limit of registered callbacks per UID.
- final int mAsUid;
-
- // In order to preserve the mapping of NetworkRequest-to-callback when apps register
- // callbacks using a returned NetworkRequest, the original NetworkRequest needs to be
- // maintained for keying off of. This is only a concern when the original nri
- // mNetworkRequests changes which happens currently for apps that register callbacks to
- // track the default network. In those cases, the nri is updated to have mNetworkRequests
- // that match the per-app default nri that currently tracks the calling app's uid so that
- // callbacks are fired at the appropriate time. When the callbacks fire,
- // mNetworkRequestForCallback will be used so as to preserve the caller's mapping. When
- // callbacks are updated to key off of an nri vs NetworkRequest, this stops being an issue.
- // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects.
- @NonNull
- private final NetworkRequest mNetworkRequestForCallback;
- NetworkRequest getNetworkRequestForCallback() {
- return mNetworkRequestForCallback;
- }
-
- /**
- * Get the list of UIDs this nri applies to.
- */
- @NonNull
- private Set<UidRange> getUids() {
- // networkCapabilities.getUids() returns a defensive copy.
- // multilayer requests will all have the same uids so return the first one.
- final Set<UidRange> uids = mRequests.get(0).networkCapabilities.getUidRanges();
- return (null == uids) ? new ArraySet<>() : uids;
- }
-
- NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r,
- @Nullable final PendingIntent pi, @Nullable String callingAttributionTag) {
- this(asUid, Collections.singletonList(r), r, pi, callingAttributionTag);
- }
-
- NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
- @NonNull final NetworkRequest requestForCallback, @Nullable final PendingIntent pi,
- @Nullable String callingAttributionTag) {
- ensureAllNetworkRequestsHaveType(r);
- mRequests = initializeRequests(r);
- mNetworkRequestForCallback = requestForCallback;
- mPendingIntent = pi;
- mMessenger = null;
- mBinder = null;
- mPid = getCallingPid();
- mUid = mDeps.getCallingUid();
- mAsUid = asUid;
- mPerUidCounter = getRequestCounter(this);
- mPerUidCounter.incrementCountOrThrow(mUid);
- /**
- * Location sensitive data not included in pending intent. Only included in
- * {@link NetworkCallback}.
- */
- mCallbackFlags = NetworkCallback.FLAG_NONE;
- mCallingAttributionTag = callingAttributionTag;
- }
-
- NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final Messenger m,
- @Nullable final IBinder binder,
- @NetworkCallback.Flag int callbackFlags,
- @Nullable String callingAttributionTag) {
- this(asUid, Collections.singletonList(r), r, m, binder, callbackFlags,
- callingAttributionTag);
- }
-
- NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
- @NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m,
- @Nullable final IBinder binder,
- @NetworkCallback.Flag int callbackFlags,
- @Nullable String callingAttributionTag) {
- super();
- ensureAllNetworkRequestsHaveType(r);
- mRequests = initializeRequests(r);
- mNetworkRequestForCallback = requestForCallback;
- mMessenger = m;
- mBinder = binder;
- mPid = getCallingPid();
- mUid = mDeps.getCallingUid();
- mAsUid = asUid;
- mPendingIntent = null;
- mPerUidCounter = getRequestCounter(this);
- mPerUidCounter.incrementCountOrThrow(mUid);
- mCallbackFlags = callbackFlags;
- mCallingAttributionTag = callingAttributionTag;
- linkDeathRecipient();
- }
-
- NetworkRequestInfo(@NonNull final NetworkRequestInfo nri,
- @NonNull final List<NetworkRequest> r) {
- super();
- ensureAllNetworkRequestsHaveType(r);
- mRequests = initializeRequests(r);
- mNetworkRequestForCallback = nri.getNetworkRequestForCallback();
- final NetworkAgentInfo satisfier = nri.getSatisfier();
- if (null != satisfier) {
- // If the old NRI was satisfied by an NAI, then it may have had an active request.
- // The active request is necessary to figure out what callbacks to send, in
- // particular then a network updates its capabilities.
- // As this code creates a new NRI with a new set of requests, figure out which of
- // the list of requests should be the active request. It is always the first
- // request of the list that can be satisfied by the satisfier since the order of
- // requests is a priority order.
- // Note even in the presence of a satisfier there may not be an active request,
- // when the satisfier is the no-service network.
- NetworkRequest activeRequest = null;
- for (final NetworkRequest candidate : r) {
- if (candidate.canBeSatisfiedBy(satisfier.networkCapabilities)) {
- activeRequest = candidate;
- break;
- }
- }
- setSatisfier(satisfier, activeRequest);
- }
- mMessenger = nri.mMessenger;
- mBinder = nri.mBinder;
- mPid = nri.mPid;
- mUid = nri.mUid;
- mAsUid = nri.mAsUid;
- mPendingIntent = nri.mPendingIntent;
- mPerUidCounter = getRequestCounter(this);
- mPerUidCounter.incrementCountOrThrow(mUid);
- mCallbackFlags = nri.mCallbackFlags;
- mCallingAttributionTag = nri.mCallingAttributionTag;
- linkDeathRecipient();
- }
-
- NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r) {
- this(asUid, Collections.singletonList(r));
- }
-
- NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r) {
- this(asUid, r, r.get(0), null /* pi */, null /* callingAttributionTag */);
- }
-
- // True if this NRI is being satisfied. It also accounts for if the nri has its satisifer
- // set to the mNoServiceNetwork in which case mActiveRequest will be null thus returning
- // false.
- boolean isBeingSatisfied() {
- return (null != mSatisfier && null != mActiveRequest);
- }
-
- boolean isMultilayerRequest() {
- return mRequests.size() > 1;
- }
-
- private List<NetworkRequest> initializeRequests(List<NetworkRequest> r) {
- // Creating a defensive copy to prevent the sender from modifying the list being
- // reflected in the return value of this method.
- final List<NetworkRequest> tempRequests = new ArrayList<>(r);
- return Collections.unmodifiableList(tempRequests);
- }
-
- void decrementRequestCount() {
- mPerUidCounter.decrementCount(mUid);
- }
-
- void linkDeathRecipient() {
- if (null != mBinder) {
- try {
- mBinder.linkToDeath(this, 0);
- } catch (RemoteException e) {
- binderDied();
- }
- }
- }
-
- void unlinkDeathRecipient() {
- if (null != mBinder) {
- mBinder.unlinkToDeath(this, 0);
- }
- }
-
- @Override
- public void binderDied() {
- log("ConnectivityService NetworkRequestInfo binderDied(" +
- mRequests + ", " + mBinder + ")");
- releaseNetworkRequests(mRequests);
- }
-
- @Override
- public String toString() {
- final String asUidString = (mAsUid == mUid) ? "" : " asUid: " + mAsUid;
- return "uid/pid:" + mUid + "/" + mPid + asUidString + " activeRequest: "
- + (mActiveRequest == null ? null : mActiveRequest.requestId)
- + " callbackRequest: "
- + mNetworkRequestForCallback.requestId
- + " " + mRequests
- + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent)
- + " callback flags: " + mCallbackFlags;
- }
- }
-
- private void ensureRequestableCapabilities(NetworkCapabilities networkCapabilities) {
- final String badCapability = networkCapabilities.describeFirstNonRequestableCapability();
- if (badCapability != null) {
- throw new IllegalArgumentException("Cannot request network with " + badCapability);
- }
- }
-
- // This checks that the passed capabilities either do not request a
- // specific SSID/SignalStrength, or the calling app has permission to do so.
- private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
- int callerPid, int callerUid, String callerPackageName) {
- if (null != nc.getSsid() && !checkSettingsPermission(callerPid, callerUid)) {
- throw new SecurityException("Insufficient permissions to request a specific SSID");
- }
-
- if (nc.hasSignalStrength()
- && !checkNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) {
- throw new SecurityException(
- "Insufficient permissions to request a specific signal strength");
- }
- mAppOpsManager.checkPackage(callerUid, callerPackageName);
-
- if (!nc.getSubscriptionIds().isEmpty()) {
- enforceNetworkFactoryPermission();
- }
- }
-
- private int[] getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) {
- final SortedSet<Integer> thresholds = new TreeSet<>();
- synchronized (nai) {
- // mNetworkRequests may contain the same value multiple times in case of
- // multilayer requests. It won't matter in this case because the thresholds
- // will then be the same and be deduplicated as they enter the `thresholds` set.
- // TODO : have mNetworkRequests be a Set<NetworkRequestInfo> or the like.
- for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
- for (final NetworkRequest req : nri.mRequests) {
- if (req.networkCapabilities.hasSignalStrength()
- && nai.satisfiesImmutableCapabilitiesOf(req)) {
- thresholds.add(req.networkCapabilities.getSignalStrength());
- }
- }
- }
- }
- return CollectionUtils.toIntArray(new ArrayList<>(thresholds));
- }
-
- private void updateSignalStrengthThresholds(
- NetworkAgentInfo nai, String reason, NetworkRequest request) {
- final int[] thresholdsArray = getSignalStrengthThresholds(nai);
-
- if (VDBG || (DBG && !"CONNECT".equals(reason))) {
- String detail;
- if (request != null && request.networkCapabilities.hasSignalStrength()) {
- detail = reason + " " + request.networkCapabilities.getSignalStrength();
- } else {
- detail = reason;
- }
- log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s",
- detail, Arrays.toString(thresholdsArray), nai.toShortString()));
- }
-
- nai.onSignalStrengthThresholdsUpdated(thresholdsArray);
- }
-
- private void ensureValidNetworkSpecifier(NetworkCapabilities nc) {
- if (nc == null) {
- return;
- }
- NetworkSpecifier ns = nc.getNetworkSpecifier();
- if (ns == null) {
- return;
- }
- if (ns instanceof MatchAllNetworkSpecifier) {
- throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted");
- }
- }
-
- private void ensureValid(NetworkCapabilities nc) {
- ensureValidNetworkSpecifier(nc);
- if (nc.isPrivateDnsBroken()) {
- throw new IllegalArgumentException("Can't request broken private DNS");
- }
- }
-
- private boolean isTargetSdkAtleast(int version, int callingUid,
- @NonNull String callingPackageName) {
- final UserHandle user = UserHandle.getUserHandleForUid(callingUid);
- final PackageManager pm =
- mContext.createContextAsUser(user, 0 /* flags */).getPackageManager();
- try {
- final int callingVersion = pm.getTargetSdkVersion(callingPackageName);
- if (callingVersion < version) return false;
- } catch (PackageManager.NameNotFoundException e) { }
- return true;
- }
-
- @Override
- public NetworkRequest requestNetwork(int asUid, NetworkCapabilities networkCapabilities,
- int reqTypeInt, Messenger messenger, int timeoutMs, IBinder binder,
- int legacyType, int callbackFlags, @NonNull String callingPackageName,
- @Nullable String callingAttributionTag) {
- if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) {
- if (isTargetSdkAtleast(Build.VERSION_CODES.M, mDeps.getCallingUid(),
- callingPackageName)) {
- throw new SecurityException("Insufficient permissions to specify legacy type");
- }
- }
- final NetworkCapabilities defaultNc = mDefaultRequest.mRequests.get(0).networkCapabilities;
- final int callingUid = mDeps.getCallingUid();
- // Privileged callers can track the default network of another UID by passing in a UID.
- if (asUid != Process.INVALID_UID) {
- enforceSettingsPermission();
- } else {
- asUid = callingUid;
- }
- final NetworkRequest.Type reqType;
- try {
- reqType = NetworkRequest.Type.values()[reqTypeInt];
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new IllegalArgumentException("Unsupported request type " + reqTypeInt);
- }
- switch (reqType) {
- case TRACK_DEFAULT:
- // If the request type is TRACK_DEFAULT, the passed {@code networkCapabilities}
- // is unused and will be replaced by ones appropriate for the UID (usually, the
- // calling app). This allows callers to keep track of the default network.
- networkCapabilities = copyDefaultNetworkCapabilitiesForUid(
- defaultNc, asUid, callingUid, callingPackageName);
- enforceAccessPermission();
- break;
- case TRACK_SYSTEM_DEFAULT:
- enforceSettingsPermission();
- networkCapabilities = new NetworkCapabilities(defaultNc);
- break;
- case BACKGROUND_REQUEST:
- enforceNetworkStackOrSettingsPermission();
- // Fall-through since other checks are the same with normal requests.
- case REQUEST:
- networkCapabilities = new NetworkCapabilities(networkCapabilities);
- enforceNetworkRequestPermissions(networkCapabilities, callingPackageName,
- callingAttributionTag);
- // TODO: this is incorrect. We mark the request as metered or not depending on
- // the state of the app when the request is filed, but we never change the
- // request if the app changes network state. http://b/29964605
- enforceMeteredApnPolicy(networkCapabilities);
- break;
- case LISTEN_FOR_BEST:
- enforceAccessPermission();
- networkCapabilities = new NetworkCapabilities(networkCapabilities);
- break;
- default:
- throw new IllegalArgumentException("Unsupported request type " + reqType);
- }
- ensureRequestableCapabilities(networkCapabilities);
- ensureSufficientPermissionsForRequest(networkCapabilities,
- Binder.getCallingPid(), callingUid, callingPackageName);
-
- // Enforce FOREGROUND if the caller does not have permission to use background network.
- if (reqType == LISTEN_FOR_BEST) {
- restrictBackgroundRequestForCaller(networkCapabilities);
- }
-
- // Set the UID range for this request to the single UID of the requester, unless the
- // requester has the permission to specify other UIDs.
- // This will overwrite any allowed UIDs in the requested capabilities. Though there
- // are no visible methods to set the UIDs, an app could use reflection to try and get
- // networks for other apps so it's essential that the UIDs are overwritten.
- // Also set the requester UID and package name in the request.
- restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
- callingUid, callingPackageName);
-
- if (timeoutMs < 0) {
- throw new IllegalArgumentException("Bad timeout specified");
- }
- ensureValid(networkCapabilities);
-
- final NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
- nextNetworkRequestId(), reqType);
- final NetworkRequestInfo nri = getNriToRegister(
- asUid, networkRequest, messenger, binder, callbackFlags,
- callingAttributionTag);
- if (DBG) log("requestNetwork for " + nri);
-
- // For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were
- // copied from the default request above. (This is necessary to ensure, for example, that
- // the callback does not leak sensitive information to unprivileged apps.) Check that the
- // changes don't alter request matching.
- if (reqType == NetworkRequest.Type.TRACK_SYSTEM_DEFAULT &&
- (!networkCapabilities.equalRequestableCapabilities(defaultNc))) {
- throw new IllegalStateException(
- "TRACK_SYSTEM_DEFAULT capabilities don't match default request: "
- + networkCapabilities + " vs. " + defaultNc);
- }
-
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
- if (timeoutMs > 0) {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST,
- nri), timeoutMs);
- }
- return networkRequest;
- }
-
- /**
- * Return the nri to be used when registering a network request. Specifically, this is used with
- * requests registered to track the default request. If there is currently a per-app default
- * tracking the app requestor, then we need to create a version of this nri that mirrors that of
- * the tracking per-app default so that callbacks are sent to the app requestor appropriately.
- * @param asUid the uid on behalf of which to file the request. Different from requestorUid
- * when a privileged caller is tracking the default network for another uid.
- * @param nr the network request for the nri.
- * @param msgr the messenger for the nri.
- * @param binder the binder for the nri.
- * @param callingAttributionTag the calling attribution tag for the nri.
- * @return the nri to register.
- */
- private NetworkRequestInfo getNriToRegister(final int asUid, @NonNull final NetworkRequest nr,
- @Nullable final Messenger msgr, @Nullable final IBinder binder,
- @NetworkCallback.Flag int callbackFlags,
- @Nullable String callingAttributionTag) {
- final List<NetworkRequest> requests;
- if (NetworkRequest.Type.TRACK_DEFAULT == nr.type) {
- requests = copyDefaultNetworkRequestsForUid(
- asUid, nr.getRequestorUid(), nr.getRequestorPackageName());
- } else {
- requests = Collections.singletonList(nr);
- }
- return new NetworkRequestInfo(
- asUid, requests, nr, msgr, binder, callbackFlags, callingAttributionTag);
- }
-
- private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities,
- String callingPackageName, String callingAttributionTag) {
- if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
- enforceConnectivityRestrictedNetworksPermission();
- } else {
- enforceChangePermission(callingPackageName, callingAttributionTag);
- }
- }
-
- @Override
- public boolean requestBandwidthUpdate(Network network) {
- enforceAccessPermission();
- NetworkAgentInfo nai = null;
- if (network == null) {
- return false;
- }
- synchronized (mNetworkForNetId) {
- nai = mNetworkForNetId.get(network.getNetId());
- }
- if (nai != null) {
- nai.onBandwidthUpdateRequested();
- synchronized (mBandwidthRequests) {
- final int uid = mDeps.getCallingUid();
- Integer uidReqs = mBandwidthRequests.get(uid);
- if (uidReqs == null) {
- uidReqs = 0;
- }
- mBandwidthRequests.put(uid, ++uidReqs);
- }
- return true;
- }
- return false;
- }
-
- private boolean isSystem(int uid) {
- return uid < Process.FIRST_APPLICATION_UID;
- }
-
- private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) {
- final int uid = mDeps.getCallingUid();
- if (isSystem(uid)) {
- // Exemption for system uid.
- return;
- }
- if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
- // Policy already enforced.
- return;
- }
- final long ident = Binder.clearCallingIdentity();
- try {
- if (mPolicyManager.isUidRestrictedOnMeteredNetworks(uid)) {
- // If UID is restricted, don't allow them to bring up metered APNs.
- networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
- PendingIntent operation, @NonNull String callingPackageName,
- @Nullable String callingAttributionTag) {
- Objects.requireNonNull(operation, "PendingIntent cannot be null.");
- final int callingUid = mDeps.getCallingUid();
- networkCapabilities = new NetworkCapabilities(networkCapabilities);
- enforceNetworkRequestPermissions(networkCapabilities, callingPackageName,
- callingAttributionTag);
- enforceMeteredApnPolicy(networkCapabilities);
- ensureRequestableCapabilities(networkCapabilities);
- ensureSufficientPermissionsForRequest(networkCapabilities,
- Binder.getCallingPid(), callingUid, callingPackageName);
- ensureValidNetworkSpecifier(networkCapabilities);
- restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
- callingUid, callingPackageName);
-
- NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
- nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
- NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation,
- callingAttributionTag);
- if (DBG) log("pendingRequest for " + nri);
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT,
- nri));
- return networkRequest;
- }
-
- private void releasePendingNetworkRequestWithDelay(PendingIntent operation) {
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
- mDeps.getCallingUid(), 0, operation), mReleasePendingIntentDelayMs);
- }
-
- @Override
- public void releasePendingNetworkRequest(PendingIntent operation) {
- Objects.requireNonNull(operation, "PendingIntent cannot be null.");
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
- mDeps.getCallingUid(), 0, operation));
- }
-
- // In order to implement the compatibility measure for pre-M apps that call
- // WifiManager.enableNetwork(..., true) without also binding to that network explicitly,
- // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork.
- // This ensures it has permission to do so.
- private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) {
- if (nc == null) {
- return false;
- }
- int[] transportTypes = nc.getTransportTypes();
- if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) {
- return false;
- }
- try {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_WIFI_STATE,
- "ConnectivityService");
- } catch (SecurityException e) {
- return false;
- }
- return true;
- }
-
- @Override
- public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
- Messenger messenger, IBinder binder,
- @NetworkCallback.Flag int callbackFlags,
- @NonNull String callingPackageName, @NonNull String callingAttributionTag) {
- final int callingUid = mDeps.getCallingUid();
- if (!hasWifiNetworkListenPermission(networkCapabilities)) {
- enforceAccessPermission();
- }
-
- NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
- ensureSufficientPermissionsForRequest(networkCapabilities,
- Binder.getCallingPid(), callingUid, callingPackageName);
- restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
- // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so
- // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get
- // onLost and onAvailable callbacks when networks move in and out of the background.
- // There is no need to do this for requests because an app without CHANGE_NETWORK_STATE
- // can't request networks.
- restrictBackgroundRequestForCaller(nc);
- ensureValid(nc);
-
- NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
- NetworkRequest.Type.LISTEN);
- NetworkRequestInfo nri =
- new NetworkRequestInfo(callingUid, networkRequest, messenger, binder, callbackFlags,
- callingAttributionTag);
- if (VDBG) log("listenForNetwork for " + nri);
-
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
- return networkRequest;
- }
-
- @Override
- public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
- PendingIntent operation, @NonNull String callingPackageName,
- @Nullable String callingAttributionTag) {
- Objects.requireNonNull(operation, "PendingIntent cannot be null.");
- final int callingUid = mDeps.getCallingUid();
- if (!hasWifiNetworkListenPermission(networkCapabilities)) {
- enforceAccessPermission();
- }
- ensureValid(networkCapabilities);
- ensureSufficientPermissionsForRequest(networkCapabilities,
- Binder.getCallingPid(), callingUid, callingPackageName);
- final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
- restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
-
- NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
- NetworkRequest.Type.LISTEN);
- NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation,
- callingAttributionTag);
- if (VDBG) log("pendingListenForNetwork for " + nri);
-
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
- }
-
- /** Returns the next Network provider ID. */
- public final int nextNetworkProviderId() {
- return mNextNetworkProviderId.getAndIncrement();
- }
-
- private void releaseNetworkRequests(List<NetworkRequest> networkRequests) {
- for (int i = 0; i < networkRequests.size(); i++) {
- releaseNetworkRequest(networkRequests.get(i));
- }
- }
-
- @Override
- public void releaseNetworkRequest(NetworkRequest networkRequest) {
- ensureNetworkRequestHasType(networkRequest);
- mHandler.sendMessage(mHandler.obtainMessage(
- EVENT_RELEASE_NETWORK_REQUEST, mDeps.getCallingUid(), 0, networkRequest));
- }
-
- private void handleRegisterNetworkProvider(NetworkProviderInfo npi) {
- if (mNetworkProviderInfos.containsKey(npi.messenger)) {
- // Avoid creating duplicates. even if an app makes a direct AIDL call.
- // This will never happen if an app calls ConnectivityManager#registerNetworkProvider,
- // as that will throw if a duplicate provider is registered.
- loge("Attempt to register existing NetworkProviderInfo "
- + mNetworkProviderInfos.get(npi.messenger).name);
- return;
- }
-
- if (DBG) log("Got NetworkProvider Messenger for " + npi.name);
- mNetworkProviderInfos.put(npi.messenger, npi);
- npi.connect(mContext, mTrackerHandler);
- }
-
- @Override
- public int registerNetworkProvider(Messenger messenger, String name) {
- enforceNetworkFactoryOrSettingsPermission();
- Objects.requireNonNull(messenger, "messenger must be non-null");
- NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger,
- nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger));
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi));
- return npi.providerId;
- }
-
- @Override
- public void unregisterNetworkProvider(Messenger messenger) {
- enforceNetworkFactoryOrSettingsPermission();
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger));
- }
-
- @Override
- public void offerNetwork(final int providerId,
- @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps,
- @NonNull final INetworkOfferCallback callback) {
- Objects.requireNonNull(score);
- Objects.requireNonNull(caps);
- Objects.requireNonNull(callback);
- final NetworkOffer offer = new NetworkOffer(
- FullScore.makeProspectiveScore(score, caps), caps, callback, providerId);
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_OFFER, offer));
- }
-
- @Override
- public void unofferNetwork(@NonNull final INetworkOfferCallback callback) {
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_OFFER, callback));
- }
-
- private void handleUnregisterNetworkProvider(Messenger messenger) {
- NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger);
- if (npi == null) {
- loge("Failed to find Messenger in unregisterNetworkProvider");
- return;
- }
- // Unregister all the offers from this provider
- final ArrayList<NetworkOfferInfo> toRemove = new ArrayList<>();
- for (final NetworkOfferInfo noi : mNetworkOffers) {
- if (noi.offer.providerId == npi.providerId) {
- // Can't call handleUnregisterNetworkOffer here because iteration is in progress
- toRemove.add(noi);
- }
- }
- for (final NetworkOfferInfo noi : toRemove) {
- handleUnregisterNetworkOffer(noi);
- }
- if (DBG) log("unregisterNetworkProvider for " + npi.name);
- }
-
- @Override
- public void declareNetworkRequestUnfulfillable(@NonNull final NetworkRequest request) {
- if (request.hasTransport(TRANSPORT_TEST)) {
- enforceNetworkFactoryOrTestNetworksPermission();
- } else {
- enforceNetworkFactoryPermission();
- }
- final NetworkRequestInfo nri = mNetworkRequests.get(request);
- if (nri != null) {
- // declareNetworkRequestUnfulfillable() paths don't apply to multilayer requests.
- ensureNotMultilayerRequest(nri, "declareNetworkRequestUnfulfillable");
- mHandler.post(() -> handleReleaseNetworkRequest(
- nri.mRequests.get(0), mDeps.getCallingUid(), true));
- }
- }
-
- // NOTE: Accessed on multiple threads, must be synchronized on itself.
- @GuardedBy("mNetworkForNetId")
- private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>();
- // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId.
- // An entry is first reserved with NetIdManager, prior to being added to mNetworkForNetId, so
- // there may not be a strict 1:1 correlation between the two.
- private final NetIdManager mNetIdManager;
-
- // NetworkAgentInfo keyed off its connecting messenger
- // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays
- // NOTE: Only should be accessed on ConnectivityServiceThread, except dump().
- private final ArraySet<NetworkAgentInfo> mNetworkAgentInfos = new ArraySet<>();
-
- // UID ranges for users that are currently blocked by VPNs.
- // This array is accessed and iterated on multiple threads without holding locks, so its
- // contents must never be mutated. When the ranges change, the array is replaced with a new one
- // (on the handler thread).
- private volatile List<UidRange> mVpnBlockedUidRanges = new ArrayList<>();
-
- // Must only be accessed on the handler thread
- @NonNull
- private final ArrayList<NetworkOfferInfo> mNetworkOffers = new ArrayList<>();
-
- @GuardedBy("mBlockedAppUids")
- private final HashSet<Integer> mBlockedAppUids = new HashSet<>();
-
- // Current OEM network preferences. This object must only be written to on the handler thread.
- // Since it is immutable and always non-null, other threads may read it if they only care
- // about seeing a consistent object but not that it is current.
- @NonNull
- private OemNetworkPreferences mOemNetworkPreferences =
- new OemNetworkPreferences.Builder().build();
- // Current per-profile network preferences. This object follows the same threading rules as
- // the OEM network preferences above.
- @NonNull
- private ProfileNetworkPreferences mProfileNetworkPreferences = new ProfileNetworkPreferences();
-
- // OemNetworkPreferences activity String log entries.
- private static final int MAX_OEM_NETWORK_PREFERENCE_LOGS = 20;
- @NonNull
- private final LocalLog mOemNetworkPreferencesLogs =
- new LocalLog(MAX_OEM_NETWORK_PREFERENCE_LOGS);
-
- /**
- * Determine whether a given package has a mapping in the current OemNetworkPreferences.
- * @param packageName the package name to check existence of a mapping for.
- * @return true if a mapping exists, false otherwise
- */
- private boolean isMappedInOemNetworkPreference(@NonNull final String packageName) {
- return mOemNetworkPreferences.getNetworkPreferences().containsKey(packageName);
- }
-
- // The always-on request for an Internet-capable network that apps without a specific default
- // fall back to.
- @VisibleForTesting
- @NonNull
- final NetworkRequestInfo mDefaultRequest;
- // Collection of NetworkRequestInfo's used for default networks.
- @VisibleForTesting
- @NonNull
- final ArraySet<NetworkRequestInfo> mDefaultNetworkRequests = new ArraySet<>();
-
- private boolean isPerAppDefaultRequest(@NonNull final NetworkRequestInfo nri) {
- return (mDefaultNetworkRequests.contains(nri) && mDefaultRequest != nri);
- }
-
- /**
- * Return the default network request currently tracking the given uid.
- * @param uid the uid to check.
- * @return the NetworkRequestInfo tracking the given uid.
- */
- @NonNull
- private NetworkRequestInfo getDefaultRequestTrackingUid(final int uid) {
- for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
- if (nri == mDefaultRequest) {
- continue;
- }
- // Checking the first request is sufficient as only multilayer requests will have more
- // than one request and for multilayer, all requests will track the same uids.
- if (nri.mRequests.get(0).networkCapabilities.appliesToUid(uid)) {
- return nri;
- }
- }
- return mDefaultRequest;
- }
-
- /**
- * Get a copy of the network requests of the default request that is currently tracking the
- * given uid.
- * @param asUid the uid on behalf of which to file the request. Different from requestorUid
- * when a privileged caller is tracking the default network for another uid.
- * @param requestorUid the uid to check the default for.
- * @param requestorPackageName the requestor's package name.
- * @return a copy of the default's NetworkRequest that is tracking the given uid.
- */
- @NonNull
- private List<NetworkRequest> copyDefaultNetworkRequestsForUid(
- final int asUid, final int requestorUid, @NonNull final String requestorPackageName) {
- return copyNetworkRequestsForUid(
- getDefaultRequestTrackingUid(asUid).mRequests,
- asUid, requestorUid, requestorPackageName);
- }
-
- /**
- * Copy the given nri's NetworkRequest collection.
- * @param requestsToCopy the NetworkRequest collection to be copied.
- * @param asUid the uid on behalf of which to file the request. Different from requestorUid
- * when a privileged caller is tracking the default network for another uid.
- * @param requestorUid the uid to set on the copied collection.
- * @param requestorPackageName the package name to set on the copied collection.
- * @return the copied NetworkRequest collection.
- */
- @NonNull
- private List<NetworkRequest> copyNetworkRequestsForUid(
- @NonNull final List<NetworkRequest> requestsToCopy, final int asUid,
- final int requestorUid, @NonNull final String requestorPackageName) {
- final List<NetworkRequest> requests = new ArrayList<>();
- for (final NetworkRequest nr : requestsToCopy) {
- requests.add(new NetworkRequest(copyDefaultNetworkCapabilitiesForUid(
- nr.networkCapabilities, asUid, requestorUid, requestorPackageName),
- nr.legacyType, nextNetworkRequestId(), nr.type));
- }
- return requests;
- }
-
- @NonNull
- private NetworkCapabilities copyDefaultNetworkCapabilitiesForUid(
- @NonNull final NetworkCapabilities netCapToCopy, final int asUid,
- final int requestorUid, @NonNull final String requestorPackageName) {
- // These capabilities are for a TRACK_DEFAULT callback, so:
- // 1. Remove NET_CAPABILITY_VPN, because it's (currently!) the only difference between
- // mDefaultRequest and a per-UID default request.
- // TODO: stop depending on the fact that these two unrelated things happen to be the same
- // 2. Always set the UIDs to asUid. restrictRequestUidsForCallerAndSetRequestorInfo will
- // not do this in the case of a privileged application.
- final NetworkCapabilities netCap = new NetworkCapabilities(netCapToCopy);
- netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
- netCap.setSingleUid(asUid);
- restrictRequestUidsForCallerAndSetRequestorInfo(
- netCap, requestorUid, requestorPackageName);
- return netCap;
- }
-
- /**
- * Get the nri that is currently being tracked for callbacks by per-app defaults.
- * @param nr the network request to check for equality against.
- * @return the nri if one exists, null otherwise.
- */
- @Nullable
- private NetworkRequestInfo getNriForAppRequest(@NonNull final NetworkRequest nr) {
- for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
- if (nri.getNetworkRequestForCallback().equals(nr)) {
- return nri;
- }
- }
- return null;
- }
-
- /**
- * Check if an nri is currently being managed by per-app default networking.
- * @param nri the nri to check.
- * @return true if this nri is currently being managed by per-app default networking.
- */
- private boolean isPerAppTrackedNri(@NonNull final NetworkRequestInfo nri) {
- // nri.mRequests.get(0) is only different from the original request filed in
- // nri.getNetworkRequestForCallback() if nri.mRequests was changed by per-app default
- // functionality therefore if these two don't match, it means this particular nri is
- // currently being managed by a per-app default.
- return nri.getNetworkRequestForCallback() != nri.mRequests.get(0);
- }
-
- /**
- * Determine if an nri is a managed default request that disallows default networking.
- * @param nri the request to evaluate
- * @return true if device-default networking is disallowed
- */
- private boolean isDefaultBlocked(@NonNull final NetworkRequestInfo nri) {
- // Check if this nri is a managed default that supports the default network at its
- // lowest priority request.
- final NetworkRequest defaultNetworkRequest = mDefaultRequest.mRequests.get(0);
- final NetworkCapabilities lowestPriorityNetCap =
- nri.mRequests.get(nri.mRequests.size() - 1).networkCapabilities;
- return isPerAppDefaultRequest(nri)
- && !(defaultNetworkRequest.networkCapabilities.equalRequestableCapabilities(
- lowestPriorityNetCap));
- }
-
- // Request used to optionally keep mobile data active even when higher
- // priority networks like Wi-Fi are active.
- private final NetworkRequest mDefaultMobileDataRequest;
-
- // Request used to optionally keep wifi data active even when higher
- // priority networks like ethernet are active.
- private final NetworkRequest mDefaultWifiRequest;
-
- // Request used to optionally keep vehicle internal network always active
- private final NetworkRequest mDefaultVehicleRequest;
-
- // Sentinel NAI used to direct apps with default networks that should have no connectivity to a
- // network with no service. This NAI should never be matched against, nor should any public API
- // ever return the associated network. For this reason, this NAI is not in the list of available
- // NAIs. It is used in computeNetworkReassignment() to be set as the satisfier for non-device
- // default requests that don't support using the device default network which will ultimately
- // allow ConnectivityService to use this no-service network when calling makeDefaultForApps().
- @VisibleForTesting
- final NetworkAgentInfo mNoServiceNetwork;
-
- // The NetworkAgentInfo currently satisfying the default request, if any.
- private NetworkAgentInfo getDefaultNetwork() {
- return mDefaultRequest.mSatisfier;
- }
-
- private NetworkAgentInfo getDefaultNetworkForUid(final int uid) {
- for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
- // Currently, all network requests will have the same uids therefore checking the first
- // one is sufficient. If/when uids are tracked at the nri level, this can change.
- final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUidRanges();
- if (null == uids) {
- continue;
- }
- for (final UidRange range : uids) {
- if (range.contains(uid)) {
- return nri.getSatisfier();
- }
- }
- }
- return getDefaultNetwork();
- }
-
- @Nullable
- private Network getNetwork(@Nullable NetworkAgentInfo nai) {
- return nai != null ? nai.network : null;
- }
-
- private void ensureRunningOnConnectivityServiceThread() {
- if (mHandler.getLooper().getThread() != Thread.currentThread()) {
- throw new IllegalStateException(
- "Not running on ConnectivityService thread: "
- + Thread.currentThread().getName());
- }
- }
-
- @VisibleForTesting
- protected boolean isDefaultNetwork(NetworkAgentInfo nai) {
- return nai == getDefaultNetwork();
- }
-
- /**
- * Register a new agent with ConnectivityService to handle a network.
- *
- * @param na a reference for ConnectivityService to contact the agent asynchronously.
- * @param networkInfo the initial info associated with this network. It can be updated later :
- * see {@link #updateNetworkInfo}.
- * @param linkProperties the initial link properties of this network. They can be updated
- * later : see {@link #updateLinkProperties}.
- * @param networkCapabilities the initial capabilites of this network. They can be updated
- * later : see {@link #updateCapabilities}.
- * @param initialScore the initial score of the network. See
- * {@link NetworkAgentInfo#getCurrentScore}.
- * @param networkAgentConfig metadata about the network. This is never updated.
- * @param providerId the ID of the provider owning this NetworkAgent.
- * @return the network created for this agent.
- */
- public Network registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo,
- LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
- @NonNull NetworkScore initialScore, NetworkAgentConfig networkAgentConfig,
- int providerId) {
- Objects.requireNonNull(networkInfo, "networkInfo must not be null");
- Objects.requireNonNull(linkProperties, "linkProperties must not be null");
- Objects.requireNonNull(networkCapabilities, "networkCapabilities must not be null");
- Objects.requireNonNull(initialScore, "initialScore must not be null");
- Objects.requireNonNull(networkAgentConfig, "networkAgentConfig must not be null");
- if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
- enforceAnyPermissionOf(Manifest.permission.MANAGE_TEST_NETWORKS);
- } else {
- enforceNetworkFactoryPermission();
- }
-
- final int uid = mDeps.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- return registerNetworkAgentInternal(na, networkInfo, linkProperties,
- networkCapabilities, initialScore, networkAgentConfig, providerId, uid);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- private Network registerNetworkAgentInternal(INetworkAgent na, NetworkInfo networkInfo,
- LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
- NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId,
- int uid) {
- if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
- // Strictly, sanitizing here is unnecessary as the capabilities will be sanitized in
- // the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
- // sees capabilities that may be malicious, which might prevent mistakes in the future.
- networkCapabilities = new NetworkCapabilities(networkCapabilities);
- networkCapabilities.restrictCapabilitesForTestNetwork(uid);
- }
-
- LinkProperties lp = new LinkProperties(linkProperties);
-
- final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
- final NetworkAgentInfo nai = new NetworkAgentInfo(na,
- new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
- currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
- this, mNetd, mDnsResolver, providerId, uid, mLingerDelayMs,
- mQosCallbackTracker, mDeps);
-
- // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
- processCapabilitiesFromAgent(nai, nc);
- nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
- processLinkPropertiesFromAgent(nai, nai.linkProperties);
-
- final String extraInfo = networkInfo.getExtraInfo();
- final String name = TextUtils.isEmpty(extraInfo)
- ? nai.networkCapabilities.getSsid() : extraInfo;
- if (DBG) log("registerNetworkAgent " + nai);
- mDeps.getNetworkStack().makeNetworkMonitor(
- nai.network, name, new NetworkMonitorCallbacks(nai));
- // NetworkAgentInfo registration will finish when the NetworkMonitor is created.
- // If the network disconnects or sends any other event before that, messages are deferred by
- // NetworkAgent until nai.connect(), which will be called when finalizing the
- // registration.
- return nai.network;
- }
-
- private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) {
- nai.onNetworkMonitorCreated(networkMonitor);
- if (VDBG) log("Got NetworkAgent Messenger");
- mNetworkAgentInfos.add(nai);
- synchronized (mNetworkForNetId) {
- mNetworkForNetId.put(nai.network.getNetId(), nai);
- }
-
- try {
- networkMonitor.start();
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- nai.notifyRegistered();
- NetworkInfo networkInfo = nai.networkInfo;
- updateNetworkInfo(nai, networkInfo);
- updateUids(nai, null, nai.networkCapabilities);
- }
-
- private class NetworkOfferInfo implements IBinder.DeathRecipient {
- @NonNull public final NetworkOffer offer;
-
- NetworkOfferInfo(@NonNull final NetworkOffer offer) {
- this.offer = offer;
- }
-
- @Override
- public void binderDied() {
- mHandler.post(() -> handleUnregisterNetworkOffer(this));
- }
- }
-
- private boolean isNetworkProviderWithIdRegistered(final int providerId) {
- for (final NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
- if (npi.providerId == providerId) return true;
- }
- return false;
- }
-
- /**
- * Register or update a network offer.
- * @param newOffer The new offer. If the callback member is the same as an existing
- * offer, it is an update of that offer.
- */
- private void handleRegisterNetworkOffer(@NonNull final NetworkOffer newOffer) {
- ensureRunningOnConnectivityServiceThread();
- if (!isNetworkProviderWithIdRegistered(newOffer.providerId)) {
- // This may actually happen if a provider updates its score or registers and then
- // immediately unregisters. The offer would still be in the handler queue, but the
- // provider would have been removed.
- if (DBG) log("Received offer from an unregistered provider");
- return;
- }
- final NetworkOfferInfo existingOffer = findNetworkOfferInfoByCallback(newOffer.callback);
- if (null != existingOffer) {
- handleUnregisterNetworkOffer(existingOffer);
- newOffer.migrateFrom(existingOffer.offer);
- }
- final NetworkOfferInfo noi = new NetworkOfferInfo(newOffer);
- try {
- noi.offer.callback.asBinder().linkToDeath(noi, 0 /* flags */);
- } catch (RemoteException e) {
- noi.binderDied();
- return;
- }
- mNetworkOffers.add(noi);
- issueNetworkNeeds(noi);
- }
-
- private void handleUnregisterNetworkOffer(@NonNull final NetworkOfferInfo noi) {
- ensureRunningOnConnectivityServiceThread();
- mNetworkOffers.remove(noi);
- noi.offer.callback.asBinder().unlinkToDeath(noi, 0 /* flags */);
- }
-
- @Nullable private NetworkOfferInfo findNetworkOfferInfoByCallback(
- @NonNull final INetworkOfferCallback callback) {
- ensureRunningOnConnectivityServiceThread();
- for (final NetworkOfferInfo noi : mNetworkOffers) {
- if (noi.offer.callback.asBinder().equals(callback.asBinder())) return noi;
- }
- return null;
- }
-
- /**
- * Called when receiving LinkProperties directly from a NetworkAgent.
- * Stores into |nai| any data coming from the agent that might also be written to the network's
- * LinkProperties by ConnectivityService itself. This ensures that the data provided by the
- * agent is not lost when updateLinkProperties is called.
- * This method should never alter the agent's LinkProperties, only store data in |nai|.
- */
- private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) {
- lp.ensureDirectlyConnectedRoutes();
- nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix());
- nai.networkAgentPortalData = lp.getCaptivePortalData();
- }
-
- private void updateLinkProperties(NetworkAgentInfo networkAgent, @NonNull LinkProperties newLp,
- @NonNull LinkProperties oldLp) {
- int netId = networkAgent.network.getNetId();
-
- // The NetworkAgent does not know whether clatd is running on its network or not, or whether
- // a NAT64 prefix was discovered by the DNS resolver. Before we do anything else, make sure
- // the LinkProperties for the network are accurate.
- networkAgent.clatd.fixupLinkProperties(oldLp, newLp);
-
- updateInterfaces(newLp, oldLp, netId, networkAgent.networkCapabilities);
-
- // update filtering rules, need to happen after the interface update so netd knows about the
- // new interface (the interface name -> index map becomes initialized)
- updateVpnFiltering(newLp, oldLp, networkAgent);
-
- updateMtu(newLp, oldLp);
- // TODO - figure out what to do for clat
-// for (LinkProperties lp : newLp.getStackedLinks()) {
-// updateMtu(lp, null);
-// }
- if (isDefaultNetwork(networkAgent)) {
- updateTcpBufferSizes(newLp.getTcpBufferSizes());
- }
-
- updateRoutes(newLp, oldLp, netId);
- updateDnses(newLp, oldLp, netId);
- // Make sure LinkProperties represents the latest private DNS status.
- // This does not need to be done before updateDnses because the
- // LinkProperties are not the source of the private DNS configuration.
- // updateDnses will fetch the private DNS configuration from DnsManager.
- mDnsManager.updatePrivateDnsStatus(netId, newLp);
-
- if (isDefaultNetwork(networkAgent)) {
- handleApplyDefaultProxy(newLp.getHttpProxy());
- } else {
- updateProxy(newLp, oldLp);
- }
-
- updateWakeOnLan(newLp);
-
- // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo.
- // It is not always contained in the LinkProperties sent from NetworkAgents, and if it
- // does, it needs to be merged here.
- newLp.setCaptivePortalData(mergeCaptivePortalData(networkAgent.networkAgentPortalData,
- networkAgent.capportApiData));
-
- // TODO - move this check to cover the whole function
- if (!Objects.equals(newLp, oldLp)) {
- synchronized (networkAgent) {
- networkAgent.linkProperties = newLp;
- }
- // Start or stop DNS64 detection and 464xlat according to network state.
- networkAgent.clatd.update();
- notifyIfacesChangedForNetworkStats();
- networkAgent.networkMonitor().notifyLinkPropertiesChanged(
- new LinkProperties(newLp, true /* parcelSensitiveFields */));
- if (networkAgent.everConnected) {
- notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
- }
- }
-
- mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent);
- }
-
- /**
- * @param naData captive portal data from NetworkAgent
- * @param apiData captive portal data from capport API
- */
- @Nullable
- private CaptivePortalData mergeCaptivePortalData(CaptivePortalData naData,
- CaptivePortalData apiData) {
- if (naData == null || apiData == null) {
- return naData == null ? apiData : naData;
- }
- final CaptivePortalData.Builder captivePortalBuilder =
- new CaptivePortalData.Builder(naData);
-
- if (apiData.isCaptive()) {
- captivePortalBuilder.setCaptive(true);
- }
- if (apiData.isSessionExtendable()) {
- captivePortalBuilder.setSessionExtendable(true);
- }
- if (apiData.getExpiryTimeMillis() >= 0 || apiData.getByteLimit() >= 0) {
- // Expiry time, bytes remaining, refresh time all need to come from the same source,
- // otherwise data would be inconsistent. Prefer the capport API info if present,
- // as it can generally be refreshed more often.
- captivePortalBuilder.setExpiryTime(apiData.getExpiryTimeMillis());
- captivePortalBuilder.setBytesRemaining(apiData.getByteLimit());
- captivePortalBuilder.setRefreshTime(apiData.getRefreshTimeMillis());
- } else if (naData.getExpiryTimeMillis() < 0 && naData.getByteLimit() < 0) {
- // No source has time / bytes remaining information: surface the newest refresh time
- // for other fields
- captivePortalBuilder.setRefreshTime(
- Math.max(naData.getRefreshTimeMillis(), apiData.getRefreshTimeMillis()));
- }
-
- // Prioritize the user portal URL from the network agent if the source is authenticated.
- if (apiData.getUserPortalUrl() != null && naData.getUserPortalUrlSource()
- != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) {
- captivePortalBuilder.setUserPortalUrl(apiData.getUserPortalUrl(),
- apiData.getUserPortalUrlSource());
- }
- // Prioritize the venue information URL from the network agent if the source is
- // authenticated.
- if (apiData.getVenueInfoUrl() != null && naData.getVenueInfoUrlSource()
- != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) {
- captivePortalBuilder.setVenueInfoUrl(apiData.getVenueInfoUrl(),
- apiData.getVenueInfoUrlSource());
- }
- return captivePortalBuilder.build();
- }
-
- private void wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add) {
- // Marks are only available on WiFi interfaces. Checking for
- // marks on unsupported interfaces is harmless.
- if (!caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
- return;
- }
-
- int mark = mResources.get().getInteger(R.integer.config_networkWakeupPacketMark);
- int mask = mResources.get().getInteger(R.integer.config_networkWakeupPacketMask);
-
- // Mask/mark of zero will not detect anything interesting.
- // Don't install rules unless both values are nonzero.
- if (mark == 0 || mask == 0) {
- return;
- }
-
- final String prefix = "iface:" + iface;
- try {
- if (add) {
- mNetd.wakeupAddInterface(iface, prefix, mark, mask);
- } else {
- mNetd.wakeupDelInterface(iface, prefix, mark, mask);
- }
- } catch (Exception e) {
- loge("Exception modifying wakeup packet monitoring: " + e);
- }
-
- }
-
- private void updateInterfaces(final @Nullable LinkProperties newLp,
- final @Nullable LinkProperties oldLp, final int netId,
- final @NonNull NetworkCapabilities caps) {
- final CompareResult<String> interfaceDiff = new CompareResult<>(
- oldLp != null ? oldLp.getAllInterfaceNames() : null,
- newLp != null ? newLp.getAllInterfaceNames() : null);
- if (!interfaceDiff.added.isEmpty()) {
- for (final String iface : interfaceDiff.added) {
- try {
- if (DBG) log("Adding iface " + iface + " to network " + netId);
- mNetd.networkAddInterface(netId, iface);
- wakeupModifyInterface(iface, caps, true);
- mDeps.reportNetworkInterfaceForTransports(mContext, iface,
- caps.getTransportTypes());
- } catch (Exception e) {
- logw("Exception adding interface: " + e);
- }
- }
- }
- for (final String iface : interfaceDiff.removed) {
- try {
- if (DBG) log("Removing iface " + iface + " from network " + netId);
- wakeupModifyInterface(iface, caps, false);
- mNetd.networkRemoveInterface(netId, iface);
- } catch (Exception e) {
- loge("Exception removing interface: " + e);
- }
- }
- }
-
- // TODO: move to frameworks/libs/net.
- private RouteInfoParcel convertRouteInfo(RouteInfo route) {
- final String nextHop;
-
- switch (route.getType()) {
- case RouteInfo.RTN_UNICAST:
- if (route.hasGateway()) {
- nextHop = route.getGateway().getHostAddress();
- } else {
- nextHop = INetd.NEXTHOP_NONE;
- }
- break;
- case RouteInfo.RTN_UNREACHABLE:
- nextHop = INetd.NEXTHOP_UNREACHABLE;
- break;
- case RouteInfo.RTN_THROW:
- nextHop = INetd.NEXTHOP_THROW;
- break;
- default:
- nextHop = INetd.NEXTHOP_NONE;
- break;
- }
-
- final RouteInfoParcel rip = new RouteInfoParcel();
- rip.ifName = route.getInterface();
- rip.destination = route.getDestination().toString();
- rip.nextHop = nextHop;
- rip.mtu = route.getMtu();
-
- return rip;
- }
-
- /**
- * Have netd update routes from oldLp to newLp.
- * @return true if routes changed between oldLp and newLp
- */
- private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
- // compare the route diff to determine which routes have been updated
- final CompareOrUpdateResult<RouteInfo.RouteKey, RouteInfo> routeDiff =
- new CompareOrUpdateResult<>(
- oldLp != null ? oldLp.getAllRoutes() : null,
- newLp != null ? newLp.getAllRoutes() : null,
- (r) -> r.getRouteKey());
-
- // add routes before removing old in case it helps with continuous connectivity
-
- // do this twice, adding non-next-hop routes first, then routes they are dependent on
- for (RouteInfo route : routeDiff.added) {
- if (route.hasGateway()) continue;
- if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
- try {
- mNetd.networkAddRouteParcel(netId, convertRouteInfo(route));
- } catch (Exception e) {
- if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) {
- loge("Exception in networkAddRouteParcel for non-gateway: " + e);
- }
- }
- }
- for (RouteInfo route : routeDiff.added) {
- if (!route.hasGateway()) continue;
- if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
- try {
- mNetd.networkAddRouteParcel(netId, convertRouteInfo(route));
- } catch (Exception e) {
- if ((route.getGateway() instanceof Inet4Address) || VDBG) {
- loge("Exception in networkAddRouteParcel for gateway: " + e);
- }
- }
- }
-
- for (RouteInfo route : routeDiff.removed) {
- if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId);
- try {
- mNetd.networkRemoveRouteParcel(netId, convertRouteInfo(route));
- } catch (Exception e) {
- loge("Exception in networkRemoveRouteParcel: " + e);
- }
- }
-
- for (RouteInfo route : routeDiff.updated) {
- if (VDBG || DDBG) log("Updating Route [" + route + "] from network " + netId);
- try {
- mNetd.networkUpdateRouteParcel(netId, convertRouteInfo(route));
- } catch (Exception e) {
- loge("Exception in networkUpdateRouteParcel: " + e);
- }
- }
- return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty()
- || !routeDiff.updated.isEmpty();
- }
-
- private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
- if (oldLp != null && newLp.isIdenticalDnses(oldLp)) {
- return; // no updating necessary
- }
-
- if (DBG) {
- final Collection<InetAddress> dnses = newLp.getDnsServers();
- log("Setting DNS servers for network " + netId + " to " + dnses);
- }
- try {
- mDnsManager.noteDnsServersForNetwork(netId, newLp);
- mDnsManager.flushVmDnsCache();
- } catch (Exception e) {
- loge("Exception in setDnsConfigurationForNetwork: " + e);
- }
- }
-
- private void updateVpnFiltering(LinkProperties newLp, LinkProperties oldLp,
- NetworkAgentInfo nai) {
- final String oldIface = oldLp != null ? oldLp.getInterfaceName() : null;
- final String newIface = newLp != null ? newLp.getInterfaceName() : null;
- final boolean wasFiltering = requiresVpnIsolation(nai, nai.networkCapabilities, oldLp);
- final boolean needsFiltering = requiresVpnIsolation(nai, nai.networkCapabilities, newLp);
-
- if (!wasFiltering && !needsFiltering) {
- // Nothing to do.
- return;
- }
-
- if (Objects.equals(oldIface, newIface) && (wasFiltering == needsFiltering)) {
- // Nothing changed.
- return;
- }
-
- final Set<UidRange> ranges = nai.networkCapabilities.getUidRanges();
- final int vpnAppUid = nai.networkCapabilities.getOwnerUid();
- // TODO: this create a window of opportunity for apps to receive traffic between the time
- // when the old rules are removed and the time when new rules are added. To fix this,
- // make eBPF support two allowlisted interfaces so here new rules can be added before the
- // old rules are being removed.
- if (wasFiltering) {
- mPermissionMonitor.onVpnUidRangesRemoved(oldIface, ranges, vpnAppUid);
- }
- if (needsFiltering) {
- mPermissionMonitor.onVpnUidRangesAdded(newIface, ranges, vpnAppUid);
- }
- }
-
- private void updateWakeOnLan(@NonNull LinkProperties lp) {
- if (mWolSupportedInterfaces == null) {
- mWolSupportedInterfaces = new ArraySet<>(mResources.get().getStringArray(
- R.array.config_wakeonlan_supported_interfaces));
- }
- lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName()));
- }
-
- private int getNetworkPermission(NetworkCapabilities nc) {
- if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
- return INetd.PERMISSION_SYSTEM;
- }
- if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) {
- return INetd.PERMISSION_NETWORK;
- }
- return INetd.PERMISSION_NONE;
- }
-
- private void updateNetworkPermissions(@NonNull final NetworkAgentInfo nai,
- @NonNull final NetworkCapabilities newNc) {
- final int oldPermission = getNetworkPermission(nai.networkCapabilities);
- final int newPermission = getNetworkPermission(newNc);
- if (oldPermission != newPermission && nai.created && !nai.isVPN()) {
- try {
- mNetd.networkSetPermissionForNetwork(nai.network.getNetId(), newPermission);
- } catch (RemoteException | ServiceSpecificException e) {
- loge("Exception in networkSetPermissionForNetwork: " + e);
- }
- }
- }
-
- /**
- * Called when receiving NetworkCapabilities directly from a NetworkAgent.
- * Stores into |nai| any data coming from the agent that might also be written to the network's
- * NetworkCapabilities by ConnectivityService itself. This ensures that the data provided by the
- * agent is not lost when updateCapabilities is called.
- * This method should never alter the agent's NetworkCapabilities, only store data in |nai|.
- */
- private void processCapabilitiesFromAgent(NetworkAgentInfo nai, NetworkCapabilities nc) {
- // Note: resetting the owner UID before storing the agent capabilities in NAI means that if
- // the agent attempts to change the owner UID, then nai.declaredCapabilities will not
- // actually be the same as the capabilities sent by the agent. Still, it is safer to reset
- // the owner UID here and behave as if the agent had never tried to change it.
- if (nai.networkCapabilities.getOwnerUid() != nc.getOwnerUid()) {
- Log.e(TAG, nai.toShortString() + ": ignoring attempt to change owner from "
- + nai.networkCapabilities.getOwnerUid() + " to " + nc.getOwnerUid());
- nc.setOwnerUid(nai.networkCapabilities.getOwnerUid());
- }
- nai.declaredCapabilities = new NetworkCapabilities(nc);
- }
-
- /** Modifies |newNc| based on the capabilities of |underlyingNetworks| and |agentCaps|. */
- @VisibleForTesting
- void applyUnderlyingCapabilities(@Nullable Network[] underlyingNetworks,
- @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) {
- underlyingNetworks = underlyingNetworksOrDefault(
- agentCaps.getOwnerUid(), underlyingNetworks);
- long transportTypes = NetworkCapabilitiesUtils.packBits(agentCaps.getTransportTypes());
- int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
- int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
- // metered if any underlying is metered, or originally declared metered by the agent.
- boolean metered = !agentCaps.hasCapability(NET_CAPABILITY_NOT_METERED);
- boolean roaming = false; // roaming if any underlying is roaming
- boolean congested = false; // congested if any underlying is congested
- boolean suspended = true; // suspended if all underlying are suspended
-
- boolean hadUnderlyingNetworks = false;
- if (null != underlyingNetworks) {
- for (Network underlyingNetwork : underlyingNetworks) {
- final NetworkAgentInfo underlying =
- getNetworkAgentInfoForNetwork(underlyingNetwork);
- if (underlying == null) continue;
-
- final NetworkCapabilities underlyingCaps = underlying.networkCapabilities;
- hadUnderlyingNetworks = true;
- for (int underlyingType : underlyingCaps.getTransportTypes()) {
- transportTypes |= 1L << underlyingType;
- }
-
- // Merge capabilities of this underlying network. For bandwidth, assume the
- // worst case.
- downKbps = NetworkCapabilities.minBandwidth(downKbps,
- underlyingCaps.getLinkDownstreamBandwidthKbps());
- upKbps = NetworkCapabilities.minBandwidth(upKbps,
- underlyingCaps.getLinkUpstreamBandwidthKbps());
- // If this underlying network is metered, the VPN is metered (it may cost money
- // to send packets on this network).
- metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED);
- // If this underlying network is roaming, the VPN is roaming (the billing structure
- // is different than the usual, local one).
- roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING);
- // If this underlying network is congested, the VPN is congested (the current
- // condition of the network affects the performance of this network).
- congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED);
- // If this network is not suspended, the VPN is not suspended (the VPN
- // is able to transfer some data).
- suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
- }
- }
- if (!hadUnderlyingNetworks) {
- // No idea what the underlying networks are; assume reasonable defaults
- metered = true;
- roaming = false;
- congested = false;
- suspended = false;
- }
-
- newNc.setTransportTypes(NetworkCapabilitiesUtils.unpackBits(transportTypes));
- newNc.setLinkDownstreamBandwidthKbps(downKbps);
- newNc.setLinkUpstreamBandwidthKbps(upKbps);
- newNc.setCapability(NET_CAPABILITY_NOT_METERED, !metered);
- newNc.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming);
- newNc.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested);
- newNc.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended);
- }
-
- /**
- * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are
- * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal,
- * and foreground status).
- */
- @NonNull
- private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) {
- // Once a NetworkAgent is connected, complain if some immutable capabilities are removed.
- // Don't complain for VPNs since they're not driven by requests and there is no risk of
- // causing a connect/teardown loop.
- // TODO: remove this altogether and make it the responsibility of the NetworkProviders to
- // avoid connect/teardown loops.
- if (nai.everConnected &&
- !nai.isVPN() &&
- !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) {
- // TODO: consider not complaining when a network agent degrades its capabilities if this
- // does not cause any request (that is not a listen) currently matching that agent to
- // stop being matched by the updated agent.
- String diff = nai.networkCapabilities.describeImmutableDifferences(nc);
- if (!TextUtils.isEmpty(diff)) {
- Log.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff);
- }
- }
-
- // Don't modify caller's NetworkCapabilities.
- final NetworkCapabilities newNc = new NetworkCapabilities(nc);
- if (nai.lastValidated) {
- newNc.addCapability(NET_CAPABILITY_VALIDATED);
- } else {
- newNc.removeCapability(NET_CAPABILITY_VALIDATED);
- }
- if (nai.lastCaptivePortalDetected) {
- newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
- } else {
- newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
- }
- if (nai.isBackgroundNetwork()) {
- newNc.removeCapability(NET_CAPABILITY_FOREGROUND);
- } else {
- newNc.addCapability(NET_CAPABILITY_FOREGROUND);
- }
- if (nai.partialConnectivity) {
- newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
- } else {
- newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
- }
- newNc.setPrivateDnsBroken(nai.networkCapabilities.isPrivateDnsBroken());
-
- // TODO : remove this once all factories are updated to send NOT_SUSPENDED and NOT_ROAMING
- if (!newNc.hasTransport(TRANSPORT_CELLULAR)) {
- newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
- newNc.addCapability(NET_CAPABILITY_NOT_ROAMING);
- }
-
- if (nai.supportsUnderlyingNetworks()) {
- applyUnderlyingCapabilities(nai.declaredUnderlyingNetworks, nai.declaredCapabilities,
- newNc);
- }
-
- return newNc;
- }
-
- private void updateNetworkInfoForRoamingAndSuspended(NetworkAgentInfo nai,
- NetworkCapabilities prevNc, NetworkCapabilities newNc) {
- final boolean prevSuspended = !prevNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
- final boolean suspended = !newNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
- final boolean prevRoaming = !prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
- final boolean roaming = !newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
- if (prevSuspended != suspended) {
- // TODO (b/73132094) : remove this call once the few users of onSuspended and
- // onResumed have been removed.
- notifyNetworkCallbacks(nai, suspended ? ConnectivityManager.CALLBACK_SUSPENDED
- : ConnectivityManager.CALLBACK_RESUMED);
- }
- if (prevSuspended != suspended || prevRoaming != roaming) {
- // updateNetworkInfo will mix in the suspended info from the capabilities and
- // take appropriate action for the network having possibly changed state.
- updateNetworkInfo(nai, nai.networkInfo);
- }
- }
-
- /**
- * Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically:
- *
- * 1. Calls mixInCapabilities to merge the passed-in NetworkCapabilities {@code nc} with the
- * capabilities we manage and store in {@code nai}, such as validated status and captive
- * portal status)
- * 2. Takes action on the result: changes network permissions, sends CAP_CHANGED callbacks, and
- * potentially triggers rematches.
- * 3. Directly informs other network stack components (NetworkStatsService, VPNs, etc. of the
- * change.)
- *
- * @param oldScore score of the network before any of the changes that prompted us
- * to call this function.
- * @param nai the network having its capabilities updated.
- * @param nc the new network capabilities.
- */
- private void updateCapabilities(final int oldScore, @NonNull final NetworkAgentInfo nai,
- @NonNull final NetworkCapabilities nc) {
- NetworkCapabilities newNc = mixInCapabilities(nai, nc);
- if (Objects.equals(nai.networkCapabilities, newNc)) return;
- updateNetworkPermissions(nai, newNc);
- final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc);
-
- updateUids(nai, prevNc, newNc);
- nai.updateScoreForNetworkAgentUpdate();
-
- if (nai.getCurrentScore() == oldScore && newNc.equalRequestableCapabilities(prevNc)) {
- // If the requestable capabilities haven't changed, and the score hasn't changed, then
- // the change we're processing can't affect any requests, it can only affect the listens
- // on this network. We might have been called by rematchNetworkAndRequests when a
- // network changed foreground state.
- processListenRequests(nai);
- } else {
- // If the requestable capabilities have changed or the score changed, we can't have been
- // called by rematchNetworkAndRequests, so it's safe to start a rematch.
- rematchAllNetworksAndRequests();
- notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
- }
- updateNetworkInfoForRoamingAndSuspended(nai, prevNc, newNc);
-
- final boolean oldMetered = prevNc.isMetered();
- final boolean newMetered = newNc.isMetered();
- final boolean meteredChanged = oldMetered != newMetered;
-
- if (meteredChanged) {
- maybeNotifyNetworkBlocked(nai, oldMetered, newMetered,
- mVpnBlockedUidRanges, mVpnBlockedUidRanges);
- }
-
- final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING)
- != newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
-
- // Report changes that are interesting for network statistics tracking.
- if (meteredChanged || roamingChanged) {
- notifyIfacesChangedForNetworkStats();
- }
-
- // This network might have been underlying another network. Propagate its capabilities.
- propagateUnderlyingNetworkCapabilities(nai.network);
-
- if (!newNc.equalsTransportTypes(prevNc)) {
- mDnsManager.updateTransportsForNetwork(
- nai.network.getNetId(), newNc.getTransportTypes());
- }
- }
-
- /** Convenience method to update the capabilities for a given network. */
- private void updateCapabilitiesForNetwork(NetworkAgentInfo nai) {
- updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
- }
-
- /**
- * Returns whether VPN isolation (ingress interface filtering) should be applied on the given
- * network.
- *
- * Ingress interface filtering enforces that all apps under the given network can only receive
- * packets from the network's interface (and loopback). This is important for VPNs because
- * apps that cannot bypass a fully-routed VPN shouldn't be able to receive packets from any
- * non-VPN interfaces.
- *
- * As a result, this method should return true iff
- * 1. the network is an app VPN (not legacy VPN)
- * 2. the VPN does not allow bypass
- * 3. the VPN is fully-routed
- * 4. the VPN interface is non-null
- *
- * @see INetd#firewallAddUidInterfaceRules
- * @see INetd#firewallRemoveUidInterfaceRules
- */
- private boolean requiresVpnIsolation(@NonNull NetworkAgentInfo nai, NetworkCapabilities nc,
- LinkProperties lp) {
- if (nc == null || lp == null) return false;
- return nai.isVPN()
- && !nai.networkAgentConfig.allowBypass
- && nc.getOwnerUid() != Process.SYSTEM_UID
- && lp.getInterfaceName() != null
- && (lp.hasIpv4DefaultRoute() || lp.hasIpv4UnreachableDefaultRoute())
- && (lp.hasIpv6DefaultRoute() || lp.hasIpv6UnreachableDefaultRoute());
- }
-
- private static UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) {
- final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.size()];
- int index = 0;
- for (UidRange range : ranges) {
- stableRanges[index] = new UidRangeParcel(range.start, range.stop);
- index++;
- }
- return stableRanges;
- }
-
- private static UidRangeParcel[] toUidRangeStableParcels(UidRange[] ranges) {
- final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length];
- for (int i = 0; i < ranges.length; i++) {
- stableRanges[i] = new UidRangeParcel(ranges[i].start, ranges[i].stop);
- }
- return stableRanges;
- }
-
- private void maybeCloseSockets(NetworkAgentInfo nai, UidRangeParcel[] ranges,
- int[] exemptUids) {
- if (nai.isVPN() && !nai.networkAgentConfig.allowBypass) {
- try {
- mNetd.socketDestroy(ranges, exemptUids);
- } catch (Exception e) {
- loge("Exception in socket destroy: ", e);
- }
- }
- }
-
- private void updateUidRanges(boolean add, NetworkAgentInfo nai, Set<UidRange> uidRanges) {
- int[] exemptUids = new int[2];
- // TODO: Excluding VPN_UID is necessary in order to not to kill the TCP connection used
- // by PPTP. Fix this by making Vpn set the owner UID to VPN_UID instead of system when
- // starting a legacy VPN, and remove VPN_UID here. (b/176542831)
- exemptUids[0] = VPN_UID;
- exemptUids[1] = nai.networkCapabilities.getOwnerUid();
- UidRangeParcel[] ranges = toUidRangeStableParcels(uidRanges);
-
- maybeCloseSockets(nai, ranges, exemptUids);
- try {
- if (add) {
- mNetd.networkAddUidRanges(nai.network.netId, ranges);
- } else {
- mNetd.networkRemoveUidRanges(nai.network.netId, ranges);
- }
- } catch (Exception e) {
- loge("Exception while " + (add ? "adding" : "removing") + " uid ranges " + uidRanges +
- " on netId " + nai.network.netId + ". " + e);
- }
- maybeCloseSockets(nai, ranges, exemptUids);
- }
-
- private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc,
- NetworkCapabilities newNc) {
- Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUidRanges();
- Set<UidRange> newRanges = null == newNc ? null : newNc.getUidRanges();
- if (null == prevRanges) prevRanges = new ArraySet<>();
- if (null == newRanges) newRanges = new ArraySet<>();
- final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges);
-
- prevRanges.removeAll(newRanges);
- newRanges.removeAll(prevRangesCopy);
-
- try {
- // When updating the VPN uid routing rules, add the new range first then remove the old
- // range. If old range were removed first, there would be a window between the old
- // range being removed and the new range being added, during which UIDs contained
- // in both ranges are not subject to any VPN routing rules. Adding new range before
- // removing old range works because, unlike the filtering rules below, it's possible to
- // add duplicate UID routing rules.
- // TODO: calculate the intersection of add & remove. Imagining that we are trying to
- // remove uid 3 from a set containing 1-5. Intersection of the prev and new sets is:
- // [1-5] & [1-2],[4-5] == [3]
- // Then we can do:
- // maybeCloseSockets([3])
- // mNetd.networkAddUidRanges([1-2],[4-5])
- // mNetd.networkRemoveUidRanges([1-5])
- // maybeCloseSockets([3])
- // This can prevent the sockets of uid 1-2, 4-5 from being closed. It also reduce the
- // number of binder calls from 6 to 4.
- if (!newRanges.isEmpty()) {
- updateUidRanges(true, nai, newRanges);
- }
- if (!prevRanges.isEmpty()) {
- updateUidRanges(false, nai, prevRanges);
- }
- final boolean wasFiltering = requiresVpnIsolation(nai, prevNc, nai.linkProperties);
- final boolean shouldFilter = requiresVpnIsolation(nai, newNc, nai.linkProperties);
- final String iface = nai.linkProperties.getInterfaceName();
- // For VPN uid interface filtering, old ranges need to be removed before new ranges can
- // be added, due to the range being expanded and stored as individual UIDs. For example
- // the UIDs might be updated from [0, 99999] to ([0, 10012], [10014, 99999]) which means
- // prevRanges = [0, 99999] while newRanges = [0, 10012], [10014, 99999]. If prevRanges
- // were added first and then newRanges got removed later, there would be only one uid
- // 10013 left. A consequence of removing old ranges before adding new ranges is that
- // there is now a window of opportunity when the UIDs are not subject to any filtering.
- // Note that this is in contrast with the (more robust) update of VPN routing rules
- // above, where the addition of new ranges happens before the removal of old ranges.
- // TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range
- // to be removed will never overlap with the new range to be added.
- if (wasFiltering && !prevRanges.isEmpty()) {
- mPermissionMonitor.onVpnUidRangesRemoved(iface, prevRanges, prevNc.getOwnerUid());
- }
- if (shouldFilter && !newRanges.isEmpty()) {
- mPermissionMonitor.onVpnUidRangesAdded(iface, newRanges, newNc.getOwnerUid());
- }
- } catch (Exception e) {
- // Never crash!
- loge("Exception in updateUids: ", e);
- }
- }
-
- public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) {
- ensureRunningOnConnectivityServiceThread();
-
- if (getNetworkAgentInfoForNetId(nai.network.getNetId()) != nai) {
- // Ignore updates for disconnected networks
- return;
- }
- if (VDBG || DDBG) {
- log("Update of LinkProperties for " + nai.toShortString()
- + "; created=" + nai.created
- + "; everConnected=" + nai.everConnected);
- }
- // TODO: eliminate this defensive copy after confirming that updateLinkProperties does not
- // modify its oldLp parameter.
- updateLinkProperties(nai, newLp, new LinkProperties(nai.linkProperties));
- }
-
- private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent,
- int notificationType) {
- if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) {
- Intent intent = new Intent();
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network);
- // If apps could file multi-layer requests with PendingIntents, they'd need to know
- // which of the layer is satisfied alongside with some ID for the request. Hence, if
- // such an API is ever implemented, there is no doubt the right request to send in
- // EXTRA_NETWORK_REQUEST is mActiveRequest, and whatever ID would be added would need to
- // be sent as a separate extra.
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, nri.getActiveRequest());
- nri.mPendingIntentSent = true;
- sendIntent(nri.mPendingIntent, intent);
- }
- // else not handled
- }
-
- private void sendIntent(PendingIntent pendingIntent, Intent intent) {
- mPendingIntentWakeLock.acquire();
- try {
- if (DBG) log("Sending " + pendingIntent);
- pendingIntent.send(mContext, 0, intent, this /* onFinished */, null /* Handler */);
- } catch (PendingIntent.CanceledException e) {
- if (DBG) log(pendingIntent + " was not sent, it had been canceled.");
- mPendingIntentWakeLock.release();
- releasePendingNetworkRequest(pendingIntent);
- }
- // ...otherwise, mPendingIntentWakeLock.release() gets called by onSendFinished()
- }
-
- @Override
- public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
- String resultData, Bundle resultExtras) {
- if (DBG) log("Finished sending " + pendingIntent);
- mPendingIntentWakeLock.release();
- // Release with a delay so the receiving client has an opportunity to put in its
- // own request.
- releasePendingNetworkRequestWithDelay(pendingIntent);
- }
-
- private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri,
- @NonNull final NetworkAgentInfo networkAgent, final int notificationType,
- final int arg1) {
- if (nri.mMessenger == null) {
- // Default request has no msgr. Also prevents callbacks from being invoked for
- // NetworkRequestInfos registered with ConnectivityDiagnostics requests. Those callbacks
- // are Type.LISTEN, but should not have NetworkCallbacks invoked.
- return;
- }
- Bundle bundle = new Bundle();
- // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects.
- // TODO: check if defensive copies of data is needed.
- final NetworkRequest nrForCallback = nri.getNetworkRequestForCallback();
- putParcelable(bundle, nrForCallback);
- Message msg = Message.obtain();
- if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) {
- putParcelable(bundle, networkAgent.network);
- }
- final boolean includeLocationSensitiveInfo =
- (nri.mCallbackFlags & NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) != 0;
- switch (notificationType) {
- case ConnectivityManager.CALLBACK_AVAILABLE: {
- final NetworkCapabilities nc =
- networkCapabilitiesRestrictedForCallerPermissions(
- networkAgent.networkCapabilities, nri.mPid, nri.mUid);
- putParcelable(
- bundle,
- createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- nc, includeLocationSensitiveInfo, nri.mPid, nri.mUid,
- nrForCallback.getRequestorPackageName(),
- nri.mCallingAttributionTag));
- putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
- networkAgent.linkProperties, nri.mPid, nri.mUid));
- // For this notification, arg1 contains the blocked status.
- msg.arg1 = arg1;
- break;
- }
- case ConnectivityManager.CALLBACK_LOSING: {
- msg.arg1 = arg1;
- break;
- }
- case ConnectivityManager.CALLBACK_CAP_CHANGED: {
- // networkAgent can't be null as it has been accessed a few lines above.
- final NetworkCapabilities netCap =
- networkCapabilitiesRestrictedForCallerPermissions(
- networkAgent.networkCapabilities, nri.mPid, nri.mUid);
- putParcelable(
- bundle,
- createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- netCap, includeLocationSensitiveInfo, nri.mPid, nri.mUid,
- nrForCallback.getRequestorPackageName(),
- nri.mCallingAttributionTag));
- break;
- }
- case ConnectivityManager.CALLBACK_IP_CHANGED: {
- putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
- networkAgent.linkProperties, nri.mPid, nri.mUid));
- break;
- }
- case ConnectivityManager.CALLBACK_BLK_CHANGED: {
- maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1);
- msg.arg1 = arg1;
- break;
- }
- }
- msg.what = notificationType;
- msg.setData(bundle);
- try {
- if (VDBG) {
- String notification = ConnectivityManager.getCallbackName(notificationType);
- log("sending notification " + notification + " for " + nrForCallback);
- }
- nri.mMessenger.send(msg);
- } catch (RemoteException e) {
- // may occur naturally in the race of binder death.
- loge("RemoteException caught trying to send a callback msg for " + nrForCallback);
- }
- }
-
- private static <T extends Parcelable> void putParcelable(Bundle bundle, T t) {
- bundle.putParcelable(t.getClass().getSimpleName(), t);
- }
-
- private void teardownUnneededNetwork(NetworkAgentInfo nai) {
- if (nai.numRequestNetworkRequests() != 0) {
- for (int i = 0; i < nai.numNetworkRequests(); i++) {
- NetworkRequest nr = nai.requestAt(i);
- // Ignore listening and track default requests.
- if (!nr.isRequest()) continue;
- loge("Dead network still had at least " + nr);
- break;
- }
- }
- nai.disconnect();
- }
-
- private void handleLingerComplete(NetworkAgentInfo oldNetwork) {
- if (oldNetwork == null) {
- loge("Unknown NetworkAgentInfo in handleLingerComplete");
- return;
- }
- if (DBG) log("handleLingerComplete for " + oldNetwork.toShortString());
-
- // If we get here it means that the last linger timeout for this network expired. So there
- // must be no other active linger timers, and we must stop lingering.
- oldNetwork.clearInactivityState();
-
- if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) {
- // Tear the network down.
- teardownUnneededNetwork(oldNetwork);
- } else {
- // Put the network in the background if it doesn't satisfy any foreground request.
- updateCapabilitiesForNetwork(oldNetwork);
- }
- }
-
- private void processDefaultNetworkChanges(@NonNull final NetworkReassignment changes) {
- boolean isDefaultChanged = false;
- for (final NetworkRequestInfo defaultRequestInfo : mDefaultNetworkRequests) {
- final NetworkReassignment.RequestReassignment reassignment =
- changes.getReassignment(defaultRequestInfo);
- if (null == reassignment) {
- continue;
- }
- // reassignment only contains those instances where the satisfying network changed.
- isDefaultChanged = true;
- // Notify system services of the new default.
- makeDefault(defaultRequestInfo, reassignment.mOldNetwork, reassignment.mNewNetwork);
- }
-
- if (isDefaultChanged) {
- // Hold a wakelock for a short time to help apps in migrating to a new default.
- scheduleReleaseNetworkTransitionWakelock();
- }
- }
-
- private void makeDefault(@NonNull final NetworkRequestInfo nri,
- @Nullable final NetworkAgentInfo oldDefaultNetwork,
- @Nullable final NetworkAgentInfo newDefaultNetwork) {
- if (DBG) {
- log("Switching to new default network for: " + nri + " using " + newDefaultNetwork);
- }
-
- // Fix up the NetworkCapabilities of any networks that have this network as underlying.
- if (newDefaultNetwork != null) {
- propagateUnderlyingNetworkCapabilities(newDefaultNetwork.network);
- }
-
- // Set an app level managed default and return since further processing only applies to the
- // default network.
- if (mDefaultRequest != nri) {
- makeDefaultForApps(nri, oldDefaultNetwork, newDefaultNetwork);
- return;
- }
-
- makeDefaultNetwork(newDefaultNetwork);
-
- if (oldDefaultNetwork != null) {
- mLingerMonitor.noteLingerDefaultNetwork(oldDefaultNetwork, newDefaultNetwork);
- }
- mNetworkActivityTracker.updateDataActivityTracking(newDefaultNetwork, oldDefaultNetwork);
- handleApplyDefaultProxy(null != newDefaultNetwork
- ? newDefaultNetwork.linkProperties.getHttpProxy() : null);
- updateTcpBufferSizes(null != newDefaultNetwork
- ? newDefaultNetwork.linkProperties.getTcpBufferSizes() : null);
- notifyIfacesChangedForNetworkStats();
- }
-
- private void makeDefaultForApps(@NonNull final NetworkRequestInfo nri,
- @Nullable final NetworkAgentInfo oldDefaultNetwork,
- @Nullable final NetworkAgentInfo newDefaultNetwork) {
- try {
- if (VDBG) {
- log("Setting default network for " + nri
- + " using UIDs " + nri.getUids()
- + " with old network " + (oldDefaultNetwork != null
- ? oldDefaultNetwork.network().getNetId() : "null")
- + " and new network " + (newDefaultNetwork != null
- ? newDefaultNetwork.network().getNetId() : "null"));
- }
- if (nri.getUids().isEmpty()) {
- throw new IllegalStateException("makeDefaultForApps called without specifying"
- + " any applications to set as the default." + nri);
- }
- if (null != newDefaultNetwork) {
- mNetd.networkAddUidRanges(
- newDefaultNetwork.network.getNetId(),
- toUidRangeStableParcels(nri.getUids()));
- }
- if (null != oldDefaultNetwork) {
- mNetd.networkRemoveUidRanges(
- oldDefaultNetwork.network.getNetId(),
- toUidRangeStableParcels(nri.getUids()));
- }
- } catch (RemoteException | ServiceSpecificException e) {
- loge("Exception setting app default network", e);
- }
- }
-
- private void makeDefaultNetwork(@Nullable final NetworkAgentInfo newDefaultNetwork) {
- try {
- if (null != newDefaultNetwork) {
- mNetd.networkSetDefault(newDefaultNetwork.network.getNetId());
- } else {
- mNetd.networkClearDefault();
- }
- } catch (RemoteException | ServiceSpecificException e) {
- loge("Exception setting default network :" + e);
- }
- }
-
- private void processListenRequests(@NonNull final NetworkAgentInfo nai) {
- // For consistency with previous behaviour, send onLost callbacks before onAvailable.
- processNewlyLostListenRequests(nai);
- notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
- processNewlySatisfiedListenRequests(nai);
- }
-
- private void processNewlyLostListenRequests(@NonNull final NetworkAgentInfo nai) {
- for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
- if (nri.isMultilayerRequest()) {
- continue;
- }
- final NetworkRequest nr = nri.mRequests.get(0);
- if (!nr.isListen()) continue;
- if (nai.isSatisfyingRequest(nr.requestId) && !nai.satisfies(nr)) {
- nai.removeRequest(nr.requestId);
- callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_LOST, 0);
- }
- }
- }
-
- private void processNewlySatisfiedListenRequests(@NonNull final NetworkAgentInfo nai) {
- for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
- if (nri.isMultilayerRequest()) {
- continue;
- }
- final NetworkRequest nr = nri.mRequests.get(0);
- if (!nr.isListen()) continue;
- if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) {
- nai.addRequest(nr);
- notifyNetworkAvailable(nai, nri);
- }
- }
- }
-
- // An accumulator class to gather the list of changes that result from a rematch.
- private static class NetworkReassignment {
- static class RequestReassignment {
- @NonNull public final NetworkRequestInfo mNetworkRequestInfo;
- @Nullable public final NetworkRequest mOldNetworkRequest;
- @Nullable public final NetworkRequest mNewNetworkRequest;
- @Nullable public final NetworkAgentInfo mOldNetwork;
- @Nullable public final NetworkAgentInfo mNewNetwork;
- RequestReassignment(@NonNull final NetworkRequestInfo networkRequestInfo,
- @Nullable final NetworkRequest oldNetworkRequest,
- @Nullable final NetworkRequest newNetworkRequest,
- @Nullable final NetworkAgentInfo oldNetwork,
- @Nullable final NetworkAgentInfo newNetwork) {
- mNetworkRequestInfo = networkRequestInfo;
- mOldNetworkRequest = oldNetworkRequest;
- mNewNetworkRequest = newNetworkRequest;
- mOldNetwork = oldNetwork;
- mNewNetwork = newNetwork;
- }
-
- public String toString() {
- final NetworkRequest requestToShow = null != mNewNetworkRequest
- ? mNewNetworkRequest : mNetworkRequestInfo.mRequests.get(0);
- return requestToShow.requestId + " : "
- + (null != mOldNetwork ? mOldNetwork.network.getNetId() : "null")
- + " → " + (null != mNewNetwork ? mNewNetwork.network.getNetId() : "null");
- }
- }
-
- @NonNull private final ArrayList<RequestReassignment> mReassignments = new ArrayList<>();
-
- @NonNull Iterable<RequestReassignment> getRequestReassignments() {
- return mReassignments;
- }
-
- void addRequestReassignment(@NonNull final RequestReassignment reassignment) {
- if (Build.isDebuggable()) {
- // The code is never supposed to add two reassignments of the same request. Make
- // sure this stays true, but without imposing this expensive check on all
- // reassignments on all user devices.
- for (final RequestReassignment existing : mReassignments) {
- if (existing.mNetworkRequestInfo.equals(reassignment.mNetworkRequestInfo)) {
- throw new IllegalStateException("Trying to reassign ["
- + reassignment + "] but already have ["
- + existing + "]");
- }
- }
- }
- mReassignments.add(reassignment);
- }
-
- // Will return null if this reassignment does not change the network assigned to
- // the passed request.
- @Nullable
- private RequestReassignment getReassignment(@NonNull final NetworkRequestInfo nri) {
- for (final RequestReassignment event : getRequestReassignments()) {
- if (nri == event.mNetworkRequestInfo) return event;
- }
- return null;
- }
-
- public String toString() {
- final StringJoiner sj = new StringJoiner(", " /* delimiter */,
- "NetReassign [" /* prefix */, "]" /* suffix */);
- if (mReassignments.isEmpty()) return sj.add("no changes").toString();
- for (final RequestReassignment rr : getRequestReassignments()) {
- sj.add(rr.toString());
- }
- return sj.toString();
- }
-
- public String debugString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("NetworkReassignment :");
- if (mReassignments.isEmpty()) return sb.append(" no changes").toString();
- for (final RequestReassignment rr : getRequestReassignments()) {
- sb.append("\n ").append(rr);
- }
- return sb.append("\n").toString();
- }
- }
-
- private void updateSatisfiersForRematchRequest(@NonNull final NetworkRequestInfo nri,
- @Nullable final NetworkRequest previousRequest,
- @Nullable final NetworkRequest newRequest,
- @Nullable final NetworkAgentInfo previousSatisfier,
- @Nullable final NetworkAgentInfo newSatisfier,
- final long now) {
- if (null != newSatisfier && mNoServiceNetwork != newSatisfier) {
- if (VDBG) log("rematch for " + newSatisfier.toShortString());
- if (null != previousRequest && null != previousSatisfier) {
- if (VDBG || DDBG) {
- log(" accepting network in place of " + previousSatisfier.toShortString());
- }
- previousSatisfier.removeRequest(previousRequest.requestId);
- previousSatisfier.lingerRequest(previousRequest.requestId, now);
- } else {
- if (VDBG || DDBG) log(" accepting network in place of null");
- }
-
- // To prevent constantly CPU wake up for nascent timer, if a network comes up
- // and immediately satisfies a request then remove the timer. This will happen for
- // all networks except in the case of an underlying network for a VCN.
- if (newSatisfier.isNascent()) {
- newSatisfier.unlingerRequest(NetworkRequest.REQUEST_ID_NONE);
- newSatisfier.unsetInactive();
- }
-
- // if newSatisfier is not null, then newRequest may not be null.
- newSatisfier.unlingerRequest(newRequest.requestId);
- if (!newSatisfier.addRequest(newRequest)) {
- Log.wtf(TAG, "BUG: " + newSatisfier.toShortString() + " already has "
- + newRequest);
- }
- } else if (null != previousRequest && null != previousSatisfier) {
- if (DBG) {
- log("Network " + previousSatisfier.toShortString() + " stopped satisfying"
- + " request " + previousRequest.requestId);
- }
- previousSatisfier.removeRequest(previousRequest.requestId);
- }
- nri.setSatisfier(newSatisfier, newRequest);
- }
-
- /**
- * This function is triggered when something can affect what network should satisfy what
- * request, and it computes the network reassignment from the passed collection of requests to
- * network match to the one that the system should now have. That data is encoded in an
- * object that is a list of changes, each of them having an NRI, and old satisfier, and a new
- * satisfier.
- *
- * After the reassignment is computed, it is applied to the state objects.
- *
- * @param networkRequests the nri objects to evaluate for possible network reassignment
- * @return NetworkReassignment listing of proposed network assignment changes
- */
- @NonNull
- private NetworkReassignment computeNetworkReassignment(
- @NonNull final Collection<NetworkRequestInfo> networkRequests) {
- final NetworkReassignment changes = new NetworkReassignment();
-
- // Gather the list of all relevant agents.
- final ArrayList<NetworkAgentInfo> nais = new ArrayList<>();
- for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
- if (!nai.everConnected) {
- continue;
- }
- nais.add(nai);
- }
-
- for (final NetworkRequestInfo nri : networkRequests) {
- // Non-multilayer listen requests can be ignored.
- if (!nri.isMultilayerRequest() && nri.mRequests.get(0).isListen()) {
- continue;
- }
- NetworkAgentInfo bestNetwork = null;
- NetworkRequest bestRequest = null;
- for (final NetworkRequest req : nri.mRequests) {
- bestNetwork = mNetworkRanker.getBestNetwork(req, nais, nri.getSatisfier());
- // Stop evaluating as the highest possible priority request is satisfied.
- if (null != bestNetwork) {
- bestRequest = req;
- break;
- }
- }
- if (null == bestNetwork && isDefaultBlocked(nri)) {
- // Remove default networking if disallowed for managed default requests.
- bestNetwork = mNoServiceNetwork;
- }
- if (nri.getSatisfier() != bestNetwork) {
- // bestNetwork may be null if no network can satisfy this request.
- changes.addRequestReassignment(new NetworkReassignment.RequestReassignment(
- nri, nri.mActiveRequest, bestRequest, nri.getSatisfier(), bestNetwork));
- }
- }
- return changes;
- }
-
- private Set<NetworkRequestInfo> getNrisFromGlobalRequests() {
- return new HashSet<>(mNetworkRequests.values());
- }
-
- /**
- * Attempt to rematch all Networks with all NetworkRequests. This may result in Networks
- * being disconnected.
- */
- private void rematchAllNetworksAndRequests() {
- rematchNetworksAndRequests(getNrisFromGlobalRequests());
- }
-
- /**
- * Attempt to rematch all Networks with given NetworkRequests. This may result in Networks
- * being disconnected.
- */
- private void rematchNetworksAndRequests(
- @NonNull final Set<NetworkRequestInfo> networkRequests) {
- ensureRunningOnConnectivityServiceThread();
- // TODO: This may be slow, and should be optimized.
- final long now = SystemClock.elapsedRealtime();
- final NetworkReassignment changes = computeNetworkReassignment(networkRequests);
- if (VDBG || DDBG) {
- log(changes.debugString());
- } else if (DBG) {
- log(changes.toString()); // Shorter form, only one line of log
- }
- applyNetworkReassignment(changes, now);
- issueNetworkNeeds();
- }
-
- private void applyNetworkReassignment(@NonNull final NetworkReassignment changes,
- final long now) {
- final Collection<NetworkAgentInfo> nais = mNetworkAgentInfos;
-
- // Since most of the time there are only 0 or 1 background networks, it would probably
- // be more efficient to just use an ArrayList here. TODO : measure performance
- final ArraySet<NetworkAgentInfo> oldBgNetworks = new ArraySet<>();
- for (final NetworkAgentInfo nai : nais) {
- if (nai.isBackgroundNetwork()) oldBgNetworks.add(nai);
- }
-
- // First, update the lists of satisfied requests in the network agents. This is necessary
- // because some code later depends on this state to be correct, most prominently computing
- // the linger status.
- for (final NetworkReassignment.RequestReassignment event :
- changes.getRequestReassignments()) {
- updateSatisfiersForRematchRequest(event.mNetworkRequestInfo,
- event.mOldNetworkRequest, event.mNewNetworkRequest,
- event.mOldNetwork, event.mNewNetwork,
- now);
- }
-
- // Process default network changes if applicable.
- processDefaultNetworkChanges(changes);
-
- // Notify requested networks are available after the default net is switched, but
- // before LegacyTypeTracker sends legacy broadcasts
- for (final NetworkReassignment.RequestReassignment event :
- changes.getRequestReassignments()) {
- if (null != event.mNewNetwork) {
- notifyNetworkAvailable(event.mNewNetwork, event.mNetworkRequestInfo);
- } else {
- callCallbackForRequest(event.mNetworkRequestInfo, event.mOldNetwork,
- ConnectivityManager.CALLBACK_LOST, 0);
- }
- }
-
- // Update the inactivity state before processing listen callbacks, because the background
- // computation depends on whether the network is inactive. Don't send the LOSING callbacks
- // just yet though, because they have to be sent after the listens are processed to keep
- // backward compatibility.
- final ArrayList<NetworkAgentInfo> inactiveNetworks = new ArrayList<>();
- for (final NetworkAgentInfo nai : nais) {
- // Rematching may have altered the inactivity state of some networks, so update all
- // inactivity timers. updateInactivityState reads the state from the network agent
- // and does nothing if the state has not changed : the source of truth is controlled
- // with NetworkAgentInfo#lingerRequest and NetworkAgentInfo#unlingerRequest, which
- // have been called while rematching the individual networks above.
- if (updateInactivityState(nai, now)) {
- inactiveNetworks.add(nai);
- }
- }
-
- for (final NetworkAgentInfo nai : nais) {
- if (!nai.everConnected) continue;
- final boolean oldBackground = oldBgNetworks.contains(nai);
- // Process listen requests and update capabilities if the background state has
- // changed for this network. For consistency with previous behavior, send onLost
- // callbacks before onAvailable.
- processNewlyLostListenRequests(nai);
- if (oldBackground != nai.isBackgroundNetwork()) {
- applyBackgroundChangeForRematch(nai);
- }
- processNewlySatisfiedListenRequests(nai);
- }
-
- for (final NetworkAgentInfo nai : inactiveNetworks) {
- // For nascent networks, if connecting with no foreground request, skip broadcasting
- // LOSING for backward compatibility. This is typical when mobile data connected while
- // wifi connected with mobile data always-on enabled.
- if (nai.isNascent()) continue;
- notifyNetworkLosing(nai, now);
- }
-
- updateLegacyTypeTrackerAndVpnLockdownForRematch(changes, nais);
-
- // Tear down all unneeded networks.
- for (NetworkAgentInfo nai : mNetworkAgentInfos) {
- if (unneeded(nai, UnneededFor.TEARDOWN)) {
- if (nai.getInactivityExpiry() > 0) {
- // This network has active linger timers and no requests, but is not
- // lingering. Linger it.
- //
- // One way (the only way?) this can happen if this network is unvalidated
- // and became unneeded due to another network improving its score to the
- // point where this network will no longer be able to satisfy any requests
- // even if it validates.
- if (updateInactivityState(nai, now)) {
- notifyNetworkLosing(nai, now);
- }
- } else {
- if (DBG) log("Reaping " + nai.toShortString());
- teardownUnneededNetwork(nai);
- }
- }
- }
- }
-
- /**
- * Apply a change in background state resulting from rematching networks with requests.
- *
- * During rematch, a network may change background states by starting to satisfy or stopping
- * to satisfy a foreground request. Listens don't count for this. When a network changes
- * background states, its capabilities need to be updated and callbacks fired for the
- * capability change.
- *
- * @param nai The network that changed background states
- */
- private void applyBackgroundChangeForRematch(@NonNull final NetworkAgentInfo nai) {
- final NetworkCapabilities newNc = mixInCapabilities(nai, nai.networkCapabilities);
- if (Objects.equals(nai.networkCapabilities, newNc)) return;
- updateNetworkPermissions(nai, newNc);
- nai.getAndSetNetworkCapabilities(newNc);
- notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
- }
-
- private void updateLegacyTypeTrackerAndVpnLockdownForRematch(
- @NonNull final NetworkReassignment changes,
- @NonNull final Collection<NetworkAgentInfo> nais) {
- final NetworkReassignment.RequestReassignment reassignmentOfDefault =
- changes.getReassignment(mDefaultRequest);
- final NetworkAgentInfo oldDefaultNetwork =
- null != reassignmentOfDefault ? reassignmentOfDefault.mOldNetwork : null;
- final NetworkAgentInfo newDefaultNetwork =
- null != reassignmentOfDefault ? reassignmentOfDefault.mNewNetwork : null;
-
- if (oldDefaultNetwork != newDefaultNetwork) {
- // Maintain the illusion : since the legacy API only understands one network at a time,
- // if the default network changed, apps should see a disconnected broadcast for the
- // old default network before they see a connected broadcast for the new one.
- if (oldDefaultNetwork != null) {
- mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
- oldDefaultNetwork, true);
- }
- if (newDefaultNetwork != null) {
- // The new default network can be newly null if and only if the old default
- // network doesn't satisfy the default request any more because it lost a
- // capability.
- mDefaultInetConditionPublished = newDefaultNetwork.lastValidated ? 100 : 0;
- mLegacyTypeTracker.add(
- newDefaultNetwork.networkInfo.getType(), newDefaultNetwork);
- }
- }
-
- // Now that all the callbacks have been sent, send the legacy network broadcasts
- // as needed. This is necessary so that legacy requests correctly bind dns
- // requests to this network. The legacy users are listening for this broadcast
- // and will generally do a dns request so they can ensureRouteToHost and if
- // they do that before the callbacks happen they'll use the default network.
- //
- // TODO: Is there still a race here? The legacy broadcast will be sent after sending
- // callbacks, but if apps can receive the broadcast before the callback, they still might
- // have an inconsistent view of networking.
- //
- // This *does* introduce a race where if the user uses the new api
- // (notification callbacks) and then uses the old api (getNetworkInfo(type))
- // they may get old info. Reverse this after the old startUsing api is removed.
- // This is on top of the multiple intent sequencing referenced in the todo above.
- for (NetworkAgentInfo nai : nais) {
- if (nai.everConnected) {
- addNetworkToLegacyTypeTracker(nai);
- }
- }
- }
-
- private void issueNetworkNeeds() {
- ensureRunningOnConnectivityServiceThread();
- for (final NetworkOfferInfo noi : mNetworkOffers) {
- issueNetworkNeeds(noi);
- }
- }
-
- private void issueNetworkNeeds(@NonNull final NetworkOfferInfo noi) {
- ensureRunningOnConnectivityServiceThread();
- for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
- informOffer(nri, noi.offer, mNetworkRanker);
- }
- }
-
- /**
- * Inform a NetworkOffer about any new situation of a request.
- *
- * This function handles updates to offers. A number of events may happen that require
- * updating the registrant for this offer about the situation :
- * • The offer itself was updated. This may lead the offer to no longer being able
- * to satisfy a request or beat a satisfier (and therefore be no longer needed),
- * or conversely being strengthened enough to beat the satisfier (and therefore
- * start being needed)
- * • The network satisfying a request changed (including cases where the request
- * starts or stops being satisfied). The new network may be a stronger or weaker
- * match than the old one, possibly affecting whether the offer is needed.
- * • The network satisfying a request updated their score. This may lead the offer
- * to no longer be able to beat it if the current satisfier got better, or
- * conversely start being a good choice if the current satisfier got weaker.
- *
- * @param nri The request
- * @param offer The offer. This may be an updated offer.
- */
- private static void informOffer(@NonNull NetworkRequestInfo nri,
- @NonNull final NetworkOffer offer, @NonNull final NetworkRanker networkRanker) {
- final NetworkRequest activeRequest = nri.isBeingSatisfied() ? nri.getActiveRequest() : null;
- final NetworkAgentInfo satisfier = null != activeRequest ? nri.getSatisfier() : null;
-
- // Multi-layer requests have a currently active request, the one being satisfied.
- // Since the system will try to bring up a better network than is currently satisfying
- // the request, NetworkProviders need to be told the offers matching the requests *above*
- // the currently satisfied one are needed, that the ones *below* the satisfied one are
- // not needed, and the offer is needed for the active request iff the offer can beat
- // the satisfier.
- // For non-multilayer requests, the logic above gracefully degenerates to only the
- // last case.
- // To achieve this, the loop below will proceed in three steps. In a first phase, inform
- // providers that the offer is needed for this request, until the active request is found.
- // In a second phase, deal with the currently active request. In a third phase, inform
- // the providers that offer is unneeded for the remaining requests.
-
- // First phase : inform providers of all requests above the active request.
- int i;
- for (i = 0; nri.mRequests.size() > i; ++i) {
- final NetworkRequest request = nri.mRequests.get(i);
- if (activeRequest == request) break; // Found the active request : go to phase 2
- if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers
- // Since this request is higher-priority than the one currently satisfied, if the
- // offer can satisfy it, the provider should try and bring up the network for sure ;
- // no need to even ask the ranker – an offer that can satisfy is always better than
- // no network. Hence tell the provider so unless it already knew.
- if (request.canBeSatisfiedBy(offer.caps) && !offer.neededFor(request)) {
- offer.onNetworkNeeded(request);
- }
- }
-
- // Second phase : deal with the active request (if any)
- if (null != activeRequest && activeRequest.isRequest()) {
- final boolean oldNeeded = offer.neededFor(activeRequest);
- // An offer is needed if it is currently served by this provider or if this offer
- // can beat the current satisfier.
- final boolean currentlyServing = satisfier != null
- && satisfier.factorySerialNumber == offer.providerId;
- final boolean newNeeded = (currentlyServing
- || (activeRequest.canBeSatisfiedBy(offer.caps)
- && networkRanker.mightBeat(activeRequest, satisfier, offer)));
- if (newNeeded != oldNeeded) {
- if (newNeeded) {
- offer.onNetworkNeeded(activeRequest);
- } else {
- // The offer used to be able to beat the satisfier. Now it can't.
- offer.onNetworkUnneeded(activeRequest);
- }
- }
- }
-
- // Third phase : inform the providers that the offer isn't needed for any request
- // below the active one.
- for (++i /* skip the active request */; nri.mRequests.size() > i; ++i) {
- final NetworkRequest request = nri.mRequests.get(i);
- if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers
- // Since this request is lower-priority than the one currently satisfied, if the
- // offer can satisfy it, the provider should not try and bring up the network.
- // Hence tell the provider so unless it already knew.
- if (offer.neededFor(request)) {
- offer.onNetworkUnneeded(request);
- }
- }
- }
-
- private void addNetworkToLegacyTypeTracker(@NonNull final NetworkAgentInfo nai) {
- for (int i = 0; i < nai.numNetworkRequests(); i++) {
- NetworkRequest nr = nai.requestAt(i);
- if (nr.legacyType != TYPE_NONE && nr.isRequest()) {
- // legacy type tracker filters out repeat adds
- mLegacyTypeTracker.add(nr.legacyType, nai);
- }
- }
-
- // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above,
- // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest
- // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the
- // newNetwork to the tracker explicitly (it's a no-op if it has already been added).
- if (nai.isVPN()) {
- mLegacyTypeTracker.add(TYPE_VPN, nai);
- }
- }
-
- private void updateInetCondition(NetworkAgentInfo nai) {
- // Don't bother updating until we've graduated to validated at least once.
- if (!nai.everValidated) return;
- // For now only update icons for the default connection.
- // TODO: Update WiFi and cellular icons separately. b/17237507
- if (!isDefaultNetwork(nai)) return;
-
- int newInetCondition = nai.lastValidated ? 100 : 0;
- // Don't repeat publish.
- if (newInetCondition == mDefaultInetConditionPublished) return;
-
- mDefaultInetConditionPublished = newInetCondition;
- sendInetConditionBroadcast(nai.networkInfo);
- }
-
- @NonNull
- private NetworkInfo mixInInfo(@NonNull final NetworkAgentInfo nai, @NonNull NetworkInfo info) {
- final NetworkInfo newInfo = new NetworkInfo(info);
- // The suspended and roaming bits are managed in NetworkCapabilities.
- final boolean suspended =
- !nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
- if (suspended && info.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
- // Only override the state with SUSPENDED if the network is currently in CONNECTED
- // state. This is because the network could have been suspended before connecting,
- // or it could be disconnecting while being suspended, and in both these cases
- // the state should not be overridden. Note that the only detailed state that
- // maps to State.CONNECTED is DetailedState.CONNECTED, so there is also no need to
- // worry about multiple different substates of CONNECTED.
- newInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, info.getReason(),
- info.getExtraInfo());
- } else if (!suspended && info.getDetailedState() == NetworkInfo.DetailedState.SUSPENDED) {
- // SUSPENDED state is currently only overridden from CONNECTED state. In the case the
- // network agent is created, then goes to suspended, then goes out of suspended without
- // ever setting connected. Check if network agent is ever connected to update the state.
- newInfo.setDetailedState(nai.everConnected
- ? NetworkInfo.DetailedState.CONNECTED
- : NetworkInfo.DetailedState.CONNECTING,
- info.getReason(),
- info.getExtraInfo());
- }
- newInfo.setRoaming(!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING));
- return newInfo;
- }
-
- private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo info) {
- final NetworkInfo newInfo = mixInInfo(networkAgent, info);
-
- final NetworkInfo.State state = newInfo.getState();
- NetworkInfo oldInfo = null;
- synchronized (networkAgent) {
- oldInfo = networkAgent.networkInfo;
- networkAgent.networkInfo = newInfo;
- }
-
- if (DBG) {
- log(networkAgent.toShortString() + " EVENT_NETWORK_INFO_CHANGED, going from "
- + oldInfo.getState() + " to " + state);
- }
-
- if (!networkAgent.created
- && (state == NetworkInfo.State.CONNECTED
- || (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) {
-
- // A network that has just connected has zero requests and is thus a foreground network.
- networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND);
-
- if (!createNativeNetwork(networkAgent)) return;
- if (networkAgent.supportsUnderlyingNetworks()) {
- // Initialize the network's capabilities to their starting values according to the
- // underlying networks. This ensures that the capabilities are correct before
- // anything happens to the network.
- updateCapabilitiesForNetwork(networkAgent);
- }
- networkAgent.created = true;
- networkAgent.onNetworkCreated();
- }
-
- if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) {
- networkAgent.everConnected = true;
-
- // NetworkCapabilities need to be set before sending the private DNS config to
- // NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required.
- networkAgent.getAndSetNetworkCapabilities(networkAgent.networkCapabilities);
-
- handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig());
- updateLinkProperties(networkAgent, new LinkProperties(networkAgent.linkProperties),
- null);
-
- // Until parceled LinkProperties are sent directly to NetworkMonitor, the connect
- // command must be sent after updating LinkProperties to maximize chances of
- // NetworkMonitor seeing the correct LinkProperties when starting.
- // TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call.
- if (networkAgent.networkAgentConfig.acceptPartialConnectivity) {
- networkAgent.networkMonitor().setAcceptPartialConnectivity();
- }
- networkAgent.networkMonitor().notifyNetworkConnected(
- new LinkProperties(networkAgent.linkProperties,
- true /* parcelSensitiveFields */),
- networkAgent.networkCapabilities);
- scheduleUnvalidatedPrompt(networkAgent);
-
- // Whether a particular NetworkRequest listen should cause signal strength thresholds to
- // be communicated to a particular NetworkAgent depends only on the network's immutable,
- // capabilities, so it only needs to be done once on initial connect, not every time the
- // network's capabilities change. Note that we do this before rematching the network,
- // so we could decide to tear it down immediately afterwards. That's fine though - on
- // disconnection NetworkAgents should stop any signal strength monitoring they have been
- // doing.
- updateSignalStrengthThresholds(networkAgent, "CONNECT", null);
-
- // Before first rematching networks, put an inactivity timer without any request, this
- // allows {@code updateInactivityState} to update the state accordingly and prevent
- // tearing down for any {@code unneeded} evaluation in this period.
- // Note that the timer will not be rescheduled since the expiry time is
- // fixed after connection regardless of the network satisfying other requests or not.
- // But it will be removed as soon as the network satisfies a request for the first time.
- networkAgent.lingerRequest(NetworkRequest.REQUEST_ID_NONE,
- SystemClock.elapsedRealtime(), mNascentDelayMs);
- networkAgent.setInactive();
-
- // Consider network even though it is not yet validated.
- rematchAllNetworksAndRequests();
-
- // This has to happen after matching the requests, because callbacks are just requests.
- notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
- } else if (state == NetworkInfo.State.DISCONNECTED) {
- networkAgent.disconnect();
- if (networkAgent.isVPN()) {
- updateUids(networkAgent, networkAgent.networkCapabilities, null);
- }
- disconnectAndDestroyNetwork(networkAgent);
- if (networkAgent.isVPN()) {
- // As the active or bound network changes for apps, broadcast the default proxy, as
- // apps may need to update their proxy data. This is called after disconnecting from
- // VPN to make sure we do not broadcast the old proxy data.
- // TODO(b/122649188): send the broadcast only to VPN users.
- mProxyTracker.sendProxyBroadcast();
- }
- } else if (networkAgent.created && (oldInfo.getState() == NetworkInfo.State.SUSPENDED ||
- state == NetworkInfo.State.SUSPENDED)) {
- mLegacyTypeTracker.update(networkAgent);
- }
- }
-
- private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final NetworkScore score) {
- if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score);
- nai.setScore(score);
- rematchAllNetworksAndRequests();
- }
-
- // Notify only this one new request of the current state. Transfer all the
- // current state by calling NetworkCapabilities and LinkProperties callbacks
- // so that callers can be guaranteed to have as close to atomicity in state
- // transfer as can be supported by this current API.
- protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) {
- mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri);
- if (nri.mPendingIntent != null) {
- sendPendingIntentForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE);
- // Attempt no subsequent state pushes where intents are involved.
- return;
- }
-
- final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
- final boolean metered = nai.networkCapabilities.isMetered();
- final boolean vpnBlocked = isUidBlockedByVpn(nri.mAsUid, mVpnBlockedUidRanges);
- callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE,
- getBlockedState(blockedReasons, metered, vpnBlocked));
- }
-
- // Notify the requests on this NAI that the network is now lingered.
- private void notifyNetworkLosing(@NonNull final NetworkAgentInfo nai, final long now) {
- final int lingerTime = (int) (nai.getInactivityExpiry() - now);
- notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime);
- }
-
- private static int getBlockedState(int reasons, boolean metered, boolean vpnBlocked) {
- if (!metered) reasons &= ~BLOCKED_METERED_REASON_MASK;
- return vpnBlocked
- ? reasons | BLOCKED_REASON_LOCKDOWN_VPN
- : reasons & ~BLOCKED_REASON_LOCKDOWN_VPN;
- }
-
- private void setUidBlockedReasons(int uid, @BlockedReason int blockedReasons) {
- if (blockedReasons == BLOCKED_REASON_NONE) {
- mUidBlockedReasons.delete(uid);
- } else {
- mUidBlockedReasons.put(uid, blockedReasons);
- }
- }
-
- /**
- * Notify of the blocked state apps with a registered callback matching a given NAI.
- *
- * Unlike other callbacks, blocked status is different between each individual uid. So for
- * any given nai, all requests need to be considered according to the uid who filed it.
- *
- * @param nai The target NetworkAgentInfo.
- * @param oldMetered True if the previous network capabilities were metered.
- * @param newMetered True if the current network capabilities are metered.
- * @param oldBlockedUidRanges list of UID ranges previously blocked by lockdown VPN.
- * @param newBlockedUidRanges list of UID ranges blocked by lockdown VPN.
- */
- private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
- boolean newMetered, List<UidRange> oldBlockedUidRanges,
- List<UidRange> newBlockedUidRanges) {
-
- for (int i = 0; i < nai.numNetworkRequests(); i++) {
- NetworkRequest nr = nai.requestAt(i);
- NetworkRequestInfo nri = mNetworkRequests.get(nr);
-
- final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
- final boolean oldVpnBlocked = isUidBlockedByVpn(nri.mAsUid, oldBlockedUidRanges);
- final boolean newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges)
- ? isUidBlockedByVpn(nri.mAsUid, newBlockedUidRanges)
- : oldVpnBlocked;
-
- final int oldBlockedState = getBlockedState(blockedReasons, oldMetered, oldVpnBlocked);
- final int newBlockedState = getBlockedState(blockedReasons, newMetered, newVpnBlocked);
- if (oldBlockedState != newBlockedState) {
- callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
- newBlockedState);
- }
- }
- }
-
- /**
- * Notify apps with a given UID of the new blocked state according to new uid state.
- * @param uid The uid for which the rules changed.
- * @param blockedReasons The reasons for why an uid is blocked.
- */
- private void maybeNotifyNetworkBlockedForNewState(int uid, @BlockedReason int blockedReasons) {
- for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
- final boolean metered = nai.networkCapabilities.isMetered();
- final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges);
-
- final int oldBlockedState = getBlockedState(
- mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered, vpnBlocked);
- final int newBlockedState = getBlockedState(blockedReasons, metered, vpnBlocked);
- if (oldBlockedState == newBlockedState) {
- continue;
- }
- for (int i = 0; i < nai.numNetworkRequests(); i++) {
- NetworkRequest nr = nai.requestAt(i);
- NetworkRequestInfo nri = mNetworkRequests.get(nr);
- if (nri != null && nri.mAsUid == uid) {
- callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
- newBlockedState);
- }
- }
- }
- }
-
- @VisibleForTesting
- protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
- // The NetworkInfo we actually send out has no bearing on the real
- // state of affairs. For example, if the default connection is mobile,
- // and a request for HIPRI has just gone away, we need to pretend that
- // HIPRI has just disconnected. So we need to set the type to HIPRI and
- // the state to DISCONNECTED, even though the network is of type MOBILE
- // and is still connected.
- NetworkInfo info = new NetworkInfo(nai.networkInfo);
- info.setType(type);
- filterForLegacyLockdown(info);
- if (state != DetailedState.DISCONNECTED) {
- info.setDetailedState(state, null, info.getExtraInfo());
- sendConnectedBroadcast(info);
- } else {
- info.setDetailedState(state, info.getReason(), info.getExtraInfo());
- Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
- if (info.isFailover()) {
- intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
- nai.networkInfo.setFailover(false);
- }
- if (info.getReason() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
- }
- if (info.getExtraInfo() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
- }
- NetworkAgentInfo newDefaultAgent = null;
- if (nai.isSatisfyingRequest(mDefaultRequest.mRequests.get(0).requestId)) {
- newDefaultAgent = mDefaultRequest.getSatisfier();
- if (newDefaultAgent != null) {
- intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
- newDefaultAgent.networkInfo);
- } else {
- intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
- }
- }
- intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
- mDefaultInetConditionPublished);
- sendStickyBroadcast(intent);
- if (newDefaultAgent != null) {
- sendConnectedBroadcast(newDefaultAgent.networkInfo);
- }
- }
- }
-
- protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) {
- if (VDBG || DDBG) {
- String notification = ConnectivityManager.getCallbackName(notifyType);
- log("notifyType " + notification + " for " + networkAgent.toShortString());
- }
- for (int i = 0; i < networkAgent.numNetworkRequests(); i++) {
- NetworkRequest nr = networkAgent.requestAt(i);
- NetworkRequestInfo nri = mNetworkRequests.get(nr);
- if (VDBG) log(" sending notification for " + nr);
- if (nri.mPendingIntent == null) {
- callCallbackForRequest(nri, networkAgent, notifyType, arg1);
- } else {
- sendPendingIntentForRequest(nri, networkAgent, notifyType);
- }
- }
- }
-
- protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
- notifyNetworkCallbacks(networkAgent, notifyType, 0);
- }
-
- /**
- * Returns the list of all interfaces that could be used by network traffic that does not
- * explicitly specify a network. This includes the default network, but also all VPNs that are
- * currently connected.
- *
- * Must be called on the handler thread.
- */
- @NonNull
- private ArrayList<Network> getDefaultNetworks() {
- ensureRunningOnConnectivityServiceThread();
- final ArrayList<Network> defaultNetworks = new ArrayList<>();
- final Set<Integer> activeNetIds = new ArraySet<>();
- for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
- if (nri.isBeingSatisfied()) {
- activeNetIds.add(nri.getSatisfier().network().netId);
- }
- }
- for (NetworkAgentInfo nai : mNetworkAgentInfos) {
- if (nai.everConnected && (activeNetIds.contains(nai.network().netId) || nai.isVPN())) {
- defaultNetworks.add(nai.network);
- }
- }
- return defaultNetworks;
- }
-
- /**
- * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the
- * active iface's tracked properties has changed.
- */
- private void notifyIfacesChangedForNetworkStats() {
- ensureRunningOnConnectivityServiceThread();
- String activeIface = null;
- LinkProperties activeLinkProperties = getActiveLinkProperties();
- if (activeLinkProperties != null) {
- activeIface = activeLinkProperties.getInterfaceName();
- }
-
- final UnderlyingNetworkInfo[] underlyingNetworkInfos = getAllVpnInfo();
- try {
- final ArrayList<NetworkStateSnapshot> snapshots = new ArrayList<>();
- for (final NetworkStateSnapshot snapshot : getAllNetworkStateSnapshots()) {
- snapshots.add(snapshot);
- }
- mStatsManager.notifyNetworkStatus(getDefaultNetworks(),
- snapshots, activeIface, Arrays.asList(underlyingNetworkInfos));
- } catch (Exception ignored) {
- }
- }
-
- @Override
- public String getCaptivePortalServerUrl() {
- enforceNetworkStackOrSettingsPermission();
- String settingUrl = mResources.get().getString(
- R.string.config_networkCaptivePortalServerUrl);
-
- if (!TextUtils.isEmpty(settingUrl)) {
- return settingUrl;
- }
-
- settingUrl = Settings.Global.getString(mContext.getContentResolver(),
- ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL);
- if (!TextUtils.isEmpty(settingUrl)) {
- return settingUrl;
- }
-
- return DEFAULT_CAPTIVE_PORTAL_HTTP_URL;
- }
-
- @Override
- public void startNattKeepalive(Network network, int intervalSeconds,
- ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr) {
- enforceKeepalivePermission();
- mKeepaliveTracker.startNattKeepalive(
- getNetworkAgentInfoForNetwork(network), null /* fd */,
- intervalSeconds, cb,
- srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT);
- }
-
- @Override
- public void startNattKeepaliveWithFd(Network network, ParcelFileDescriptor pfd, int resourceId,
- int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr,
- String dstAddr) {
- try {
- final FileDescriptor fd = pfd.getFileDescriptor();
- mKeepaliveTracker.startNattKeepalive(
- getNetworkAgentInfoForNetwork(network), fd, resourceId,
- intervalSeconds, cb,
- srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT);
- } finally {
- // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
- // startNattKeepalive calls Os.dup(fd) before returning, so we can close immediately.
- if (pfd != null && Binder.getCallingPid() != Process.myPid()) {
- IoUtils.closeQuietly(pfd);
- }
- }
- }
-
- @Override
- public void startTcpKeepalive(Network network, ParcelFileDescriptor pfd, int intervalSeconds,
- ISocketKeepaliveCallback cb) {
- try {
- enforceKeepalivePermission();
- final FileDescriptor fd = pfd.getFileDescriptor();
- mKeepaliveTracker.startTcpKeepalive(
- getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb);
- } finally {
- // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
- // startTcpKeepalive calls Os.dup(fd) before returning, so we can close immediately.
- if (pfd != null && Binder.getCallingPid() != Process.myPid()) {
- IoUtils.closeQuietly(pfd);
- }
- }
- }
-
- @Override
- public void stopKeepalive(Network network, int slot) {
- mHandler.sendMessage(mHandler.obtainMessage(
- NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE, slot, SocketKeepalive.SUCCESS, network));
- }
-
- @Override
- public void factoryReset() {
- enforceSettingsPermission();
-
- final int uid = mDeps.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- if (mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_NETWORK_RESET,
- UserHandle.getUserHandleForUid(uid))) {
- return;
- }
-
- final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext);
- ipMemoryStore.factoryReset();
-
- // Turn airplane mode off
- setAirplaneMode(false);
-
- // restore private DNS settings to default mode (opportunistic)
- if (!mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_CONFIG_PRIVATE_DNS,
- UserHandle.getUserHandleForUid(uid))) {
- ConnectivitySettingsManager.setPrivateDnsMode(mContext,
- PRIVATE_DNS_MODE_OPPORTUNISTIC);
- }
-
- Settings.Global.putString(mContext.getContentResolver(),
- ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public byte[] getNetworkWatchlistConfigHash() {
- NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class);
- if (nwm == null) {
- loge("Unable to get NetworkWatchlistManager");
- return null;
- }
- // Redirect it to network watchlist service to access watchlist file and calculate hash.
- return nwm.getWatchlistConfigHash();
- }
-
- private void logNetworkEvent(NetworkAgentInfo nai, int evtype) {
- int[] transports = nai.networkCapabilities.getTransportTypes();
- mMetricsLog.log(nai.network.getNetId(), transports, new NetworkEvent(evtype));
- }
-
- private static boolean toBool(int encodedBoolean) {
- return encodedBoolean != 0; // Only 0 means false.
- }
-
- private static int encodeBool(boolean b) {
- return b ? 1 : 0;
- }
-
- @Override
- public int handleShellCommand(@NonNull ParcelFileDescriptor in,
- @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
- @NonNull String[] args) {
- return new ShellCmd().exec(this, in.getFileDescriptor(), out.getFileDescriptor(),
- err.getFileDescriptor(), args);
- }
-
- private class ShellCmd extends BasicShellCommandHandler {
- @Override
- public int onCommand(String cmd) {
- if (cmd == null) {
- return handleDefaultCommands(cmd);
- }
- final PrintWriter pw = getOutPrintWriter();
- try {
- switch (cmd) {
- case "airplane-mode":
- final String action = getNextArg();
- if ("enable".equals(action)) {
- setAirplaneMode(true);
- return 0;
- } else if ("disable".equals(action)) {
- setAirplaneMode(false);
- return 0;
- } else if (action == null) {
- final ContentResolver cr = mContext.getContentResolver();
- final int enabled = Settings.Global.getInt(cr,
- Settings.Global.AIRPLANE_MODE_ON);
- pw.println(enabled == 0 ? "disabled" : "enabled");
- return 0;
- } else {
- onHelp();
- return -1;
- }
- default:
- return handleDefaultCommands(cmd);
- }
- } catch (Exception e) {
- pw.println(e);
- }
- return -1;
- }
-
- @Override
- public void onHelp() {
- PrintWriter pw = getOutPrintWriter();
- pw.println("Connectivity service commands:");
- pw.println(" help");
- pw.println(" Print this help text.");
- pw.println(" airplane-mode [enable|disable]");
- pw.println(" Turn airplane mode on or off.");
- pw.println(" airplane-mode");
- pw.println(" Get airplane mode.");
- }
- }
-
- private int getVpnType(@Nullable NetworkAgentInfo vpn) {
- if (vpn == null) return VpnManager.TYPE_VPN_NONE;
- final TransportInfo ti = vpn.networkCapabilities.getTransportInfo();
- if (!(ti instanceof VpnTransportInfo)) return VpnManager.TYPE_VPN_NONE;
- return ((VpnTransportInfo) ti).getType();
- }
-
- /**
- * @param connectionInfo the connection to resolve.
- * @return {@code uid} if the connection is found and the app has permission to observe it
- * (e.g., if it is associated with the calling VPN app's tunnel) or {@code INVALID_UID} if the
- * connection is not found.
- */
- public int getConnectionOwnerUid(ConnectionInfo connectionInfo) {
- if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) {
- throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol);
- }
-
- final int uid = mDeps.getConnectionOwnerUid(connectionInfo.protocol,
- connectionInfo.local, connectionInfo.remote);
-
- if (uid == INVALID_UID) return uid; // Not found.
-
- // Connection owner UIDs are visible only to the network stack and to the VpnService-based
- // VPN, if any, that applies to the UID that owns the connection.
- if (checkNetworkStackPermission()) return uid;
-
- final NetworkAgentInfo vpn = getVpnForUid(uid);
- if (vpn == null || getVpnType(vpn) != VpnManager.TYPE_VPN_SERVICE
- || vpn.networkCapabilities.getOwnerUid() != mDeps.getCallingUid()) {
- return INVALID_UID;
- }
-
- return uid;
- }
-
- /**
- * Returns a IBinder to a TestNetworkService. Will be lazily created as needed.
- *
- * <p>The TestNetworkService must be run in the system server due to TUN creation.
- */
- @Override
- public IBinder startOrGetTestNetworkService() {
- synchronized (mTNSLock) {
- TestNetworkService.enforceTestNetworkPermissions(mContext);
-
- if (mTNS == null) {
- mTNS = new TestNetworkService(mContext);
- }
-
- return mTNS;
- }
- }
-
- /**
- * Handler used for managing all Connectivity Diagnostics related functions.
- *
- * @see android.net.ConnectivityDiagnosticsManager
- *
- * TODO(b/147816404): Explore moving ConnectivityDiagnosticsHandler to a separate file
- */
- @VisibleForTesting
- class ConnectivityDiagnosticsHandler extends Handler {
- private final String mTag = ConnectivityDiagnosticsHandler.class.getSimpleName();
-
- /**
- * Used to handle ConnectivityDiagnosticsCallback registration events from {@link
- * android.net.ConnectivityDiagnosticsManager}.
- * obj = ConnectivityDiagnosticsCallbackInfo with IConnectivityDiagnosticsCallback and
- * NetworkRequestInfo to be registered
- */
- private static final int EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 1;
-
- /**
- * Used to handle ConnectivityDiagnosticsCallback unregister events from {@link
- * android.net.ConnectivityDiagnosticsManager}.
- * obj = the IConnectivityDiagnosticsCallback to be unregistered
- * arg1 = the uid of the caller
- */
- private static final int EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 2;
-
- /**
- * Event for {@link NetworkStateTrackerHandler} to trigger ConnectivityReport callbacks
- * after processing {@link #EVENT_NETWORK_TESTED} events.
- * obj = {@link ConnectivityReportEvent} representing ConnectivityReport info reported from
- * NetworkMonitor.
- * data = PersistableBundle of extras passed from NetworkMonitor.
- *
- * <p>See {@link ConnectivityService#EVENT_NETWORK_TESTED}.
- */
- private static final int EVENT_NETWORK_TESTED = ConnectivityService.EVENT_NETWORK_TESTED;
-
- /**
- * Event for NetworkMonitor to inform ConnectivityService that a potential data stall has
- * been detected on the network.
- * obj = Long the timestamp (in millis) for when the suspected data stall was detected.
- * arg1 = {@link DataStallReport#DetectionMethod} indicating the detection method.
- * arg2 = NetID.
- * data = PersistableBundle of extras passed from NetworkMonitor.
- */
- private static final int EVENT_DATA_STALL_SUSPECTED = 4;
-
- /**
- * Event for ConnectivityDiagnosticsHandler to handle network connectivity being reported to
- * the platform. This event will invoke {@link
- * IConnectivityDiagnosticsCallback#onNetworkConnectivityReported} for permissioned
- * callbacks.
- * obj = Network that was reported on
- * arg1 = boolint for the quality reported
- */
- private static final int EVENT_NETWORK_CONNECTIVITY_REPORTED = 5;
-
- private ConnectivityDiagnosticsHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: {
- handleRegisterConnectivityDiagnosticsCallback(
- (ConnectivityDiagnosticsCallbackInfo) msg.obj);
- break;
- }
- case EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: {
- handleUnregisterConnectivityDiagnosticsCallback(
- (IConnectivityDiagnosticsCallback) msg.obj, msg.arg1);
- break;
- }
- case EVENT_NETWORK_TESTED: {
- final ConnectivityReportEvent reportEvent =
- (ConnectivityReportEvent) msg.obj;
-
- handleNetworkTestedWithExtras(reportEvent, reportEvent.mExtras);
- break;
- }
- case EVENT_DATA_STALL_SUSPECTED: {
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
- final Pair<Long, PersistableBundle> arg =
- (Pair<Long, PersistableBundle>) msg.obj;
- if (nai == null) break;
-
- handleDataStallSuspected(nai, arg.first, msg.arg1, arg.second);
- break;
- }
- case EVENT_NETWORK_CONNECTIVITY_REPORTED: {
- handleNetworkConnectivityReported((NetworkAgentInfo) msg.obj, toBool(msg.arg1));
- break;
- }
- default: {
- Log.e(mTag, "Unrecognized event in ConnectivityDiagnostics: " + msg.what);
- }
- }
- }
- }
-
- /** Class used for cleaning up IConnectivityDiagnosticsCallback instances after their death. */
- @VisibleForTesting
- class ConnectivityDiagnosticsCallbackInfo implements Binder.DeathRecipient {
- @NonNull private final IConnectivityDiagnosticsCallback mCb;
- @NonNull private final NetworkRequestInfo mRequestInfo;
- @NonNull private final String mCallingPackageName;
-
- @VisibleForTesting
- ConnectivityDiagnosticsCallbackInfo(
- @NonNull IConnectivityDiagnosticsCallback cb,
- @NonNull NetworkRequestInfo nri,
- @NonNull String callingPackageName) {
- mCb = cb;
- mRequestInfo = nri;
- mCallingPackageName = callingPackageName;
- }
-
- @Override
- public void binderDied() {
- log("ConnectivityDiagnosticsCallback IBinder died.");
- unregisterConnectivityDiagnosticsCallback(mCb);
- }
- }
-
- /**
- * Class used for sending information from {@link
- * NetworkMonitorCallbacks#notifyNetworkTestedWithExtras} to the handler for processing it.
- */
- private static class NetworkTestedResults {
- private final int mNetId;
- private final int mTestResult;
- private final long mTimestampMillis;
- @Nullable private final String mRedirectUrl;
-
- private NetworkTestedResults(
- int netId, int testResult, long timestampMillis, @Nullable String redirectUrl) {
- mNetId = netId;
- mTestResult = testResult;
- mTimestampMillis = timestampMillis;
- mRedirectUrl = redirectUrl;
- }
- }
-
- /**
- * Class used for sending information from {@link NetworkStateTrackerHandler} to {@link
- * ConnectivityDiagnosticsHandler}.
- */
- private static class ConnectivityReportEvent {
- private final long mTimestampMillis;
- @NonNull private final NetworkAgentInfo mNai;
- private final PersistableBundle mExtras;
-
- private ConnectivityReportEvent(long timestampMillis, @NonNull NetworkAgentInfo nai,
- PersistableBundle p) {
- mTimestampMillis = timestampMillis;
- mNai = nai;
- mExtras = p;
- }
- }
-
- private void handleRegisterConnectivityDiagnosticsCallback(
- @NonNull ConnectivityDiagnosticsCallbackInfo cbInfo) {
- ensureRunningOnConnectivityServiceThread();
-
- final IConnectivityDiagnosticsCallback cb = cbInfo.mCb;
- final IBinder iCb = cb.asBinder();
- final NetworkRequestInfo nri = cbInfo.mRequestInfo;
-
- // Connectivity Diagnostics are meant to be used with a single network request. It would be
- // confusing for these networks to change when an NRI is satisfied in another layer.
- if (nri.isMultilayerRequest()) {
- throw new IllegalArgumentException("Connectivity Diagnostics do not support multilayer "
- + "network requests.");
- }
-
- // This means that the client registered the same callback multiple times. Do
- // not override the previous entry, and exit silently.
- if (mConnectivityDiagnosticsCallbacks.containsKey(iCb)) {
- if (VDBG) log("Diagnostics callback is already registered");
-
- // Decrement the reference count for this NetworkRequestInfo. The reference count is
- // incremented when the NetworkRequestInfo is created as part of
- // enforceRequestCountLimit().
- nri.decrementRequestCount();
- return;
- }
-
- mConnectivityDiagnosticsCallbacks.put(iCb, cbInfo);
-
- try {
- iCb.linkToDeath(cbInfo, 0);
- } catch (RemoteException e) {
- cbInfo.binderDied();
- return;
- }
-
- // Once registered, provide ConnectivityReports for matching Networks
- final List<NetworkAgentInfo> matchingNetworks = new ArrayList<>();
- synchronized (mNetworkForNetId) {
- for (int i = 0; i < mNetworkForNetId.size(); i++) {
- final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
- // Connectivity Diagnostics rejects multilayer requests at registration hence get(0)
- if (nai.satisfies(nri.mRequests.get(0))) {
- matchingNetworks.add(nai);
- }
- }
- }
- for (final NetworkAgentInfo nai : matchingNetworks) {
- final ConnectivityReport report = nai.getConnectivityReport();
- if (report == null) {
- continue;
- }
- if (!checkConnectivityDiagnosticsPermissions(
- nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) {
- continue;
- }
-
- try {
- cb.onConnectivityReportAvailable(report);
- } catch (RemoteException e) {
- // Exception while sending the ConnectivityReport. Move on to the next network.
- }
- }
- }
-
- private void handleUnregisterConnectivityDiagnosticsCallback(
- @NonNull IConnectivityDiagnosticsCallback cb, int uid) {
- ensureRunningOnConnectivityServiceThread();
- final IBinder iCb = cb.asBinder();
-
- final ConnectivityDiagnosticsCallbackInfo cbInfo =
- mConnectivityDiagnosticsCallbacks.remove(iCb);
- if (cbInfo == null) {
- if (VDBG) log("Removing diagnostics callback that is not currently registered");
- return;
- }
-
- final NetworkRequestInfo nri = cbInfo.mRequestInfo;
-
- // Caller's UID must either be the registrants (if they are unregistering) or the System's
- // (if the Binder died)
- if (uid != nri.mUid && uid != Process.SYSTEM_UID) {
- if (DBG) loge("Uid(" + uid + ") not registrant's (" + nri.mUid + ") or System's");
- return;
- }
-
- // Decrement the reference count for this NetworkRequestInfo. The reference count is
- // incremented when the NetworkRequestInfo is created as part of
- // enforceRequestCountLimit().
- nri.decrementRequestCount();
-
- iCb.unlinkToDeath(cbInfo, 0);
- }
-
- private void handleNetworkTestedWithExtras(
- @NonNull ConnectivityReportEvent reportEvent, @NonNull PersistableBundle extras) {
- final NetworkAgentInfo nai = reportEvent.mNai;
- final NetworkCapabilities networkCapabilities =
- getNetworkCapabilitiesWithoutUids(nai.networkCapabilities);
- final ConnectivityReport report =
- new ConnectivityReport(
- reportEvent.mNai.network,
- reportEvent.mTimestampMillis,
- nai.linkProperties,
- networkCapabilities,
- extras);
- nai.setConnectivityReport(report);
- final List<IConnectivityDiagnosticsCallback> results =
- getMatchingPermissionedCallbacks(nai);
- for (final IConnectivityDiagnosticsCallback cb : results) {
- try {
- cb.onConnectivityReportAvailable(report);
- } catch (RemoteException ex) {
- loge("Error invoking onConnectivityReport", ex);
- }
- }
- }
-
- private void handleDataStallSuspected(
- @NonNull NetworkAgentInfo nai, long timestampMillis, int detectionMethod,
- @NonNull PersistableBundle extras) {
- final NetworkCapabilities networkCapabilities =
- getNetworkCapabilitiesWithoutUids(nai.networkCapabilities);
- final DataStallReport report =
- new DataStallReport(
- nai.network,
- timestampMillis,
- detectionMethod,
- nai.linkProperties,
- networkCapabilities,
- extras);
- final List<IConnectivityDiagnosticsCallback> results =
- getMatchingPermissionedCallbacks(nai);
- for (final IConnectivityDiagnosticsCallback cb : results) {
- try {
- cb.onDataStallSuspected(report);
- } catch (RemoteException ex) {
- loge("Error invoking onDataStallSuspected", ex);
- }
- }
- }
-
- private void handleNetworkConnectivityReported(
- @NonNull NetworkAgentInfo nai, boolean connectivity) {
- final List<IConnectivityDiagnosticsCallback> results =
- getMatchingPermissionedCallbacks(nai);
- for (final IConnectivityDiagnosticsCallback cb : results) {
- try {
- cb.onNetworkConnectivityReported(nai.network, connectivity);
- } catch (RemoteException ex) {
- loge("Error invoking onNetworkConnectivityReported", ex);
- }
- }
- }
-
- private NetworkCapabilities getNetworkCapabilitiesWithoutUids(@NonNull NetworkCapabilities nc) {
- final NetworkCapabilities sanitized = new NetworkCapabilities(nc,
- NetworkCapabilities.REDACT_ALL);
- sanitized.setUids(null);
- sanitized.setAdministratorUids(new int[0]);
- sanitized.setOwnerUid(Process.INVALID_UID);
- return sanitized;
- }
-
- private List<IConnectivityDiagnosticsCallback> getMatchingPermissionedCallbacks(
- @NonNull NetworkAgentInfo nai) {
- final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>();
- for (Entry<IBinder, ConnectivityDiagnosticsCallbackInfo> entry :
- mConnectivityDiagnosticsCallbacks.entrySet()) {
- final ConnectivityDiagnosticsCallbackInfo cbInfo = entry.getValue();
- final NetworkRequestInfo nri = cbInfo.mRequestInfo;
- // Connectivity Diagnostics rejects multilayer requests at registration hence get(0).
- if (nai.satisfies(nri.mRequests.get(0))) {
- if (checkConnectivityDiagnosticsPermissions(
- nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) {
- results.add(entry.getValue().mCb);
- }
- }
- }
- return results;
- }
-
- private boolean hasLocationPermission(String packageName, int uid) {
- // LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid
- // and package name don't match. Throwing on the CS thread is not acceptable, so wrap the
- // call in a try-catch.
- try {
- if (!mLocationPermissionChecker.checkLocationPermission(
- packageName, null /* featureId */, uid, null /* message */)) {
- return false;
- }
- } catch (SecurityException e) {
- return false;
- }
-
- return true;
- }
-
- private boolean ownsVpnRunningOverNetwork(int uid, Network network) {
- for (NetworkAgentInfo virtual : mNetworkAgentInfos) {
- if (virtual.supportsUnderlyingNetworks()
- && virtual.networkCapabilities.getOwnerUid() == uid
- && CollectionUtils.contains(virtual.declaredUnderlyingNetworks, network)) {
- return true;
- }
- }
-
- return false;
- }
-
- @VisibleForTesting
- boolean checkConnectivityDiagnosticsPermissions(
- int callbackPid, int callbackUid, NetworkAgentInfo nai, String callbackPackageName) {
- if (checkNetworkStackPermission(callbackPid, callbackUid)) {
- return true;
- }
-
- // Administrator UIDs also contains the Owner UID
- final int[] administratorUids = nai.networkCapabilities.getAdministratorUids();
- if (!CollectionUtils.contains(administratorUids, callbackUid)
- && !ownsVpnRunningOverNetwork(callbackUid, nai.network)) {
- return false;
- }
-
- return hasLocationPermission(callbackPackageName, callbackUid);
- }
-
- @Override
- public void registerConnectivityDiagnosticsCallback(
- @NonNull IConnectivityDiagnosticsCallback callback,
- @NonNull NetworkRequest request,
- @NonNull String callingPackageName) {
- if (request.legacyType != TYPE_NONE) {
- throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated."
- + " Please use NetworkCapabilities instead.");
- }
- final int callingUid = mDeps.getCallingUid();
- mAppOpsManager.checkPackage(callingUid, callingPackageName);
-
- // This NetworkCapabilities is only used for matching to Networks. Clear out its owner uid
- // and administrator uids to be safe.
- final NetworkCapabilities nc = new NetworkCapabilities(request.networkCapabilities);
- restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
-
- final NetworkRequest requestWithId =
- new NetworkRequest(
- nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN);
-
- // NetworkRequestInfos created here count towards MAX_NETWORK_REQUESTS_PER_UID limit.
- //
- // nri is not bound to the death of callback. Instead, callback.bindToDeath() is set in
- // handleRegisterConnectivityDiagnosticsCallback(). nri will be cleaned up as part of the
- // callback's binder death.
- final NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, requestWithId);
- final ConnectivityDiagnosticsCallbackInfo cbInfo =
- new ConnectivityDiagnosticsCallbackInfo(callback, nri, callingPackageName);
-
- mConnectivityDiagnosticsHandler.sendMessage(
- mConnectivityDiagnosticsHandler.obtainMessage(
- ConnectivityDiagnosticsHandler
- .EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK,
- cbInfo));
- }
-
- @Override
- public void unregisterConnectivityDiagnosticsCallback(
- @NonNull IConnectivityDiagnosticsCallback callback) {
- Objects.requireNonNull(callback, "callback must be non-null");
- mConnectivityDiagnosticsHandler.sendMessage(
- mConnectivityDiagnosticsHandler.obtainMessage(
- ConnectivityDiagnosticsHandler
- .EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK,
- mDeps.getCallingUid(),
- 0,
- callback));
- }
-
- @Override
- public void simulateDataStall(int detectionMethod, long timestampMillis,
- @NonNull Network network, @NonNull PersistableBundle extras) {
- enforceAnyPermissionOf(android.Manifest.permission.MANAGE_TEST_NETWORKS,
- android.Manifest.permission.NETWORK_STACK);
- final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
- if (!nc.hasTransport(TRANSPORT_TEST)) {
- throw new SecurityException("Data Stall simluation is only possible for test networks");
- }
-
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
- if (nai == null || nai.creatorUid != mDeps.getCallingUid()) {
- throw new SecurityException("Data Stall simulation is only possible for network "
- + "creators");
- }
-
- // Instead of passing the data stall directly to the ConnectivityDiagnostics handler, treat
- // this as a Data Stall received directly from NetworkMonitor. This requires wrapping the
- // Data Stall information as a DataStallReportParcelable and passing to
- // #notifyDataStallSuspected. This ensures that unknown Data Stall detection methods are
- // still passed to ConnectivityDiagnostics (with new detection methods masked).
- final DataStallReportParcelable p = new DataStallReportParcelable();
- p.timestampMillis = timestampMillis;
- p.detectionMethod = detectionMethod;
-
- if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) {
- p.dnsConsecutiveTimeouts = extras.getInt(KEY_DNS_CONSECUTIVE_TIMEOUTS);
- }
- if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) {
- p.tcpPacketFailRate = extras.getInt(KEY_TCP_PACKET_FAIL_RATE);
- p.tcpMetricsCollectionPeriodMillis = extras.getInt(
- KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS);
- }
-
- notifyDataStallSuspected(p, network.getNetId());
- }
-
- private class NetdCallback extends BaseNetdUnsolicitedEventListener {
- @Override
- public void onInterfaceClassActivityChanged(boolean isActive, int transportType,
- long timestampNs, int uid) {
- mNetworkActivityTracker.setAndReportNetworkActive(isActive, transportType, timestampNs);
- }
-
- @Override
- public void onInterfaceLinkStateChanged(String iface, boolean up) {
- for (NetworkAgentInfo nai : mNetworkAgentInfos) {
- nai.clatd.interfaceLinkStateChanged(iface, up);
- }
- }
-
- @Override
- public void onInterfaceRemoved(String iface) {
- for (NetworkAgentInfo nai : mNetworkAgentInfos) {
- nai.clatd.interfaceRemoved(iface);
- }
- }
- }
-
- private final LegacyNetworkActivityTracker mNetworkActivityTracker;
-
- /**
- * Class used for updating network activity tracking with netd and notify network activity
- * changes.
- */
- private static final class LegacyNetworkActivityTracker {
- private static final int NO_UID = -1;
- private final Context mContext;
- private final INetd mNetd;
- private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
- new RemoteCallbackList<>();
- // Indicate the current system default network activity is active or not.
- @GuardedBy("mActiveIdleTimers")
- private boolean mNetworkActive;
- @GuardedBy("mActiveIdleTimers")
- private final ArrayMap<String, IdleTimerParams> mActiveIdleTimers = new ArrayMap();
- private final Handler mHandler;
-
- private class IdleTimerParams {
- public final int timeout;
- public final int transportType;
-
- IdleTimerParams(int timeout, int transport) {
- this.timeout = timeout;
- this.transportType = transport;
- }
- }
-
- LegacyNetworkActivityTracker(@NonNull Context context, @NonNull Handler handler,
- @NonNull INetd netd) {
- mContext = context;
- mNetd = netd;
- mHandler = handler;
- }
-
- public void setAndReportNetworkActive(boolean active, int transportType, long tsNanos) {
- sendDataActivityBroadcast(transportTypeToLegacyType(transportType), active, tsNanos);
- synchronized (mActiveIdleTimers) {
- mNetworkActive = active;
- // If there are no idle timers, it means that system is not monitoring
- // activity, so the system default network for those default network
- // unspecified apps is always considered active.
- //
- // TODO: If the mActiveIdleTimers is empty, netd will actually not send
- // any network activity change event. Whenever this event is received,
- // the mActiveIdleTimers should be always not empty. The legacy behavior
- // is no-op. Remove to refer to mNetworkActive only.
- if (mNetworkActive || mActiveIdleTimers.isEmpty()) {
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_REPORT_NETWORK_ACTIVITY));
- }
- }
- }
-
- // The network activity should only be updated from ConnectivityService handler thread
- // when mActiveIdleTimers lock is held.
- @GuardedBy("mActiveIdleTimers")
- private void reportNetworkActive() {
- final int length = mNetworkActivityListeners.beginBroadcast();
- if (DDBG) log("reportNetworkActive, notify " + length + " listeners");
- try {
- for (int i = 0; i < length; i++) {
- try {
- mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
- } catch (RemoteException | RuntimeException e) {
- loge("Fail to send network activie to listener " + e);
- }
- }
- } finally {
- mNetworkActivityListeners.finishBroadcast();
- }
- }
-
- @GuardedBy("mActiveIdleTimers")
- public void handleReportNetworkActivity() {
- synchronized (mActiveIdleTimers) {
- reportNetworkActive();
- }
- }
-
- // This is deprecated and only to support legacy use cases.
- private int transportTypeToLegacyType(int type) {
- switch (type) {
- case NetworkCapabilities.TRANSPORT_CELLULAR:
- return TYPE_MOBILE;
- case NetworkCapabilities.TRANSPORT_WIFI:
- return TYPE_WIFI;
- case NetworkCapabilities.TRANSPORT_BLUETOOTH:
- return TYPE_BLUETOOTH;
- case NetworkCapabilities.TRANSPORT_ETHERNET:
- return TYPE_ETHERNET;
- default:
- loge("Unexpected transport in transportTypeToLegacyType: " + type);
- }
- return ConnectivityManager.TYPE_NONE;
- }
-
- public void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) {
- final Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE);
- intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType);
- intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active);
- intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos);
- final long ident = Binder.clearCallingIdentity();
- try {
- mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL,
- RECEIVE_DATA_ACTIVITY_CHANGE,
- null /* resultReceiver */,
- null /* scheduler */,
- 0 /* initialCode */,
- null /* initialData */,
- null /* initialExtra */);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- /**
- * Setup data activity tracking for the given network.
- *
- * Every {@code setupDataActivityTracking} should be paired with a
- * {@link #removeDataActivityTracking} for cleanup.
- */
- private void setupDataActivityTracking(NetworkAgentInfo networkAgent) {
- final String iface = networkAgent.linkProperties.getInterfaceName();
-
- final int timeout;
- final int type;
-
- if (networkAgent.networkCapabilities.hasTransport(
- NetworkCapabilities.TRANSPORT_CELLULAR)) {
- timeout = Settings.Global.getInt(mContext.getContentResolver(),
- ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_MOBILE,
- 10);
- type = NetworkCapabilities.TRANSPORT_CELLULAR;
- } else if (networkAgent.networkCapabilities.hasTransport(
- NetworkCapabilities.TRANSPORT_WIFI)) {
- timeout = Settings.Global.getInt(mContext.getContentResolver(),
- ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_WIFI,
- 15);
- type = NetworkCapabilities.TRANSPORT_WIFI;
- } else {
- return; // do not track any other networks
- }
-
- updateRadioPowerState(true /* isActive */, type);
-
- if (timeout > 0 && iface != null) {
- try {
- synchronized (mActiveIdleTimers) {
- // Networks start up.
- mNetworkActive = true;
- mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
- mNetd.idletimerAddInterface(iface, timeout, Integer.toString(type));
- reportNetworkActive();
- }
- } catch (Exception e) {
- // You shall not crash!
- loge("Exception in setupDataActivityTracking " + e);
- }
- }
- }
-
- /**
- * Remove data activity tracking when network disconnects.
- */
- private void removeDataActivityTracking(NetworkAgentInfo networkAgent) {
- final String iface = networkAgent.linkProperties.getInterfaceName();
- final NetworkCapabilities caps = networkAgent.networkCapabilities;
-
- if (iface == null) return;
-
- final int type;
- if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
- type = NetworkCapabilities.TRANSPORT_CELLULAR;
- } else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
- type = NetworkCapabilities.TRANSPORT_WIFI;
- } else {
- return; // do not track any other networks
- }
-
- try {
- updateRadioPowerState(false /* isActive */, type);
- synchronized (mActiveIdleTimers) {
- final IdleTimerParams params = mActiveIdleTimers.remove(iface);
- // The call fails silently if no idle timer setup for this interface
- mNetd.idletimerRemoveInterface(iface, params.timeout,
- Integer.toString(params.transportType));
- }
- } catch (Exception e) {
- // You shall not crash!
- loge("Exception in removeDataActivityTracking " + e);
- }
- }
-
- /**
- * Update data activity tracking when network state is updated.
- */
- public void updateDataActivityTracking(NetworkAgentInfo newNetwork,
- NetworkAgentInfo oldNetwork) {
- if (newNetwork != null) {
- setupDataActivityTracking(newNetwork);
- }
- if (oldNetwork != null) {
- removeDataActivityTracking(oldNetwork);
- }
- }
-
- private void updateRadioPowerState(boolean isActive, int transportType) {
- final BatteryStatsManager bs = mContext.getSystemService(BatteryStatsManager.class);
- switch (transportType) {
- case NetworkCapabilities.TRANSPORT_CELLULAR:
- bs.reportMobileRadioPowerState(isActive, NO_UID);
- break;
- case NetworkCapabilities.TRANSPORT_WIFI:
- bs.reportWifiRadioPowerState(isActive, NO_UID);
- break;
- default:
- logw("Untracked transport type:" + transportType);
- }
- }
-
- public boolean isDefaultNetworkActive() {
- synchronized (mActiveIdleTimers) {
- // If there are no idle timers, it means that system is not monitoring activity,
- // so the default network is always considered active.
- //
- // TODO : Distinguish between the cases where mActiveIdleTimers is empty because
- // tracking is disabled (negative idle timer value configured), or no active default
- // network. In the latter case, this reports active but it should report inactive.
- return mNetworkActive || mActiveIdleTimers.isEmpty();
- }
- }
-
- public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
- mNetworkActivityListeners.register(l);
- }
-
- public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
- mNetworkActivityListeners.unregister(l);
- }
-
- public void dump(IndentingPrintWriter pw) {
- synchronized (mActiveIdleTimers) {
- pw.print("mNetworkActive="); pw.println(mNetworkActive);
- pw.println("Idle timers:");
- for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
- pw.print(" "); pw.print(ent.getKey()); pw.println(":");
- final IdleTimerParams params = ent.getValue();
- pw.print(" timeout="); pw.print(params.timeout);
- pw.print(" type="); pw.println(params.transportType);
- }
- }
- }
- }
-
- /**
- * Registers {@link QosSocketFilter} with {@link IQosCallback}.
- *
- * @param socketInfo the socket information
- * @param callback the callback to register
- */
- @Override
- public void registerQosSocketCallback(@NonNull final QosSocketInfo socketInfo,
- @NonNull final IQosCallback callback) {
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(socketInfo.getNetwork());
- if (nai == null || nai.networkCapabilities == null) {
- try {
- callback.onError(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED);
- } catch (final RemoteException ex) {
- loge("registerQosCallbackInternal: RemoteException", ex);
- }
- return;
- }
- registerQosCallbackInternal(new QosSocketFilter(socketInfo), callback, nai);
- }
-
- /**
- * Register a {@link IQosCallback} with base {@link QosFilter}.
- *
- * @param filter the filter to register
- * @param callback the callback to register
- * @param nai the agent information related to the filter's network
- */
- @VisibleForTesting
- public void registerQosCallbackInternal(@NonNull final QosFilter filter,
- @NonNull final IQosCallback callback, @NonNull final NetworkAgentInfo nai) {
- if (filter == null) throw new IllegalArgumentException("filter must be non-null");
- if (callback == null) throw new IllegalArgumentException("callback must be non-null");
-
- if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
- enforceConnectivityRestrictedNetworksPermission();
- }
- mQosCallbackTracker.registerCallback(callback, filter, nai);
- }
-
- /**
- * Unregisters the given callback.
- *
- * @param callback the callback to unregister
- */
- @Override
- public void unregisterQosCallback(@NonNull final IQosCallback callback) {
- Objects.requireNonNull(callback, "callback must be non-null");
- mQosCallbackTracker.unregisterCallback(callback);
- }
-
- // Network preference per-profile and OEM network preferences can't be set at the same
- // time, because it is unclear what should happen if both preferences are active for
- // one given UID. To make it possible, the stack would have to clarify what would happen
- // in case both are active at the same time. The implementation may have to be adjusted
- // to implement the resulting rules. For example, a priority could be defined between them,
- // where the OEM preference would be considered less or more important than the enterprise
- // preference ; this would entail implementing the priorities somehow, e.g. by doing
- // UID arithmetic with UID ranges or passing a priority to netd so that the routing rules
- // are set at the right level. Other solutions are possible, e.g. merging of the
- // preferences for the relevant UIDs.
- private static void throwConcurrentPreferenceException() {
- throw new IllegalStateException("Can't set NetworkPreferenceForUser and "
- + "set OemNetworkPreference at the same time");
- }
-
- /**
- * Request that a user profile is put by default on a network matching a given preference.
- *
- * See the documentation for the individual preferences for a description of the supported
- * behaviors.
- *
- * @param profile the profile concerned.
- * @param preference the preference for this profile, as one of the PROFILE_NETWORK_PREFERENCE_*
- * constants.
- * @param listener an optional listener to listen for completion of the operation.
- */
- @Override
- public void setProfileNetworkPreference(@NonNull final UserHandle profile,
- @ConnectivityManager.ProfileNetworkPreference final int preference,
- @Nullable final IOnCompleteListener listener) {
- Objects.requireNonNull(profile);
- PermissionUtils.enforceNetworkStackPermission(mContext);
- if (DBG) {
- log("setProfileNetworkPreference " + profile + " to " + preference);
- }
- if (profile.getIdentifier() < 0) {
- throw new IllegalArgumentException("Must explicitly specify a user handle ("
- + "UserHandle.CURRENT not supported)");
- }
- final UserManager um = mContext.getSystemService(UserManager.class);
- if (!um.isManagedProfile(profile.getIdentifier())) {
- throw new IllegalArgumentException("Profile must be a managed profile");
- }
- // Strictly speaking, mOemNetworkPreferences should only be touched on the
- // handler thread. However it is an immutable object, so reading the reference is
- // safe - it's just possible the value is slightly outdated. For the final check,
- // see #handleSetProfileNetworkPreference. But if this can be caught here it is a
- // lot easier to understand, so opportunistically check it.
- if (!mOemNetworkPreferences.isEmpty()) {
- throwConcurrentPreferenceException();
- }
- final NetworkCapabilities nc;
- switch (preference) {
- case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT:
- nc = null;
- break;
- case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE:
- final UidRange uids = UidRange.createForUser(profile);
- nc = createDefaultNetworkCapabilitiesForUidRange(uids);
- nc.addCapability(NET_CAPABILITY_ENTERPRISE);
- nc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
- break;
- default:
- throw new IllegalArgumentException(
- "Invalid preference in setProfileNetworkPreference");
- }
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_PROFILE_NETWORK_PREFERENCE,
- new Pair<>(new ProfileNetworkPreferences.Preference(profile, nc), listener)));
- }
-
- private void validateNetworkCapabilitiesOfProfileNetworkPreference(
- @Nullable final NetworkCapabilities nc) {
- if (null == nc) return; // Null caps are always allowed. It means to remove the setting.
- ensureRequestableCapabilities(nc);
- }
-
- private ArraySet<NetworkRequestInfo> createNrisFromProfileNetworkPreferences(
- @NonNull final ProfileNetworkPreferences prefs) {
- final ArraySet<NetworkRequestInfo> result = new ArraySet<>();
- for (final ProfileNetworkPreferences.Preference pref : prefs.preferences) {
- // The NRI for a user should be comprised of two layers:
- // - The request for the capabilities
- // - The request for the default network, for fallback. Create an image of it to
- // have the correct UIDs in it (also a request can only be part of one NRI, because
- // of lookups in 1:1 associations like mNetworkRequests).
- // Note that denying a fallback can be implemented simply by not adding the second
- // request.
- final ArrayList<NetworkRequest> nrs = new ArrayList<>();
- nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities));
- nrs.add(createDefaultInternetRequestForTransport(
- TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
- setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids()));
- final NetworkRequestInfo nri = new NetworkRequestInfo(Process.myUid(), nrs);
- result.add(nri);
- }
- return result;
- }
-
- private void handleSetProfileNetworkPreference(
- @NonNull final ProfileNetworkPreferences.Preference preference,
- @Nullable final IOnCompleteListener listener) {
- // setProfileNetworkPreference and setOemNetworkPreference are mutually exclusive, in
- // particular because it's not clear what preference should win in case both apply
- // to the same app.
- // The binder call has already checked this, but as mOemNetworkPreferences is only
- // touched on the handler thread, it's theoretically not impossible that it has changed
- // since.
- if (!mOemNetworkPreferences.isEmpty()) {
- // This may happen on a device with an OEM preference set when a user is removed.
- // In this case, it's safe to ignore. In particular this happens in the tests.
- loge("handleSetProfileNetworkPreference, but OEM network preferences not empty");
- return;
- }
-
- validateNetworkCapabilitiesOfProfileNetworkPreference(preference.capabilities);
-
- mProfileNetworkPreferences = mProfileNetworkPreferences.plus(preference);
- mSystemNetworkRequestCounter.transact(
- mDeps.getCallingUid(), mProfileNetworkPreferences.preferences.size(),
- () -> {
- final ArraySet<NetworkRequestInfo> nris =
- createNrisFromProfileNetworkPreferences(mProfileNetworkPreferences);
- replaceDefaultNetworkRequestsForPreference(nris);
- });
- // Finally, rematch.
- rematchAllNetworksAndRequests();
-
- if (null != listener) {
- try {
- listener.onComplete();
- } catch (RemoteException e) {
- loge("Listener for setProfileNetworkPreference has died");
- }
- }
- }
-
- private void enforceAutomotiveDevice() {
- final boolean isAutomotiveDevice =
- mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
- if (!isAutomotiveDevice) {
- throw new UnsupportedOperationException(
- "setOemNetworkPreference() is only available on automotive devices.");
- }
- }
-
- /**
- * Used by automotive devices to set the network preferences used to direct traffic at an
- * application level as per the given OemNetworkPreferences. An example use-case would be an
- * automotive OEM wanting to provide connectivity for applications critical to the usage of a
- * vehicle via a particular network.
- *
- * Calling this will overwrite the existing preference.
- *
- * @param preference {@link OemNetworkPreferences} The application network preference to be set.
- * @param listener {@link ConnectivityManager.OnCompleteListener} Listener used
- * to communicate completion of setOemNetworkPreference();
- */
- @Override
- public void setOemNetworkPreference(
- @NonNull final OemNetworkPreferences preference,
- @Nullable final IOnCompleteListener listener) {
-
- enforceAutomotiveDevice();
- enforceOemNetworkPreferencesPermission();
-
- if (!mProfileNetworkPreferences.isEmpty()) {
- // Strictly speaking, mProfileNetworkPreferences should only be touched on the
- // handler thread. However it is an immutable object, so reading the reference is
- // safe - it's just possible the value is slightly outdated. For the final check,
- // see #handleSetOemPreference. But if this can be caught here it is a
- // lot easier to understand, so opportunistically check it.
- throwConcurrentPreferenceException();
- }
-
- Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
- validateOemNetworkPreferences(preference);
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_OEM_NETWORK_PREFERENCE,
- new Pair<>(preference, listener)));
- }
-
- private void validateOemNetworkPreferences(@NonNull OemNetworkPreferences preference) {
- for (@OemNetworkPreferences.OemNetworkPreference final int pref
- : preference.getNetworkPreferences().values()) {
- if (OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED == pref) {
- final String msg = "OEM_NETWORK_PREFERENCE_UNINITIALIZED is an invalid value.";
- throw new IllegalArgumentException(msg);
- }
- }
- }
-
- private void handleSetOemNetworkPreference(
- @NonNull final OemNetworkPreferences preference,
- @Nullable final IOnCompleteListener listener) {
- Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
- if (DBG) {
- log("set OEM network preferences :" + preference.toString());
- }
- // setProfileNetworkPreference and setOemNetworkPreference are mutually exclusive, in
- // particular because it's not clear what preference should win in case both apply
- // to the same app.
- // The binder call has already checked this, but as mOemNetworkPreferences is only
- // touched on the handler thread, it's theoretically not impossible that it has changed
- // since.
- if (!mProfileNetworkPreferences.isEmpty()) {
- logwtf("handleSetOemPreference, but per-profile network preferences not empty");
- return;
- }
-
- mOemNetworkPreferencesLogs.log("UPDATE INITIATED: " + preference);
- final int uniquePreferenceCount = new ArraySet<>(
- preference.getNetworkPreferences().values()).size();
- mSystemNetworkRequestCounter.transact(
- mDeps.getCallingUid(), uniquePreferenceCount,
- () -> {
- final ArraySet<NetworkRequestInfo> nris =
- new OemNetworkRequestFactory()
- .createNrisFromOemNetworkPreferences(preference);
- replaceDefaultNetworkRequestsForPreference(nris);
- });
- mOemNetworkPreferences = preference;
-
- if (null != listener) {
- try {
- listener.onComplete();
- } catch (RemoteException e) {
- loge("Can't send onComplete in handleSetOemNetworkPreference", e);
- }
- }
- }
-
- private void replaceDefaultNetworkRequestsForPreference(
- @NonNull final Set<NetworkRequestInfo> nris) {
- // Pass in a defensive copy as this collection will be updated on remove.
- handleRemoveNetworkRequests(new ArraySet<>(mDefaultNetworkRequests));
- addPerAppDefaultNetworkRequests(nris);
- }
-
- private void addPerAppDefaultNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
- ensureRunningOnConnectivityServiceThread();
- mDefaultNetworkRequests.addAll(nris);
- final ArraySet<NetworkRequestInfo> perAppCallbackRequestsToUpdate =
- getPerAppCallbackRequestsToUpdate();
- final ArraySet<NetworkRequestInfo> nrisToRegister = new ArraySet<>(nris);
- mSystemNetworkRequestCounter.transact(
- mDeps.getCallingUid(), perAppCallbackRequestsToUpdate.size(),
- () -> {
- nrisToRegister.addAll(
- createPerAppCallbackRequestsToRegister(perAppCallbackRequestsToUpdate));
- handleRemoveNetworkRequests(perAppCallbackRequestsToUpdate);
- handleRegisterNetworkRequests(nrisToRegister);
- });
- }
-
- /**
- * All current requests that are tracking the default network need to be assessed as to whether
- * or not the current set of per-application default requests will be changing their default
- * network. If so, those requests will need to be updated so that they will send callbacks for
- * default network changes at the appropriate time. Additionally, those requests tracking the
- * default that were previously updated by this flow will need to be reassessed.
- * @return the nris which will need to be updated.
- */
- private ArraySet<NetworkRequestInfo> getPerAppCallbackRequestsToUpdate() {
- final ArraySet<NetworkRequestInfo> defaultCallbackRequests = new ArraySet<>();
- // Get the distinct nris to check since for multilayer requests, it is possible to have the
- // same nri in the map's values for each of its NetworkRequest objects.
- final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(mNetworkRequests.values());
- for (final NetworkRequestInfo nri : nris) {
- // Include this nri if it is currently being tracked.
- if (isPerAppTrackedNri(nri)) {
- defaultCallbackRequests.add(nri);
- continue;
- }
- // We only track callbacks for requests tracking the default.
- if (NetworkRequest.Type.TRACK_DEFAULT != nri.mRequests.get(0).type) {
- continue;
- }
- // Include this nri if it will be tracked by the new per-app default requests.
- final boolean isNriGoingToBeTracked =
- getDefaultRequestTrackingUid(nri.mAsUid) != mDefaultRequest;
- if (isNriGoingToBeTracked) {
- defaultCallbackRequests.add(nri);
- }
- }
- return defaultCallbackRequests;
- }
-
- /**
- * Create nris for those network requests that are currently tracking the default network that
- * are being controlled by a per-application default.
- * @param perAppCallbackRequestsForUpdate the baseline network requests to be used as the
- * foundation when creating the nri. Important items include the calling uid's original
- * NetworkRequest to be used when mapping callbacks as well as the caller's uid and name. These
- * requests are assumed to have already been validated as needing to be updated.
- * @return the Set of nris to use when registering network requests.
- */
- private ArraySet<NetworkRequestInfo> createPerAppCallbackRequestsToRegister(
- @NonNull final ArraySet<NetworkRequestInfo> perAppCallbackRequestsForUpdate) {
- final ArraySet<NetworkRequestInfo> callbackRequestsToRegister = new ArraySet<>();
- for (final NetworkRequestInfo callbackRequest : perAppCallbackRequestsForUpdate) {
- final NetworkRequestInfo trackingNri =
- getDefaultRequestTrackingUid(callbackRequest.mAsUid);
-
- // If this nri is not being tracked, the change it back to an untracked nri.
- if (trackingNri == mDefaultRequest) {
- callbackRequestsToRegister.add(new NetworkRequestInfo(
- callbackRequest,
- Collections.singletonList(callbackRequest.getNetworkRequestForCallback())));
- continue;
- }
-
- final NetworkRequest request = callbackRequest.mRequests.get(0);
- callbackRequestsToRegister.add(new NetworkRequestInfo(
- callbackRequest,
- copyNetworkRequestsForUid(
- trackingNri.mRequests, callbackRequest.mAsUid,
- callbackRequest.mUid, request.getRequestorPackageName())));
- }
- return callbackRequestsToRegister;
- }
-
- private static void setNetworkRequestUids(@NonNull final List<NetworkRequest> requests,
- @NonNull final Set<UidRange> uids) {
- for (final NetworkRequest req : requests) {
- req.networkCapabilities.setUids(UidRange.toIntRanges(uids));
- }
- }
-
- /**
- * Class used to generate {@link NetworkRequestInfo} based off of {@link OemNetworkPreferences}.
- */
- @VisibleForTesting
- final class OemNetworkRequestFactory {
- ArraySet<NetworkRequestInfo> createNrisFromOemNetworkPreferences(
- @NonNull final OemNetworkPreferences preference) {
- final ArraySet<NetworkRequestInfo> nris = new ArraySet<>();
- final SparseArray<Set<Integer>> uids =
- createUidsFromOemNetworkPreferences(preference);
- for (int i = 0; i < uids.size(); i++) {
- final int key = uids.keyAt(i);
- final Set<Integer> value = uids.valueAt(i);
- final NetworkRequestInfo nri = createNriFromOemNetworkPreferences(key, value);
- // No need to add an nri without any requests.
- if (0 == nri.mRequests.size()) {
- continue;
- }
- nris.add(nri);
- }
-
- return nris;
- }
-
- private SparseArray<Set<Integer>> createUidsFromOemNetworkPreferences(
- @NonNull final OemNetworkPreferences preference) {
- final SparseArray<Set<Integer>> uids = new SparseArray<>();
- final PackageManager pm = mContext.getPackageManager();
- final List<UserHandle> users =
- mContext.getSystemService(UserManager.class).getUserHandles(true);
- if (null == users || users.size() == 0) {
- if (VDBG || DDBG) {
- log("No users currently available for setting the OEM network preference.");
- }
- return uids;
- }
- for (final Map.Entry<String, Integer> entry :
- preference.getNetworkPreferences().entrySet()) {
- @OemNetworkPreferences.OemNetworkPreference final int pref = entry.getValue();
- try {
- final int uid = pm.getApplicationInfo(entry.getKey(), 0).uid;
- if (!uids.contains(pref)) {
- uids.put(pref, new ArraySet<>());
- }
- for (final UserHandle ui : users) {
- // Add the rules for all users as this policy is device wide.
- uids.get(pref).add(ui.getUid(uid));
- }
- } catch (PackageManager.NameNotFoundException e) {
- // Although this may seem like an error scenario, it is ok that uninstalled
- // packages are sent on a network preference as the system will watch for
- // package installations associated with this network preference and update
- // accordingly. This is done so as to minimize race conditions on app install.
- continue;
- }
- }
- return uids;
- }
-
- private NetworkRequestInfo createNriFromOemNetworkPreferences(
- @OemNetworkPreferences.OemNetworkPreference final int preference,
- @NonNull final Set<Integer> uids) {
- final List<NetworkRequest> requests = new ArrayList<>();
- // Requests will ultimately be evaluated by order of insertion therefore it matters.
- switch (preference) {
- case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID:
- requests.add(createUnmeteredNetworkRequest());
- requests.add(createOemPaidNetworkRequest());
- requests.add(createDefaultInternetRequestForTransport(
- TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
- break;
- case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK:
- requests.add(createUnmeteredNetworkRequest());
- requests.add(createOemPaidNetworkRequest());
- break;
- case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY:
- requests.add(createOemPaidNetworkRequest());
- break;
- case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY:
- requests.add(createOemPrivateNetworkRequest());
- break;
- default:
- // This should never happen.
- throw new IllegalArgumentException("createNriFromOemNetworkPreferences()"
- + " called with invalid preference of " + preference);
- }
-
- final ArraySet ranges = new ArraySet<Integer>();
- for (final int uid : uids) {
- ranges.add(new UidRange(uid, uid));
- }
- setNetworkRequestUids(requests, ranges);
- return new NetworkRequestInfo(Process.myUid(), requests);
- }
-
- private NetworkRequest createUnmeteredNetworkRequest() {
- final NetworkCapabilities netcap = createDefaultPerAppNetCap()
- .addCapability(NET_CAPABILITY_NOT_METERED)
- .addCapability(NET_CAPABILITY_VALIDATED);
- return createNetworkRequest(NetworkRequest.Type.LISTEN, netcap);
- }
-
- private NetworkRequest createOemPaidNetworkRequest() {
- // NET_CAPABILITY_OEM_PAID is a restricted capability.
- final NetworkCapabilities netcap = createDefaultPerAppNetCap()
- .addCapability(NET_CAPABILITY_OEM_PAID)
- .removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
- return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
- }
-
- private NetworkRequest createOemPrivateNetworkRequest() {
- // NET_CAPABILITY_OEM_PRIVATE is a restricted capability.
- final NetworkCapabilities netcap = createDefaultPerAppNetCap()
- .addCapability(NET_CAPABILITY_OEM_PRIVATE)
- .removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
- return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
- }
-
- private NetworkCapabilities createDefaultPerAppNetCap() {
- final NetworkCapabilities netCap = new NetworkCapabilities();
- netCap.addCapability(NET_CAPABILITY_INTERNET);
- netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
- return netCap;
- }
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/ConnectivityServiceInitializer.java b/packages/Connectivity/service/src/com/android/server/ConnectivityServiceInitializer.java
deleted file mode 100644
index 2465479..0000000
--- a/packages/Connectivity/service/src/com/android/server/ConnectivityServiceInitializer.java
+++ /dev/null
@@ -1,44 +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;
-
-import android.content.Context;
-import android.util.Log;
-
-/**
- * Connectivity service initializer for core networking. This is called by system server to create
- * a new instance of ConnectivityService.
- */
-public final class ConnectivityServiceInitializer extends SystemService {
- private static final String TAG = ConnectivityServiceInitializer.class.getSimpleName();
- private final ConnectivityService mConnectivity;
-
- public ConnectivityServiceInitializer(Context context) {
- super(context);
- // Load JNI libraries used by ConnectivityService and its dependencies
- System.loadLibrary("service-connectivity");
- // TODO: Define formal APIs to get the needed services.
- mConnectivity = new ConnectivityService(context);
- }
-
- @Override
- public void onStart() {
- Log.i(TAG, "Registering " + Context.CONNECTIVITY_SERVICE);
- publishBinderService(Context.CONNECTIVITY_SERVICE, mConnectivity,
- /* allowIsolated= */ false);
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/NetIdManager.java b/packages/Connectivity/service/src/com/android/server/NetIdManager.java
deleted file mode 100644
index 61925c8..0000000
--- a/packages/Connectivity/service/src/com/android/server/NetIdManager.java
+++ /dev/null
@@ -1,89 +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 android.annotation.NonNull;
-import android.net.ConnectivityManager;
-import android.util.SparseBooleanArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * Class used to reserve and release net IDs.
- *
- * <p>Instances of this class are thread-safe.
- */
-public class NetIdManager {
- // Sequence number for Networks; keep in sync with system/netd/NetworkController.cpp
- public static final int MIN_NET_ID = 100; // some reserved marks
- // Top IDs reserved by IpSecService
- public static final int MAX_NET_ID = ConnectivityManager.getIpSecNetIdRange().getLower() - 1;
-
- @GuardedBy("mNetIdInUse")
- private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray();
-
- @GuardedBy("mNetIdInUse")
- private int mLastNetId = MIN_NET_ID - 1;
-
- private final int mMaxNetId;
-
- public NetIdManager() {
- this(MAX_NET_ID);
- }
-
- @VisibleForTesting
- NetIdManager(int maxNetId) {
- mMaxNetId = maxNetId;
- }
-
- /**
- * Get the first netId that follows the provided lastId and is available.
- */
- private int getNextAvailableNetIdLocked(
- int lastId, @NonNull SparseBooleanArray netIdInUse) {
- int netId = lastId;
- for (int i = MIN_NET_ID; i <= mMaxNetId; i++) {
- netId = netId < mMaxNetId ? netId + 1 : MIN_NET_ID;
- if (!netIdInUse.get(netId)) {
- return netId;
- }
- }
- throw new IllegalStateException("No free netIds");
- }
-
- /**
- * Reserve a new ID for a network.
- */
- public int reserveNetId() {
- synchronized (mNetIdInUse) {
- mLastNetId = getNextAvailableNetIdLocked(mLastNetId, mNetIdInUse);
- // Make sure NetID unused. http://b/16815182
- mNetIdInUse.put(mLastNetId, true);
- return mLastNetId;
- }
- }
-
- /**
- * Clear a previously reserved ID for a network.
- */
- public void releaseNetId(int id) {
- synchronized (mNetIdInUse) {
- mNetIdInUse.delete(id);
- }
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/TestNetworkService.java b/packages/Connectivity/service/src/com/android/server/TestNetworkService.java
deleted file mode 100644
index 09873f4..0000000
--- a/packages/Connectivity/service/src/com/android/server/TestNetworkService.java
+++ /dev/null
@@ -1,387 +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;
-
-import static android.net.TestNetworkManager.TEST_TAP_PREFIX;
-import static android.net.TestNetworkManager.TEST_TUN_PREFIX;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.INetd;
-import android.net.ITestNetworkManager;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NetworkAgent;
-import android.net.NetworkAgentConfig;
-import android.net.NetworkCapabilities;
-import android.net.NetworkProvider;
-import android.net.RouteInfo;
-import android.net.TestNetworkInterface;
-import android.net.TestNetworkSpecifier;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.net.module.util.NetdUtils;
-import com.android.net.module.util.NetworkStackConstants;
-import com.android.net.module.util.PermissionUtils;
-
-import java.io.UncheckedIOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InterfaceAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.ArrayList;
-import java.util.Objects;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/** @hide */
-class TestNetworkService extends ITestNetworkManager.Stub {
- @NonNull private static final String TEST_NETWORK_LOGTAG = "TestNetworkAgent";
- @NonNull private static final String TEST_NETWORK_PROVIDER_NAME = "TestNetworkProvider";
- @NonNull private static final AtomicInteger sTestTunIndex = new AtomicInteger();
-
- @NonNull private final Context mContext;
- @NonNull private final INetd mNetd;
-
- @NonNull private final HandlerThread mHandlerThread;
- @NonNull private final Handler mHandler;
-
- @NonNull private final ConnectivityManager mCm;
- @NonNull private final NetworkProvider mNetworkProvider;
-
- // Native method stubs
- private static native int jniCreateTunTap(boolean isTun, @NonNull String iface);
-
- @VisibleForTesting
- protected TestNetworkService(@NonNull Context context) {
- mHandlerThread = new HandlerThread("TestNetworkServiceThread");
- mHandlerThread.start();
- mHandler = new Handler(mHandlerThread.getLooper());
-
- mContext = Objects.requireNonNull(context, "missing Context");
- mNetd = Objects.requireNonNull(
- INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)),
- "could not get netd instance");
- mCm = mContext.getSystemService(ConnectivityManager.class);
- mNetworkProvider = new NetworkProvider(mContext, mHandler.getLooper(),
- TEST_NETWORK_PROVIDER_NAME);
- final long token = Binder.clearCallingIdentity();
- try {
- mCm.registerNetworkProvider(mNetworkProvider);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Create a TUN or TAP interface with the given interface name and link addresses
- *
- * <p>This method will return the FileDescriptor to the interface. Close it to tear down the
- * interface.
- */
- private TestNetworkInterface createInterface(boolean isTun, LinkAddress[] linkAddrs) {
- enforceTestNetworkPermissions(mContext);
-
- Objects.requireNonNull(linkAddrs, "missing linkAddrs");
-
- String ifacePrefix = isTun ? TEST_TUN_PREFIX : TEST_TAP_PREFIX;
- String iface = ifacePrefix + sTestTunIndex.getAndIncrement();
- final long token = Binder.clearCallingIdentity();
- try {
- ParcelFileDescriptor tunIntf =
- ParcelFileDescriptor.adoptFd(jniCreateTunTap(isTun, iface));
- for (LinkAddress addr : linkAddrs) {
- mNetd.interfaceAddAddress(
- iface,
- addr.getAddress().getHostAddress(),
- addr.getPrefixLength());
- }
-
- return new TestNetworkInterface(tunIntf, iface);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Create a TUN interface with the given interface name and link addresses
- *
- * <p>This method will return the FileDescriptor to the TUN interface. Close it to tear down the
- * TUN interface.
- */
- @Override
- public TestNetworkInterface createTunInterface(@NonNull LinkAddress[] linkAddrs) {
- return createInterface(true, linkAddrs);
- }
-
- /**
- * Create a TAP interface with the given interface name
- *
- * <p>This method will return the FileDescriptor to the TAP interface. Close it to tear down the
- * TAP interface.
- */
- @Override
- public TestNetworkInterface createTapInterface() {
- return createInterface(false, new LinkAddress[0]);
- }
-
- // Tracker for TestNetworkAgents
- @GuardedBy("mTestNetworkTracker")
- @NonNull
- private final SparseArray<TestNetworkAgent> mTestNetworkTracker = new SparseArray<>();
-
- public class TestNetworkAgent extends NetworkAgent implements IBinder.DeathRecipient {
- private static final int NETWORK_SCORE = 1; // Use a low, non-zero score.
-
- private final int mUid;
-
- @GuardedBy("mBinderLock")
- @NonNull
- private IBinder mBinder;
-
- @NonNull private final Object mBinderLock = new Object();
-
- private TestNetworkAgent(
- @NonNull Context context,
- @NonNull Looper looper,
- @NonNull NetworkCapabilities nc,
- @NonNull LinkProperties lp,
- @NonNull NetworkAgentConfig config,
- int uid,
- @NonNull IBinder binder,
- @NonNull NetworkProvider np)
- throws RemoteException {
- super(context, looper, TEST_NETWORK_LOGTAG, nc, lp, NETWORK_SCORE, config, np);
- mUid = uid;
- synchronized (mBinderLock) {
- mBinder = binder; // Binder null-checks in create()
-
- try {
- mBinder.linkToDeath(this, 0);
- } catch (RemoteException e) {
- binderDied();
- throw e; // Abort, signal failure up the stack.
- }
- }
- }
-
- /**
- * If the Binder object dies, this function is called to free the resources of this
- * TestNetworkAgent
- */
- @Override
- public void binderDied() {
- teardown();
- }
-
- @Override
- protected void unwanted() {
- teardown();
- }
-
- private void teardown() {
- unregister();
-
- // Synchronize on mBinderLock to ensure that unlinkToDeath is never called more than
- // once (otherwise it could throw an exception)
- synchronized (mBinderLock) {
- // If mBinder is null, this Test Network has already been cleaned up.
- if (mBinder == null) return;
- mBinder.unlinkToDeath(this, 0);
- mBinder = null;
- }
-
- // Has to be in TestNetworkAgent to ensure all teardown codepaths properly clean up
- // resources, even for binder death or unwanted calls.
- synchronized (mTestNetworkTracker) {
- mTestNetworkTracker.remove(getNetwork().getNetId());
- }
- }
- }
-
- private TestNetworkAgent registerTestNetworkAgent(
- @NonNull Looper looper,
- @NonNull Context context,
- @NonNull String iface,
- @Nullable LinkProperties lp,
- boolean isMetered,
- int callingUid,
- @NonNull int[] administratorUids,
- @NonNull IBinder binder)
- throws RemoteException, SocketException {
- Objects.requireNonNull(looper, "missing Looper");
- Objects.requireNonNull(context, "missing Context");
- // iface and binder validity checked by caller
-
- // Build narrow set of NetworkCapabilities, useful only for testing
- NetworkCapabilities nc = new NetworkCapabilities();
- nc.clearAll(); // Remove default capabilities.
- nc.addTransportType(NetworkCapabilities.TRANSPORT_TEST);
- nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
- nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
- nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
- nc.setNetworkSpecifier(new TestNetworkSpecifier(iface));
- nc.setAdministratorUids(administratorUids);
- if (!isMetered) {
- nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
- }
-
- // Build LinkProperties
- if (lp == null) {
- lp = new LinkProperties();
- } else {
- lp = new LinkProperties(lp);
- // Use LinkAddress(es) from the interface itself to minimize how much the caller
- // is trusted.
- lp.setLinkAddresses(new ArrayList<>());
- }
- lp.setInterfaceName(iface);
-
- // Find the currently assigned addresses, and add them to LinkProperties
- boolean allowIPv4 = false, allowIPv6 = false;
- NetworkInterface netIntf = NetworkInterface.getByName(iface);
- Objects.requireNonNull(netIntf, "No such network interface found: " + netIntf);
-
- for (InterfaceAddress intfAddr : netIntf.getInterfaceAddresses()) {
- lp.addLinkAddress(
- new LinkAddress(intfAddr.getAddress(), intfAddr.getNetworkPrefixLength()));
-
- if (intfAddr.getAddress() instanceof Inet6Address) {
- allowIPv6 |= !intfAddr.getAddress().isLinkLocalAddress();
- } else if (intfAddr.getAddress() instanceof Inet4Address) {
- allowIPv4 = true;
- }
- }
-
- // Add global routes (but as non-default, non-internet providing network)
- if (allowIPv4) {
- lp.addRoute(new RouteInfo(new IpPrefix(
- NetworkStackConstants.IPV4_ADDR_ANY, 0), null, iface));
- }
- if (allowIPv6) {
- lp.addRoute(new RouteInfo(new IpPrefix(
- NetworkStackConstants.IPV6_ADDR_ANY, 0), null, iface));
- }
-
- final TestNetworkAgent agent = new TestNetworkAgent(context, looper, nc, lp,
- new NetworkAgentConfig.Builder().build(), callingUid, binder,
- mNetworkProvider);
- agent.register();
- agent.markConnected();
- return agent;
- }
-
- /**
- * Sets up a Network with extremely limited privileges, guarded by the MANAGE_TEST_NETWORKS
- * permission.
- *
- * <p>This method provides a Network that is useful only for testing.
- */
- @Override
- public void setupTestNetwork(
- @NonNull String iface,
- @Nullable LinkProperties lp,
- boolean isMetered,
- @NonNull int[] administratorUids,
- @NonNull IBinder binder) {
- enforceTestNetworkPermissions(mContext);
-
- Objects.requireNonNull(iface, "missing Iface");
- Objects.requireNonNull(binder, "missing IBinder");
-
- if (!(iface.startsWith(INetd.IPSEC_INTERFACE_PREFIX)
- || iface.startsWith(TEST_TUN_PREFIX))) {
- throw new IllegalArgumentException(
- "Cannot create network for non ipsec, non-testtun interface");
- }
-
- try {
- final long token = Binder.clearCallingIdentity();
- try {
- PermissionUtils.enforceNetworkStackPermission(mContext);
- NetdUtils.setInterfaceUp(mNetd, iface);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
-
- // Synchronize all accesses to mTestNetworkTracker to prevent the case where:
- // 1. TestNetworkAgent successfully binds to death of binder
- // 2. Before it is added to the mTestNetworkTracker, binder dies, binderDied() is called
- // (on a different thread)
- // 3. This thread is pre-empted, put() is called after remove()
- synchronized (mTestNetworkTracker) {
- TestNetworkAgent agent =
- registerTestNetworkAgent(
- mHandler.getLooper(),
- mContext,
- iface,
- lp,
- isMetered,
- Binder.getCallingUid(),
- administratorUids,
- binder);
-
- mTestNetworkTracker.put(agent.getNetwork().getNetId(), agent);
- }
- } catch (SocketException e) {
- throw new UncheckedIOException(e);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** Teardown a test network */
- @Override
- public void teardownTestNetwork(int netId) {
- enforceTestNetworkPermissions(mContext);
-
- final TestNetworkAgent agent;
- synchronized (mTestNetworkTracker) {
- agent = mTestNetworkTracker.get(netId);
- }
-
- if (agent == null) {
- return; // Already torn down
- } else if (agent.mUid != Binder.getCallingUid()) {
- throw new SecurityException("Attempted to modify other user's test networks");
- }
-
- // Safe to be called multiple times.
- agent.teardown();
- }
-
- private static final String PERMISSION_NAME =
- android.Manifest.permission.MANAGE_TEST_NETWORKS;
-
- public static void enforceTestNetworkPermissions(@NonNull Context context) {
- context.enforceCallingOrSelfPermission(PERMISSION_NAME, "TestNetworkService");
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/AutodestructReference.java b/packages/Connectivity/service/src/com/android/server/connectivity/AutodestructReference.java
deleted file mode 100644
index 009a43e..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/AutodestructReference.java
+++ /dev/null
@@ -1,42 +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.connectivity;
-
-import android.annotation.NonNull;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * A ref that autodestructs at the first usage of it.
- * @param <T> The type of the held object
- * @hide
- */
-public class AutodestructReference<T> {
- private final AtomicReference<T> mHeld;
- public AutodestructReference(@NonNull T obj) {
- if (null == obj) throw new NullPointerException("Autodestruct reference to null");
- mHeld = new AtomicReference<>(obj);
- }
-
- /** Get the ref and destruct it. NPE if already destructed. */
- @NonNull
- public T getAndDestroy() {
- final T obj = mHeld.getAndSet(null);
- if (null == obj) throw new NullPointerException("Already autodestructed");
- return obj;
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/DnsManager.java b/packages/Connectivity/service/src/com/android/server/connectivity/DnsManager.java
deleted file mode 100644
index 05b12ba..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/DnsManager.java
+++ /dev/null
@@ -1,494 +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.DNS_RESOLVER_MAX_SAMPLES;
-import static android.net.ConnectivitySettingsManager.DNS_RESOLVER_MIN_SAMPLES;
-import static android.net.ConnectivitySettingsManager.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS;
-import static android.net.ConnectivitySettingsManager.DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT;
-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.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE;
-import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS;
-
-import android.annotation.NonNull;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.ConnectivitySettingsManager;
-import android.net.IDnsResolver;
-import android.net.InetAddresses;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.ResolverOptionsParcel;
-import android.net.ResolverParamsParcel;
-import android.net.Uri;
-import android.net.shared.PrivateDnsConfig;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import java.net.InetAddress;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
-
-/**
- * Encapsulate the management of DNS settings for networks.
- *
- * This class it NOT designed for concurrent access. Furthermore, all non-static
- * methods MUST be called from ConnectivityService's thread. However, an exceptional
- * case is getPrivateDnsConfig(Network) which is exclusively for
- * ConnectivityService#dumpNetworkDiagnostics() on a random binder thread.
- *
- * [ Private DNS ]
- * The code handling Private DNS is spread across several components, but this
- * seems like the least bad place to collect all the observations.
- *
- * Private DNS handling and updating occurs in response to several different
- * events. Each is described here with its corresponding intended handling.
- *
- * [A] Event: A new network comes up.
- * Mechanics:
- * [1] ConnectivityService gets notifications from NetworkAgents.
- * [2] in updateNetworkInfo(), the first time the NetworkAgent goes into
- * into CONNECTED state, the Private DNS configuration is retrieved,
- * programmed, and strict mode hostname resolution (if applicable) is
- * enqueued in NetworkAgent's NetworkMonitor, via a call to
- * handlePerNetworkPrivateDnsConfig().
- * [3] Re-resolution of strict mode hostnames that fail to return any
- * IP addresses happens inside NetworkMonitor; it sends itself a
- * delayed CMD_EVALUATE_PRIVATE_DNS message in a simple backoff
- * schedule.
- * [4] Successfully resolved hostnames are sent to ConnectivityService
- * inside an EVENT_PRIVATE_DNS_CONFIG_RESOLVED message. The resolved
- * IP addresses are programmed into netd via:
- *
- * updatePrivateDns() -> updateDnses()
- *
- * both of which make calls into DnsManager.
- * [5] Upon a successful hostname resolution NetworkMonitor initiates a
- * validation attempt in the form of a lookup for a one-time hostname
- * that uses Private DNS.
- *
- * [B] Event: Private DNS settings are changed.
- * Mechanics:
- * [1] ConnectivityService gets notifications from its SettingsObserver.
- * [2] handlePrivateDnsSettingsChanged() is called, which calls
- * handlePerNetworkPrivateDnsConfig() and the process proceeds
- * as if from A.3 above.
- *
- * [C] Event: An application calls ConnectivityManager#reportBadNetwork().
- * Mechanics:
- * [1] NetworkMonitor is notified and initiates a reevaluation, which
- * always bypasses Private DNS.
- * [2] Once completed, NetworkMonitor checks if strict mode is in operation
- * and if so enqueues another evaluation of Private DNS, as if from
- * step A.5 above.
- *
- * @hide
- */
-public class DnsManager {
- private static final String TAG = DnsManager.class.getSimpleName();
- private static final PrivateDnsConfig PRIVATE_DNS_OFF = new PrivateDnsConfig();
-
- /* Defaults for resolver parameters. */
- private static final int DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS = 1800;
- private static final int DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT = 25;
- private static final int DNS_RESOLVER_DEFAULT_MIN_SAMPLES = 8;
- private static final int DNS_RESOLVER_DEFAULT_MAX_SAMPLES = 64;
-
- /**
- * Get PrivateDnsConfig.
- */
- public static PrivateDnsConfig getPrivateDnsConfig(Context context) {
- final int mode = ConnectivitySettingsManager.getPrivateDnsMode(context);
-
- final boolean useTls = mode != PRIVATE_DNS_MODE_OFF;
-
- if (PRIVATE_DNS_MODE_PROVIDER_HOSTNAME == mode) {
- final String specifier = getStringSetting(context.getContentResolver(),
- PRIVATE_DNS_SPECIFIER);
- return new PrivateDnsConfig(specifier, null);
- }
-
- return new PrivateDnsConfig(useTls);
- }
-
- public static Uri[] getPrivateDnsSettingsUris() {
- return new Uri[]{
- Settings.Global.getUriFor(PRIVATE_DNS_DEFAULT_MODE),
- Settings.Global.getUriFor(PRIVATE_DNS_MODE),
- Settings.Global.getUriFor(PRIVATE_DNS_SPECIFIER),
- };
- }
-
- public static class PrivateDnsValidationUpdate {
- public final int netId;
- public final InetAddress ipAddress;
- public final String hostname;
- // Refer to IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_*.
- public final int validationResult;
-
- public PrivateDnsValidationUpdate(int netId, InetAddress ipAddress,
- String hostname, int validationResult) {
- this.netId = netId;
- this.ipAddress = ipAddress;
- this.hostname = hostname;
- this.validationResult = validationResult;
- }
- }
-
- private static class PrivateDnsValidationStatuses {
- enum ValidationStatus {
- IN_PROGRESS,
- FAILED,
- SUCCEEDED
- }
-
- // Validation statuses of <hostname, ipAddress> pairs for a single netId
- // Caution : not thread-safe. As mentioned in the top file comment, all
- // methods of this class must only be called on ConnectivityService's thread.
- private Map<Pair<String, InetAddress>, ValidationStatus> mValidationMap;
-
- private PrivateDnsValidationStatuses() {
- mValidationMap = new HashMap<>();
- }
-
- private boolean hasValidatedServer() {
- for (ValidationStatus status : mValidationMap.values()) {
- if (status == ValidationStatus.SUCCEEDED) {
- return true;
- }
- }
- return false;
- }
-
- private void updateTrackedDnses(String[] ipAddresses, String hostname) {
- Set<Pair<String, InetAddress>> latestDnses = new HashSet<>();
- for (String ipAddress : ipAddresses) {
- try {
- latestDnses.add(new Pair(hostname,
- InetAddresses.parseNumericAddress(ipAddress)));
- } catch (IllegalArgumentException e) {}
- }
- // Remove <hostname, ipAddress> pairs that should not be tracked.
- for (Iterator<Map.Entry<Pair<String, InetAddress>, ValidationStatus>> it =
- mValidationMap.entrySet().iterator(); it.hasNext(); ) {
- Map.Entry<Pair<String, InetAddress>, ValidationStatus> entry = it.next();
- if (!latestDnses.contains(entry.getKey())) {
- it.remove();
- }
- }
- // Add new <hostname, ipAddress> pairs that should be tracked.
- for (Pair<String, InetAddress> p : latestDnses) {
- if (!mValidationMap.containsKey(p)) {
- mValidationMap.put(p, ValidationStatus.IN_PROGRESS);
- }
- }
- }
-
- private void updateStatus(PrivateDnsValidationUpdate update) {
- Pair<String, InetAddress> p = new Pair(update.hostname,
- update.ipAddress);
- if (!mValidationMap.containsKey(p)) {
- return;
- }
- if (update.validationResult == VALIDATION_RESULT_SUCCESS) {
- mValidationMap.put(p, ValidationStatus.SUCCEEDED);
- } else if (update.validationResult == VALIDATION_RESULT_FAILURE) {
- mValidationMap.put(p, ValidationStatus.FAILED);
- } else {
- Log.e(TAG, "Unknown private dns validation operation="
- + update.validationResult);
- }
- }
-
- private LinkProperties fillInValidatedPrivateDns(LinkProperties lp) {
- lp.setValidatedPrivateDnsServers(Collections.EMPTY_LIST);
- mValidationMap.forEach((key, value) -> {
- if (value == ValidationStatus.SUCCEEDED) {
- lp.addValidatedPrivateDnsServer(key.second);
- }
- });
- return lp;
- }
- }
-
- private final Context mContext;
- private final ContentResolver mContentResolver;
- private final IDnsResolver mDnsResolver;
- private final ConcurrentHashMap<Integer, PrivateDnsConfig> mPrivateDnsMap;
- // TODO: Replace the Map with SparseArrays.
- private final Map<Integer, PrivateDnsValidationStatuses> mPrivateDnsValidationMap;
- private final Map<Integer, LinkProperties> mLinkPropertiesMap;
- private final Map<Integer, int[]> mTransportsMap;
-
- private int mSampleValidity;
- private int mSuccessThreshold;
- private int mMinSamples;
- private int mMaxSamples;
-
- public DnsManager(Context ctx, IDnsResolver dnsResolver) {
- mContext = ctx;
- mContentResolver = mContext.getContentResolver();
- mDnsResolver = dnsResolver;
- mPrivateDnsMap = new ConcurrentHashMap<>();
- mPrivateDnsValidationMap = new HashMap<>();
- mLinkPropertiesMap = new HashMap<>();
- mTransportsMap = new HashMap<>();
-
- // TODO: Create and register ContentObservers to track every setting
- // used herein, posting messages to respond to changes.
- }
-
- public PrivateDnsConfig getPrivateDnsConfig() {
- return getPrivateDnsConfig(mContext);
- }
-
- public void removeNetwork(Network network) {
- mPrivateDnsMap.remove(network.getNetId());
- mPrivateDnsValidationMap.remove(network.getNetId());
- mTransportsMap.remove(network.getNetId());
- mLinkPropertiesMap.remove(network.getNetId());
- }
-
- // This is exclusively called by ConnectivityService#dumpNetworkDiagnostics() which
- // is not on the ConnectivityService handler thread.
- public PrivateDnsConfig getPrivateDnsConfig(@NonNull Network network) {
- return mPrivateDnsMap.getOrDefault(network.getNetId(), PRIVATE_DNS_OFF);
- }
-
- public PrivateDnsConfig updatePrivateDns(Network network, PrivateDnsConfig cfg) {
- Log.w(TAG, "updatePrivateDns(" + network + ", " + cfg + ")");
- return (cfg != null)
- ? mPrivateDnsMap.put(network.getNetId(), cfg)
- : mPrivateDnsMap.remove(network.getNetId());
- }
-
- public void updatePrivateDnsStatus(int netId, LinkProperties lp) {
- // Use the PrivateDnsConfig data pushed to this class instance
- // from ConnectivityService.
- final PrivateDnsConfig privateDnsCfg = mPrivateDnsMap.getOrDefault(netId,
- PRIVATE_DNS_OFF);
-
- final boolean useTls = privateDnsCfg.useTls;
- final PrivateDnsValidationStatuses statuses =
- useTls ? mPrivateDnsValidationMap.get(netId) : null;
- final boolean validated = (null != statuses) && statuses.hasValidatedServer();
- final boolean strictMode = privateDnsCfg.inStrictMode();
- final String tlsHostname = strictMode ? privateDnsCfg.hostname : null;
- final boolean usingPrivateDns = strictMode || validated;
-
- lp.setUsePrivateDns(usingPrivateDns);
- lp.setPrivateDnsServerName(tlsHostname);
- if (usingPrivateDns && null != statuses) {
- statuses.fillInValidatedPrivateDns(lp);
- } else {
- lp.setValidatedPrivateDnsServers(Collections.EMPTY_LIST);
- }
- }
-
- public void updatePrivateDnsValidation(PrivateDnsValidationUpdate update) {
- final PrivateDnsValidationStatuses statuses = mPrivateDnsValidationMap.get(update.netId);
- if (statuses == null) return;
- statuses.updateStatus(update);
- }
-
- /**
- * When creating a new network or transport types are changed in a specific network,
- * transport types are always saved to a hashMap before update dns config.
- * When destroying network, the specific network will be removed from the hashMap.
- * The hashMap is always accessed on the same thread.
- */
- public void updateTransportsForNetwork(int netId, @NonNull int[] transportTypes) {
- mTransportsMap.put(netId, transportTypes);
- sendDnsConfigurationForNetwork(netId);
- }
-
- /**
- * When {@link LinkProperties} are changed in a specific network, they are
- * always saved to a hashMap before update dns config.
- * When destroying network, the specific network will be removed from the hashMap.
- * The hashMap is always accessed on the same thread.
- */
- public void noteDnsServersForNetwork(int netId, @NonNull LinkProperties lp) {
- mLinkPropertiesMap.put(netId, lp);
- sendDnsConfigurationForNetwork(netId);
- }
-
- /**
- * Send dns configuration parameters to resolver for a given network.
- */
- public void sendDnsConfigurationForNetwork(int netId) {
- final LinkProperties lp = mLinkPropertiesMap.get(netId);
- final int[] transportTypes = mTransportsMap.get(netId);
- if (lp == null || transportTypes == null) return;
- updateParametersSettings();
- final ResolverParamsParcel paramsParcel = new ResolverParamsParcel();
-
- // We only use the PrivateDnsConfig data pushed to this class instance
- // from ConnectivityService because it works in coordination with
- // NetworkMonitor to decide which networks need validation and runs the
- // blocking calls to resolve Private DNS strict mode hostnames.
- //
- // At this time we do not attempt to enable Private DNS on non-Internet
- // networks like IMS.
- final PrivateDnsConfig privateDnsCfg = mPrivateDnsMap.getOrDefault(netId,
- PRIVATE_DNS_OFF);
- final boolean useTls = privateDnsCfg.useTls;
- final boolean strictMode = privateDnsCfg.inStrictMode();
-
- paramsParcel.netId = netId;
- paramsParcel.sampleValiditySeconds = mSampleValidity;
- paramsParcel.successThreshold = mSuccessThreshold;
- paramsParcel.minSamples = mMinSamples;
- paramsParcel.maxSamples = mMaxSamples;
- paramsParcel.servers = makeStrings(lp.getDnsServers());
- paramsParcel.domains = getDomainStrings(lp.getDomains());
- paramsParcel.tlsName = strictMode ? privateDnsCfg.hostname : "";
- paramsParcel.tlsServers =
- strictMode ? makeStrings(
- Arrays.stream(privateDnsCfg.ips)
- .filter((ip) -> lp.isReachable(ip))
- .collect(Collectors.toList()))
- : useTls ? paramsParcel.servers // Opportunistic
- : new String[0]; // Off
- paramsParcel.resolverOptions = new ResolverOptionsParcel();
- paramsParcel.transportTypes = transportTypes;
- // Prepare to track the validation status of the DNS servers in the
- // resolver config when private DNS is in opportunistic or strict mode.
- if (useTls) {
- if (!mPrivateDnsValidationMap.containsKey(netId)) {
- mPrivateDnsValidationMap.put(netId, new PrivateDnsValidationStatuses());
- }
- mPrivateDnsValidationMap.get(netId).updateTrackedDnses(paramsParcel.tlsServers,
- paramsParcel.tlsName);
- } else {
- mPrivateDnsValidationMap.remove(netId);
- }
-
- Log.d(TAG, String.format("sendDnsConfigurationForNetwork(%d, %s, %s, %d, %d, %d, %d, "
- + "%d, %d, %s, %s)", paramsParcel.netId, Arrays.toString(paramsParcel.servers),
- Arrays.toString(paramsParcel.domains), paramsParcel.sampleValiditySeconds,
- paramsParcel.successThreshold, paramsParcel.minSamples,
- paramsParcel.maxSamples, paramsParcel.baseTimeoutMsec,
- paramsParcel.retryCount, paramsParcel.tlsName,
- Arrays.toString(paramsParcel.tlsServers)));
-
- try {
- mDnsResolver.setResolverConfiguration(paramsParcel);
- } catch (RemoteException | ServiceSpecificException e) {
- Log.e(TAG, "Error setting DNS configuration: " + e);
- return;
- }
- }
-
- /**
- * Flush DNS caches and events work before boot has completed.
- */
- public void flushVmDnsCache() {
- /*
- * Tell the VMs to toss their DNS caches
- */
- final Intent intent = new Intent(ConnectivityManager.ACTION_CLEAR_DNS_CACHE);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- /*
- * Connectivity events can happen before boot has completed ...
- */
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- final long ident = Binder.clearCallingIdentity();
- try {
- mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- private void updateParametersSettings() {
- mSampleValidity = getIntSetting(
- DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS,
- DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS);
- if (mSampleValidity < 0 || mSampleValidity > 65535) {
- Log.w(TAG, "Invalid sampleValidity=" + mSampleValidity + ", using default="
- + DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS);
- mSampleValidity = DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS;
- }
-
- mSuccessThreshold = getIntSetting(
- DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT,
- DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT);
- if (mSuccessThreshold < 0 || mSuccessThreshold > 100) {
- Log.w(TAG, "Invalid successThreshold=" + mSuccessThreshold + ", using default="
- + DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT);
- mSuccessThreshold = DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT;
- }
-
- mMinSamples = getIntSetting(DNS_RESOLVER_MIN_SAMPLES, DNS_RESOLVER_DEFAULT_MIN_SAMPLES);
- mMaxSamples = getIntSetting(DNS_RESOLVER_MAX_SAMPLES, DNS_RESOLVER_DEFAULT_MAX_SAMPLES);
- if (mMinSamples < 0 || mMinSamples > mMaxSamples || mMaxSamples > 64) {
- Log.w(TAG, "Invalid sample count (min, max)=(" + mMinSamples + ", " + mMaxSamples
- + "), using default=(" + DNS_RESOLVER_DEFAULT_MIN_SAMPLES + ", "
- + DNS_RESOLVER_DEFAULT_MAX_SAMPLES + ")");
- mMinSamples = DNS_RESOLVER_DEFAULT_MIN_SAMPLES;
- mMaxSamples = DNS_RESOLVER_DEFAULT_MAX_SAMPLES;
- }
- }
-
- private int getIntSetting(String which, int dflt) {
- return Settings.Global.getInt(mContentResolver, which, dflt);
- }
-
- /**
- * Create a string array of host addresses from a collection of InetAddresses
- *
- * @param addrs a Collection of InetAddresses
- * @return an array of Strings containing their host addresses
- */
- private String[] makeStrings(Collection<InetAddress> addrs) {
- String[] result = new String[addrs.size()];
- int i = 0;
- for (InetAddress addr : addrs) {
- result[i++] = addr.getHostAddress();
- }
- return result;
- }
-
- private static String getStringSetting(ContentResolver cr, String which) {
- return Settings.Global.getString(cr, which);
- }
-
- private static String[] getDomainStrings(String domains) {
- return (TextUtils.isEmpty(domains)) ? new String[0] : domains.split(" ");
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/FullScore.java b/packages/Connectivity/service/src/com/android/server/connectivity/FullScore.java
deleted file mode 100644
index fbfa7a1..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/FullScore.java
+++ /dev/null
@@ -1,344 +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 static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
-import static android.net.NetworkCapabilities.TRANSPORT_VPN;
-import static android.net.NetworkScore.KEEP_CONNECTED_NONE;
-import static android.net.NetworkScore.POLICY_EXITING;
-import static android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY;
-import static android.net.NetworkScore.POLICY_YIELD_TO_BAD_WIFI;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.net.NetworkAgentConfig;
-import android.net.NetworkCapabilities;
-import android.net.NetworkScore;
-import android.net.NetworkScore.KeepConnectedReason;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.StringJoiner;
-
-/**
- * This class represents how desirable a network is.
- *
- * FullScore is very similar to NetworkScore, but it contains the bits that are managed
- * by ConnectivityService. This provides static guarantee that all users must know whether
- * they are handling a score that had the CS-managed bits set.
- */
-public class FullScore {
- // This will be removed soon. Do *NOT* depend on it for any new code that is not part of
- // a migration.
- private final int mLegacyInt;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"POLICY_"}, value = {
- POLICY_IS_VALIDATED,
- POLICY_IS_VPN,
- POLICY_EVER_USER_SELECTED,
- POLICY_ACCEPT_UNVALIDATED,
- POLICY_IS_UNMETERED
- })
- public @interface Policy {
- }
-
- // Agent-managed policies are in NetworkScore. They start from 1.
- // CS-managed policies, counting from 63 downward
- // This network is validated. CS-managed because the source of truth is in NetworkCapabilities.
- /** @hide */
- public static final int POLICY_IS_VALIDATED = 63;
-
- // This is a VPN and behaves as one for scoring purposes.
- /** @hide */
- public static final int POLICY_IS_VPN = 62;
-
- // This network has been selected by the user manually from settings or a 3rd party app
- // at least once. {@see NetworkAgentConfig#explicitlySelected}.
- /** @hide */
- public static final int POLICY_EVER_USER_SELECTED = 61;
-
- // The user has indicated in UI that this network should be used even if it doesn't
- // validate. {@see NetworkAgentConfig#acceptUnvalidated}.
- /** @hide */
- public static final int POLICY_ACCEPT_UNVALIDATED = 60;
-
- // This network is unmetered. {@see NetworkCapabilities.NET_CAPABILITY_NOT_METERED}.
- /** @hide */
- public static final int POLICY_IS_UNMETERED = 59;
-
- // This network is invincible. This is useful for offers until there is an API to listen
- // to requests.
- /** @hide */
- public static final int POLICY_IS_INVINCIBLE = 58;
-
- // This network has been validated at least once since it was connected, but not explicitly
- // avoided in UI.
- // TODO : remove setAvoidUnvalidated and instead disconnect the network when the user
- // chooses to move away from this network, and remove this flag.
- /** @hide */
- public static final int POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD = 57;
-
- // To help iterate when printing
- @VisibleForTesting
- static final int MIN_CS_MANAGED_POLICY = POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD;
- @VisibleForTesting
- static final int MAX_CS_MANAGED_POLICY = POLICY_IS_VALIDATED;
-
- // Mask for policies in NetworkScore. This should have all bits managed by NetworkScore set
- // and all bits managed by FullScore unset. As bits are handled from 0 up in NetworkScore and
- // from 63 down in FullScore, cut at the 32nd bit for simplicity, but change this if some day
- // there are more than 32 bits handled on either side.
- // YIELD_TO_BAD_WIFI is temporarily handled by ConnectivityService, but the factory is still
- // allowed to set it, so that it's possible to transition from handling it in CS to handling
- // it in the factory.
- private static final long EXTERNAL_POLICIES_MASK = 0x00000000FFFFFFFFL;
-
- @VisibleForTesting
- static @NonNull String policyNameOf(final int policy) {
- switch (policy) {
- case POLICY_IS_VALIDATED: return "IS_VALIDATED";
- case POLICY_IS_VPN: return "IS_VPN";
- case POLICY_EVER_USER_SELECTED: return "EVER_USER_SELECTED";
- case POLICY_ACCEPT_UNVALIDATED: return "ACCEPT_UNVALIDATED";
- case POLICY_IS_UNMETERED: return "IS_UNMETERED";
- case POLICY_YIELD_TO_BAD_WIFI: return "YIELD_TO_BAD_WIFI";
- case POLICY_TRANSPORT_PRIMARY: return "TRANSPORT_PRIMARY";
- case POLICY_EXITING: return "EXITING";
- case POLICY_IS_INVINCIBLE: return "INVINCIBLE";
- case POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD: return "EVER_VALIDATED";
- }
- throw new IllegalArgumentException("Unknown policy : " + policy);
- }
-
- // Bitmask of all the policies applied to this score.
- private final long mPolicies;
-
- private final int mKeepConnectedReason;
-
- FullScore(final int legacyInt, final long policies,
- @KeepConnectedReason final int keepConnectedReason) {
- mLegacyInt = legacyInt;
- mPolicies = policies;
- mKeepConnectedReason = keepConnectedReason;
- }
-
- /**
- * Given a score supplied by the NetworkAgent and CS-managed objects, produce a full score.
- *
- * @param score the score supplied by the agent
- * @param caps the NetworkCapabilities of the network
- * @param config the NetworkAgentConfig of the network
- * @param everValidated whether this network has ever validated
- * @param yieldToBadWiFi whether this network yields to a previously validated wifi gone bad
- * @return a FullScore that is appropriate to use for ranking.
- */
- // TODO : this shouldn't manage bad wifi avoidance – instead this should be done by the
- // telephony factory, so that it depends on the carrier. For now this is handled by
- // connectivity for backward compatibility.
- public static FullScore fromNetworkScore(@NonNull final NetworkScore score,
- @NonNull final NetworkCapabilities caps, @NonNull final NetworkAgentConfig config,
- final boolean everValidated, final boolean yieldToBadWiFi) {
- return withPolicies(score.getLegacyInt(), score.getPolicies(),
- score.getKeepConnectedReason(),
- caps.hasCapability(NET_CAPABILITY_VALIDATED),
- caps.hasTransport(TRANSPORT_VPN),
- caps.hasCapability(NET_CAPABILITY_NOT_METERED),
- everValidated,
- config.explicitlySelected,
- config.acceptUnvalidated,
- yieldToBadWiFi,
- false /* invincible */); // only prospective scores can be invincible
- }
-
- /**
- * Given a score supplied by a NetworkProvider, produce a prospective score for an offer.
- *
- * NetworkOffers have score filters that are compared to the scores of actual networks
- * to see if they could possibly beat the current satisfier. Some things the agent can't
- * know in advance ; a good example is the validation bit – some networks will validate,
- * others won't. For comparison purposes, assume the best, so all possibly beneficial
- * networks will be brought up.
- *
- * @param score the score supplied by the agent for this offer
- * @param caps the capabilities supplied by the agent for this offer
- * @return a FullScore appropriate for comparing to actual network's scores.
- */
- public static FullScore makeProspectiveScore(@NonNull final NetworkScore score,
- @NonNull final NetworkCapabilities caps) {
- // If the network offers Internet access, it may validate.
- final boolean mayValidate = caps.hasCapability(NET_CAPABILITY_INTERNET);
- // VPN transports are known in advance.
- final boolean vpn = caps.hasTransport(TRANSPORT_VPN);
- // Prospective scores are always unmetered, because unmetered networks are stronger
- // than metered networks, and it's not known in advance whether the network is metered.
- final boolean unmetered = true;
- // If the offer may validate, then it should be considered to have validated at some point
- final boolean everValidated = mayValidate;
- // The network hasn't been chosen by the user (yet, at least).
- final boolean everUserSelected = false;
- // Don't assume the user will accept unvalidated connectivity.
- final boolean acceptUnvalidated = false;
- // Don't assume clinging to bad wifi
- final boolean yieldToBadWiFi = false;
- // A prospective score is invincible if the legacy int in the filter is over the maximum
- // score.
- final boolean invincible = score.getLegacyInt() > NetworkRanker.LEGACY_INT_MAX;
- return withPolicies(score.getLegacyInt(), score.getPolicies(), KEEP_CONNECTED_NONE,
- mayValidate, vpn, unmetered, everValidated, everUserSelected, acceptUnvalidated,
- yieldToBadWiFi, invincible);
- }
-
- /**
- * Return a new score given updated caps and config.
- *
- * @param caps the NetworkCapabilities of the network
- * @param config the NetworkAgentConfig of the network
- * @return a score with the policies from the arguments reset
- */
- // TODO : this shouldn't manage bad wifi avoidance – instead this should be done by the
- // telephony factory, so that it depends on the carrier. For now this is handled by
- // connectivity for backward compatibility.
- public FullScore mixInScore(@NonNull final NetworkCapabilities caps,
- @NonNull final NetworkAgentConfig config,
- final boolean everValidated,
- final boolean yieldToBadWifi) {
- return withPolicies(mLegacyInt, mPolicies, mKeepConnectedReason,
- caps.hasCapability(NET_CAPABILITY_VALIDATED),
- caps.hasTransport(TRANSPORT_VPN),
- caps.hasCapability(NET_CAPABILITY_NOT_METERED),
- everValidated,
- config.explicitlySelected,
- config.acceptUnvalidated,
- yieldToBadWifi,
- false /* invincible */); // only prospective scores can be invincible
- }
-
- // TODO : this shouldn't manage bad wifi avoidance – instead this should be done by the
- // telephony factory, so that it depends on the carrier. For now this is handled by
- // connectivity for backward compatibility.
- private static FullScore withPolicies(@NonNull final int legacyInt,
- final long externalPolicies,
- @KeepConnectedReason final int keepConnectedReason,
- final boolean isValidated,
- final boolean isVpn,
- final boolean isUnmetered,
- final boolean everValidated,
- final boolean everUserSelected,
- final boolean acceptUnvalidated,
- final boolean yieldToBadWiFi,
- final boolean invincible) {
- return new FullScore(legacyInt, (externalPolicies & EXTERNAL_POLICIES_MASK)
- | (isValidated ? 1L << POLICY_IS_VALIDATED : 0)
- | (isVpn ? 1L << POLICY_IS_VPN : 0)
- | (isUnmetered ? 1L << POLICY_IS_UNMETERED : 0)
- | (everValidated ? 1L << POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD : 0)
- | (everUserSelected ? 1L << POLICY_EVER_USER_SELECTED : 0)
- | (acceptUnvalidated ? 1L << POLICY_ACCEPT_UNVALIDATED : 0)
- | (yieldToBadWiFi ? 1L << POLICY_YIELD_TO_BAD_WIFI : 0)
- | (invincible ? 1L << POLICY_IS_INVINCIBLE : 0),
- keepConnectedReason);
- }
-
- /**
- * Returns this score but validated.
- */
- public FullScore asValidated() {
- return new FullScore(mLegacyInt, mPolicies | (1L << POLICY_IS_VALIDATED),
- mKeepConnectedReason);
- }
-
- /**
- * For backward compatibility, get the legacy int.
- * This will be removed before S is published.
- */
- public int getLegacyInt() {
- return getLegacyInt(false /* pretendValidated */);
- }
-
- public int getLegacyIntAsValidated() {
- return getLegacyInt(true /* pretendValidated */);
- }
-
- // TODO : remove these two constants
- // Penalty applied to scores of Networks that have not been validated.
- private static final int UNVALIDATED_SCORE_PENALTY = 40;
-
- // Score for a network that can be used unvalidated
- private static final int ACCEPT_UNVALIDATED_NETWORK_SCORE = 100;
-
- private int getLegacyInt(boolean pretendValidated) {
- // If the user has chosen this network at least once, give it the maximum score when
- // checking to pretend it's validated, or if it doesn't need to validate because the
- // user said to use it even if it doesn't validate.
- // This ensures that networks that have been selected in UI are not torn down before the
- // user gets a chance to prefer it when a higher-scoring network (e.g., Ethernet) is
- // available.
- if (hasPolicy(POLICY_EVER_USER_SELECTED)
- && (hasPolicy(POLICY_ACCEPT_UNVALIDATED) || pretendValidated)) {
- return ACCEPT_UNVALIDATED_NETWORK_SCORE;
- }
-
- int score = mLegacyInt;
- // Except for VPNs, networks are subject to a penalty for not being validated.
- // Apply the penalty unless the network is a VPN, or it's validated or pretending to be.
- if (!hasPolicy(POLICY_IS_VALIDATED) && !pretendValidated && !hasPolicy(POLICY_IS_VPN)) {
- score -= UNVALIDATED_SCORE_PENALTY;
- }
- if (score < 0) score = 0;
- return score;
- }
-
- /**
- * @return whether this score has a particular policy.
- */
- @VisibleForTesting
- public boolean hasPolicy(final int policy) {
- return 0 != (mPolicies & (1L << policy));
- }
-
- /**
- * Returns the keep-connected reason, or KEEP_CONNECTED_NONE.
- */
- public int getKeepConnectedReason() {
- return mKeepConnectedReason;
- }
-
- // Example output :
- // Score(50 ; Policies : EVER_USER_SELECTED&IS_VALIDATED)
- @Override
- public String toString() {
- final StringJoiner sj = new StringJoiner(
- "&", // delimiter
- "Score(" + mLegacyInt + " ; KeepConnected : " + mKeepConnectedReason
- + " ; Policies : ", // prefix
- ")"); // suffix
- for (int i = NetworkScore.MIN_AGENT_MANAGED_POLICY;
- i <= NetworkScore.MAX_AGENT_MANAGED_POLICY; ++i) {
- if (hasPolicy(i)) sj.add(policyNameOf(i));
- }
- for (int i = MIN_CS_MANAGED_POLICY; i <= MAX_CS_MANAGED_POLICY; ++i) {
- if (hasPolicy(i)) sj.add(policyNameOf(i));
- }
- return sj.toString();
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/KeepaliveTracker.java b/packages/Connectivity/service/src/com/android/server/connectivity/KeepaliveTracker.java
deleted file mode 100644
index 7d922a4..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/KeepaliveTracker.java
+++ /dev/null
@@ -1,761 +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.connectivity;
-
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.net.NattSocketKeepalive.NATT_PORT;
-import static android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE;
-import static android.net.SocketKeepalive.BINDER_DIED;
-import static android.net.SocketKeepalive.DATA_RECEIVED;
-import static android.net.SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES;
-import static android.net.SocketKeepalive.ERROR_INVALID_INTERVAL;
-import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
-import static android.net.SocketKeepalive.ERROR_INVALID_NETWORK;
-import static android.net.SocketKeepalive.ERROR_INVALID_SOCKET;
-import static android.net.SocketKeepalive.ERROR_NO_SUCH_SLOT;
-import static android.net.SocketKeepalive.ERROR_STOP_REASON_UNINITIALIZED;
-import static android.net.SocketKeepalive.ERROR_UNSUPPORTED;
-import static android.net.SocketKeepalive.MAX_INTERVAL_SEC;
-import static android.net.SocketKeepalive.MIN_INTERVAL_SEC;
-import static android.net.SocketKeepalive.NO_KEEPALIVE;
-import static android.net.SocketKeepalive.SUCCESS;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.ConnectivityResources;
-import android.net.ISocketKeepaliveCallback;
-import android.net.InetAddresses;
-import android.net.InvalidPacketException;
-import android.net.KeepalivePacketData;
-import android.net.NattKeepalivePacketData;
-import android.net.NetworkAgent;
-import android.net.SocketKeepalive.InvalidSocketException;
-import android.net.TcpKeepalivePacketData;
-import android.net.util.KeepaliveUtils;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Process;
-import android.os.RemoteException;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.connectivity.resources.R;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.net.module.util.HexDump;
-import com.android.net.module.util.IpUtils;
-
-import java.io.FileDescriptor;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-
-/**
- * Manages socket keepalive requests.
- *
- * Provides methods to stop and start keepalive requests, and keeps track of keepalives across all
- * networks. This class is tightly coupled to ConnectivityService. It is not thread-safe and its
- * handle* methods must be called only from the ConnectivityService handler thread.
- */
-public class KeepaliveTracker {
-
- private static final String TAG = "KeepaliveTracker";
- private static final boolean DBG = false;
-
- public static final String PERMISSION = android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD;
-
- /** Keeps track of keepalive requests. */
- private final HashMap <NetworkAgentInfo, HashMap<Integer, KeepaliveInfo>> mKeepalives =
- new HashMap<> ();
- private final Handler mConnectivityServiceHandler;
- @NonNull
- private final TcpKeepaliveController mTcpController;
- @NonNull
- private final Context mContext;
-
- // Supported keepalive count for each transport type, can be configured through
- // config_networkSupportedKeepaliveCount. For better error handling, use
- // {@link getSupportedKeepalivesForNetworkCapabilities} instead of direct access.
- @NonNull
- private final int[] mSupportedKeepalives;
-
- // Reserved privileged keepalive slots per transport. Caller's permission will be enforced if
- // the number of remaining keepalive slots is less than or equal to the threshold.
- private final int mReservedPrivilegedSlots;
-
- // Allowed unprivileged keepalive slots per uid. Caller's permission will be enforced if
- // the number of remaining keepalive slots is less than or equal to the threshold.
- private final int mAllowedUnprivilegedSlotsForUid;
-
- public KeepaliveTracker(Context context, Handler handler) {
- mConnectivityServiceHandler = handler;
- mTcpController = new TcpKeepaliveController(handler);
- mContext = context;
- mSupportedKeepalives = KeepaliveUtils.getSupportedKeepalives(mContext);
-
- final ConnectivityResources res = new ConnectivityResources(mContext);
- mReservedPrivilegedSlots = res.get().getInteger(
- R.integer.config_reservedPrivilegedKeepaliveSlots);
- mAllowedUnprivilegedSlotsForUid = res.get().getInteger(
- R.integer.config_allowedUnprivilegedKeepalivePerUid);
- }
-
- /**
- * Tracks information about a socket keepalive.
- *
- * All information about this keepalive is known at construction time except the slot number,
- * which is only returned when the hardware has successfully started the keepalive.
- */
- class KeepaliveInfo implements IBinder.DeathRecipient {
- // Bookkeeping data.
- private final ISocketKeepaliveCallback mCallback;
- private final int mUid;
- private final int mPid;
- private final boolean mPrivileged;
- private final NetworkAgentInfo mNai;
- private final int mType;
- private final FileDescriptor mFd;
-
- public static final int TYPE_NATT = 1;
- public static final int TYPE_TCP = 2;
-
- // Keepalive slot. A small integer that identifies this keepalive among the ones handled
- // by this network.
- private int mSlot = NO_KEEPALIVE;
-
- // Packet data.
- private final KeepalivePacketData mPacket;
- private final int mInterval;
-
- // Whether the keepalive is started or not. The initial state is NOT_STARTED.
- private static final int NOT_STARTED = 1;
- private static final int STARTING = 2;
- private static final int STARTED = 3;
- private static final int STOPPING = 4;
- private int mStartedState = NOT_STARTED;
- private int mStopReason = ERROR_STOP_REASON_UNINITIALIZED;
-
- KeepaliveInfo(@NonNull ISocketKeepaliveCallback callback,
- @NonNull NetworkAgentInfo nai,
- @NonNull KeepalivePacketData packet,
- int interval,
- int type,
- @Nullable FileDescriptor fd) throws InvalidSocketException {
- mCallback = callback;
- mPid = Binder.getCallingPid();
- mUid = Binder.getCallingUid();
- mPrivileged = (PERMISSION_GRANTED == mContext.checkPermission(PERMISSION, mPid, mUid));
-
- mNai = nai;
- mPacket = packet;
- mInterval = interval;
- mType = type;
-
- // For SocketKeepalive, a dup of fd is kept in mFd so the source port from which the
- // keepalives are sent cannot be reused by another app even if the fd gets closed by
- // the user. A null is acceptable here for backward compatibility of PacketKeepalive
- // API.
- try {
- if (fd != null) {
- mFd = Os.dup(fd);
- } else {
- Log.d(TAG, toString() + " calls with null fd");
- if (!mPrivileged) {
- throw new SecurityException(
- "null fd is not allowed for unprivileged access.");
- }
- if (mType == TYPE_TCP) {
- throw new IllegalArgumentException(
- "null fd is not allowed for tcp socket keepalives.");
- }
- mFd = null;
- }
- } catch (ErrnoException e) {
- Log.e(TAG, "Cannot dup fd: ", e);
- throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
- }
-
- try {
- mCallback.asBinder().linkToDeath(this, 0);
- } catch (RemoteException e) {
- binderDied();
- }
- }
-
- public NetworkAgentInfo getNai() {
- return mNai;
- }
-
- private String startedStateString(final int state) {
- switch (state) {
- case NOT_STARTED : return "NOT_STARTED";
- case STARTING : return "STARTING";
- case STARTED : return "STARTED";
- case STOPPING : return "STOPPING";
- }
- throw new IllegalArgumentException("Unknown state");
- }
-
- public String toString() {
- return "KeepaliveInfo ["
- + " type=" + mType
- + " network=" + mNai.network
- + " startedState=" + startedStateString(mStartedState)
- + " "
- + IpUtils.addressAndPortToString(mPacket.getSrcAddress(), mPacket.getSrcPort())
- + "->"
- + IpUtils.addressAndPortToString(mPacket.getDstAddress(), mPacket.getDstPort())
- + " interval=" + mInterval
- + " uid=" + mUid + " pid=" + mPid + " privileged=" + mPrivileged
- + " packetData=" + HexDump.toHexString(mPacket.getPacket())
- + " ]";
- }
-
- /** Called when the application process is killed. */
- public void binderDied() {
- stop(BINDER_DIED);
- }
-
- void unlinkDeathRecipient() {
- if (mCallback != null) {
- mCallback.asBinder().unlinkToDeath(this, 0);
- }
- }
-
- private int checkNetworkConnected() {
- if (!mNai.networkInfo.isConnectedOrConnecting()) {
- return ERROR_INVALID_NETWORK;
- }
- return SUCCESS;
- }
-
- private int checkSourceAddress() {
- // Check that we have the source address.
- for (InetAddress address : mNai.linkProperties.getAddresses()) {
- if (address.equals(mPacket.getSrcAddress())) {
- return SUCCESS;
- }
- }
- return ERROR_INVALID_IP_ADDRESS;
- }
-
- private int checkInterval() {
- if (mInterval < MIN_INTERVAL_SEC || mInterval > MAX_INTERVAL_SEC) {
- return ERROR_INVALID_INTERVAL;
- }
- return SUCCESS;
- }
-
- private int checkPermission() {
- final HashMap<Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(mNai);
- if (networkKeepalives == null) {
- return ERROR_INVALID_NETWORK;
- }
-
- if (mPrivileged) return SUCCESS;
-
- final int supported = KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities(
- mSupportedKeepalives, mNai.networkCapabilities);
-
- int takenUnprivilegedSlots = 0;
- for (final KeepaliveInfo ki : networkKeepalives.values()) {
- if (!ki.mPrivileged) ++takenUnprivilegedSlots;
- }
- if (takenUnprivilegedSlots > supported - mReservedPrivilegedSlots) {
- return ERROR_INSUFFICIENT_RESOURCES;
- }
-
- // Count unprivileged keepalives for the same uid across networks.
- int unprivilegedCountSameUid = 0;
- for (final HashMap<Integer, KeepaliveInfo> kaForNetwork : mKeepalives.values()) {
- for (final KeepaliveInfo ki : kaForNetwork.values()) {
- if (ki.mUid == mUid) {
- unprivilegedCountSameUid++;
- }
- }
- }
- if (unprivilegedCountSameUid > mAllowedUnprivilegedSlotsForUid) {
- return ERROR_INSUFFICIENT_RESOURCES;
- }
- return SUCCESS;
- }
-
- private int checkLimit() {
- final HashMap<Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(mNai);
- if (networkKeepalives == null) {
- return ERROR_INVALID_NETWORK;
- }
- final int supported = KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities(
- mSupportedKeepalives, mNai.networkCapabilities);
- if (supported == 0) return ERROR_UNSUPPORTED;
- if (networkKeepalives.size() > supported) return ERROR_INSUFFICIENT_RESOURCES;
- return SUCCESS;
- }
-
- private int isValid() {
- synchronized (mNai) {
- int error = checkInterval();
- if (error == SUCCESS) error = checkLimit();
- if (error == SUCCESS) error = checkPermission();
- if (error == SUCCESS) error = checkNetworkConnected();
- if (error == SUCCESS) error = checkSourceAddress();
- return error;
- }
- }
-
- void start(int slot) {
- mSlot = slot;
- int error = isValid();
- if (error == SUCCESS) {
- Log.d(TAG, "Starting keepalive " + mSlot + " on " + mNai.toShortString());
- switch (mType) {
- case TYPE_NATT:
- final NattKeepalivePacketData nattData = (NattKeepalivePacketData) mPacket;
- mNai.onAddNattKeepalivePacketFilter(slot, nattData);
- mNai.onStartNattSocketKeepalive(slot, mInterval, nattData);
- break;
- case TYPE_TCP:
- try {
- mTcpController.startSocketMonitor(mFd, this, mSlot);
- } catch (InvalidSocketException e) {
- handleStopKeepalive(mNai, mSlot, ERROR_INVALID_SOCKET);
- return;
- }
- final TcpKeepalivePacketData tcpData = (TcpKeepalivePacketData) mPacket;
- mNai.onAddTcpKeepalivePacketFilter(slot, tcpData);
- // TODO: check result from apf and notify of failure as needed.
- mNai.onStartTcpSocketKeepalive(slot, mInterval, tcpData);
- break;
- default:
- Log.wtf(TAG, "Starting keepalive with unknown type: " + mType);
- handleStopKeepalive(mNai, mSlot, error);
- return;
- }
- mStartedState = STARTING;
- } else {
- handleStopKeepalive(mNai, mSlot, error);
- return;
- }
- }
-
- void stop(int reason) {
- int uid = Binder.getCallingUid();
- if (uid != mUid && uid != Process.SYSTEM_UID) {
- if (DBG) {
- Log.e(TAG, "Cannot stop unowned keepalive " + mSlot + " on " + mNai.network);
- }
- }
- // Ignore the case when the network disconnects immediately after stop() has been
- // called and the keepalive code is waiting for the response from the modem. This
- // might happen when the caller listens for a lower-layer network disconnect
- // callback and stop the keepalive at that time. But the stop() races with the
- // stop() generated in ConnectivityService network disconnection code path.
- if (mStartedState == STOPPING && reason == ERROR_INVALID_NETWORK) return;
-
- // Store the reason of stopping, and report it after the keepalive is fully stopped.
- if (mStopReason != ERROR_STOP_REASON_UNINITIALIZED) {
- throw new IllegalStateException("Unexpected stop reason: " + mStopReason);
- }
- mStopReason = reason;
- Log.d(TAG, "Stopping keepalive " + mSlot + " on " + mNai.toShortString()
- + ": " + reason);
- switch (mStartedState) {
- case NOT_STARTED:
- // Remove the reference of the keepalive that meet error before starting,
- // e.g. invalid parameter.
- cleanupStoppedKeepalive(mNai, mSlot);
- break;
- default:
- mStartedState = STOPPING;
- switch (mType) {
- case TYPE_TCP:
- mTcpController.stopSocketMonitor(mSlot);
- // fall through
- case TYPE_NATT:
- mNai.onStopSocketKeepalive(mSlot);
- mNai.onRemoveKeepalivePacketFilter(mSlot);
- break;
- default:
- Log.wtf(TAG, "Stopping keepalive with unknown type: " + mType);
- }
- }
-
- // Close the duplicated fd that maintains the lifecycle of socket whenever
- // keepalive is running.
- if (mFd != null) {
- try {
- Os.close(mFd);
- } catch (ErrnoException e) {
- // This should not happen since system server controls the lifecycle of fd when
- // keepalive offload is running.
- Log.wtf(TAG, "Error closing fd for keepalive " + mSlot + ": " + e);
- }
- }
- }
-
- void onFileDescriptorInitiatedStop(final int socketKeepaliveReason) {
- handleStopKeepalive(mNai, mSlot, socketKeepaliveReason);
- }
- }
-
- void notifyErrorCallback(ISocketKeepaliveCallback cb, int error) {
- if (DBG) Log.w(TAG, "Sending onError(" + error + ") callback");
- try {
- cb.onError(error);
- } catch (RemoteException e) {
- Log.w(TAG, "Discarded onError(" + error + ") callback");
- }
- }
-
- private int findFirstFreeSlot(NetworkAgentInfo nai) {
- HashMap networkKeepalives = mKeepalives.get(nai);
- if (networkKeepalives == null) {
- networkKeepalives = new HashMap<Integer, KeepaliveInfo>();
- mKeepalives.put(nai, networkKeepalives);
- }
-
- // Find the lowest-numbered free slot. Slot numbers start from 1, because that's what two
- // separate chipset implementations independently came up with.
- int slot;
- for (slot = 1; slot <= networkKeepalives.size(); slot++) {
- if (networkKeepalives.get(slot) == null) {
- return slot;
- }
- }
- return slot;
- }
-
- public void handleStartKeepalive(Message message) {
- KeepaliveInfo ki = (KeepaliveInfo) message.obj;
- NetworkAgentInfo nai = ki.getNai();
- int slot = findFirstFreeSlot(nai);
- mKeepalives.get(nai).put(slot, ki);
- ki.start(slot);
- }
-
- public void handleStopAllKeepalives(NetworkAgentInfo nai, int reason) {
- final HashMap<Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(nai);
- if (networkKeepalives != null) {
- final ArrayList<KeepaliveInfo> kalist = new ArrayList(networkKeepalives.values());
- for (KeepaliveInfo ki : kalist) {
- ki.stop(reason);
- // Clean up keepalives since the network agent is disconnected and unable to pass
- // back asynchronous result of stop().
- cleanupStoppedKeepalive(nai, ki.mSlot);
- }
- }
- }
-
- public void handleStopKeepalive(NetworkAgentInfo nai, int slot, int reason) {
- final String networkName = NetworkAgentInfo.toShortString(nai);
- HashMap <Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(nai);
- if (networkKeepalives == null) {
- Log.e(TAG, "Attempt to stop keepalive on nonexistent network " + networkName);
- return;
- }
- KeepaliveInfo ki = networkKeepalives.get(slot);
- if (ki == null) {
- Log.e(TAG, "Attempt to stop nonexistent keepalive " + slot + " on " + networkName);
- return;
- }
- ki.stop(reason);
- // Clean up keepalives will be done as a result of calling ki.stop() after the slots are
- // freed.
- }
-
- private void cleanupStoppedKeepalive(NetworkAgentInfo nai, int slot) {
- final String networkName = NetworkAgentInfo.toShortString(nai);
- HashMap<Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(nai);
- if (networkKeepalives == null) {
- Log.e(TAG, "Attempt to remove keepalive on nonexistent network " + networkName);
- return;
- }
- KeepaliveInfo ki = networkKeepalives.get(slot);
- if (ki == null) {
- Log.e(TAG, "Attempt to remove nonexistent keepalive " + slot + " on " + networkName);
- return;
- }
-
- // Remove the keepalive from hash table so the slot can be considered available when reusing
- // it.
- networkKeepalives.remove(slot);
- Log.d(TAG, "Remove keepalive " + slot + " on " + networkName + ", "
- + networkKeepalives.size() + " remains.");
- if (networkKeepalives.isEmpty()) {
- mKeepalives.remove(nai);
- }
-
- // Notify app that the keepalive is stopped.
- final int reason = ki.mStopReason;
- if (reason == SUCCESS) {
- try {
- ki.mCallback.onStopped();
- } catch (RemoteException e) {
- Log.w(TAG, "Discarded onStop callback: " + reason);
- }
- } else if (reason == DATA_RECEIVED) {
- try {
- ki.mCallback.onDataReceived();
- } catch (RemoteException e) {
- Log.w(TAG, "Discarded onDataReceived callback: " + reason);
- }
- } else if (reason == ERROR_STOP_REASON_UNINITIALIZED) {
- throw new IllegalStateException("Unexpected stop reason: " + reason);
- } else if (reason == ERROR_NO_SUCH_SLOT) {
- throw new IllegalStateException("No such slot: " + reason);
- } else {
- notifyErrorCallback(ki.mCallback, reason);
- }
-
- ki.unlinkDeathRecipient();
- }
-
- public void handleCheckKeepalivesStillValid(NetworkAgentInfo nai) {
- HashMap <Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(nai);
- if (networkKeepalives != null) {
- ArrayList<Pair<Integer, Integer>> invalidKeepalives = new ArrayList<>();
- for (int slot : networkKeepalives.keySet()) {
- int error = networkKeepalives.get(slot).isValid();
- if (error != SUCCESS) {
- invalidKeepalives.add(Pair.create(slot, error));
- }
- }
- for (Pair<Integer, Integer> slotAndError: invalidKeepalives) {
- handleStopKeepalive(nai, slotAndError.first, slotAndError.second);
- }
- }
- }
-
- /** Handle keepalive events from lower layer. */
- public void handleEventSocketKeepalive(@NonNull NetworkAgentInfo nai, int slot, int reason) {
- KeepaliveInfo ki = null;
- try {
- ki = mKeepalives.get(nai).get(slot);
- } catch(NullPointerException e) {}
- if (ki == null) {
- Log.e(TAG, "Event " + NetworkAgent.EVENT_SOCKET_KEEPALIVE + "," + slot + "," + reason
- + " for unknown keepalive " + slot + " on " + nai.toShortString());
- return;
- }
-
- // This can be called in a number of situations :
- // - startedState is STARTING.
- // - reason is SUCCESS => go to STARTED.
- // - reason isn't SUCCESS => it's an error starting. Go to NOT_STARTED and stop keepalive.
- // - startedState is STARTED.
- // - reason is SUCCESS => it's a success stopping. Go to NOT_STARTED and stop keepalive.
- // - reason isn't SUCCESS => it's an error in exec. Go to NOT_STARTED and stop keepalive.
- // The control is not supposed to ever come here if the state is NOT_STARTED. This is
- // because in NOT_STARTED state, the code will switch to STARTING before sending messages
- // to start, and the only way to NOT_STARTED is this function, through the edges outlined
- // above : in all cases, keepalive gets stopped and can't restart without going into
- // STARTING as messages are ordered. This also depends on the hardware processing the
- // messages in order.
- // TODO : clarify this code and get rid of mStartedState. Using a StateMachine is an
- // option.
- if (KeepaliveInfo.STARTING == ki.mStartedState) {
- if (SUCCESS == reason) {
- // Keepalive successfully started.
- Log.d(TAG, "Started keepalive " + slot + " on " + nai.toShortString());
- ki.mStartedState = KeepaliveInfo.STARTED;
- try {
- ki.mCallback.onStarted(slot);
- } catch (RemoteException e) {
- Log.w(TAG, "Discarded onStarted(" + slot + ") callback");
- }
- } else {
- Log.d(TAG, "Failed to start keepalive " + slot + " on " + nai.toShortString()
- + ": " + reason);
- // The message indicated some error trying to start: do call handleStopKeepalive.
- handleStopKeepalive(nai, slot, reason);
- }
- } else if (KeepaliveInfo.STOPPING == ki.mStartedState) {
- // The message indicated result of stopping : clean up keepalive slots.
- Log.d(TAG, "Stopped keepalive " + slot + " on " + nai.toShortString()
- + " stopped: " + reason);
- ki.mStartedState = KeepaliveInfo.NOT_STARTED;
- cleanupStoppedKeepalive(nai, slot);
- } else {
- Log.wtf(TAG, "Event " + NetworkAgent.EVENT_SOCKET_KEEPALIVE + "," + slot + "," + reason
- + " for keepalive in wrong state: " + ki.toString());
- }
- }
-
- /**
- * Called when requesting that keepalives be started on a IPsec NAT-T socket. See
- * {@link android.net.SocketKeepalive}.
- **/
- public void startNattKeepalive(@Nullable NetworkAgentInfo nai,
- @Nullable FileDescriptor fd,
- int intervalSeconds,
- @NonNull ISocketKeepaliveCallback cb,
- @NonNull String srcAddrString,
- int srcPort,
- @NonNull String dstAddrString,
- int dstPort) {
- if (nai == null) {
- notifyErrorCallback(cb, ERROR_INVALID_NETWORK);
- return;
- }
-
- InetAddress srcAddress, dstAddress;
- try {
- srcAddress = InetAddresses.parseNumericAddress(srcAddrString);
- dstAddress = InetAddresses.parseNumericAddress(dstAddrString);
- } catch (IllegalArgumentException e) {
- notifyErrorCallback(cb, ERROR_INVALID_IP_ADDRESS);
- return;
- }
-
- KeepalivePacketData packet;
- try {
- packet = NattKeepalivePacketData.nattKeepalivePacket(
- srcAddress, srcPort, dstAddress, NATT_PORT);
- } catch (InvalidPacketException e) {
- notifyErrorCallback(cb, e.getError());
- return;
- }
- KeepaliveInfo ki = null;
- try {
- ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
- KeepaliveInfo.TYPE_NATT, fd);
- } catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
- Log.e(TAG, "Fail to construct keepalive", e);
- notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
- return;
- }
- Log.d(TAG, "Created keepalive: " + ki.toString());
- mConnectivityServiceHandler.obtainMessage(
- NetworkAgent.CMD_START_SOCKET_KEEPALIVE, ki).sendToTarget();
- }
-
- /**
- * Called by ConnectivityService to start TCP keepalive on a file descriptor.
- *
- * In order to offload keepalive for application correctly, sequence number, ack number and
- * other fields are needed to form the keepalive packet. Thus, this function synchronously
- * puts the socket into repair mode to get the necessary information. After the socket has been
- * put into repair mode, the application cannot access the socket until reverted to normal.
- *
- * See {@link android.net.SocketKeepalive}.
- **/
- public void startTcpKeepalive(@Nullable NetworkAgentInfo nai,
- @NonNull FileDescriptor fd,
- int intervalSeconds,
- @NonNull ISocketKeepaliveCallback cb) {
- if (nai == null) {
- notifyErrorCallback(cb, ERROR_INVALID_NETWORK);
- return;
- }
-
- final TcpKeepalivePacketData packet;
- try {
- packet = TcpKeepaliveController.getTcpKeepalivePacket(fd);
- } catch (InvalidSocketException e) {
- notifyErrorCallback(cb, e.error);
- return;
- } catch (InvalidPacketException e) {
- notifyErrorCallback(cb, e.getError());
- return;
- }
- KeepaliveInfo ki = null;
- try {
- ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
- KeepaliveInfo.TYPE_TCP, fd);
- } catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
- Log.e(TAG, "Fail to construct keepalive e=" + e);
- notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
- return;
- }
- Log.d(TAG, "Created keepalive: " + ki.toString());
- mConnectivityServiceHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, ki).sendToTarget();
- }
-
- /**
- * Called when requesting that keepalives be started on a IPsec NAT-T socket. This function is
- * identical to {@link #startNattKeepalive}, but also takes a {@code resourceId}, which is the
- * resource index bound to the {@link UdpEncapsulationSocket} when creating by
- * {@link com.android.server.IpSecService} to verify whether the given
- * {@link UdpEncapsulationSocket} is legitimate.
- **/
- public void startNattKeepalive(@Nullable NetworkAgentInfo nai,
- @Nullable FileDescriptor fd,
- int resourceId,
- int intervalSeconds,
- @NonNull ISocketKeepaliveCallback cb,
- @NonNull String srcAddrString,
- @NonNull String dstAddrString,
- int dstPort) {
- // Ensure that the socket is created by IpSecService.
- if (!isNattKeepaliveSocketValid(fd, resourceId)) {
- notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
- }
-
- // Get src port to adopt old API.
- int srcPort = 0;
- try {
- final SocketAddress srcSockAddr = Os.getsockname(fd);
- srcPort = ((InetSocketAddress) srcSockAddr).getPort();
- } catch (ErrnoException e) {
- notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
- }
-
- // Forward request to old API.
- startNattKeepalive(nai, fd, intervalSeconds, cb, srcAddrString, srcPort,
- dstAddrString, dstPort);
- }
-
- /**
- * Verify if the IPsec NAT-T file descriptor and resource Id hold for IPsec keepalive is valid.
- **/
- public static boolean isNattKeepaliveSocketValid(@Nullable FileDescriptor fd, int resourceId) {
- // TODO: 1. confirm whether the fd is called from system api or created by IpSecService.
- // 2. If the fd is created from the system api, check that it's bounded. And
- // call dup to keep the fd open.
- // 3. If the fd is created from IpSecService, check if the resource ID is valid. And
- // hold the resource needed in IpSecService.
- if (null == fd) {
- return false;
- }
- return true;
- }
-
- public void dump(IndentingPrintWriter pw) {
- pw.println("Supported Socket keepalives: " + Arrays.toString(mSupportedKeepalives));
- pw.println("Reserved Privileged keepalives: " + mReservedPrivilegedSlots);
- pw.println("Allowed Unprivileged keepalives per uid: " + mAllowedUnprivilegedSlotsForUid);
- pw.println("Socket keepalives:");
- pw.increaseIndent();
- for (NetworkAgentInfo nai : mKeepalives.keySet()) {
- pw.println(nai.toShortString());
- pw.increaseIndent();
- for (int slot : mKeepalives.get(nai).keySet()) {
- KeepaliveInfo ki = mKeepalives.get(nai).get(slot);
- pw.println(slot + ": " + ki.toString());
- }
- pw.decreaseIndent();
- }
- pw.decreaseIndent();
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/LingerMonitor.java b/packages/Connectivity/service/src/com/android/server/connectivity/LingerMonitor.java
deleted file mode 100644
index 032612c..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/LingerMonitor.java
+++ /dev/null
@@ -1,330 +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.ConnectivityManager.NETID_UNSET;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.net.ConnectivityResources;
-import android.net.NetworkCapabilities;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.SparseBooleanArray;
-import android.util.SparseIntArray;
-
-import com.android.connectivity.resources.R;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.MessageUtils;
-import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-/**
- * Class that monitors default network linger events and possibly notifies the user of network
- * switches.
- *
- * This class is not thread-safe and all its methods must be called on the ConnectivityService
- * handler thread.
- */
-public class LingerMonitor {
-
- private static final boolean DBG = true;
- private static final boolean VDBG = false;
- private static final String TAG = LingerMonitor.class.getSimpleName();
-
- public static final int DEFAULT_NOTIFICATION_DAILY_LIMIT = 3;
- public static final long DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS = DateUtils.MINUTE_IN_MILLIS;
-
- private static final HashMap<String, Integer> TRANSPORT_NAMES = makeTransportToNameMap();
- @VisibleForTesting
- public static final Intent CELLULAR_SETTINGS = new Intent().setComponent(new ComponentName(
- "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"));
-
- @VisibleForTesting
- public static final int NOTIFY_TYPE_NONE = 0;
- public static final int NOTIFY_TYPE_NOTIFICATION = 1;
- public static final int NOTIFY_TYPE_TOAST = 2;
-
- private static SparseArray<String> sNotifyTypeNames = MessageUtils.findMessageNames(
- new Class[] { LingerMonitor.class }, new String[]{ "NOTIFY_TYPE_" });
-
- private final Context mContext;
- final Resources mResources;
- private final NetworkNotificationManager mNotifier;
- private final int mDailyLimit;
- private final long mRateLimitMillis;
-
- private long mFirstNotificationMillis;
- private long mLastNotificationMillis;
- private int mNotificationCounter;
-
- /** Current notifications. Maps the netId we switched away from to the netId we switched to. */
- private final SparseIntArray mNotifications = new SparseIntArray();
-
- /** Whether we ever notified that we switched away from a particular network. */
- private final SparseBooleanArray mEverNotified = new SparseBooleanArray();
-
- public LingerMonitor(Context context, NetworkNotificationManager notifier,
- int dailyLimit, long rateLimitMillis) {
- mContext = context;
- mResources = new ConnectivityResources(mContext).get();
- mNotifier = notifier;
- mDailyLimit = dailyLimit;
- mRateLimitMillis = rateLimitMillis;
- // Ensure that (now - mLastNotificationMillis) >= rateLimitMillis at first
- mLastNotificationMillis = -rateLimitMillis;
- }
-
- private static HashMap<String, Integer> makeTransportToNameMap() {
- SparseArray<String> numberToName = MessageUtils.findMessageNames(
- new Class[] { NetworkCapabilities.class }, new String[]{ "TRANSPORT_" });
- HashMap<String, Integer> nameToNumber = new HashMap<>();
- for (int i = 0; i < numberToName.size(); i++) {
- // MessageUtils will fail to initialize if there are duplicate constant values, so there
- // are no duplicates here.
- nameToNumber.put(numberToName.valueAt(i), numberToName.keyAt(i));
- }
- return nameToNumber;
- }
-
- private static boolean hasTransport(NetworkAgentInfo nai, int transport) {
- return nai.networkCapabilities.hasTransport(transport);
- }
-
- private int getNotificationSource(NetworkAgentInfo toNai) {
- for (int i = 0; i < mNotifications.size(); i++) {
- if (mNotifications.valueAt(i) == toNai.network.getNetId()) {
- return mNotifications.keyAt(i);
- }
- }
- return NETID_UNSET;
- }
-
- private boolean everNotified(NetworkAgentInfo nai) {
- return mEverNotified.get(nai.network.getNetId(), false);
- }
-
- @VisibleForTesting
- public boolean isNotificationEnabled(NetworkAgentInfo fromNai, NetworkAgentInfo toNai) {
- // TODO: Evaluate moving to CarrierConfigManager.
- String[] notifySwitches = mResources.getStringArray(R.array.config_networkNotifySwitches);
-
- if (VDBG) {
- Log.d(TAG, "Notify on network switches: " + Arrays.toString(notifySwitches));
- }
-
- for (String notifySwitch : notifySwitches) {
- if (TextUtils.isEmpty(notifySwitch)) continue;
- String[] transports = notifySwitch.split("-", 2);
- if (transports.length != 2) {
- Log.e(TAG, "Invalid network switch notification configuration: " + notifySwitch);
- continue;
- }
- int fromTransport = TRANSPORT_NAMES.get("TRANSPORT_" + transports[0]);
- int toTransport = TRANSPORT_NAMES.get("TRANSPORT_" + transports[1]);
- if (hasTransport(fromNai, fromTransport) && hasTransport(toNai, toTransport)) {
- return true;
- }
- }
-
- return false;
- }
-
- private void showNotification(NetworkAgentInfo fromNai, NetworkAgentInfo toNai) {
- mNotifier.showNotification(fromNai.network.getNetId(), NotificationType.NETWORK_SWITCH,
- fromNai, toNai, createNotificationIntent(), true);
- }
-
- @VisibleForTesting
- protected PendingIntent createNotificationIntent() {
- return PendingIntent.getActivity(
- mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */),
- 0 /* requestCode */,
- CELLULAR_SETTINGS,
- PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
- }
-
- // Removes any notification that was put up as a result of switching to nai.
- private void maybeStopNotifying(NetworkAgentInfo nai) {
- int fromNetId = getNotificationSource(nai);
- if (fromNetId != NETID_UNSET) {
- mNotifications.delete(fromNetId);
- mNotifier.clearNotification(fromNetId);
- // Toasts can't be deleted.
- }
- }
-
- // Notify the user of a network switch using a notification or a toast.
- private void notify(NetworkAgentInfo fromNai, NetworkAgentInfo toNai, boolean forceToast) {
- int notifyType = mResources.getInteger(R.integer.config_networkNotifySwitchType);
- if (notifyType == NOTIFY_TYPE_NOTIFICATION && forceToast) {
- notifyType = NOTIFY_TYPE_TOAST;
- }
-
- if (VDBG) {
- Log.d(TAG, "Notify type: " + sNotifyTypeNames.get(notifyType, "" + notifyType));
- }
-
- switch (notifyType) {
- case NOTIFY_TYPE_NONE:
- return;
- case NOTIFY_TYPE_NOTIFICATION:
- showNotification(fromNai, toNai);
- break;
- case NOTIFY_TYPE_TOAST:
- mNotifier.showToast(fromNai, toNai);
- break;
- default:
- Log.e(TAG, "Unknown notify type " + notifyType);
- return;
- }
-
- if (DBG) {
- Log.d(TAG, "Notifying switch from=" + fromNai.toShortString()
- + " to=" + toNai.toShortString()
- + " type=" + sNotifyTypeNames.get(notifyType, "unknown(" + notifyType + ")"));
- }
-
- mNotifications.put(fromNai.network.getNetId(), toNai.network.getNetId());
- mEverNotified.put(fromNai.network.getNetId(), true);
- }
-
- /**
- * Put up or dismiss a notification or toast for of a change in the default network if needed.
- *
- * Putting up a notification when switching from no network to some network is not supported
- * and as such this method can't be called with a null |fromNai|. It can be called with a
- * null |toNai| if there isn't a default network any more.
- *
- * @param fromNai switching from this NAI
- * @param toNai switching to this NAI
- */
- // The default network changed from fromNai to toNai due to a change in score.
- public void noteLingerDefaultNetwork(@NonNull final NetworkAgentInfo fromNai,
- @Nullable final NetworkAgentInfo toNai) {
- if (VDBG) {
- Log.d(TAG, "noteLingerDefaultNetwork from=" + fromNai.toShortString()
- + " everValidated=" + fromNai.everValidated
- + " lastValidated=" + fromNai.lastValidated
- + " to=" + toNai.toShortString());
- }
-
- // If we are currently notifying the user because the device switched to fromNai, now that
- // we are switching away from it we should remove the notification. This includes the case
- // where we switch back to toNai because its score improved again (e.g., because it regained
- // Internet access).
- maybeStopNotifying(fromNai);
-
- // If the network was simply lost (either because it disconnected or because it stopped
- // being the default with no replacement), then don't show a notification.
- if (null == toNai) return;
-
- // If this network never validated, don't notify. Otherwise, we could do things like:
- //
- // 1. Unvalidated wifi connects.
- // 2. Unvalidated mobile data connects.
- // 3. Cell validates, and we show a notification.
- // or:
- // 1. User connects to wireless printer.
- // 2. User turns on cellular data.
- // 3. We show a notification.
- if (!fromNai.everValidated) return;
-
- // If this network is a captive portal, don't notify. This cannot happen on initial connect
- // to a captive portal, because the everValidated check above will fail. However, it can
- // happen if the captive portal reasserts itself (e.g., because its timeout fires). In that
- // case, as soon as the captive portal reasserts itself, we'll show a sign-in notification.
- // We don't want to overwrite that notification with this one; the user has already been
- // notified, and of the two, the captive portal notification is the more useful one because
- // it allows the user to sign in to the captive portal. In this case, display a toast
- // in addition to the captive portal notification.
- //
- // Note that if the network we switch to is already up when the captive portal reappears,
- // this won't work because NetworkMonitor tells ConnectivityService that the network is
- // unvalidated (causing a switch) before asking it to show the sign in notification. In this
- // case, the toast won't show and we'll only display the sign in notification. This is the
- // best we can do at this time.
- boolean forceToast = fromNai.networkCapabilities.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
-
- // Only show the notification once, in order to avoid irritating the user every time.
- // TODO: should we do this?
- if (everNotified(fromNai)) {
- if (VDBG) {
- Log.d(TAG, "Not notifying handover from " + fromNai.toShortString()
- + ", already notified");
- }
- return;
- }
-
- // Only show the notification if we switched away because a network became unvalidated, not
- // because its score changed.
- // TODO: instead of just skipping notification, keep a note of it, and show it if it becomes
- // unvalidated.
- if (fromNai.lastValidated) return;
-
- if (!isNotificationEnabled(fromNai, toNai)) return;
-
- final long now = SystemClock.elapsedRealtime();
- if (isRateLimited(now) || isAboveDailyLimit(now)) return;
-
- notify(fromNai, toNai, forceToast);
- }
-
- public void noteDisconnect(NetworkAgentInfo nai) {
- mNotifications.delete(nai.network.getNetId());
- mEverNotified.delete(nai.network.getNetId());
- maybeStopNotifying(nai);
- // No need to cancel notifications on nai: NetworkMonitor does that on disconnect.
- }
-
- private boolean isRateLimited(long now) {
- final long millisSinceLast = now - mLastNotificationMillis;
- if (millisSinceLast < mRateLimitMillis) {
- return true;
- }
- mLastNotificationMillis = now;
- return false;
- }
-
- private boolean isAboveDailyLimit(long now) {
- if (mFirstNotificationMillis == 0) {
- mFirstNotificationMillis = now;
- }
- final long millisSinceFirst = now - mFirstNotificationMillis;
- if (millisSinceFirst > DateUtils.DAY_IN_MILLIS) {
- mNotificationCounter = 0;
- mFirstNotificationMillis = 0;
- }
- if (mNotificationCounter >= mDailyLimit) {
- return true;
- }
- mNotificationCounter++;
- return false;
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/MockableSystemProperties.java b/packages/Connectivity/service/src/com/android/server/connectivity/MockableSystemProperties.java
deleted file mode 100644
index a25b89a..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/MockableSystemProperties.java
+++ /dev/null
@@ -1,34 +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.os.SystemProperties;
-
-public class MockableSystemProperties {
-
- public String get(String key) {
- return SystemProperties.get(key);
- }
-
- public int getInt(String key, int def) {
- return SystemProperties.getInt(key, def);
- }
-
- public boolean getBoolean(String key, boolean def) {
- return SystemProperties.getBoolean(key, def);
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/Nat464Xlat.java b/packages/Connectivity/service/src/com/android/server/connectivity/Nat464Xlat.java
deleted file mode 100644
index c66a280..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/Nat464Xlat.java
+++ /dev/null
@@ -1,523 +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.connectivity;
-
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-
-import static com.android.net.module.util.CollectionUtils.contains;
-
-import android.annotation.NonNull;
-import android.net.ConnectivityManager;
-import android.net.IDnsResolver;
-import android.net.INetd;
-import android.net.InetAddresses;
-import android.net.InterfaceConfigurationParcel;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NetworkInfo;
-import android.net.RouteInfo;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.net.module.util.NetworkStackConstants;
-import com.android.server.ConnectivityService;
-
-import java.net.Inet6Address;
-import java.util.Objects;
-
-/**
- * Class to manage a 464xlat CLAT daemon. Nat464Xlat is not thread safe and should be manipulated
- * from a consistent and unique thread context. It is the responsibility of ConnectivityService to
- * call into this class from its own Handler thread.
- *
- * @hide
- */
-public class Nat464Xlat {
- private static final String TAG = Nat464Xlat.class.getSimpleName();
-
- // This must match the interface prefix in clatd.c.
- private static final String CLAT_PREFIX = "v4-";
-
- // The network types on which we will start clatd,
- // allowing clat only on networks for which we can support IPv6-only.
- private static final int[] NETWORK_TYPES = {
- ConnectivityManager.TYPE_MOBILE,
- ConnectivityManager.TYPE_WIFI,
- ConnectivityManager.TYPE_ETHERNET,
- };
-
- // The network states in which running clatd is supported.
- private static final NetworkInfo.State[] NETWORK_STATES = {
- NetworkInfo.State.CONNECTED,
- NetworkInfo.State.SUSPENDED,
- };
-
- private final IDnsResolver mDnsResolver;
- private final INetd mNetd;
-
- // The network we're running on, and its type.
- private final NetworkAgentInfo mNetwork;
-
- private enum State {
- IDLE, // start() not called. Base iface and stacked iface names are null.
- DISCOVERING, // same as IDLE, except prefix discovery in progress.
- STARTING, // start() called. Base iface and stacked iface names are known.
- RUNNING, // start() called, and the stacked iface is known to be up.
- }
-
- /**
- * NAT64 prefix currently in use. Only valid in STARTING or RUNNING states.
- * Used, among other things, to avoid updates when switching from a prefix learned from one
- * source (e.g., RA) to the same prefix learned from another source (e.g., RA).
- */
- private IpPrefix mNat64PrefixInUse;
- /** NAT64 prefix (if any) discovered from DNS via RFC 7050. */
- private IpPrefix mNat64PrefixFromDns;
- /** NAT64 prefix (if any) learned from the network via RA. */
- private IpPrefix mNat64PrefixFromRa;
- private String mBaseIface;
- private String mIface;
- private Inet6Address mIPv6Address;
- private State mState = State.IDLE;
-
- private boolean mEnableClatOnCellular;
- private boolean mPrefixDiscoveryRunning;
-
- public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver,
- ConnectivityService.Dependencies deps) {
- mDnsResolver = dnsResolver;
- mNetd = netd;
- mNetwork = nai;
- mEnableClatOnCellular = deps.getCellular464XlatEnabled();
- }
-
- /**
- * Whether to attempt 464xlat on this network. This is true for an IPv6-only network that is
- * currently connected and where the NetworkAgent has not disabled 464xlat. It is the signal to
- * enable NAT64 prefix discovery.
- *
- * @param nai the NetworkAgentInfo corresponding to the network.
- * @return true if the network requires clat, false otherwise.
- */
- @VisibleForTesting
- protected boolean requiresClat(NetworkAgentInfo nai) {
- // TODO: migrate to NetworkCapabilities.TRANSPORT_*.
- final boolean supported = contains(NETWORK_TYPES, nai.networkInfo.getType());
- final boolean connected = contains(NETWORK_STATES, nai.networkInfo.getState());
-
- // Only run clat on networks that have a global IPv6 address and don't have a native IPv4
- // address.
- LinkProperties lp = nai.linkProperties;
- final boolean isIpv6OnlyNetwork = (lp != null) && lp.hasGlobalIpv6Address()
- && !lp.hasIpv4Address();
-
- // If the network tells us it doesn't use clat, respect that.
- final boolean skip464xlat = (nai.netAgentConfig() != null)
- && nai.netAgentConfig().skip464xlat;
-
- return supported && connected && isIpv6OnlyNetwork && !skip464xlat
- && (nai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)
- ? isCellular464XlatEnabled() : true);
- }
-
- /**
- * Whether the clat demon should be started on this network now. This is true if requiresClat is
- * true and a NAT64 prefix has been discovered.
- *
- * @param nai the NetworkAgentInfo corresponding to the network.
- * @return true if the network should start clat, false otherwise.
- */
- @VisibleForTesting
- protected boolean shouldStartClat(NetworkAgentInfo nai) {
- LinkProperties lp = nai.linkProperties;
- return requiresClat(nai) && lp != null && lp.getNat64Prefix() != null;
- }
-
- /**
- * @return true if clatd has been started and has not yet stopped.
- * A true result corresponds to internal states STARTING and RUNNING.
- */
- public boolean isStarted() {
- return (mState == State.STARTING || mState == State.RUNNING);
- }
-
- /**
- * @return true if clatd has been started but the stacked interface is not yet up.
- */
- public boolean isStarting() {
- return mState == State.STARTING;
- }
-
- /**
- * @return true if clatd has been started and the stacked interface is up.
- */
- public boolean isRunning() {
- return mState == State.RUNNING;
- }
-
- /**
- * Start clatd, register this Nat464Xlat as a network observer for the stacked interface,
- * and set internal state.
- */
- private void enterStartingState(String baseIface) {
- mNat64PrefixInUse = selectNat64Prefix();
- String addrStr = null;
- try {
- addrStr = mNetd.clatdStart(baseIface, mNat64PrefixInUse.toString());
- } catch (RemoteException | ServiceSpecificException e) {
- Log.e(TAG, "Error starting clatd on " + baseIface + ": " + e);
- }
- mIface = CLAT_PREFIX + baseIface;
- mBaseIface = baseIface;
- mState = State.STARTING;
- try {
- mIPv6Address = (Inet6Address) InetAddresses.parseNumericAddress(addrStr);
- } catch (ClassCastException | IllegalArgumentException | NullPointerException e) {
- Log.e(TAG, "Invalid IPv6 address " + addrStr);
- }
- if (mPrefixDiscoveryRunning && !isPrefixDiscoveryNeeded()) {
- stopPrefixDiscovery();
- }
- if (!mPrefixDiscoveryRunning) {
- setPrefix64(mNat64PrefixInUse);
- }
- }
-
- /**
- * Enter running state just after getting confirmation that the stacked interface is up, and
- * turn ND offload off if on WiFi.
- */
- private void enterRunningState() {
- mState = State.RUNNING;
- }
-
- /**
- * Unregister as a base observer for the stacked interface, and clear internal state.
- */
- private void leaveStartedState() {
- mNat64PrefixInUse = null;
- mIface = null;
- mBaseIface = null;
-
- if (!mPrefixDiscoveryRunning) {
- setPrefix64(null);
- }
-
- if (isPrefixDiscoveryNeeded()) {
- if (!mPrefixDiscoveryRunning) {
- startPrefixDiscovery();
- }
- mState = State.DISCOVERING;
- } else {
- stopPrefixDiscovery();
- mState = State.IDLE;
- }
- }
-
- @VisibleForTesting
- protected void start() {
- if (isStarted()) {
- Log.e(TAG, "startClat: already started");
- return;
- }
-
- String baseIface = mNetwork.linkProperties.getInterfaceName();
- if (baseIface == null) {
- Log.e(TAG, "startClat: Can't start clat on null interface");
- return;
- }
- // TODO: should we only do this if mNetd.clatdStart() succeeds?
- Log.i(TAG, "Starting clatd on " + baseIface);
- enterStartingState(baseIface);
- }
-
- @VisibleForTesting
- protected void stop() {
- if (!isStarted()) {
- Log.e(TAG, "stopClat: already stopped");
- return;
- }
-
- Log.i(TAG, "Stopping clatd on " + mBaseIface);
- try {
- mNetd.clatdStop(mBaseIface);
- } catch (RemoteException | ServiceSpecificException e) {
- Log.e(TAG, "Error stopping clatd on " + mBaseIface + ": " + e);
- }
-
- String iface = mIface;
- boolean wasRunning = isRunning();
-
- // Change state before updating LinkProperties. handleUpdateLinkProperties ends up calling
- // fixupLinkProperties, and if at that time the state is still RUNNING, fixupLinkProperties
- // would wrongly inform ConnectivityService that there is still a stacked interface.
- leaveStartedState();
-
- if (wasRunning) {
- LinkProperties lp = new LinkProperties(mNetwork.linkProperties);
- lp.removeStackedLink(iface);
- mNetwork.connService().handleUpdateLinkProperties(mNetwork, lp);
- }
- }
-
- private void startPrefixDiscovery() {
- try {
- mDnsResolver.startPrefix64Discovery(getNetId());
- } catch (RemoteException | ServiceSpecificException e) {
- Log.e(TAG, "Error starting prefix discovery on netId " + getNetId() + ": " + e);
- }
- mPrefixDiscoveryRunning = true;
- }
-
- private void stopPrefixDiscovery() {
- try {
- mDnsResolver.stopPrefix64Discovery(getNetId());
- } catch (RemoteException | ServiceSpecificException e) {
- Log.e(TAG, "Error stopping prefix discovery on netId " + getNetId() + ": " + e);
- }
- mPrefixDiscoveryRunning = false;
- }
-
- private boolean isPrefixDiscoveryNeeded() {
- // If there is no NAT64 prefix in the RA, prefix discovery is always needed. It cannot be
- // stopped after it succeeds, because stopping it will cause netd to report that the prefix
- // has been removed, and that will cause us to stop clatd.
- return requiresClat(mNetwork) && mNat64PrefixFromRa == null;
- }
-
- private void setPrefix64(IpPrefix prefix) {
- final String prefixString = (prefix != null) ? prefix.toString() : "";
- try {
- mDnsResolver.setPrefix64(getNetId(), prefixString);
- } catch (RemoteException | ServiceSpecificException e) {
- Log.e(TAG, "Error setting NAT64 prefix on netId " + getNetId() + " to "
- + prefix + ": " + e);
- }
- }
-
- private void maybeHandleNat64PrefixChange() {
- final IpPrefix newPrefix = selectNat64Prefix();
- if (!Objects.equals(mNat64PrefixInUse, newPrefix)) {
- Log.d(TAG, "NAT64 prefix changed from " + mNat64PrefixInUse + " to "
- + newPrefix);
- stop();
- // It's safe to call update here, even though this method is called from update, because
- // stop() is guaranteed to have moved out of STARTING and RUNNING, which are the only
- // states in which this method can be called.
- update();
- }
- }
-
- /**
- * Starts/stops NAT64 prefix discovery and clatd as necessary.
- */
- public void update() {
- // TODO: turn this class into a proper StateMachine. http://b/126113090
- switch (mState) {
- case IDLE:
- if (isPrefixDiscoveryNeeded()) {
- startPrefixDiscovery(); // Enters DISCOVERING state.
- mState = State.DISCOVERING;
- } else if (requiresClat(mNetwork)) {
- start(); // Enters STARTING state.
- }
- break;
-
- case DISCOVERING:
- if (shouldStartClat(mNetwork)) {
- // NAT64 prefix detected. Start clatd.
- start(); // Enters STARTING state.
- return;
- }
- if (!requiresClat(mNetwork)) {
- // IPv4 address added. Go back to IDLE state.
- stopPrefixDiscovery();
- mState = State.IDLE;
- return;
- }
- break;
-
- case STARTING:
- case RUNNING:
- // NAT64 prefix removed, or IPv4 address added.
- // Stop clatd and go back into DISCOVERING or idle.
- if (!shouldStartClat(mNetwork)) {
- stop();
- break;
- }
- // Only necessary while clat is actually started.
- maybeHandleNat64PrefixChange();
- break;
- }
- }
-
- /**
- * Picks a NAT64 prefix to use. Always prefers the prefix from the RA if one is received from
- * both RA and DNS, because the prefix in the RA has better security and updatability, and will
- * almost always be received first anyway.
- *
- * Any network that supports legacy hosts will support discovering the DNS64 prefix via DNS as
- * well. If the prefix from the RA is withdrawn, fall back to that for reliability purposes.
- */
- private IpPrefix selectNat64Prefix() {
- return mNat64PrefixFromRa != null ? mNat64PrefixFromRa : mNat64PrefixFromDns;
- }
-
- public void setNat64PrefixFromRa(IpPrefix prefix) {
- mNat64PrefixFromRa = prefix;
- }
-
- public void setNat64PrefixFromDns(IpPrefix prefix) {
- mNat64PrefixFromDns = prefix;
- }
-
- /**
- * Copies the stacked clat link in oldLp, if any, to the passed LinkProperties.
- * This is necessary because the LinkProperties in mNetwork come from the transport layer, which
- * has no idea that 464xlat is running on top of it.
- */
- public void fixupLinkProperties(@NonNull LinkProperties oldLp, @NonNull LinkProperties lp) {
- // This must be done even if clatd is not running, because otherwise shouldStartClat would
- // never return true.
- lp.setNat64Prefix(selectNat64Prefix());
-
- if (!isRunning()) {
- return;
- }
- if (lp.getAllInterfaceNames().contains(mIface)) {
- return;
- }
-
- Log.d(TAG, "clatd running, updating NAI for " + mIface);
- for (LinkProperties stacked: oldLp.getStackedLinks()) {
- if (Objects.equals(mIface, stacked.getInterfaceName())) {
- lp.addStackedLink(stacked);
- return;
- }
- }
- }
-
- private LinkProperties makeLinkProperties(LinkAddress clatAddress) {
- LinkProperties stacked = new LinkProperties();
- stacked.setInterfaceName(mIface);
-
- // Although the clat interface is a point-to-point tunnel, we don't
- // point the route directly at the interface because some apps don't
- // understand routes without gateways (see, e.g., http://b/9597256
- // http://b/9597516). Instead, set the next hop of the route to the
- // clat IPv4 address itself (for those apps, it doesn't matter what
- // the IP of the gateway is, only that there is one).
- RouteInfo ipv4Default = new RouteInfo(
- new LinkAddress(NetworkStackConstants.IPV4_ADDR_ANY, 0),
- clatAddress.getAddress(), mIface);
- stacked.addRoute(ipv4Default);
- stacked.addLinkAddress(clatAddress);
- return stacked;
- }
-
- private LinkAddress getLinkAddress(String iface) {
- try {
- final InterfaceConfigurationParcel config = mNetd.interfaceGetCfg(iface);
- return new LinkAddress(
- InetAddresses.parseNumericAddress(config.ipv4Addr), config.prefixLength);
- } catch (IllegalArgumentException | RemoteException | ServiceSpecificException e) {
- Log.e(TAG, "Error getting link properties: " + e);
- return null;
- }
- }
-
- /**
- * Adds stacked link on base link and transitions to RUNNING state.
- */
- private void handleInterfaceLinkStateChanged(String iface, boolean up) {
- // TODO: if we call start(), then stop(), then start() again, and the
- // interfaceLinkStateChanged notification for the first start is delayed past the first
- // stop, then the code becomes out of sync with system state and will behave incorrectly.
- //
- // This is not trivial to fix because:
- // 1. It is not guaranteed that start() will eventually result in the interface coming up,
- // because there could be an error starting clat (e.g., if the interface goes down before
- // the packet socket can be bound).
- // 2. If start is called multiple times, there is nothing in the interfaceLinkStateChanged
- // notification that says which start() call the interface was created by.
- //
- // Once this code is converted to StateMachine, it will be possible to use deferMessage to
- // ensure it stays in STARTING state until the interfaceLinkStateChanged notification fires,
- // and possibly use a timeout (or provide some guarantees at the lower layer) to address #1.
- if (!isStarting() || !up || !Objects.equals(mIface, iface)) {
- return;
- }
-
- LinkAddress clatAddress = getLinkAddress(iface);
- if (clatAddress == null) {
- Log.e(TAG, "clatAddress was null for stacked iface " + iface);
- return;
- }
-
- Log.i(TAG, String.format("interface %s is up, adding stacked link %s on top of %s",
- mIface, mIface, mBaseIface));
- enterRunningState();
- LinkProperties lp = new LinkProperties(mNetwork.linkProperties);
- lp.addStackedLink(makeLinkProperties(clatAddress));
- mNetwork.connService().handleUpdateLinkProperties(mNetwork, lp);
- }
-
- /**
- * Removes stacked link on base link and transitions to IDLE state.
- */
- private void handleInterfaceRemoved(String iface) {
- if (!Objects.equals(mIface, iface)) {
- return;
- }
- if (!isRunning()) {
- return;
- }
-
- Log.i(TAG, "interface " + iface + " removed");
- // If we're running, and the interface was removed, then we didn't call stop(), and it's
- // likely that clatd crashed. Ensure we call stop() so we can start clatd again. Calling
- // stop() will also update LinkProperties, and if clatd crashed, the LinkProperties update
- // will cause ConnectivityService to call start() again.
- stop();
- }
-
- public void interfaceLinkStateChanged(String iface, boolean up) {
- mNetwork.handler().post(() -> { handleInterfaceLinkStateChanged(iface, up); });
- }
-
- public void interfaceRemoved(String iface) {
- mNetwork.handler().post(() -> handleInterfaceRemoved(iface));
- }
-
- @Override
- public String toString() {
- return "mBaseIface: " + mBaseIface + ", mIface: " + mIface + ", mState: " + mState;
- }
-
- @VisibleForTesting
- protected int getNetId() {
- return mNetwork.network.getNetId();
- }
-
- @VisibleForTesting
- protected boolean isCellular464XlatEnabled() {
- return mEnableClatOnCellular;
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/NetworkAgentInfo.java b/packages/Connectivity/service/src/com/android/server/connectivity/NetworkAgentInfo.java
deleted file mode 100644
index 18becd4..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/NetworkAgentInfo.java
+++ /dev/null
@@ -1,1215 +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 com.android.server.connectivity;
-
-import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.transportNamesOf;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.CaptivePortalData;
-import android.net.IDnsResolver;
-import android.net.INetd;
-import android.net.INetworkAgent;
-import android.net.INetworkAgentRegistry;
-import android.net.INetworkMonitor;
-import android.net.LinkProperties;
-import android.net.NattKeepalivePacketData;
-import android.net.Network;
-import android.net.NetworkAgent;
-import android.net.NetworkAgentConfig;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkMonitorManager;
-import android.net.NetworkRequest;
-import android.net.NetworkScore;
-import android.net.NetworkStateSnapshot;
-import android.net.QosCallbackException;
-import android.net.QosFilter;
-import android.net.QosFilterParcelable;
-import android.net.QosSession;
-import android.net.TcpKeepalivePacketData;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.telephony.data.EpsBearerQosSessionAttributes;
-import android.telephony.data.NrQosSessionAttributes;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.internal.util.WakeupMessage;
-import com.android.server.ConnectivityService;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Objects;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- * A bag class used by ConnectivityService for holding a collection of most recent
- * information published by a particular NetworkAgent as well as the
- * AsyncChannel/messenger for reaching that NetworkAgent and lists of NetworkRequests
- * interested in using it. Default sort order is descending by score.
- */
-// States of a network:
-// --------------------
-// 1. registered, uncreated, disconnected, unvalidated
-// This state is entered when a NetworkFactory registers a NetworkAgent in any state except
-// the CONNECTED state.
-// 2. registered, uncreated, connecting, unvalidated
-// This state is entered when a registered NetworkAgent for a VPN network transitions to the
-// CONNECTING state (TODO: go through this state for every network, not just VPNs).
-// ConnectivityService will tell netd to create the network early in order to add extra UID
-// routing rules referencing the netID. These rules need to be in place before the network is
-// connected to avoid racing against client apps trying to connect to a half-setup network.
-// 3. registered, uncreated, connected, unvalidated
-// This state is entered when a registered NetworkAgent transitions to the CONNECTED state.
-// ConnectivityService will tell netd to create the network if it was not already created, and
-// immediately transition to state #4.
-// 4. registered, created, connected, unvalidated
-// If this network can satisfy the default NetworkRequest, then NetworkMonitor will
-// probe for Internet connectivity.
-// If this network cannot satisfy the default NetworkRequest, it will immediately be
-// transitioned to state #5.
-// A network may remain in this state if NetworkMonitor fails to find Internet connectivity,
-// for example:
-// a. a captive portal is present, or
-// b. a WiFi router whose Internet backhaul is down, or
-// c. a wireless connection stops transfering packets temporarily (e.g. device is in elevator
-// or tunnel) but does not disconnect from the AP/cell tower, or
-// d. a stand-alone device offering a WiFi AP without an uplink for configuration purposes.
-// 5. registered, created, connected, validated
-//
-// The device's default network connection:
-// ----------------------------------------
-// Networks in states #4 and #5 may be used as a device's default network connection if they
-// satisfy the default NetworkRequest.
-// A network, that satisfies the default NetworkRequest, in state #5 should always be chosen
-// in favor of a network, that satisfies the default NetworkRequest, in state #4.
-// When deciding between two networks, that both satisfy the default NetworkRequest, to select
-// for the default network connection, the one with the higher score should be chosen.
-//
-// When a network disconnects:
-// ---------------------------
-// If a network's transport disappears, for example:
-// a. WiFi turned off, or
-// b. cellular data turned off, or
-// c. airplane mode is turned on, or
-// d. a wireless connection disconnects from AP/cell tower entirely (e.g. device is out of range
-// of AP for an extended period of time, or switches to another AP without roaming)
-// then that network can transition from any state (#1-#5) to unregistered. This happens by
-// the transport disconnecting their NetworkAgent's AsyncChannel with ConnectivityManager.
-// ConnectivityService also tells netd to destroy the network.
-//
-// When ConnectivityService disconnects a network:
-// -----------------------------------------------
-// If a network is just connected, ConnectivityService will think it will be used soon, but might
-// not be used. Thus, a 5s timer will be held to prevent the network being torn down immediately.
-// This "nascent" state is implemented by the "lingering" logic below without relating to any
-// request, and is used in some cases where network requests race with network establishment. The
-// nascent state ends when the 5-second timer fires, or as soon as the network satisfies a
-// request, whichever is earlier. In this state, the network is considered in the background.
-//
-// If a network has no chance of satisfying any requests (even if it were to become validated
-// and enter state #5), ConnectivityService will disconnect the NetworkAgent's AsyncChannel.
-//
-// If the network was satisfying a foreground NetworkRequest (i.e. had been the highest scoring that
-// satisfied the NetworkRequest's constraints), but is no longer the highest scoring network for any
-// foreground NetworkRequest, then there will be a 30s pause to allow network communication to be
-// wrapped up rather than abruptly terminated. During this pause the network is said to be
-// "lingering". During this pause if the network begins satisfying a foreground NetworkRequest,
-// ConnectivityService will cancel the future disconnection of the NetworkAgent's AsyncChannel, and
-// the network is no longer considered "lingering". After the linger timer expires, if the network
-// is satisfying one or more background NetworkRequests it is kept up in the background. If it is
-// not, ConnectivityService disconnects the NetworkAgent's AsyncChannel.
-public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRanker.Scoreable {
-
- @NonNull public NetworkInfo networkInfo;
- // This Network object should always be used if possible, so as to encourage reuse of the
- // enclosed socket factory and connection pool. Avoid creating other Network objects.
- // This Network object is always valid.
- @NonNull public final Network network;
- @NonNull public LinkProperties linkProperties;
- // This should only be modified by ConnectivityService, via setNetworkCapabilities().
- // TODO: make this private with a getter.
- @NonNull public NetworkCapabilities networkCapabilities;
- @NonNull public final NetworkAgentConfig networkAgentConfig;
-
- // Underlying networks declared by the agent. Only set if supportsUnderlyingNetworks is true.
- // The networks in this list might be declared by a VPN app using setUnderlyingNetworks and are
- // not guaranteed to be current or correct, or even to exist.
- //
- // This array is read and iterated on multiple threads with no locking so its contents must
- // never be modified. When the list of networks changes, replace with a new array, on the
- // handler thread.
- public @Nullable volatile Network[] declaredUnderlyingNetworks;
-
- // The capabilities originally announced by the NetworkAgent, regardless of any capabilities
- // that were added or removed due to this network's underlying networks.
- // Only set if #supportsUnderlyingNetworks is true.
- public @Nullable NetworkCapabilities declaredCapabilities;
-
- // Indicates if netd has been told to create this Network. From this point on the appropriate
- // routing rules are setup and routes are added so packets can begin flowing over the Network.
- // This is a sticky bit; once set it is never cleared.
- public boolean created;
- // Set to true after the first time this network is marked as CONNECTED. Once set, the network
- // shows up in API calls, is able to satisfy NetworkRequests and can become the default network.
- // This is a sticky bit; once set it is never cleared.
- public boolean everConnected;
- // Set to true if this Network successfully passed validation or if it did not satisfy the
- // default NetworkRequest in which case validation will not be attempted.
- // This is a sticky bit; once set it is never cleared even if future validation attempts fail.
- public boolean everValidated;
-
- // The result of the last validation attempt on this network (true if validated, false if not).
- public boolean lastValidated;
-
- // If true, becoming unvalidated will lower the network's score. This is only meaningful if the
- // system is configured not to do this for certain networks, e.g., if the
- // config_networkAvoidBadWifi option is set to 0 and the user has not overridden that via
- // Settings.Global.NETWORK_AVOID_BAD_WIFI.
- public boolean avoidUnvalidated;
-
- // Whether a captive portal was ever detected on this network.
- // This is a sticky bit; once set it is never cleared.
- public boolean everCaptivePortalDetected;
-
- // Whether a captive portal was found during the last network validation attempt.
- public boolean lastCaptivePortalDetected;
-
- // Set to true when partial connectivity was detected.
- public boolean partialConnectivity;
-
- // Delay between when the network is disconnected and when the native network is destroyed.
- public int teardownDelayMs;
-
- // Captive portal info of the network from RFC8908, if any.
- // Obtained by ConnectivityService and merged into NetworkAgent-provided information.
- public CaptivePortalData capportApiData;
-
- // The UID of the remote entity that created this Network.
- public final int creatorUid;
-
- // Network agent portal info of the network, if any. This information is provided from
- // non-RFC8908 sources, such as Wi-Fi Passpoint, which can provide information such as Venue
- // URL, Terms & Conditions URL, and network friendly name.
- public CaptivePortalData networkAgentPortalData;
-
- // Networks are lingered when they become unneeded as a result of their NetworkRequests being
- // satisfied by a higher-scoring network. so as to allow communication to wrap up before the
- // network is taken down. This usually only happens to the default network. Lingering ends with
- // either the linger timeout expiring and the network being taken down, or the network
- // satisfying a request again.
- public static class InactivityTimer implements Comparable<InactivityTimer> {
- public final int requestId;
- public final long expiryMs;
-
- public InactivityTimer(int requestId, long expiryMs) {
- this.requestId = requestId;
- this.expiryMs = expiryMs;
- }
- public boolean equals(Object o) {
- if (!(o instanceof InactivityTimer)) return false;
- InactivityTimer other = (InactivityTimer) o;
- return (requestId == other.requestId) && (expiryMs == other.expiryMs);
- }
- public int hashCode() {
- return Objects.hash(requestId, expiryMs);
- }
- public int compareTo(InactivityTimer other) {
- return (expiryMs != other.expiryMs) ?
- Long.compare(expiryMs, other.expiryMs) :
- Integer.compare(requestId, other.requestId);
- }
- public String toString() {
- return String.format("%s, expires %dms", requestId,
- expiryMs - SystemClock.elapsedRealtime());
- }
- }
-
- /**
- * Inform ConnectivityService that the network LINGER period has
- * expired.
- * obj = this NetworkAgentInfo
- */
- public static final int EVENT_NETWORK_LINGER_COMPLETE = 1001;
-
- /**
- * Inform ConnectivityService that the agent is half-connected.
- * arg1 = ARG_AGENT_SUCCESS or ARG_AGENT_FAILURE
- * obj = NetworkAgentInfo
- * @hide
- */
- public static final int EVENT_AGENT_REGISTERED = 1002;
-
- /**
- * Inform ConnectivityService that the agent was disconnected.
- * obj = NetworkAgentInfo
- * @hide
- */
- public static final int EVENT_AGENT_DISCONNECTED = 1003;
-
- /**
- * Argument for EVENT_AGENT_HALF_CONNECTED indicating failure.
- */
- public static final int ARG_AGENT_FAILURE = 0;
-
- /**
- * Argument for EVENT_AGENT_HALF_CONNECTED indicating success.
- */
- public static final int ARG_AGENT_SUCCESS = 1;
-
- // How long this network should linger for.
- private int mLingerDurationMs;
-
- // All inactivity timers for this network, sorted by expiry time. A timer is added whenever
- // a request is moved to a network with a better score, regardless of whether the network is or
- // was lingering or not. An inactivity timer is also added when a network connects
- // without immediately satisfying any requests.
- // TODO: determine if we can replace this with a smaller or unsorted data structure. (e.g.,
- // SparseLongArray) combined with the timestamp of when the last timer is scheduled to fire.
- private final SortedSet<InactivityTimer> mInactivityTimers = new TreeSet<>();
-
- // For fast lookups. Indexes into mInactivityTimers by request ID.
- private final SparseArray<InactivityTimer> mInactivityTimerForRequest = new SparseArray<>();
-
- // Inactivity expiry timer. Armed whenever mInactivityTimers is non-empty, regardless of
- // whether the network is inactive or not. Always set to the expiry of the mInactivityTimers
- // that expires last. When the timer fires, all inactivity state is cleared, and if the network
- // has no requests, it is torn down.
- private WakeupMessage mInactivityMessage;
-
- // Inactivity expiry. Holds the expiry time of the inactivity timer, or 0 if the timer is not
- // armed.
- private long mInactivityExpiryMs;
-
- // Whether the network is inactive or not. Must be maintained separately from the above because
- // it depends on the state of other networks and requests, which only ConnectivityService knows.
- // (Example: we don't linger a network if it would become the best for a NetworkRequest if it
- // validated).
- private boolean mInactive;
-
- // This represents the quality of the network. As opposed to NetworkScore, FullScore includes
- // the ConnectivityService-managed bits.
- private FullScore mScore;
-
- // The list of NetworkRequests being satisfied by this Network.
- private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>();
-
- // How many of the satisfied requests are actual requests and not listens.
- private int mNumRequestNetworkRequests = 0;
-
- // How many of the satisfied requests are of type BACKGROUND_REQUEST.
- private int mNumBackgroundNetworkRequests = 0;
-
- // The last ConnectivityReport made available for this network. This value is only null before a
- // report is generated. Once non-null, it will never be null again.
- @Nullable private ConnectivityReport mConnectivityReport;
-
- public final INetworkAgent networkAgent;
- // Only accessed from ConnectivityService handler thread
- private final AgentDeathMonitor mDeathMonitor = new AgentDeathMonitor();
-
- public final int factorySerialNumber;
-
- // Used by ConnectivityService to keep track of 464xlat.
- public final Nat464Xlat clatd;
-
- // Set after asynchronous creation of the NetworkMonitor.
- private volatile NetworkMonitorManager mNetworkMonitor;
-
- private static final String TAG = ConnectivityService.class.getSimpleName();
- private static final boolean VDBG = false;
- private final ConnectivityService mConnService;
- private final Context mContext;
- private final Handler mHandler;
- private final QosCallbackTracker mQosCallbackTracker;
-
- public NetworkAgentInfo(INetworkAgent na, Network net, NetworkInfo info,
- @NonNull LinkProperties lp, @NonNull NetworkCapabilities nc,
- @NonNull NetworkScore score, Context context,
- Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd,
- IDnsResolver dnsResolver, int factorySerialNumber, int creatorUid,
- int lingerDurationMs, QosCallbackTracker qosCallbackTracker,
- ConnectivityService.Dependencies deps) {
- Objects.requireNonNull(net);
- Objects.requireNonNull(info);
- Objects.requireNonNull(lp);
- Objects.requireNonNull(nc);
- Objects.requireNonNull(context);
- Objects.requireNonNull(config);
- Objects.requireNonNull(qosCallbackTracker);
- networkAgent = na;
- network = net;
- networkInfo = info;
- linkProperties = lp;
- networkCapabilities = nc;
- networkAgentConfig = config;
- mConnService = connService;
- setScore(score); // uses members connService, networkCapabilities and networkAgentConfig
- clatd = new Nat464Xlat(this, netd, dnsResolver, deps);
- mContext = context;
- mHandler = handler;
- this.factorySerialNumber = factorySerialNumber;
- this.creatorUid = creatorUid;
- mLingerDurationMs = lingerDurationMs;
- mQosCallbackTracker = qosCallbackTracker;
- }
-
- private class AgentDeathMonitor implements IBinder.DeathRecipient {
- @Override
- public void binderDied() {
- notifyDisconnected();
- }
- }
-
- /**
- * Notify the NetworkAgent that it was registered, and should be unregistered if it dies.
- *
- * Must be called from the ConnectivityService handler thread. A NetworkAgent can only be
- * registered once.
- */
- public void notifyRegistered() {
- try {
- networkAgent.asBinder().linkToDeath(mDeathMonitor, 0);
- networkAgent.onRegistered(new NetworkAgentMessageHandler(mHandler));
- } catch (RemoteException e) {
- Log.e(TAG, "Error registering NetworkAgent", e);
- maybeUnlinkDeathMonitor();
- mHandler.obtainMessage(EVENT_AGENT_REGISTERED, ARG_AGENT_FAILURE, 0, this)
- .sendToTarget();
- return;
- }
-
- mHandler.obtainMessage(EVENT_AGENT_REGISTERED, ARG_AGENT_SUCCESS, 0, this).sendToTarget();
- }
-
- /**
- * Disconnect the NetworkAgent. Must be called from the ConnectivityService handler thread.
- */
- public void disconnect() {
- try {
- networkAgent.onDisconnected();
- } catch (RemoteException e) {
- Log.i(TAG, "Error disconnecting NetworkAgent", e);
- // Fall through: it's fine if the remote has died
- }
-
- notifyDisconnected();
- maybeUnlinkDeathMonitor();
- }
-
- private void maybeUnlinkDeathMonitor() {
- try {
- networkAgent.asBinder().unlinkToDeath(mDeathMonitor, 0);
- } catch (NoSuchElementException e) {
- // Was not linked: ignore
- }
- }
-
- private void notifyDisconnected() {
- // Note this may be called multiple times if ConnectivityService disconnects while the
- // NetworkAgent also dies. ConnectivityService ignores disconnects of already disconnected
- // agents.
- mHandler.obtainMessage(EVENT_AGENT_DISCONNECTED, this).sendToTarget();
- }
-
- /**
- * Notify the NetworkAgent that bandwidth update was requested.
- */
- public void onBandwidthUpdateRequested() {
- try {
- networkAgent.onBandwidthUpdateRequested();
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending bandwidth update request event", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that validation status has changed.
- */
- public void onValidationStatusChanged(int validationStatus, @Nullable String captivePortalUrl) {
- try {
- networkAgent.onValidationStatusChanged(validationStatus, captivePortalUrl);
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending validation status change event", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that the acceptUnvalidated setting should be saved.
- */
- public void onSaveAcceptUnvalidated(boolean acceptUnvalidated) {
- try {
- networkAgent.onSaveAcceptUnvalidated(acceptUnvalidated);
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending accept unvalidated event", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that NATT socket keepalive should be started.
- */
- public void onStartNattSocketKeepalive(int slot, int intervalDurationMs,
- @NonNull NattKeepalivePacketData packetData) {
- try {
- networkAgent.onStartNattSocketKeepalive(slot, intervalDurationMs, packetData);
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending NATT socket keepalive start event", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that TCP socket keepalive should be started.
- */
- public void onStartTcpSocketKeepalive(int slot, int intervalDurationMs,
- @NonNull TcpKeepalivePacketData packetData) {
- try {
- networkAgent.onStartTcpSocketKeepalive(slot, intervalDurationMs, packetData);
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending TCP socket keepalive start event", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that socket keepalive should be stopped.
- */
- public void onStopSocketKeepalive(int slot) {
- try {
- networkAgent.onStopSocketKeepalive(slot);
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending TCP socket keepalive stop event", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that signal strength thresholds should be updated.
- */
- public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) {
- try {
- networkAgent.onSignalStrengthThresholdsUpdated(thresholds);
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending signal strength thresholds event", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that automatic reconnect should be prevented.
- */
- public void onPreventAutomaticReconnect() {
- try {
- networkAgent.onPreventAutomaticReconnect();
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending prevent automatic reconnect event", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that a NATT keepalive packet filter should be added.
- */
- public void onAddNattKeepalivePacketFilter(int slot,
- @NonNull NattKeepalivePacketData packetData) {
- try {
- networkAgent.onAddNattKeepalivePacketFilter(slot, packetData);
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending add NATT keepalive packet filter event", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that a TCP keepalive packet filter should be added.
- */
- public void onAddTcpKeepalivePacketFilter(int slot,
- @NonNull TcpKeepalivePacketData packetData) {
- try {
- networkAgent.onAddTcpKeepalivePacketFilter(slot, packetData);
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending add TCP keepalive packet filter event", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that a keepalive packet filter should be removed.
- */
- public void onRemoveKeepalivePacketFilter(int slot) {
- try {
- networkAgent.onRemoveKeepalivePacketFilter(slot);
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending remove keepalive packet filter event", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that the qos filter should be registered against the given qos
- * callback id.
- */
- public void onQosFilterCallbackRegistered(final int qosCallbackId,
- final QosFilter qosFilter) {
- try {
- networkAgent.onQosFilterCallbackRegistered(qosCallbackId,
- new QosFilterParcelable(qosFilter));
- } catch (final RemoteException e) {
- Log.e(TAG, "Error registering a qos callback id against a qos filter", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that the given qos callback id should be unregistered.
- */
- public void onQosCallbackUnregistered(final int qosCallbackId) {
- try {
- networkAgent.onQosCallbackUnregistered(qosCallbackId);
- } catch (RemoteException e) {
- Log.e(TAG, "Error unregistering a qos callback id", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that the network is successfully connected.
- */
- public void onNetworkCreated() {
- try {
- networkAgent.onNetworkCreated();
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending network created event", e);
- }
- }
-
- /**
- * Notify the NetworkAgent that the native network has been destroyed.
- */
- public void onNetworkDestroyed() {
- try {
- networkAgent.onNetworkDestroyed();
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending network destroyed event", e);
- }
- }
-
- // TODO: consider moving out of NetworkAgentInfo into its own class
- private class NetworkAgentMessageHandler extends INetworkAgentRegistry.Stub {
- private final Handler mHandler;
-
- private NetworkAgentMessageHandler(Handler handler) {
- mHandler = handler;
- }
-
- @Override
- public void sendNetworkCapabilities(@NonNull NetworkCapabilities nc) {
- Objects.requireNonNull(nc);
- mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED,
- new Pair<>(NetworkAgentInfo.this, nc)).sendToTarget();
- }
-
- @Override
- public void sendLinkProperties(@NonNull LinkProperties lp) {
- Objects.requireNonNull(lp);
- mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED,
- new Pair<>(NetworkAgentInfo.this, lp)).sendToTarget();
- }
-
- @Override
- public void sendNetworkInfo(@NonNull NetworkInfo info) {
- Objects.requireNonNull(info);
- mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_INFO_CHANGED,
- new Pair<>(NetworkAgentInfo.this, info)).sendToTarget();
- }
-
- @Override
- public void sendScore(@NonNull final NetworkScore score) {
- mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_SCORE_CHANGED,
- new Pair<>(NetworkAgentInfo.this, score)).sendToTarget();
- }
-
- @Override
- public void sendExplicitlySelected(boolean explicitlySelected, boolean acceptPartial) {
- mHandler.obtainMessage(NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED,
- explicitlySelected ? 1 : 0, acceptPartial ? 1 : 0,
- new Pair<>(NetworkAgentInfo.this, null)).sendToTarget();
- }
-
- @Override
- public void sendSocketKeepaliveEvent(int slot, int reason) {
- mHandler.obtainMessage(NetworkAgent.EVENT_SOCKET_KEEPALIVE,
- slot, reason, new Pair<>(NetworkAgentInfo.this, null)).sendToTarget();
- }
-
- @Override
- public void sendUnderlyingNetworks(@Nullable List<Network> networks) {
- mHandler.obtainMessage(NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED,
- new Pair<>(NetworkAgentInfo.this, networks)).sendToTarget();
- }
-
- @Override
- public void sendEpsQosSessionAvailable(final int qosCallbackId, final QosSession session,
- final EpsBearerQosSessionAttributes attributes) {
- mQosCallbackTracker.sendEventEpsQosSessionAvailable(qosCallbackId, session, attributes);
- }
-
- @Override
- public void sendNrQosSessionAvailable(final int qosCallbackId, final QosSession session,
- final NrQosSessionAttributes attributes) {
- mQosCallbackTracker.sendEventNrQosSessionAvailable(qosCallbackId, session, attributes);
- }
-
- @Override
- public void sendQosSessionLost(final int qosCallbackId, final QosSession session) {
- mQosCallbackTracker.sendEventQosSessionLost(qosCallbackId, session);
- }
-
- @Override
- public void sendQosCallbackError(final int qosCallbackId,
- @QosCallbackException.ExceptionType final int exceptionType) {
- mQosCallbackTracker.sendEventQosCallbackError(qosCallbackId, exceptionType);
- }
-
- @Override
- public void sendTeardownDelayMs(int teardownDelayMs) {
- mHandler.obtainMessage(NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED,
- teardownDelayMs, 0, new Pair<>(NetworkAgentInfo.this, null)).sendToTarget();
- }
-
- @Override
- public void sendLingerDuration(final int durationMs) {
- mHandler.obtainMessage(NetworkAgent.EVENT_LINGER_DURATION_CHANGED,
- new Pair<>(NetworkAgentInfo.this, durationMs)).sendToTarget();
- }
- }
-
- /**
- * Inform NetworkAgentInfo that a new NetworkMonitor was created.
- */
- public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) {
- mNetworkMonitor = new NetworkMonitorManager(networkMonitor);
- }
-
- /**
- * Set the NetworkCapabilities on this NetworkAgentInfo. Also attempts to notify NetworkMonitor
- * of the new capabilities, if NetworkMonitor has been created.
- *
- * <p>If {@link NetworkMonitor#notifyNetworkCapabilitiesChanged(NetworkCapabilities)} fails,
- * the exception is logged but not reported to callers.
- *
- * @return the old capabilities of this network.
- */
- @NonNull public synchronized NetworkCapabilities getAndSetNetworkCapabilities(
- @NonNull final NetworkCapabilities nc) {
- final NetworkCapabilities oldNc = networkCapabilities;
- networkCapabilities = nc;
- mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig, everValidatedForYield(),
- yieldToBadWiFi());
- final NetworkMonitorManager nm = mNetworkMonitor;
- if (nm != null) {
- nm.notifyNetworkCapabilitiesChanged(nc);
- }
- return oldNc;
- }
-
- private boolean yieldToBadWiFi() {
- // Only cellular networks yield to bad wifi
- return networkCapabilities.hasTransport(TRANSPORT_CELLULAR) && !mConnService.avoidBadWifi();
- }
-
- public ConnectivityService connService() {
- return mConnService;
- }
-
- public NetworkAgentConfig netAgentConfig() {
- return networkAgentConfig;
- }
-
- public Handler handler() {
- return mHandler;
- }
-
- public Network network() {
- return network;
- }
-
- /**
- * Get the NetworkMonitorManager in this NetworkAgentInfo.
- *
- * <p>This will be null before {@link #onNetworkMonitorCreated(INetworkMonitor)} is called.
- */
- public NetworkMonitorManager networkMonitor() {
- return mNetworkMonitor;
- }
-
- // Functions for manipulating the requests satisfied by this network.
- //
- // These functions must only called on ConnectivityService's main thread.
-
- private static final boolean ADD = true;
- private static final boolean REMOVE = false;
-
- private void updateRequestCounts(boolean add, NetworkRequest request) {
- int delta = add ? +1 : -1;
- switch (request.type) {
- case REQUEST:
- mNumRequestNetworkRequests += delta;
- break;
-
- case BACKGROUND_REQUEST:
- mNumRequestNetworkRequests += delta;
- mNumBackgroundNetworkRequests += delta;
- break;
-
- case LISTEN:
- case LISTEN_FOR_BEST:
- case TRACK_DEFAULT:
- case TRACK_SYSTEM_DEFAULT:
- break;
-
- case NONE:
- default:
- Log.wtf(TAG, "Unhandled request type " + request.type);
- break;
- }
- }
-
- /**
- * Add {@code networkRequest} to this network as it's satisfied by this network.
- * @return true if {@code networkRequest} was added or false if {@code networkRequest} was
- * already present.
- */
- public boolean addRequest(NetworkRequest networkRequest) {
- NetworkRequest existing = mNetworkRequests.get(networkRequest.requestId);
- if (existing == networkRequest) return false;
- if (existing != null) {
- // Should only happen if the requestId wraps. If that happens lots of other things will
- // be broken as well.
- Log.wtf(TAG, String.format("Duplicate requestId for %s and %s on %s",
- networkRequest, existing, toShortString()));
- updateRequestCounts(REMOVE, existing);
- }
- mNetworkRequests.put(networkRequest.requestId, networkRequest);
- updateRequestCounts(ADD, networkRequest);
- return true;
- }
-
- /**
- * Remove the specified request from this network.
- */
- public void removeRequest(int requestId) {
- NetworkRequest existing = mNetworkRequests.get(requestId);
- if (existing == null) return;
- updateRequestCounts(REMOVE, existing);
- mNetworkRequests.remove(requestId);
- if (existing.isRequest()) {
- unlingerRequest(existing.requestId);
- }
- }
-
- /**
- * Returns whether this network is currently satisfying the request with the specified ID.
- */
- public boolean isSatisfyingRequest(int id) {
- return mNetworkRequests.get(id) != null;
- }
-
- /**
- * Returns the request at the specified position in the list of requests satisfied by this
- * network.
- */
- public NetworkRequest requestAt(int index) {
- return mNetworkRequests.valueAt(index);
- }
-
- /**
- * Returns the number of requests currently satisfied by this network for which
- * {@link android.net.NetworkRequest#isRequest} returns {@code true}.
- */
- public int numRequestNetworkRequests() {
- return mNumRequestNetworkRequests;
- }
-
- /**
- * Returns the number of requests currently satisfied by this network of type
- * {@link android.net.NetworkRequest.Type.BACKGROUND_REQUEST}.
- */
- public int numBackgroundNetworkRequests() {
- return mNumBackgroundNetworkRequests;
- }
-
- /**
- * Returns the number of foreground requests currently satisfied by this network.
- */
- public int numForegroundNetworkRequests() {
- return mNumRequestNetworkRequests - mNumBackgroundNetworkRequests;
- }
-
- /**
- * Returns the number of requests of any type currently satisfied by this network.
- */
- public int numNetworkRequests() {
- return mNetworkRequests.size();
- }
-
- /**
- * Returns whether the network is a background network. A network is a background network if it
- * does not have the NET_CAPABILITY_FOREGROUND capability, which implies it is satisfying no
- * foreground request, is not lingering (i.e. kept for a while after being outscored), and is
- * not a speculative network (i.e. kept pending validation when validation would have it
- * outscore another foreground network). That implies it is being kept up by some background
- * request (otherwise it would be torn down), maybe the mobile always-on request.
- */
- public boolean isBackgroundNetwork() {
- return !isVPN() && numForegroundNetworkRequests() == 0 && mNumBackgroundNetworkRequests > 0
- && !isLingering();
- }
-
- // Does this network satisfy request?
- public boolean satisfies(NetworkRequest request) {
- return created &&
- request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities);
- }
-
- public boolean satisfiesImmutableCapabilitiesOf(NetworkRequest request) {
- return created &&
- request.networkCapabilities.satisfiedByImmutableNetworkCapabilities(
- networkCapabilities);
- }
-
- /** Whether this network is a VPN. */
- public boolean isVPN() {
- return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
- }
-
- /** Whether this network might have underlying networks. Currently only true for VPNs. */
- public boolean supportsUnderlyingNetworks() {
- return isVPN();
- }
-
- // Caller must not mutate. This method is called frequently and making a defensive copy
- // would be too expensive. This is used by NetworkRanker.Scoreable, so it can be compared
- // against other scoreables.
- @Override public NetworkCapabilities getCapsNoCopy() {
- return networkCapabilities;
- }
-
- // NetworkRanker.Scoreable
- @Override public FullScore getScore() {
- return mScore;
- }
-
- // Get the current score for this Network. This may be modified from what the
- // NetworkAgent sent, as it has modifiers applied to it.
- public int getCurrentScore() {
- return mScore.getLegacyInt();
- }
-
- // Get the current score for this Network as if it was validated. This may be modified from
- // what the NetworkAgent sent, as it has modifiers applied to it.
- public int getCurrentScoreAsValidated() {
- return mScore.getLegacyIntAsValidated();
- }
-
- /**
- * Mix-in the ConnectivityService-managed bits in the score.
- */
- public void setScore(final NetworkScore score) {
- mScore = FullScore.fromNetworkScore(score, networkCapabilities, networkAgentConfig,
- everValidatedForYield(), yieldToBadWiFi());
- }
-
- /**
- * Update the ConnectivityService-managed bits in the score.
- *
- * Call this after updating the network agent config.
- */
- public void updateScoreForNetworkAgentUpdate() {
- mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig,
- everValidatedForYield(), yieldToBadWiFi());
- }
-
- private boolean everValidatedForYield() {
- return everValidated && !avoidUnvalidated;
- }
-
- /**
- * Returns a Scoreable identical to this NAI, but validated.
- *
- * This is useful to probe what scoring would be if this network validated, to know
- * whether to provisionally keep a network that may or may not validate.
- *
- * @return a Scoreable identical to this NAI, but validated.
- */
- public NetworkRanker.Scoreable getValidatedScoreable() {
- return new NetworkRanker.Scoreable() {
- @Override public FullScore getScore() {
- return mScore.asValidated();
- }
-
- @Override public NetworkCapabilities getCapsNoCopy() {
- return networkCapabilities;
- }
- };
- }
-
- /**
- * Return a {@link NetworkStateSnapshot} for this network.
- */
- @NonNull
- public NetworkStateSnapshot getNetworkStateSnapshot() {
- synchronized (this) {
- // Network objects are outwardly immutable so there is no point in duplicating.
- // Duplicating also precludes sharing socket factories and connection pools.
- final String subscriberId = (networkAgentConfig != null)
- ? networkAgentConfig.subscriberId : null;
- return new NetworkStateSnapshot(network, new NetworkCapabilities(networkCapabilities),
- new LinkProperties(linkProperties), subscriberId, networkInfo.getType());
- }
- }
-
- /**
- * Sets the specified requestId to linger on this network for the specified time. Called by
- * ConnectivityService when any request is moved to another network with a higher score, or
- * when a network is newly created.
- *
- * @param requestId The requestId of the request that no longer need to be served by this
- * network. Or {@link NetworkRequest.REQUEST_ID_NONE} if this is the
- * {@code InactivityTimer} for a newly created network.
- */
- // TODO: Consider creating a dedicated function for nascent network, e.g. start/stopNascent.
- public void lingerRequest(int requestId, long now, long duration) {
- if (mInactivityTimerForRequest.get(requestId) != null) {
- // Cannot happen. Once a request is lingering on a particular network, we cannot
- // re-linger it unless that network becomes the best for that request again, in which
- // case we should have unlingered it.
- Log.wtf(TAG, toShortString() + ": request " + requestId + " already lingered");
- }
- final long expiryMs = now + duration;
- InactivityTimer timer = new InactivityTimer(requestId, expiryMs);
- if (VDBG) Log.d(TAG, "Adding InactivityTimer " + timer + " to " + toShortString());
- mInactivityTimers.add(timer);
- mInactivityTimerForRequest.put(requestId, timer);
- }
-
- /**
- * Sets the specified requestId to linger on this network for the timeout set when
- * initializing or modified by {@link #setLingerDuration(int)}. Called by
- * ConnectivityService when any request is moved to another network with a higher score.
- *
- * @param requestId The requestId of the request that no longer need to be served by this
- * network.
- * @param now current system timestamp obtained by {@code SystemClock.elapsedRealtime}.
- */
- public void lingerRequest(int requestId, long now) {
- lingerRequest(requestId, now, mLingerDurationMs);
- }
-
- /**
- * Cancel lingering. Called by ConnectivityService when a request is added to this network.
- * Returns true if the given requestId was lingering on this network, false otherwise.
- */
- public boolean unlingerRequest(int requestId) {
- InactivityTimer timer = mInactivityTimerForRequest.get(requestId);
- if (timer != null) {
- if (VDBG) {
- Log.d(TAG, "Removing InactivityTimer " + timer + " from " + toShortString());
- }
- mInactivityTimers.remove(timer);
- mInactivityTimerForRequest.remove(requestId);
- return true;
- }
- return false;
- }
-
- public long getInactivityExpiry() {
- return mInactivityExpiryMs;
- }
-
- public void updateInactivityTimer() {
- long newExpiry = mInactivityTimers.isEmpty() ? 0 : mInactivityTimers.last().expiryMs;
- if (newExpiry == mInactivityExpiryMs) return;
-
- // Even if we're going to reschedule the timer, cancel it first. This is because the
- // semantics of WakeupMessage guarantee that if cancel is called then the alarm will
- // never call its callback (handleLingerComplete), even if it has already fired.
- // WakeupMessage makes no such guarantees about rescheduling a message, so if mLingerMessage
- // has already been dispatched, rescheduling to some time in the future won't stop it
- // from calling its callback immediately.
- if (mInactivityMessage != null) {
- mInactivityMessage.cancel();
- mInactivityMessage = null;
- }
-
- if (newExpiry > 0) {
- // If the newExpiry timestamp is in the past, the wakeup message will fire immediately.
- mInactivityMessage = new WakeupMessage(
- mContext, mHandler,
- "NETWORK_LINGER_COMPLETE." + network.getNetId() /* cmdName */,
- EVENT_NETWORK_LINGER_COMPLETE /* cmd */,
- 0 /* arg1 (unused) */, 0 /* arg2 (unused) */,
- this /* obj (NetworkAgentInfo) */);
- mInactivityMessage.schedule(newExpiry);
- }
-
- mInactivityExpiryMs = newExpiry;
- }
-
- public void setInactive() {
- mInactive = true;
- }
-
- public void unsetInactive() {
- mInactive = false;
- }
-
- public boolean isInactive() {
- return mInactive;
- }
-
- public boolean isLingering() {
- return mInactive && !isNascent();
- }
-
- /**
- * Set the linger duration for this NAI.
- * @param durationMs The new linger duration, in milliseconds.
- */
- public void setLingerDuration(final int durationMs) {
- final long diff = durationMs - mLingerDurationMs;
- final ArrayList<InactivityTimer> newTimers = new ArrayList<>();
- for (final InactivityTimer timer : mInactivityTimers) {
- if (timer.requestId == NetworkRequest.REQUEST_ID_NONE) {
- // Don't touch nascent timer, re-add as is.
- newTimers.add(timer);
- } else {
- newTimers.add(new InactivityTimer(timer.requestId, timer.expiryMs + diff));
- }
- }
- mInactivityTimers.clear();
- mInactivityTimers.addAll(newTimers);
- updateInactivityTimer();
- mLingerDurationMs = durationMs;
- }
-
- /**
- * Return whether the network satisfies no request, but is still being kept up
- * because it has just connected less than
- * {@code ConnectivityService#DEFAULT_NASCENT_DELAY_MS}ms ago and is thus still considered
- * nascent. Note that nascent mechanism uses inactivity timer which isn't
- * associated with a request. Thus, use {@link NetworkRequest#REQUEST_ID_NONE} to identify it.
- *
- */
- public boolean isNascent() {
- return mInactive && mInactivityTimers.size() == 1
- && mInactivityTimers.first().requestId == NetworkRequest.REQUEST_ID_NONE;
- }
-
- public void clearInactivityState() {
- if (mInactivityMessage != null) {
- mInactivityMessage.cancel();
- mInactivityMessage = null;
- }
- mInactivityTimers.clear();
- mInactivityTimerForRequest.clear();
- // Sets mInactivityExpiryMs, cancels and nulls out mInactivityMessage.
- updateInactivityTimer();
- mInactive = false;
- }
-
- public void dumpInactivityTimers(PrintWriter pw) {
- for (InactivityTimer timer : mInactivityTimers) {
- pw.println(timer);
- }
- }
-
- /**
- * Sets the most recent ConnectivityReport for this network.
- *
- * <p>This should only be called from the ConnectivityService thread.
- *
- * @hide
- */
- public void setConnectivityReport(@NonNull ConnectivityReport connectivityReport) {
- mConnectivityReport = connectivityReport;
- }
-
- /**
- * Returns the most recent ConnectivityReport for this network, or null if none have been
- * reported yet.
- *
- * <p>This should only be called from the ConnectivityService thread.
- *
- * @hide
- */
- @Nullable
- public ConnectivityReport getConnectivityReport() {
- return mConnectivityReport;
- }
-
- // TODO: Print shorter members first and only print the boolean variable which value is true
- // to improve readability.
- public String toString() {
- return "NetworkAgentInfo{"
- + "network{" + network + "} handle{" + network.getNetworkHandle() + "} ni{"
- + networkInfo.toShortString() + "} "
- + mScore + " "
- + (isNascent() ? " nascent" : (isLingering() ? " lingering" : ""))
- + (everValidated ? " everValidated" : "")
- + (lastValidated ? " lastValidated" : "")
- + (partialConnectivity ? " partialConnectivity" : "")
- + (everCaptivePortalDetected ? " everCaptivePortal" : "")
- + (lastCaptivePortalDetected ? " isCaptivePortal" : "")
- + (networkAgentConfig.explicitlySelected ? " explicitlySelected" : "")
- + (networkAgentConfig.acceptUnvalidated ? " acceptUnvalidated" : "")
- + (networkAgentConfig.acceptPartialConnectivity ? " acceptPartialConnectivity" : "")
- + (clatd.isStarted() ? " clat{" + clatd + "} " : "")
- + (declaredUnderlyingNetworks != null
- ? " underlying{" + Arrays.toString(declaredUnderlyingNetworks) + "}" : "")
- + " lp{" + linkProperties + "}"
- + " nc{" + networkCapabilities + "}"
- + "}";
- }
-
- /**
- * Show a short string representing a Network.
- *
- * This is often not enough for debugging purposes for anything complex, but the full form
- * is very long and hard to read, so this is useful when there isn't a lot of ambiguity.
- * This represents the network with something like "[100 WIFI|VPN]" or "[108 MOBILE]".
- */
- public String toShortString() {
- return "[" + network.getNetId() + " "
- + transportNamesOf(networkCapabilities.getTransportTypes()) + "]";
- }
-
- // Enables sorting in descending order of score.
- @Override
- public int compareTo(NetworkAgentInfo other) {
- return other.getCurrentScore() - getCurrentScore();
- }
-
- /**
- * Null-guarding version of NetworkAgentInfo#toShortString()
- */
- @NonNull
- public static String toShortString(@Nullable final NetworkAgentInfo nai) {
- return null != nai ? nai.toShortString() : "[null]";
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/NetworkDiagnostics.java b/packages/Connectivity/service/src/com/android/server/connectivity/NetworkDiagnostics.java
deleted file mode 100644
index 2e51be3..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/NetworkDiagnostics.java
+++ /dev/null
@@ -1,757 +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.connectivity;
-
-import static android.system.OsConstants.*;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.InetAddresses;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.RouteInfo;
-import android.net.TrafficStats;
-import android.net.shared.PrivateDnsConfig;
-import android.net.util.NetworkConstants;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.StructTimeval;
-import android.text.TextUtils;
-import android.util.Pair;
-
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.net.module.util.NetworkStackConstants;
-
-import libcore.io.IoUtils;
-
-import java.io.Closeable;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.NetworkInterface;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.net.ssl.SNIHostName;
-import javax.net.ssl.SNIServerName;
-import javax.net.ssl.SSLParameters;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-
-/**
- * NetworkDiagnostics
- *
- * A simple class to diagnose network connectivity fundamentals. Current
- * checks performed are:
- * - ICMPv4/v6 echo requests for all routers
- * - ICMPv4/v6 echo requests for all DNS servers
- * - DNS UDP queries to all DNS servers
- *
- * Currently unimplemented checks include:
- * - report ARP/ND data about on-link neighbors
- * - DNS TCP queries to all DNS servers
- * - HTTP DIRECT and PROXY checks
- * - port 443 blocking/TLS intercept checks
- * - QUIC reachability checks
- * - MTU checks
- *
- * The supplied timeout bounds the entire diagnostic process. Each specific
- * check class must implement this upper bound on measurements in whichever
- * manner is most appropriate and effective.
- *
- * @hide
- */
-public class NetworkDiagnostics {
- private static final String TAG = "NetworkDiagnostics";
-
- private static final InetAddress TEST_DNS4 = InetAddresses.parseNumericAddress("8.8.8.8");
- private static final InetAddress TEST_DNS6 = InetAddresses.parseNumericAddress(
- "2001:4860:4860::8888");
-
- // For brevity elsewhere.
- private static final long now() {
- return SystemClock.elapsedRealtime();
- }
-
- // Values from RFC 1035 section 4.1.1, names from <arpa/nameser.h>.
- // Should be a member of DnsUdpCheck, but "compiler says no".
- public static enum DnsResponseCode { NOERROR, FORMERR, SERVFAIL, NXDOMAIN, NOTIMP, REFUSED };
-
- private final Network mNetwork;
- private final LinkProperties mLinkProperties;
- private final PrivateDnsConfig mPrivateDnsCfg;
- private final Integer mInterfaceIndex;
-
- private final long mTimeoutMs;
- private final long mStartTime;
- private final long mDeadlineTime;
-
- // A counter, initialized to the total number of measurements,
- // so callers can wait for completion.
- private final CountDownLatch mCountDownLatch;
-
- public class Measurement {
- private static final String SUCCEEDED = "SUCCEEDED";
- private static final String FAILED = "FAILED";
-
- private boolean succeeded;
-
- // Package private. TODO: investigate better encapsulation.
- String description = "";
- long startTime;
- long finishTime;
- String result = "";
- Thread thread;
-
- public boolean checkSucceeded() { return succeeded; }
-
- void recordSuccess(String msg) {
- maybeFixupTimes();
- succeeded = true;
- result = SUCCEEDED + ": " + msg;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- void recordFailure(String msg) {
- maybeFixupTimes();
- succeeded = false;
- result = FAILED + ": " + msg;
- if (mCountDownLatch != null) {
- mCountDownLatch.countDown();
- }
- }
-
- private void maybeFixupTimes() {
- // Allows the caller to just set success/failure and not worry
- // about also setting the correct finishing time.
- if (finishTime == 0) { finishTime = now(); }
-
- // In cases where, for example, a failure has occurred before the
- // measurement even began, fixup the start time to reflect as much.
- if (startTime == 0) { startTime = finishTime; }
- }
-
- @Override
- public String toString() {
- return description + ": " + result + " (" + (finishTime - startTime) + "ms)";
- }
- }
-
- private final Map<InetAddress, Measurement> mIcmpChecks = new HashMap<>();
- private final Map<Pair<InetAddress, InetAddress>, Measurement> mExplicitSourceIcmpChecks =
- new HashMap<>();
- private final Map<InetAddress, Measurement> mDnsUdpChecks = new HashMap<>();
- private final Map<InetAddress, Measurement> mDnsTlsChecks = new HashMap<>();
- private final String mDescription;
-
-
- public NetworkDiagnostics(Network network, LinkProperties lp,
- @NonNull PrivateDnsConfig privateDnsCfg, long timeoutMs) {
- mNetwork = network;
- mLinkProperties = lp;
- mPrivateDnsCfg = privateDnsCfg;
- mInterfaceIndex = getInterfaceIndex(mLinkProperties.getInterfaceName());
- mTimeoutMs = timeoutMs;
- mStartTime = now();
- mDeadlineTime = mStartTime + mTimeoutMs;
-
- // Hardcode measurements to TEST_DNS4 and TEST_DNS6 in order to test off-link connectivity.
- // We are free to modify mLinkProperties with impunity because ConnectivityService passes us
- // a copy and not the original object. It's easier to do it this way because we don't need
- // to check whether the LinkProperties already contains these DNS servers because
- // LinkProperties#addDnsServer checks for duplicates.
- if (mLinkProperties.isReachable(TEST_DNS4)) {
- mLinkProperties.addDnsServer(TEST_DNS4);
- }
- // TODO: we could use mLinkProperties.isReachable(TEST_DNS6) here, because we won't set any
- // DNS servers for which isReachable() is false, but since this is diagnostic code, be extra
- // careful.
- if (mLinkProperties.hasGlobalIpv6Address() || mLinkProperties.hasIpv6DefaultRoute()) {
- mLinkProperties.addDnsServer(TEST_DNS6);
- }
-
- for (RouteInfo route : mLinkProperties.getRoutes()) {
- if (route.hasGateway()) {
- InetAddress gateway = route.getGateway();
- prepareIcmpMeasurement(gateway);
- if (route.isIPv6Default()) {
- prepareExplicitSourceIcmpMeasurements(gateway);
- }
- }
- }
- for (InetAddress nameserver : mLinkProperties.getDnsServers()) {
- prepareIcmpMeasurement(nameserver);
- prepareDnsMeasurement(nameserver);
-
- // Unlike the DnsResolver which doesn't do certificate validation in opportunistic mode,
- // DoT probes to the DNS servers will fail if certificate validation fails.
- prepareDnsTlsMeasurement(null /* hostname */, nameserver);
- }
-
- for (InetAddress tlsNameserver : mPrivateDnsCfg.ips) {
- // Reachability check is necessary since when resolving the strict mode hostname,
- // NetworkMonitor always queries for both A and AAAA records, even if the network
- // is IPv4-only or IPv6-only.
- if (mLinkProperties.isReachable(tlsNameserver)) {
- // If there are IPs, there must have been a name that resolved to them.
- prepareDnsTlsMeasurement(mPrivateDnsCfg.hostname, tlsNameserver);
- }
- }
-
- mCountDownLatch = new CountDownLatch(totalMeasurementCount());
-
- startMeasurements();
-
- mDescription = "ifaces{" + TextUtils.join(",", mLinkProperties.getAllInterfaceNames()) + "}"
- + " index{" + mInterfaceIndex + "}"
- + " network{" + mNetwork + "}"
- + " nethandle{" + mNetwork.getNetworkHandle() + "}";
- }
-
- private static Integer getInterfaceIndex(String ifname) {
- try {
- NetworkInterface ni = NetworkInterface.getByName(ifname);
- return ni.getIndex();
- } catch (NullPointerException | SocketException e) {
- return null;
- }
- }
-
- private static String socketAddressToString(@NonNull SocketAddress sockAddr) {
- // The default toString() implementation is not the prettiest.
- InetSocketAddress inetSockAddr = (InetSocketAddress) sockAddr;
- InetAddress localAddr = inetSockAddr.getAddress();
- return String.format(
- (localAddr instanceof Inet6Address ? "[%s]:%d" : "%s:%d"),
- localAddr.getHostAddress(), inetSockAddr.getPort());
- }
-
- private void prepareIcmpMeasurement(InetAddress target) {
- if (!mIcmpChecks.containsKey(target)) {
- Measurement measurement = new Measurement();
- measurement.thread = new Thread(new IcmpCheck(target, measurement));
- mIcmpChecks.put(target, measurement);
- }
- }
-
- private void prepareExplicitSourceIcmpMeasurements(InetAddress target) {
- for (LinkAddress l : mLinkProperties.getLinkAddresses()) {
- InetAddress source = l.getAddress();
- if (source instanceof Inet6Address && l.isGlobalPreferred()) {
- Pair<InetAddress, InetAddress> srcTarget = new Pair<>(source, target);
- if (!mExplicitSourceIcmpChecks.containsKey(srcTarget)) {
- Measurement measurement = new Measurement();
- measurement.thread = new Thread(new IcmpCheck(source, target, measurement));
- mExplicitSourceIcmpChecks.put(srcTarget, measurement);
- }
- }
- }
- }
-
- private void prepareDnsMeasurement(InetAddress target) {
- if (!mDnsUdpChecks.containsKey(target)) {
- Measurement measurement = new Measurement();
- measurement.thread = new Thread(new DnsUdpCheck(target, measurement));
- mDnsUdpChecks.put(target, measurement);
- }
- }
-
- private void prepareDnsTlsMeasurement(@Nullable String hostname, @NonNull InetAddress target) {
- // This might overwrite an existing entry in mDnsTlsChecks, because |target| can be an IP
- // address configured by the network as well as an IP address learned by resolving the
- // strict mode DNS hostname. If the entry is overwritten, the overwritten measurement
- // thread will not execute.
- Measurement measurement = new Measurement();
- measurement.thread = new Thread(new DnsTlsCheck(hostname, target, measurement));
- mDnsTlsChecks.put(target, measurement);
- }
-
- private int totalMeasurementCount() {
- return mIcmpChecks.size() + mExplicitSourceIcmpChecks.size() + mDnsUdpChecks.size()
- + mDnsTlsChecks.size();
- }
-
- private void startMeasurements() {
- for (Measurement measurement : mIcmpChecks.values()) {
- measurement.thread.start();
- }
- for (Measurement measurement : mExplicitSourceIcmpChecks.values()) {
- measurement.thread.start();
- }
- for (Measurement measurement : mDnsUdpChecks.values()) {
- measurement.thread.start();
- }
- for (Measurement measurement : mDnsTlsChecks.values()) {
- measurement.thread.start();
- }
- }
-
- public void waitForMeasurements() {
- try {
- mCountDownLatch.await(mDeadlineTime - now(), TimeUnit.MILLISECONDS);
- } catch (InterruptedException ignored) {}
- }
-
- public List<Measurement> getMeasurements() {
- // TODO: Consider moving waitForMeasurements() in here to minimize the
- // chance of caller errors.
-
- ArrayList<Measurement> measurements = new ArrayList(totalMeasurementCount());
-
- // Sort measurements IPv4 first.
- for (Map.Entry<InetAddress, Measurement> entry : mIcmpChecks.entrySet()) {
- if (entry.getKey() instanceof Inet4Address) {
- measurements.add(entry.getValue());
- }
- }
- for (Map.Entry<Pair<InetAddress, InetAddress>, Measurement> entry :
- mExplicitSourceIcmpChecks.entrySet()) {
- if (entry.getKey().first instanceof Inet4Address) {
- measurements.add(entry.getValue());
- }
- }
- for (Map.Entry<InetAddress, Measurement> entry : mDnsUdpChecks.entrySet()) {
- if (entry.getKey() instanceof Inet4Address) {
- measurements.add(entry.getValue());
- }
- }
- for (Map.Entry<InetAddress, Measurement> entry : mDnsTlsChecks.entrySet()) {
- if (entry.getKey() instanceof Inet4Address) {
- measurements.add(entry.getValue());
- }
- }
-
- // IPv6 measurements second.
- for (Map.Entry<InetAddress, Measurement> entry : mIcmpChecks.entrySet()) {
- if (entry.getKey() instanceof Inet6Address) {
- measurements.add(entry.getValue());
- }
- }
- for (Map.Entry<Pair<InetAddress, InetAddress>, Measurement> entry :
- mExplicitSourceIcmpChecks.entrySet()) {
- if (entry.getKey().first instanceof Inet6Address) {
- measurements.add(entry.getValue());
- }
- }
- for (Map.Entry<InetAddress, Measurement> entry : mDnsUdpChecks.entrySet()) {
- if (entry.getKey() instanceof Inet6Address) {
- measurements.add(entry.getValue());
- }
- }
- for (Map.Entry<InetAddress, Measurement> entry : mDnsTlsChecks.entrySet()) {
- if (entry.getKey() instanceof Inet6Address) {
- measurements.add(entry.getValue());
- }
- }
-
- return measurements;
- }
-
- public void dump(IndentingPrintWriter pw) {
- pw.println(TAG + ":" + mDescription);
- final long unfinished = mCountDownLatch.getCount();
- if (unfinished > 0) {
- // This can't happen unless a caller forgets to call waitForMeasurements()
- // or a measurement isn't implemented to correctly honor the timeout.
- pw.println("WARNING: countdown wait incomplete: "
- + unfinished + " unfinished measurements");
- }
-
- pw.increaseIndent();
-
- String prefix;
- for (Measurement m : getMeasurements()) {
- prefix = m.checkSucceeded() ? "." : "F";
- pw.println(prefix + " " + m.toString());
- }
-
- pw.decreaseIndent();
- }
-
-
- private class SimpleSocketCheck implements Closeable {
- protected final InetAddress mSource; // Usually null.
- protected final InetAddress mTarget;
- protected final int mAddressFamily;
- protected final Measurement mMeasurement;
- protected FileDescriptor mFileDescriptor;
- protected SocketAddress mSocketAddress;
-
- protected SimpleSocketCheck(
- InetAddress source, InetAddress target, Measurement measurement) {
- mMeasurement = measurement;
-
- if (target instanceof Inet6Address) {
- Inet6Address targetWithScopeId = null;
- if (target.isLinkLocalAddress() && mInterfaceIndex != null) {
- try {
- targetWithScopeId = Inet6Address.getByAddress(
- null, target.getAddress(), mInterfaceIndex);
- } catch (UnknownHostException e) {
- mMeasurement.recordFailure(e.toString());
- }
- }
- mTarget = (targetWithScopeId != null) ? targetWithScopeId : target;
- mAddressFamily = AF_INET6;
- } else {
- mTarget = target;
- mAddressFamily = AF_INET;
- }
-
- // We don't need to check the scope ID here because we currently only do explicit-source
- // measurements from global IPv6 addresses.
- mSource = source;
- }
-
- protected SimpleSocketCheck(InetAddress target, Measurement measurement) {
- this(null, target, measurement);
- }
-
- protected void setupSocket(
- int sockType, int protocol, long writeTimeout, long readTimeout, int dstPort)
- throws ErrnoException, IOException {
- final int oldTag = TrafficStats.getAndSetThreadStatsTag(
- NetworkStackConstants.TAG_SYSTEM_PROBE);
- try {
- mFileDescriptor = Os.socket(mAddressFamily, sockType, protocol);
- } finally {
- // TODO: The tag should remain set until all traffic is sent and received.
- // Consider tagging the socket after the measurement thread is started.
- TrafficStats.setThreadStatsTag(oldTag);
- }
- // Setting SNDTIMEO is purely for defensive purposes.
- Os.setsockoptTimeval(mFileDescriptor,
- SOL_SOCKET, SO_SNDTIMEO, StructTimeval.fromMillis(writeTimeout));
- Os.setsockoptTimeval(mFileDescriptor,
- SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(readTimeout));
- // TODO: Use IP_RECVERR/IPV6_RECVERR, pending OsContants availability.
- mNetwork.bindSocket(mFileDescriptor);
- if (mSource != null) {
- Os.bind(mFileDescriptor, mSource, 0);
- }
- Os.connect(mFileDescriptor, mTarget, dstPort);
- mSocketAddress = Os.getsockname(mFileDescriptor);
- }
-
- protected boolean ensureMeasurementNecessary() {
- if (mMeasurement.finishTime == 0) return false;
-
- // Countdown latch was not decremented when the measurement failed during setup.
- mCountDownLatch.countDown();
- return true;
- }
-
- @Override
- public void close() {
- IoUtils.closeQuietly(mFileDescriptor);
- }
- }
-
-
- private class IcmpCheck extends SimpleSocketCheck implements Runnable {
- private static final int TIMEOUT_SEND = 100;
- private static final int TIMEOUT_RECV = 300;
- private static final int PACKET_BUFSIZE = 512;
- private final int mProtocol;
- private final int mIcmpType;
-
- public IcmpCheck(InetAddress source, InetAddress target, Measurement measurement) {
- super(source, target, measurement);
-
- if (mAddressFamily == AF_INET6) {
- mProtocol = IPPROTO_ICMPV6;
- mIcmpType = NetworkConstants.ICMPV6_ECHO_REQUEST_TYPE;
- mMeasurement.description = "ICMPv6";
- } else {
- mProtocol = IPPROTO_ICMP;
- mIcmpType = NetworkConstants.ICMPV4_ECHO_REQUEST_TYPE;
- mMeasurement.description = "ICMPv4";
- }
-
- mMeasurement.description += " dst{" + mTarget.getHostAddress() + "}";
- }
-
- public IcmpCheck(InetAddress target, Measurement measurement) {
- this(null, target, measurement);
- }
-
- @Override
- public void run() {
- if (ensureMeasurementNecessary()) return;
-
- try {
- setupSocket(SOCK_DGRAM, mProtocol, TIMEOUT_SEND, TIMEOUT_RECV, 0);
- } catch (ErrnoException | IOException e) {
- mMeasurement.recordFailure(e.toString());
- return;
- }
- mMeasurement.description += " src{" + socketAddressToString(mSocketAddress) + "}";
-
- // Build a trivial ICMP packet.
- final byte[] icmpPacket = {
- (byte) mIcmpType, 0, 0, 0, 0, 0, 0, 0 // ICMP header
- };
-
- int count = 0;
- mMeasurement.startTime = now();
- while (now() < mDeadlineTime - (TIMEOUT_SEND + TIMEOUT_RECV)) {
- count++;
- icmpPacket[icmpPacket.length - 1] = (byte) count;
- try {
- Os.write(mFileDescriptor, icmpPacket, 0, icmpPacket.length);
- } catch (ErrnoException | InterruptedIOException e) {
- mMeasurement.recordFailure(e.toString());
- break;
- }
-
- try {
- ByteBuffer reply = ByteBuffer.allocate(PACKET_BUFSIZE);
- Os.read(mFileDescriptor, reply);
- // TODO: send a few pings back to back to guesstimate packet loss.
- mMeasurement.recordSuccess("1/" + count);
- break;
- } catch (ErrnoException | InterruptedIOException e) {
- continue;
- }
- }
- if (mMeasurement.finishTime == 0) {
- mMeasurement.recordFailure("0/" + count);
- }
-
- close();
- }
- }
-
-
- private class DnsUdpCheck extends SimpleSocketCheck implements Runnable {
- private static final int TIMEOUT_SEND = 100;
- private static final int TIMEOUT_RECV = 500;
- private static final int RR_TYPE_A = 1;
- private static final int RR_TYPE_AAAA = 28;
- private static final int PACKET_BUFSIZE = 512;
-
- protected final Random mRandom = new Random();
-
- // Should be static, but the compiler mocks our puny, human attempts at reason.
- protected String responseCodeStr(int rcode) {
- try {
- return DnsResponseCode.values()[rcode].toString();
- } catch (IndexOutOfBoundsException e) {
- return String.valueOf(rcode);
- }
- }
-
- protected final int mQueryType;
-
- public DnsUdpCheck(InetAddress target, Measurement measurement) {
- super(target, measurement);
-
- // TODO: Ideally, query the target for both types regardless of address family.
- if (mAddressFamily == AF_INET6) {
- mQueryType = RR_TYPE_AAAA;
- } else {
- mQueryType = RR_TYPE_A;
- }
-
- mMeasurement.description = "DNS UDP dst{" + mTarget.getHostAddress() + "}";
- }
-
- @Override
- public void run() {
- if (ensureMeasurementNecessary()) return;
-
- try {
- setupSocket(SOCK_DGRAM, IPPROTO_UDP, TIMEOUT_SEND, TIMEOUT_RECV,
- NetworkConstants.DNS_SERVER_PORT);
- } catch (ErrnoException | IOException e) {
- mMeasurement.recordFailure(e.toString());
- return;
- }
-
- // This needs to be fixed length so it can be dropped into the pre-canned packet.
- final String sixRandomDigits = String.valueOf(mRandom.nextInt(900000) + 100000);
- appendDnsToMeasurementDescription(sixRandomDigits, mSocketAddress);
-
- // Build a trivial DNS packet.
- final byte[] dnsPacket = getDnsQueryPacket(sixRandomDigits);
-
- int count = 0;
- mMeasurement.startTime = now();
- while (now() < mDeadlineTime - (TIMEOUT_RECV + TIMEOUT_RECV)) {
- count++;
- try {
- Os.write(mFileDescriptor, dnsPacket, 0, dnsPacket.length);
- } catch (ErrnoException | InterruptedIOException e) {
- mMeasurement.recordFailure(e.toString());
- break;
- }
-
- try {
- ByteBuffer reply = ByteBuffer.allocate(PACKET_BUFSIZE);
- Os.read(mFileDescriptor, reply);
- // TODO: more correct and detailed evaluation of the response,
- // possibly adding the returned IP address(es) to the output.
- final String rcodeStr = (reply.limit() > 3)
- ? " " + responseCodeStr((int) (reply.get(3)) & 0x0f)
- : "";
- mMeasurement.recordSuccess("1/" + count + rcodeStr);
- break;
- } catch (ErrnoException | InterruptedIOException e) {
- continue;
- }
- }
- if (mMeasurement.finishTime == 0) {
- mMeasurement.recordFailure("0/" + count);
- }
-
- close();
- }
-
- protected byte[] getDnsQueryPacket(String sixRandomDigits) {
- byte[] rnd = sixRandomDigits.getBytes(StandardCharsets.US_ASCII);
- return new byte[] {
- (byte) mRandom.nextInt(), (byte) mRandom.nextInt(), // [0-1] query ID
- 1, 0, // [2-3] flags; byte[2] = 1 for recursion desired (RD).
- 0, 1, // [4-5] QDCOUNT (number of queries)
- 0, 0, // [6-7] ANCOUNT (number of answers)
- 0, 0, // [8-9] NSCOUNT (number of name server records)
- 0, 0, // [10-11] ARCOUNT (number of additional records)
- 17, rnd[0], rnd[1], rnd[2], rnd[3], rnd[4], rnd[5],
- '-', 'a', 'n', 'd', 'r', 'o', 'i', 'd', '-', 'd', 's',
- 6, 'm', 'e', 't', 'r', 'i', 'c',
- 7, 'g', 's', 't', 'a', 't', 'i', 'c',
- 3, 'c', 'o', 'm',
- 0, // null terminator of FQDN (root TLD)
- 0, (byte) mQueryType, // QTYPE
- 0, 1 // QCLASS, set to 1 = IN (Internet)
- };
- }
-
- protected void appendDnsToMeasurementDescription(
- String sixRandomDigits, SocketAddress sockAddr) {
- mMeasurement.description += " src{" + socketAddressToString(sockAddr) + "}"
- + " qtype{" + mQueryType + "}"
- + " qname{" + sixRandomDigits + "-android-ds.metric.gstatic.com}";
- }
- }
-
- // TODO: Have it inherited from SimpleSocketCheck, and separate common DNS helpers out of
- // DnsUdpCheck.
- private class DnsTlsCheck extends DnsUdpCheck {
- private static final int TCP_CONNECT_TIMEOUT_MS = 2500;
- private static final int TCP_TIMEOUT_MS = 2000;
- private static final int DNS_TLS_PORT = 853;
- private static final int DNS_HEADER_SIZE = 12;
-
- private final String mHostname;
-
- public DnsTlsCheck(@Nullable String hostname, @NonNull InetAddress target,
- @NonNull Measurement measurement) {
- super(target, measurement);
-
- mHostname = hostname;
- mMeasurement.description = "DNS TLS dst{" + mTarget.getHostAddress() + "} hostname{"
- + (mHostname == null ? "" : mHostname) + "}";
- }
-
- private SSLSocket setupSSLSocket() throws IOException {
- // A TrustManager will be created and initialized with a KeyStore containing system
- // CaCerts. During SSL handshake, it will be used to validate the certificates from
- // the server.
- SSLSocket sslSocket = (SSLSocket) SSLSocketFactory.getDefault().createSocket();
- sslSocket.setSoTimeout(TCP_TIMEOUT_MS);
-
- if (!TextUtils.isEmpty(mHostname)) {
- // Set SNI.
- final List<SNIServerName> names =
- Collections.singletonList(new SNIHostName(mHostname));
- SSLParameters params = sslSocket.getSSLParameters();
- params.setServerNames(names);
- sslSocket.setSSLParameters(params);
- }
-
- mNetwork.bindSocket(sslSocket);
- return sslSocket;
- }
-
- private void sendDoTProbe(@Nullable SSLSocket sslSocket) throws IOException {
- final String sixRandomDigits = String.valueOf(mRandom.nextInt(900000) + 100000);
- final byte[] dnsPacket = getDnsQueryPacket(sixRandomDigits);
-
- mMeasurement.startTime = now();
- sslSocket.connect(new InetSocketAddress(mTarget, DNS_TLS_PORT), TCP_CONNECT_TIMEOUT_MS);
-
- // Synchronous call waiting for the TLS handshake complete.
- sslSocket.startHandshake();
- appendDnsToMeasurementDescription(sixRandomDigits, sslSocket.getLocalSocketAddress());
-
- final DataOutputStream output = new DataOutputStream(sslSocket.getOutputStream());
- output.writeShort(dnsPacket.length);
- output.write(dnsPacket, 0, dnsPacket.length);
-
- final DataInputStream input = new DataInputStream(sslSocket.getInputStream());
- final int replyLength = Short.toUnsignedInt(input.readShort());
- final byte[] reply = new byte[replyLength];
- int bytesRead = 0;
- while (bytesRead < replyLength) {
- bytesRead += input.read(reply, bytesRead, replyLength - bytesRead);
- }
-
- if (bytesRead > DNS_HEADER_SIZE && bytesRead == replyLength) {
- mMeasurement.recordSuccess("1/1 " + responseCodeStr((int) (reply[3]) & 0x0f));
- } else {
- mMeasurement.recordFailure("1/1 Read " + bytesRead + " bytes while expected to be "
- + replyLength + " bytes");
- }
- }
-
- @Override
- public void run() {
- if (ensureMeasurementNecessary()) return;
-
- // No need to restore the tag, since this thread is only used for this measurement.
- TrafficStats.getAndSetThreadStatsTag(NetworkStackConstants.TAG_SYSTEM_PROBE);
-
- try (SSLSocket sslSocket = setupSSLSocket()) {
- sendDoTProbe(sslSocket);
- } catch (IOException e) {
- mMeasurement.recordFailure(e.toString());
- }
- }
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/NetworkNotificationManager.java b/packages/Connectivity/service/src/com/android/server/connectivity/NetworkNotificationManager.java
deleted file mode 100644
index 3dc79c5..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/NetworkNotificationManager.java
+++ /dev/null
@@ -1,404 +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.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_VPN;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-
-import android.annotation.NonNull;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.graphics.drawable.Icon;
-import android.net.ConnectivityResources;
-import android.net.NetworkSpecifier;
-import android.net.TelephonyNetworkSpecifier;
-import android.net.wifi.WifiInfo;
-import android.os.UserHandle;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.SparseIntArray;
-import android.widget.Toast;
-
-import com.android.connectivity.resources.R;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-
-public class NetworkNotificationManager {
-
-
- public static enum NotificationType {
- LOST_INTERNET(SystemMessage.NOTE_NETWORK_LOST_INTERNET),
- NETWORK_SWITCH(SystemMessage.NOTE_NETWORK_SWITCH),
- NO_INTERNET(SystemMessage.NOTE_NETWORK_NO_INTERNET),
- PARTIAL_CONNECTIVITY(SystemMessage.NOTE_NETWORK_PARTIAL_CONNECTIVITY),
- SIGN_IN(SystemMessage.NOTE_NETWORK_SIGN_IN),
- PRIVATE_DNS_BROKEN(SystemMessage.NOTE_NETWORK_PRIVATE_DNS_BROKEN);
-
- public final int eventId;
-
- NotificationType(int eventId) {
- this.eventId = eventId;
- Holder.sIdToTypeMap.put(eventId, this);
- }
-
- private static class Holder {
- private static SparseArray<NotificationType> sIdToTypeMap = new SparseArray<>();
- }
-
- public static NotificationType getFromId(int id) {
- return Holder.sIdToTypeMap.get(id);
- }
- };
-
- private static final String TAG = NetworkNotificationManager.class.getSimpleName();
- private static final boolean DBG = true;
-
- // Notification channels used by ConnectivityService mainline module, it should be aligned with
- // SystemNotificationChannels so the channels are the same as the ones used as the system
- // server.
- public static final String NOTIFICATION_CHANNEL_NETWORK_STATUS = "NETWORK_STATUS";
- public static final String NOTIFICATION_CHANNEL_NETWORK_ALERTS = "NETWORK_ALERTS";
-
- // The context is for the current user (system server)
- private final Context mContext;
- private final ConnectivityResources mResources;
- private final TelephonyManager mTelephonyManager;
- // The notification manager is created from a context for User.ALL, so notifications
- // will be sent to all users.
- private final NotificationManager mNotificationManager;
- // Tracks the types of notifications managed by this instance, from creation to cancellation.
- private final SparseIntArray mNotificationTypeMap;
-
- public NetworkNotificationManager(@NonNull final Context c, @NonNull final TelephonyManager t) {
- mContext = c;
- mTelephonyManager = t;
- mNotificationManager =
- (NotificationManager) c.createContextAsUser(UserHandle.ALL, 0 /* flags */)
- .getSystemService(Context.NOTIFICATION_SERVICE);
- mNotificationTypeMap = new SparseIntArray();
- mResources = new ConnectivityResources(mContext);
- }
-
- @VisibleForTesting
- protected static int approximateTransportType(NetworkAgentInfo nai) {
- return nai.isVPN() ? TRANSPORT_VPN : getFirstTransportType(nai);
- }
-
- // TODO: deal more gracefully with multi-transport networks.
- private static int getFirstTransportType(NetworkAgentInfo nai) {
- // TODO: The range is wrong, the safer and correct way is to change the range from
- // MIN_TRANSPORT to MAX_TRANSPORT.
- for (int i = 0; i < 64; i++) {
- if (nai.networkCapabilities.hasTransport(i)) return i;
- }
- return -1;
- }
-
- private String getTransportName(final int transportType) {
- String[] networkTypes = mResources.get().getStringArray(R.array.network_switch_type_name);
- try {
- return networkTypes[transportType];
- } catch (IndexOutOfBoundsException e) {
- return mResources.get().getString(R.string.network_switch_type_name_unknown);
- }
- }
-
- private static int getIcon(int transportType) {
- return (transportType == TRANSPORT_WIFI)
- ? R.drawable.stat_notify_wifi_in_range // TODO: Distinguish ! from ?.
- : R.drawable.stat_notify_rssi_in_range;
- }
-
- /**
- * Show or hide network provisioning notifications.
- *
- * We use notifications for two purposes: to notify that a network requires sign in
- * (NotificationType.SIGN_IN), or to notify that a network does not have Internet access
- * (NotificationType.NO_INTERNET). We display at most one notification per ID, so on a
- * particular network we can display the notification type that was most recently requested.
- * So for example if a captive portal fails to reply within a few seconds of connecting, we
- * might first display NO_INTERNET, and then when the captive portal check completes, display
- * SIGN_IN.
- *
- * @param id an identifier that uniquely identifies this notification. This must match
- * between show and hide calls. We use the NetID value but for legacy callers
- * we concatenate the range of types with the range of NetIDs.
- * @param notifyType the type of the notification.
- * @param nai the network with which the notification is associated. For a SIGN_IN, NO_INTERNET,
- * or LOST_INTERNET notification, this is the network we're connecting to. For a
- * NETWORK_SWITCH notification it's the network that we switched from. When this network
- * disconnects the notification is removed.
- * @param switchToNai for a NETWORK_SWITCH notification, the network we are switching to. Null
- * in all other cases. Only used to determine the text of the notification.
- */
- public void showNotification(int id, NotificationType notifyType, NetworkAgentInfo nai,
- NetworkAgentInfo switchToNai, PendingIntent intent, boolean highPriority) {
- final String tag = tagFor(id);
- final int eventId = notifyType.eventId;
- final int transportType;
- final CharSequence name;
- if (nai != null) {
- transportType = approximateTransportType(nai);
- final String extraInfo = nai.networkInfo.getExtraInfo();
- if (nai.linkProperties != null && nai.linkProperties.getCaptivePortalData() != null
- && !TextUtils.isEmpty(nai.linkProperties.getCaptivePortalData()
- .getVenueFriendlyName())) {
- name = nai.linkProperties.getCaptivePortalData().getVenueFriendlyName();
- } else {
- name = TextUtils.isEmpty(extraInfo)
- ? WifiInfo.sanitizeSsid(nai.networkCapabilities.getSsid()) : extraInfo;
- }
- // Only notify for Internet-capable networks.
- if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_INTERNET)) return;
- } else {
- // Legacy notifications.
- transportType = TRANSPORT_CELLULAR;
- name = "";
- }
-
- // Clear any previous notification with lower priority, otherwise return. http://b/63676954.
- // A new SIGN_IN notification with a new intent should override any existing one.
- final int previousEventId = mNotificationTypeMap.get(id);
- final NotificationType previousNotifyType = NotificationType.getFromId(previousEventId);
- if (priority(previousNotifyType) > priority(notifyType)) {
- Log.d(TAG, String.format(
- "ignoring notification %s for network %s with existing notification %s",
- notifyType, id, previousNotifyType));
- return;
- }
- clearNotification(id);
-
- if (DBG) {
- Log.d(TAG, String.format(
- "showNotification tag=%s event=%s transport=%s name=%s highPriority=%s",
- tag, nameOf(eventId), getTransportName(transportType), name, highPriority));
- }
-
- final Resources r = mResources.get();
- final CharSequence title;
- final CharSequence details;
- Icon icon = Icon.createWithResource(
- mResources.getResourcesContext(), getIcon(transportType));
- if (notifyType == NotificationType.NO_INTERNET && transportType == TRANSPORT_WIFI) {
- title = r.getString(R.string.wifi_no_internet, name);
- details = r.getString(R.string.wifi_no_internet_detailed);
- } else if (notifyType == NotificationType.PRIVATE_DNS_BROKEN) {
- if (transportType == TRANSPORT_CELLULAR) {
- title = r.getString(R.string.mobile_no_internet);
- } else if (transportType == TRANSPORT_WIFI) {
- title = r.getString(R.string.wifi_no_internet, name);
- } else {
- title = r.getString(R.string.other_networks_no_internet);
- }
- details = r.getString(R.string.private_dns_broken_detailed);
- } else if (notifyType == NotificationType.PARTIAL_CONNECTIVITY
- && transportType == TRANSPORT_WIFI) {
- title = r.getString(R.string.network_partial_connectivity, name);
- details = r.getString(R.string.network_partial_connectivity_detailed);
- } else if (notifyType == NotificationType.LOST_INTERNET &&
- transportType == TRANSPORT_WIFI) {
- title = r.getString(R.string.wifi_no_internet, name);
- details = r.getString(R.string.wifi_no_internet_detailed);
- } else if (notifyType == NotificationType.SIGN_IN) {
- switch (transportType) {
- case TRANSPORT_WIFI:
- title = r.getString(R.string.wifi_available_sign_in, 0);
- details = r.getString(R.string.network_available_sign_in_detailed, name);
- break;
- case TRANSPORT_CELLULAR:
- title = r.getString(R.string.network_available_sign_in, 0);
- // TODO: Change this to pull from NetworkInfo once a printable
- // name has been added to it
- NetworkSpecifier specifier = nai.networkCapabilities.getNetworkSpecifier();
- int subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
- if (specifier instanceof TelephonyNetworkSpecifier) {
- subId = ((TelephonyNetworkSpecifier) specifier).getSubscriptionId();
- }
-
- details = mTelephonyManager.createForSubscriptionId(subId)
- .getNetworkOperatorName();
- break;
- default:
- title = r.getString(R.string.network_available_sign_in, 0);
- details = r.getString(R.string.network_available_sign_in_detailed, name);
- break;
- }
- } else if (notifyType == NotificationType.NETWORK_SWITCH) {
- String fromTransport = getTransportName(transportType);
- String toTransport = getTransportName(approximateTransportType(switchToNai));
- title = r.getString(R.string.network_switch_metered, toTransport);
- details = r.getString(R.string.network_switch_metered_detail, toTransport,
- fromTransport);
- } else if (notifyType == NotificationType.NO_INTERNET
- || notifyType == NotificationType.PARTIAL_CONNECTIVITY) {
- // NO_INTERNET and PARTIAL_CONNECTIVITY notification for non-WiFi networks
- // are sent, but they are not implemented yet.
- return;
- } else {
- Log.wtf(TAG, "Unknown notification type " + notifyType + " on network transport "
- + getTransportName(transportType));
- return;
- }
- // When replacing an existing notification for a given network, don't alert, just silently
- // update the existing notification. Note that setOnlyAlertOnce() will only work for the
- // same id, and the id used here is the NotificationType which is different in every type of
- // notification. This is required because the notification metrics only track the ID but not
- // the tag.
- final boolean hasPreviousNotification = previousNotifyType != null;
- final String channelId = (highPriority && !hasPreviousNotification)
- ? NOTIFICATION_CHANNEL_NETWORK_ALERTS : NOTIFICATION_CHANNEL_NETWORK_STATUS;
- Notification.Builder builder = new Notification.Builder(mContext, channelId)
- .setWhen(System.currentTimeMillis())
- .setShowWhen(notifyType == NotificationType.NETWORK_SWITCH)
- .setSmallIcon(icon)
- .setAutoCancel(true)
- .setTicker(title)
- .setColor(mContext.getColor(android.R.color.system_notification_accent_color))
- .setContentTitle(title)
- .setContentIntent(intent)
- .setLocalOnly(true)
- .setOnlyAlertOnce(true)
- // TODO: consider having action buttons to disconnect on the sign-in notification
- // especially if it is ongoing
- .setOngoing(notifyType == NotificationType.SIGN_IN
- && r.getBoolean(R.bool.config_ongoingSignInNotification));
-
- if (notifyType == NotificationType.NETWORK_SWITCH) {
- builder.setStyle(new Notification.BigTextStyle().bigText(details));
- } else {
- builder.setContentText(details);
- }
-
- if (notifyType == NotificationType.SIGN_IN) {
- builder.extend(new Notification.TvExtender().setChannelId(channelId));
- }
-
- Notification notification = builder.build();
-
- mNotificationTypeMap.put(id, eventId);
- try {
- mNotificationManager.notify(tag, eventId, notification);
- } catch (NullPointerException npe) {
- Log.d(TAG, "setNotificationVisible: visible notificationManager error", npe);
- }
- }
-
- /**
- * Clear the notification with the given id, only if it matches the given type.
- */
- public void clearNotification(int id, NotificationType notifyType) {
- final int previousEventId = mNotificationTypeMap.get(id);
- final NotificationType previousNotifyType = NotificationType.getFromId(previousEventId);
- if (notifyType != previousNotifyType) {
- return;
- }
- clearNotification(id);
- }
-
- public void clearNotification(int id) {
- if (mNotificationTypeMap.indexOfKey(id) < 0) {
- return;
- }
- final String tag = tagFor(id);
- final int eventId = mNotificationTypeMap.get(id);
- if (DBG) {
- Log.d(TAG, String.format("clearing notification tag=%s event=%s", tag,
- nameOf(eventId)));
- }
- try {
- mNotificationManager.cancel(tag, eventId);
- } catch (NullPointerException npe) {
- Log.d(TAG, String.format(
- "failed to clear notification tag=%s event=%s", tag, nameOf(eventId)), npe);
- }
- mNotificationTypeMap.delete(id);
- }
-
- /**
- * Legacy provisioning notifications coming directly from DcTracker.
- */
- public void setProvNotificationVisible(boolean visible, int id, String action) {
- if (visible) {
- // For legacy purposes, action is sent as the action + the phone ID from DcTracker.
- // Split the string here and send the phone ID as an extra instead.
- String[] splitAction = action.split(":");
- Intent intent = new Intent(splitAction[0]);
- try {
- intent.putExtra("provision.phone.id", Integer.parseInt(splitAction[1]));
- } catch (NumberFormatException ignored) { }
- PendingIntent pendingIntent = PendingIntent.getBroadcast(
- mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE);
- showNotification(id, NotificationType.SIGN_IN, null, null, pendingIntent, false);
- } else {
- clearNotification(id);
- }
- }
-
- public void showToast(NetworkAgentInfo fromNai, NetworkAgentInfo toNai) {
- String fromTransport = getTransportName(approximateTransportType(fromNai));
- String toTransport = getTransportName(approximateTransportType(toNai));
- String text = mResources.get().getString(
- R.string.network_switch_metered_toast, fromTransport, toTransport);
- Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
- }
-
- @VisibleForTesting
- static String tagFor(int id) {
- return String.format("ConnectivityNotification:%d", id);
- }
-
- @VisibleForTesting
- static String nameOf(int eventId) {
- NotificationType t = NotificationType.getFromId(eventId);
- return (t != null) ? t.name() : "UNKNOWN";
- }
-
- /**
- * A notification with a higher number will take priority over a notification with a lower
- * number.
- */
- private static int priority(NotificationType t) {
- if (t == null) {
- return 0;
- }
- switch (t) {
- case SIGN_IN:
- return 6;
- case PARTIAL_CONNECTIVITY:
- return 5;
- case PRIVATE_DNS_BROKEN:
- return 4;
- case NO_INTERNET:
- return 3;
- case NETWORK_SWITCH:
- return 2;
- case LOST_INTERNET:
- return 1;
- default:
- return 0;
- }
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/NetworkOffer.java b/packages/Connectivity/service/src/com/android/server/connectivity/NetworkOffer.java
deleted file mode 100644
index 8285e7a..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/NetworkOffer.java
+++ /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 com.android.server.connectivity;
-
-import android.annotation.NonNull;
-import android.net.INetworkOfferCallback;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.os.RemoteException;
-
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Represents an offer made by a NetworkProvider to create a network if a need arises.
- *
- * This class contains the prospective score and capabilities of the network. The provider
- * is not obligated to caps able to create a network satisfying this, nor to build a network
- * with the exact score and/or capabilities passed ; after all, not all providers know in
- * advance what a network will look like after it's connected. Instead, this is meant as a
- * filter to limit requests sent to the provider by connectivity to those that this offer stands
- * a chance to fulfill.
- *
- * @see NetworkProvider#offerNetwork.
- *
- * @hide
- */
-public class NetworkOffer implements NetworkRanker.Scoreable {
- @NonNull public final FullScore score;
- @NonNull public final NetworkCapabilities caps;
- @NonNull public final INetworkOfferCallback callback;
- @NonNull public final int providerId;
- // While this could, in principle, be deduced from the old values of the satisfying networks,
- // doing so would add a lot of complexity and performance penalties. For each request, the
- // ranker would have to run again to figure out if this offer used to be able to beat the
- // previous satisfier to know if there is a change in whether this offer is now needed ;
- // besides, there would be a need to handle an edge case when a new request comes online,
- // where it's not satisfied before the first rematch, where starting to satisfy a request
- // should not result in sending unneeded to this offer. This boolean, while requiring that
- // the offers are only ever manipulated on the CS thread, is by far a simpler and
- // economical solution.
- private final Set<NetworkRequest> mCurrentlyNeeded = new HashSet<>();
-
- public NetworkOffer(@NonNull final FullScore score,
- @NonNull final NetworkCapabilities caps,
- @NonNull final INetworkOfferCallback callback,
- @NonNull final int providerId) {
- this.score = Objects.requireNonNull(score);
- this.caps = Objects.requireNonNull(caps);
- this.callback = Objects.requireNonNull(callback);
- this.providerId = providerId;
- }
-
- /**
- * Get the score filter of this offer
- */
- @Override @NonNull public FullScore getScore() {
- return score;
- }
-
- /**
- * Get the capabilities filter of this offer
- */
- @Override @NonNull public NetworkCapabilities getCapsNoCopy() {
- return caps;
- }
-
- /**
- * Tell the provider for this offer that the network is needed for a request.
- * @param request the request for which the offer is needed
- */
- public void onNetworkNeeded(@NonNull final NetworkRequest request) {
- if (mCurrentlyNeeded.contains(request)) {
- throw new IllegalStateException("Network already needed");
- }
- mCurrentlyNeeded.add(request);
- try {
- callback.onNetworkNeeded(request);
- } catch (final RemoteException e) {
- // The provider is dead. It will be removed by the death recipient.
- }
- }
-
- /**
- * Tell the provider for this offer that the network is no longer needed for this request.
- *
- * onNetworkNeeded will have been called with the same request before.
- *
- * @param request the request
- */
- public void onNetworkUnneeded(@NonNull final NetworkRequest request) {
- if (!mCurrentlyNeeded.contains(request)) {
- throw new IllegalStateException("Network already unneeded");
- }
- mCurrentlyNeeded.remove(request);
- try {
- callback.onNetworkUnneeded(request);
- } catch (final RemoteException e) {
- // The provider is dead. It will be removed by the death recipient.
- }
- }
-
- /**
- * Returns whether this offer is currently needed for this request.
- * @param request the request
- * @return whether the offer is currently considered needed
- */
- public boolean neededFor(@NonNull final NetworkRequest request) {
- return mCurrentlyNeeded.contains(request);
- }
-
- /**
- * Migrate from, and take over, a previous offer.
- *
- * When an updated offer is sent from a provider, call this method on the new offer, passing
- * the old one, to take over the state.
- *
- * @param previousOffer the previous offer
- */
- public void migrateFrom(@NonNull final NetworkOffer previousOffer) {
- if (!callback.asBinder().equals(previousOffer.callback.asBinder())) {
- throw new IllegalArgumentException("Can only migrate from a previous version of"
- + " the same offer");
- }
- mCurrentlyNeeded.clear();
- mCurrentlyNeeded.addAll(previousOffer.mCurrentlyNeeded);
- }
-
- @Override
- public String toString() {
- return "NetworkOffer [ Score " + score + " ]";
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/NetworkRanker.java b/packages/Connectivity/service/src/com/android/server/connectivity/NetworkRanker.java
deleted file mode 100644
index d7eb9c8..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/NetworkRanker.java
+++ /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 com.android.server.connectivity;
-
-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.NetworkScore.POLICY_EXITING;
-import static android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY;
-import static android.net.NetworkScore.POLICY_YIELD_TO_BAD_WIFI;
-
-import static com.android.net.module.util.CollectionUtils.filter;
-import static com.android.server.connectivity.FullScore.POLICY_ACCEPT_UNVALIDATED;
-import static com.android.server.connectivity.FullScore.POLICY_EVER_USER_SELECTED;
-import static com.android.server.connectivity.FullScore.POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD;
-import static com.android.server.connectivity.FullScore.POLICY_IS_INVINCIBLE;
-import static com.android.server.connectivity.FullScore.POLICY_IS_VALIDATED;
-import static com.android.server.connectivity.FullScore.POLICY_IS_VPN;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-
-import com.android.net.module.util.CollectionUtils;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.function.Predicate;
-
-/**
- * A class that knows how to find the best network matching a request out of a list of networks.
- */
-public class NetworkRanker {
- // Historically the legacy ints have been 0~100 in principle (though the highest score in
- // AOSP has always been 90). This is relied on by VPNs that send a legacy score of 101.
- public static final int LEGACY_INT_MAX = 100;
-
- /**
- * A class that can be scored against other scoreables.
- */
- public interface Scoreable {
- /** Get score of this scoreable */
- FullScore getScore();
- /** Get capabilities of this scoreable */
- NetworkCapabilities getCapsNoCopy();
- }
-
- private static final boolean USE_POLICY_RANKING = true;
-
- public NetworkRanker() { }
-
- /**
- * Find the best network satisfying this request among the list of passed networks.
- */
- @Nullable
- public NetworkAgentInfo getBestNetwork(@NonNull final NetworkRequest request,
- @NonNull final Collection<NetworkAgentInfo> nais,
- @Nullable final NetworkAgentInfo currentSatisfier) {
- final ArrayList<NetworkAgentInfo> candidates = filter(nais, nai -> nai.satisfies(request));
- if (candidates.size() == 1) return candidates.get(0); // Only one potential satisfier
- if (candidates.size() <= 0) return null; // No network can satisfy this request
- if (USE_POLICY_RANKING) {
- return getBestNetworkByPolicy(candidates, currentSatisfier);
- } else {
- return getBestNetworkByLegacyInt(candidates);
- }
- }
-
- // Transport preference order, if it comes down to that.
- private static final int[] PREFERRED_TRANSPORTS_ORDER = { TRANSPORT_ETHERNET, TRANSPORT_WIFI,
- TRANSPORT_BLUETOOTH, TRANSPORT_CELLULAR };
-
- // Function used to partition a list into two working areas depending on whether they
- // satisfy a predicate. All items satisfying the predicate will be put in |positive|, all
- // items that don't will be put in |negative|.
- // This is useful in this file because many of the ranking checks will retain only networks that
- // satisfy a predicate if any of them do, but keep them all if all of them do. Having working
- // areas is uncustomary in Java, but this function is called in a fairly intensive manner
- // and doing allocation quite that often might affect performance quite badly.
- private static <T> void partitionInto(@NonNull final List<T> source, @NonNull Predicate<T> test,
- @NonNull final List<T> positive, @NonNull final List<T> negative) {
- positive.clear();
- negative.clear();
- for (final T item : source) {
- if (test.test(item)) {
- positive.add(item);
- } else {
- negative.add(item);
- }
- }
- }
-
- private <T extends Scoreable> boolean isBadWiFi(@NonNull final T candidate) {
- return candidate.getScore().hasPolicy(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD)
- && candidate.getCapsNoCopy().hasTransport(TRANSPORT_WIFI);
- }
-
- /**
- * Apply the "yield to bad WiFi" policy.
- *
- * This function must run immediately after the validation policy.
- *
- * If any of the accepted networks has the "yield to bad WiFi" policy AND there are some
- * bad WiFis in the rejected list, then move the networks with the policy to the rejected
- * list. If this leaves no accepted network, then move the bad WiFis back to the accepted list.
- *
- * This function returns nothing, but will have updated accepted and rejected in-place.
- *
- * @param accepted networks accepted by the validation policy
- * @param rejected networks rejected by the validation policy
- */
- private <T extends Scoreable> void applyYieldToBadWifiPolicy(@NonNull ArrayList<T> accepted,
- @NonNull ArrayList<T> rejected) {
- if (!CollectionUtils.any(accepted, n -> n.getScore().hasPolicy(POLICY_YIELD_TO_BAD_WIFI))) {
- // No network with the policy : do nothing.
- return;
- }
- if (!CollectionUtils.any(rejected, n -> isBadWiFi(n))) {
- // No bad WiFi : do nothing.
- return;
- }
- if (CollectionUtils.all(accepted, n -> n.getScore().hasPolicy(POLICY_YIELD_TO_BAD_WIFI))) {
- // All validated networks yield to bad WiFis : keep bad WiFis alongside with the
- // yielders. This is important because the yielders need to be compared to the bad
- // wifis by the following policies (e.g. exiting).
- final ArrayList<T> acceptedYielders = new ArrayList<>(accepted);
- final ArrayList<T> rejectedWithBadWiFis = new ArrayList<>(rejected);
- partitionInto(rejectedWithBadWiFis, n -> isBadWiFi(n), accepted, rejected);
- accepted.addAll(acceptedYielders);
- return;
- }
- // Only some of the validated networks yield to bad WiFi : keep only the ones who don't.
- final ArrayList<T> acceptedWithYielders = new ArrayList<>(accepted);
- partitionInto(acceptedWithYielders, n -> !n.getScore().hasPolicy(POLICY_YIELD_TO_BAD_WIFI),
- accepted, rejected);
- }
-
- /**
- * Get the best network among a list of candidates according to policy.
- * @param candidates the candidates
- * @param currentSatisfier the current satisfier, or null if none
- * @return the best network
- */
- @Nullable public <T extends Scoreable> T getBestNetworkByPolicy(
- @NonNull List<T> candidates,
- @Nullable final T currentSatisfier) {
- // Used as working areas.
- final ArrayList<T> accepted =
- new ArrayList<>(candidates.size() /* initialCapacity */);
- final ArrayList<T> rejected =
- new ArrayList<>(candidates.size() /* initialCapacity */);
-
- // The following tests will search for a network matching a given criterion. They all
- // function the same way : if any network matches the criterion, drop from consideration
- // all networks that don't. To achieve this, the tests below :
- // 1. partition the list of remaining candidates into accepted and rejected networks.
- // 2. if only one candidate remains, that's the winner : if accepted.size == 1 return [0]
- // 3. if multiple remain, keep only the accepted networks and go on to the next criterion.
- // Because the working areas will be wiped, a copy of the accepted networks needs to be
- // made.
- // 4. if none remain, the criterion did not help discriminate so keep them all. As an
- // optimization, skip creating a new array and go on to the next criterion.
-
- // If a network is invincible, use it.
- partitionInto(candidates, nai -> nai.getScore().hasPolicy(POLICY_IS_INVINCIBLE),
- accepted, rejected);
- if (accepted.size() == 1) return accepted.get(0);
- if (accepted.size() > 0 && rejected.size() > 0) candidates = new ArrayList<>(accepted);
-
- // If there is a connected VPN, use it.
- partitionInto(candidates, nai -> nai.getScore().hasPolicy(POLICY_IS_VPN),
- accepted, rejected);
- if (accepted.size() == 1) return accepted.get(0);
- if (accepted.size() > 0 && rejected.size() > 0) candidates = new ArrayList<>(accepted);
-
- // Selected & Accept-unvalidated policy : if any network has both of these, then don't
- // choose one that doesn't.
- partitionInto(candidates, nai -> nai.getScore().hasPolicy(POLICY_EVER_USER_SELECTED)
- && nai.getScore().hasPolicy(POLICY_ACCEPT_UNVALIDATED),
- accepted, rejected);
- if (accepted.size() == 1) return accepted.get(0);
- if (accepted.size() > 0 && rejected.size() > 0) candidates = new ArrayList<>(accepted);
-
- // If any network is validated (or should be accepted even if it's not validated), then
- // don't choose one that isn't.
- partitionInto(candidates, nai -> nai.getScore().hasPolicy(POLICY_IS_VALIDATED)
- || nai.getScore().hasPolicy(POLICY_ACCEPT_UNVALIDATED),
- accepted, rejected);
- // Yield to bad wifi policy : if any network has the "yield to bad WiFi" policy and
- // there are bad WiFis connected, then accept the bad WiFis and reject the networks with
- // the policy.
- applyYieldToBadWifiPolicy(accepted, rejected);
- if (accepted.size() == 1) return accepted.get(0);
- if (accepted.size() > 0 && rejected.size() > 0) candidates = new ArrayList<>(accepted);
-
- // If any network is not exiting, don't choose one that is.
- partitionInto(candidates, nai -> !nai.getScore().hasPolicy(POLICY_EXITING),
- accepted, rejected);
- if (accepted.size() == 1) return accepted.get(0);
- if (accepted.size() > 0 && rejected.size() > 0) candidates = new ArrayList<>(accepted);
-
- // TODO : If any network is unmetered, don't choose a metered network.
- // This can't be implemented immediately because prospective networks are always
- // considered unmetered because factories don't know if the network will be metered.
- // Saying an unmetered network always beats a metered one would mean that when metered wifi
- // is connected, the offer for telephony would beat WiFi but the actual metered network
- // would lose, so we'd have an infinite loop where telephony would continually bring up
- // a network that is immediately torn down.
- // Fix this by getting the agent to tell connectivity whether the network they will
- // bring up is metered. Cell knows that in advance, while WiFi has a good estimate and
- // can revise it if the network later turns out to be metered.
- // partitionInto(candidates, nai -> nai.getScore().hasPolicy(POLICY_IS_UNMETERED),
- // accepted, rejected);
- // if (accepted.size() == 1) return accepted.get(0);
- // if (accepted.size() > 0 && rejected.size() > 0) candidates = new ArrayList<>(accepted);
-
- // If any network is for the default subscription, don't choose a network for another
- // subscription with the same transport.
- partitionInto(candidates, nai -> nai.getScore().hasPolicy(POLICY_TRANSPORT_PRIMARY),
- accepted, rejected);
- if (accepted.size() > 0) {
- // Some networks are primary for their transport. For each transport, keep only the
- // primary, but also keep all networks for which there isn't a primary (which are now
- // in the |rejected| array).
- // So for each primary network, remove from |rejected| all networks with the same
- // transports as one of the primary networks. The remaining networks should be accepted.
- for (final T defaultSubNai : accepted) {
- final int[] transports = defaultSubNai.getCapsNoCopy().getTransportTypes();
- rejected.removeIf(
- nai -> Arrays.equals(transports, nai.getCapsNoCopy().getTransportTypes()));
- }
- // Now the |rejected| list contains networks with transports for which there isn't
- // a primary network. Add them back to the candidates.
- accepted.addAll(rejected);
- candidates = new ArrayList<>(accepted);
- }
- if (1 == candidates.size()) return candidates.get(0);
- // If there were no primary network, then candidates.size() > 0 because it didn't
- // change from the previous result. If there were, it's guaranteed candidates.size() > 0
- // because accepted.size() > 0 above.
-
- // If some of the networks have a better transport than others, keep only the ones with
- // the best transports.
- for (final int transport : PREFERRED_TRANSPORTS_ORDER) {
- partitionInto(candidates, nai -> nai.getCapsNoCopy().hasTransport(transport),
- accepted, rejected);
- if (accepted.size() == 1) return accepted.get(0);
- if (accepted.size() > 0 && rejected.size() > 0) {
- candidates = new ArrayList<>(accepted);
- break;
- }
- }
-
- // At this point there are still multiple networks passing all the tests above. If any
- // of them is the previous satisfier, keep it.
- if (candidates.contains(currentSatisfier)) return currentSatisfier;
-
- // If there are still multiple options at this point but none of them is any of the
- // transports above, it doesn't matter which is returned. They are all the same.
- return candidates.get(0);
- }
-
- // TODO : switch to the policy implementation and remove
- // Almost equivalent to Collections.max(nais), but allows returning null if no network
- // satisfies the request.
- private NetworkAgentInfo getBestNetworkByLegacyInt(
- @NonNull final Collection<NetworkAgentInfo> nais) {
- NetworkAgentInfo bestNetwork = null;
- int bestScore = Integer.MIN_VALUE;
- for (final NetworkAgentInfo nai : nais) {
- final int naiScore = nai.getCurrentScore();
- if (naiScore > bestScore) {
- bestNetwork = nai;
- bestScore = naiScore;
- }
- }
- return bestNetwork;
- }
-
- /**
- * Returns whether a {@link Scoreable} has a chance to beat a champion network for a request.
- *
- * Offers are sent by network providers when they think they might be able to make a network
- * with the characteristics contained in the offer. If the offer has no chance to beat
- * the currently best network for a given request, there is no point in the provider spending
- * power trying to find and bring up such a network.
- *
- * Note that having an offer up does not constitute a commitment from the provider part
- * to be able to bring up a network with these characteristics, or a network at all for
- * that matter. This is only used to save power by letting providers know when they can't
- * beat a current champion.
- *
- * @param request The request to evaluate against.
- * @param champion The currently best network for this request.
- * @param contestant The offer.
- * @return Whether the offer stands a chance to beat the champion.
- */
- public boolean mightBeat(@NonNull final NetworkRequest request,
- @Nullable final NetworkAgentInfo champion,
- @NonNull final Scoreable contestant) {
- // If this network can't even satisfy the request then it can't beat anything, not
- // even an absence of network. It can't satisfy it anyway.
- if (!request.canBeSatisfiedBy(contestant.getCapsNoCopy())) return false;
- // If there is no satisfying network, then this network can beat, because some network
- // is always better than no network.
- if (null == champion) return true;
- if (USE_POLICY_RANKING) {
- // If there is no champion, the offer can always beat.
- // Otherwise rank them.
- final ArrayList<Scoreable> candidates = new ArrayList<>();
- candidates.add(champion);
- candidates.add(contestant);
- return contestant == getBestNetworkByPolicy(candidates, champion);
- } else {
- return mightBeatByLegacyInt(champion.getScore(), contestant);
- }
- }
-
- /**
- * Returns whether a contestant might beat a champion according to the legacy int.
- */
- private boolean mightBeatByLegacyInt(@Nullable final FullScore championScore,
- @NonNull final Scoreable contestant) {
- final int offerIntScore;
- if (contestant.getCapsNoCopy().hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
- // If the offer might have Internet access, then it might validate.
- offerIntScore = contestant.getScore().getLegacyIntAsValidated();
- } else {
- offerIntScore = contestant.getScore().getLegacyInt();
- }
- return championScore.getLegacyInt() < offerIntScore;
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/OsCompat.java b/packages/Connectivity/service/src/com/android/server/connectivity/OsCompat.java
deleted file mode 100644
index 57e3dcd..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/OsCompat.java
+++ /dev/null
@@ -1,75 +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.system.ErrnoException;
-import android.system.Os;
-
-import java.io.FileDescriptor;
-
-/**
- * Compatibility utility for android.system.Os core platform APIs.
- *
- * Connectivity has access to such APIs, but they are not part of the module_current stubs yet
- * (only core_current). Most stable core platform APIs are included manually in the connectivity
- * build rules, but because Os is also part of the base java SDK that is earlier on the
- * classpath, the extra core platform APIs are not seen.
- *
- * TODO (b/157639992, b/183097033): remove as soon as core_current is part of system_server_current
- * @hide
- */
-public class OsCompat {
- // This value should be correct on all architectures supported by Android, but hardcoding ioctl
- // numbers should be avoided.
- /**
- * @see android.system.OsConstants#TIOCOUTQ
- */
- public static final int TIOCOUTQ = 0x5411;
-
- /**
- * @see android.system.Os#getsockoptInt(FileDescriptor, int, int)
- */
- public static int getsockoptInt(FileDescriptor fd, int level, int option) throws
- ErrnoException {
- try {
- return (int) Os.class.getMethod(
- "getsockoptInt", FileDescriptor.class, int.class, int.class)
- .invoke(null, fd, level, option);
- } catch (ReflectiveOperationException e) {
- if (e.getCause() instanceof ErrnoException) {
- throw (ErrnoException) e.getCause();
- }
- throw new IllegalStateException("Error calling getsockoptInt", e);
- }
- }
-
- /**
- * @see android.system.Os#ioctlInt(FileDescriptor, int)
- */
- public static int ioctlInt(FileDescriptor fd, int cmd) throws
- ErrnoException {
- try {
- return (int) Os.class.getMethod(
- "ioctlInt", FileDescriptor.class, int.class).invoke(null, fd, cmd);
- } catch (ReflectiveOperationException e) {
- if (e.getCause() instanceof ErrnoException) {
- throw (ErrnoException) e.getCause();
- }
- throw new IllegalStateException("Error calling ioctlInt", e);
- }
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/PermissionMonitor.java b/packages/Connectivity/service/src/com/android/server/connectivity/PermissionMonitor.java
deleted file mode 100644
index 9bda59c..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/PermissionMonitor.java
+++ /dev/null
@@ -1,829 +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 com.android.server.connectivity;
-
-import static android.Manifest.permission.CHANGE_NETWORK_STATE;
-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.PackageInfo.REQUESTED_PERMISSION_GRANTED;
-import static android.content.pm.PackageManager.GET_PERMISSIONS;
-import static android.content.pm.PackageManager.MATCH_ANY_USER;
-import static android.net.ConnectivitySettingsManager.APPS_ALLOWED_ON_RESTRICTED_NETWORKS;
-import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
-import static android.os.Process.INVALID_UID;
-import static android.os.Process.SYSTEM_UID;
-
-import static com.android.net.module.util.CollectionUtils.toIntArray;
-
-import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
-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.PackageManager.NameNotFoundException;
-import android.database.ContentObserver;
-import android.net.ConnectivitySettingsManager;
-import android.net.INetd;
-import android.net.UidRange;
-import android.net.Uri;
-import android.os.Build;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.os.SystemConfigManager;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.system.OsConstants;
-import android.util.ArraySet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.SparseIntArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.net.module.util.CollectionUtils;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * A utility class to inform Netd of UID permisisons.
- * Does a mass update at boot and then monitors for app install/remove.
- *
- * @hide
- */
-public class PermissionMonitor {
- private static final String TAG = "PermissionMonitor";
- private static final boolean DBG = true;
- protected static final Boolean SYSTEM = Boolean.TRUE;
- protected static final Boolean NETWORK = Boolean.FALSE;
- private static final int VERSION_Q = Build.VERSION_CODES.Q;
-
- private final PackageManager mPackageManager;
- private final UserManager mUserManager;
- private final SystemConfigManager mSystemConfigManager;
- private final INetd mNetd;
- private final Dependencies mDeps;
- private final Context mContext;
-
- @GuardedBy("this")
- private final Set<UserHandle> mUsers = new HashSet<>();
-
- // Keys are app uids. Values are true for SYSTEM permission and false for NETWORK permission.
- @GuardedBy("this")
- private final Map<Integer, Boolean> mApps = new HashMap<>();
-
- // Keys are active non-bypassable and fully-routed VPN's interface name, Values are uid ranges
- // for apps under the VPN
- @GuardedBy("this")
- private final Map<String, Set<UidRange>> mVpnUidRanges = new HashMap<>();
-
- // A set of appIds for apps across all users on the device. We track appIds instead of uids
- // directly to reduce its size and also eliminate the need to update this set when user is
- // added/removed.
- @GuardedBy("this")
- private final Set<Integer> mAllApps = new HashSet<>();
-
- // A set of apps which are allowed to use restricted networks. These apps can't hold the
- // CONNECTIVITY_USE_RESTRICTED_NETWORKS permission because they can't be signature|privileged
- // apps. However, these apps should still be able to use restricted networks under certain
- // conditions (e.g. government app using emergency services). So grant netd system permission
- // to uids whose package name is listed in APPS_ALLOWED_ON_RESTRICTED_NETWORKS setting.
- @GuardedBy("this")
- private final Set<String> mAppsAllowedOnRestrictedNetworks = new ArraySet<>();
-
- private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
- final Uri packageData = intent.getData();
- final String packageName =
- packageData != null ? packageData.getSchemeSpecificPart() : null;
-
- if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
- onPackageAdded(packageName, uid);
- } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
- onPackageRemoved(packageName, uid);
- } else {
- Log.wtf(TAG, "received unexpected intent: " + action);
- }
- }
- };
-
- /**
- * Dependencies of PermissionMonitor, for injection in tests.
- */
- @VisibleForTesting
- public static class Dependencies {
- /**
- * Get device first sdk version.
- */
- public int getDeviceFirstSdkInt() {
- return Build.VERSION.DEVICE_INITIAL_SDK_INT;
- }
-
- /**
- * Get apps allowed to use restricted networks via ConnectivitySettingsManager.
- */
- public Set<String> getAppsAllowedOnRestrictedNetworks(@NonNull Context context) {
- return ConnectivitySettingsManager.getAppsAllowedOnRestrictedNetworks(context);
- }
-
- /**
- * Register ContentObserver for given Uri.
- */
- public void registerContentObserver(@NonNull Context context, @NonNull Uri uri,
- boolean notifyForDescendants, @NonNull ContentObserver observer) {
- context.getContentResolver().registerContentObserver(
- uri, notifyForDescendants, observer);
- }
- }
-
- public PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd) {
- this(context, netd, new Dependencies());
- }
-
- @VisibleForTesting
- PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd,
- @NonNull final Dependencies deps) {
- mPackageManager = context.getPackageManager();
- mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- mSystemConfigManager = context.getSystemService(SystemConfigManager.class);
- mNetd = netd;
- mDeps = deps;
- mContext = context;
- }
-
- // Intended to be called only once at startup, after the system is ready. Installs a broadcast
- // receiver to monitor ongoing UID changes, so this shouldn't/needn't be called again.
- public synchronized void startMonitoring() {
- log("Monitoring");
-
- final Context userAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
- final IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
- intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- intentFilter.addDataScheme("package");
- userAllContext.registerReceiver(
- mIntentReceiver, intentFilter, null /* broadcastPermission */,
- null /* scheduler */);
-
- // Register APPS_ALLOWED_ON_RESTRICTED_NETWORKS setting observer
- mDeps.registerContentObserver(
- userAllContext,
- Settings.Secure.getUriFor(APPS_ALLOWED_ON_RESTRICTED_NETWORKS),
- false /* notifyForDescendants */,
- new ContentObserver(null) {
- @Override
- public void onChange(boolean selfChange) {
- onSettingChanged();
- }
- });
-
- // Read APPS_ALLOWED_ON_RESTRICTED_NETWORKS setting and update
- // mAppsAllowedOnRestrictedNetworks.
- updateAppsAllowedOnRestrictedNetworks(mDeps.getAppsAllowedOnRestrictedNetworks(mContext));
-
- List<PackageInfo> apps = mPackageManager.getInstalledPackages(GET_PERMISSIONS
- | MATCH_ANY_USER);
- if (apps == null) {
- loge("No apps");
- return;
- }
-
- SparseIntArray netdPermsUids = new SparseIntArray();
-
- for (PackageInfo app : apps) {
- int uid = app.applicationInfo != null ? app.applicationInfo.uid : INVALID_UID;
- if (uid < 0) {
- continue;
- }
- mAllApps.add(UserHandle.getAppId(uid));
-
- boolean isNetwork = hasNetworkPermission(app);
- boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
-
- if (isNetwork || hasRestrictedPermission) {
- Boolean permission = mApps.get(uid);
- // If multiple packages share a UID (cf: android:sharedUserId) and ask for different
- // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
- if (permission == null || permission == NETWORK) {
- mApps.put(uid, hasRestrictedPermission);
- }
- }
-
- //TODO: unify the management of the permissions into one codepath.
- int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
- app.requestedPermissionsFlags);
- netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
- }
-
- mUsers.addAll(mUserManager.getUserHandles(true /* excludeDying */));
-
- final SparseArray<String> netdPermToSystemPerm = new SparseArray<>();
- netdPermToSystemPerm.put(INetd.PERMISSION_INTERNET, INTERNET);
- netdPermToSystemPerm.put(INetd.PERMISSION_UPDATE_DEVICE_STATS, UPDATE_DEVICE_STATS);
- for (int i = 0; i < netdPermToSystemPerm.size(); i++) {
- final int netdPermission = netdPermToSystemPerm.keyAt(i);
- final String systemPermission = netdPermToSystemPerm.valueAt(i);
- final int[] hasPermissionUids =
- mSystemConfigManager.getSystemPermissionUids(systemPermission);
- for (int j = 0; j < hasPermissionUids.length; j++) {
- final int uid = hasPermissionUids[j];
- netdPermsUids.put(uid, netdPermsUids.get(uid) | netdPermission);
- }
- }
- log("Users: " + mUsers.size() + ", Apps: " + mApps.size());
- update(mUsers, mApps, true);
- sendPackagePermissionsToNetd(netdPermsUids);
- }
-
- @VisibleForTesting
- void updateAppsAllowedOnRestrictedNetworks(final Set<String> apps) {
- mAppsAllowedOnRestrictedNetworks.clear();
- mAppsAllowedOnRestrictedNetworks.addAll(apps);
- }
-
- @VisibleForTesting
- static boolean isVendorApp(@NonNull ApplicationInfo appInfo) {
- return appInfo.isVendor() || appInfo.isOem() || appInfo.isProduct();
- }
-
- @VisibleForTesting
- boolean isCarryoverPackage(final ApplicationInfo appInfo) {
- if (appInfo == null) return false;
- return (appInfo.targetSdkVersion < VERSION_Q && isVendorApp(appInfo))
- // Backward compatibility for b/114245686, on devices that launched before Q daemons
- // and apps running as the system UID are exempted from this check.
- || (appInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q);
- }
-
- @VisibleForTesting
- boolean isAppAllowedOnRestrictedNetworks(@NonNull final PackageInfo app) {
- // Check whether package name is in allowed on restricted networks app list. If so, this app
- // can have netd system permission.
- return mAppsAllowedOnRestrictedNetworks.contains(app.packageName);
- }
-
- @VisibleForTesting
- boolean hasPermission(@NonNull final PackageInfo app, @NonNull final String permission) {
- if (app.requestedPermissions == null || app.requestedPermissionsFlags == null) {
- return false;
- }
- final int index = CollectionUtils.indexOf(app.requestedPermissions, permission);
- if (index < 0 || index >= app.requestedPermissionsFlags.length) return false;
- return (app.requestedPermissionsFlags[index] & REQUESTED_PERMISSION_GRANTED) != 0;
- }
-
- @VisibleForTesting
- boolean hasNetworkPermission(@NonNull final PackageInfo app) {
- return hasPermission(app, CHANGE_NETWORK_STATE);
- }
-
- @VisibleForTesting
- boolean hasRestrictedNetworkPermission(@NonNull final PackageInfo app) {
- // TODO : remove carryover package check in the future(b/31479477). All apps should just
- // request the appropriate permission for their use case since android Q.
- return isCarryoverPackage(app.applicationInfo) || isAppAllowedOnRestrictedNetworks(app)
- || hasPermission(app, PERMISSION_MAINLINE_NETWORK_STACK)
- || hasPermission(app, NETWORK_STACK)
- || hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
- }
-
- /** Returns whether the given uid has using background network permission. */
- public synchronized boolean hasUseBackgroundNetworksPermission(final int uid) {
- // Apps with any of the CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_INTERNAL or
- // CONNECTIVITY_USE_RESTRICTED_NETWORKS permission has the permission to use background
- // networks. mApps contains the result of checks for both hasNetworkPermission and
- // hasRestrictedNetworkPermission. If uid is in the mApps list that means uid has one of
- // permissions at least.
- return mApps.containsKey(uid);
- }
-
- /**
- * Returns whether the given uid has permission to use restricted networks.
- */
- public synchronized boolean hasRestrictedNetworksPermission(int uid) {
- return Boolean.TRUE.equals(mApps.get(uid));
- }
-
- private void update(Set<UserHandle> users, Map<Integer, Boolean> apps, boolean add) {
- List<Integer> network = new ArrayList<>();
- List<Integer> system = new ArrayList<>();
- for (Entry<Integer, Boolean> app : apps.entrySet()) {
- List<Integer> list = app.getValue() ? system : network;
- for (UserHandle user : users) {
- if (user == null) continue;
-
- list.add(user.getUid(app.getKey()));
- }
- }
- try {
- if (add) {
- mNetd.networkSetPermissionForUser(INetd.PERMISSION_NETWORK, toIntArray(network));
- mNetd.networkSetPermissionForUser(INetd.PERMISSION_SYSTEM, toIntArray(system));
- } else {
- mNetd.networkClearPermissionForUser(toIntArray(network));
- mNetd.networkClearPermissionForUser(toIntArray(system));
- }
- } catch (RemoteException e) {
- loge("Exception when updating permissions: " + e);
- }
- }
-
- /**
- * Called when a user is added. See {link #ACTION_USER_ADDED}.
- *
- * @param user The integer userHandle of the added user. See {@link #EXTRA_USER_HANDLE}.
- *
- * @hide
- */
- public synchronized void onUserAdded(@NonNull UserHandle user) {
- mUsers.add(user);
-
- Set<UserHandle> users = new HashSet<>();
- users.add(user);
- update(users, mApps, true);
- }
-
- /**
- * Called when an user is removed. See {link #ACTION_USER_REMOVED}.
- *
- * @param user The integer userHandle of the removed user. See {@link #EXTRA_USER_HANDLE}.
- *
- * @hide
- */
- public synchronized void onUserRemoved(@NonNull UserHandle user) {
- mUsers.remove(user);
-
- Set<UserHandle> users = new HashSet<>();
- users.add(user);
- update(users, mApps, false);
- }
-
- @VisibleForTesting
- protected Boolean highestPermissionForUid(Boolean currentPermission, String name) {
- if (currentPermission == SYSTEM) {
- return currentPermission;
- }
- try {
- final PackageInfo app = mPackageManager.getPackageInfo(name,
- GET_PERMISSIONS | MATCH_ANY_USER);
- final boolean isNetwork = hasNetworkPermission(app);
- final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
- if (isNetwork || hasRestrictedPermission) {
- currentPermission = hasRestrictedPermission;
- }
- } catch (NameNotFoundException e) {
- // App not found.
- loge("NameNotFoundException " + name);
- }
- return currentPermission;
- }
-
- private int getPermissionForUid(final int uid) {
- int permission = INetd.PERMISSION_NONE;
- // Check all the packages for this UID. The UID has the permission if any of the
- // packages in it has the permission.
- final String[] packages = mPackageManager.getPackagesForUid(uid);
- if (packages != null && packages.length > 0) {
- for (String name : packages) {
- final PackageInfo app = getPackageInfo(name);
- if (app != null && app.requestedPermissions != null) {
- permission |= getNetdPermissionMask(app.requestedPermissions,
- app.requestedPermissionsFlags);
- }
- }
- } else {
- // The last package of this uid is removed from device. Clean the package up.
- permission = INetd.PERMISSION_UNINSTALLED;
- }
- return permission;
- }
-
- /**
- * Called when a package is added.
- *
- * @param packageName The name of the new package.
- * @param uid The uid of the new package.
- *
- * @hide
- */
- public synchronized void onPackageAdded(@NonNull final String packageName, final int uid) {
- // TODO: Netd is using appId for checking traffic permission. Correct the methods that are
- // using appId instead of uid actually
- sendPackagePermissionsForUid(UserHandle.getAppId(uid), getPermissionForUid(uid));
-
- // If multiple packages share a UID (cf: android:sharedUserId) and ask for different
- // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
- final Boolean permission = highestPermissionForUid(mApps.get(uid), packageName);
- if (permission != mApps.get(uid)) {
- mApps.put(uid, permission);
-
- Map<Integer, Boolean> apps = new HashMap<>();
- apps.put(uid, permission);
- update(mUsers, apps, true);
- }
-
- // If the newly-installed package falls within some VPN's uid range, update Netd with it.
- // This needs to happen after the mApps update above, since removeBypassingUids() depends
- // on mApps to check if the package can bypass VPN.
- for (Map.Entry<String, Set<UidRange>> vpn : mVpnUidRanges.entrySet()) {
- if (UidRange.containsUid(vpn.getValue(), uid)) {
- final Set<Integer> changedUids = new HashSet<>();
- changedUids.add(uid);
- removeBypassingUids(changedUids, /* vpnAppUid */ -1);
- updateVpnUids(vpn.getKey(), changedUids, true);
- }
- }
- mAllApps.add(UserHandle.getAppId(uid));
- }
-
- private Boolean highestUidNetworkPermission(int uid) {
- Boolean permission = null;
- final String[] packages = mPackageManager.getPackagesForUid(uid);
- if (!CollectionUtils.isEmpty(packages)) {
- for (String name : packages) {
- permission = highestPermissionForUid(permission, name);
- if (permission == SYSTEM) {
- break;
- }
- }
- }
- return permission;
- }
-
- /**
- * Called when a package is removed.
- *
- * @param packageName The name of the removed package or null.
- * @param uid containing the integer uid previously assigned to the package.
- *
- * @hide
- */
- public synchronized void onPackageRemoved(@NonNull final String packageName, final int uid) {
- // TODO: Netd is using appId for checking traffic permission. Correct the methods that are
- // using appId instead of uid actually
- sendPackagePermissionsForUid(UserHandle.getAppId(uid), getPermissionForUid(uid));
-
- // If the newly-removed package falls within some VPN's uid range, update Netd with it.
- // This needs to happen before the mApps update below, since removeBypassingUids() depends
- // on mApps to check if the package can bypass VPN.
- for (Map.Entry<String, Set<UidRange>> vpn : mVpnUidRanges.entrySet()) {
- if (UidRange.containsUid(vpn.getValue(), uid)) {
- final Set<Integer> changedUids = new HashSet<>();
- changedUids.add(uid);
- removeBypassingUids(changedUids, /* vpnAppUid */ -1);
- updateVpnUids(vpn.getKey(), changedUids, false);
- }
- }
- // If the package has been removed from all users on the device, clear it form mAllApps.
- if (mPackageManager.getNameForUid(uid) == null) {
- mAllApps.remove(UserHandle.getAppId(uid));
- }
-
- Map<Integer, Boolean> apps = new HashMap<>();
- final Boolean permission = highestUidNetworkPermission(uid);
- if (permission == SYSTEM) {
- // An app with this UID still has the SYSTEM permission.
- // Therefore, this UID must already have the SYSTEM permission.
- // Nothing to do.
- return;
- }
-
- if (permission == mApps.get(uid)) {
- // The permissions of this UID have not changed. Nothing to do.
- return;
- } else if (permission != null) {
- mApps.put(uid, permission);
- apps.put(uid, permission);
- update(mUsers, apps, true);
- } else {
- mApps.remove(uid);
- apps.put(uid, NETWORK); // doesn't matter which permission we pick here
- update(mUsers, apps, false);
- }
- }
-
- private static int getNetdPermissionMask(String[] requestedPermissions,
- int[] requestedPermissionsFlags) {
- int permissions = 0;
- if (requestedPermissions == null || requestedPermissionsFlags == null) return permissions;
- for (int i = 0; i < requestedPermissions.length; i++) {
- if (requestedPermissions[i].equals(INTERNET)
- && ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
- permissions |= INetd.PERMISSION_INTERNET;
- }
- if (requestedPermissions[i].equals(UPDATE_DEVICE_STATS)
- && ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
- permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS;
- }
- }
- return permissions;
- }
-
- private PackageInfo getPackageInfo(String packageName) {
- try {
- PackageInfo app = mPackageManager.getPackageInfo(packageName, GET_PERMISSIONS
- | MATCH_ANY_USER);
- return app;
- } catch (NameNotFoundException e) {
- return null;
- }
- }
-
- /**
- * Called when a new set of UID ranges are added to an active VPN network
- *
- * @param iface The active VPN network's interface name
- * @param rangesToAdd The new UID ranges to be added to the network
- * @param vpnAppUid The uid of the VPN app
- */
- public synchronized void onVpnUidRangesAdded(@NonNull String iface, Set<UidRange> rangesToAdd,
- int vpnAppUid) {
- // Calculate the list of new app uids under the VPN due to the new UID ranges and update
- // Netd about them. Because mAllApps only contains appIds instead of uids, the result might
- // be an overestimation if an app is not installed on the user on which the VPN is running,
- // but that's safe.
- final Set<Integer> changedUids = intersectUids(rangesToAdd, mAllApps);
- removeBypassingUids(changedUids, vpnAppUid);
- updateVpnUids(iface, changedUids, true);
- if (mVpnUidRanges.containsKey(iface)) {
- mVpnUidRanges.get(iface).addAll(rangesToAdd);
- } else {
- mVpnUidRanges.put(iface, new HashSet<UidRange>(rangesToAdd));
- }
- }
-
- /**
- * Called when a set of UID ranges are removed from an active VPN network
- *
- * @param iface The VPN network's interface name
- * @param rangesToRemove Existing UID ranges to be removed from the VPN network
- * @param vpnAppUid The uid of the VPN app
- */
- public synchronized void onVpnUidRangesRemoved(@NonNull String iface,
- Set<UidRange> rangesToRemove, int vpnAppUid) {
- // Calculate the list of app uids that are no longer under the VPN due to the removed UID
- // ranges and update Netd about them.
- final Set<Integer> changedUids = intersectUids(rangesToRemove, mAllApps);
- removeBypassingUids(changedUids, vpnAppUid);
- updateVpnUids(iface, changedUids, false);
- Set<UidRange> existingRanges = mVpnUidRanges.getOrDefault(iface, null);
- if (existingRanges == null) {
- loge("Attempt to remove unknown vpn uid Range iface = " + iface);
- return;
- }
- existingRanges.removeAll(rangesToRemove);
- if (existingRanges.size() == 0) {
- mVpnUidRanges.remove(iface);
- }
- }
-
- /**
- * Compute the intersection of a set of UidRanges and appIds. Returns a set of uids
- * that satisfies:
- * 1. falls into one of the UidRange
- * 2. matches one of the appIds
- */
- private Set<Integer> intersectUids(Set<UidRange> ranges, Set<Integer> appIds) {
- Set<Integer> result = new HashSet<>();
- for (UidRange range : ranges) {
- for (int userId = range.getStartUser(); userId <= range.getEndUser(); userId++) {
- for (int appId : appIds) {
- final UserHandle handle = UserHandle.of(userId);
- if (handle == null) continue;
-
- final int uid = handle.getUid(appId);
- if (range.contains(uid)) {
- result.add(uid);
- }
- }
- }
- }
- return result;
- }
-
- /**
- * Remove all apps which can elect to bypass the VPN from the list of uids
- *
- * An app can elect to bypass the VPN if it hold SYSTEM permission, or if its the active VPN
- * app itself.
- *
- * @param uids The list of uids to operate on
- * @param vpnAppUid The uid of the VPN app
- */
- private void removeBypassingUids(Set<Integer> uids, int vpnAppUid) {
- uids.remove(vpnAppUid);
- uids.removeIf(uid -> mApps.getOrDefault(uid, NETWORK) == SYSTEM);
- }
-
- /**
- * Update netd about the list of uids that are under an active VPN connection which they cannot
- * bypass.
- *
- * This is to instruct netd to set up appropriate filtering rules for these uids, such that they
- * can only receive ingress packets from the VPN's tunnel interface (and loopback).
- *
- * @param iface the interface name of the active VPN connection
- * @param add {@code true} if the uids are to be added to the interface, {@code false} if they
- * are to be removed from the interface.
- */
- private void updateVpnUids(String iface, Set<Integer> uids, boolean add) {
- if (uids.size() == 0) {
- return;
- }
- try {
- if (add) {
- mNetd.firewallAddUidInterfaceRules(iface, toIntArray(uids));
- } else {
- mNetd.firewallRemoveUidInterfaceRules(toIntArray(uids));
- }
- } catch (ServiceSpecificException e) {
- // Silently ignore exception when device does not support eBPF, otherwise just log
- // the exception and do not crash
- if (e.errorCode != OsConstants.EOPNOTSUPP) {
- loge("Exception when updating permissions: ", e);
- }
- } catch (RemoteException e) {
- loge("Exception when updating permissions: ", e);
- }
- }
-
- /**
- * Called by PackageListObserver when a package is installed/uninstalled. Send the updated
- * permission information to netd.
- *
- * @param uid the app uid of the package installed
- * @param permissions the permissions the app requested and netd cares about.
- *
- * @hide
- */
- @VisibleForTesting
- void sendPackagePermissionsForUid(int uid, int permissions) {
- SparseIntArray netdPermissionsAppIds = new SparseIntArray();
- netdPermissionsAppIds.put(uid, permissions);
- sendPackagePermissionsToNetd(netdPermissionsAppIds);
- }
-
- /**
- * Called by packageManagerService to send IPC to netd. Grant or revoke the INTERNET
- * and/or UPDATE_DEVICE_STATS permission of the uids in array.
- *
- * @param netdPermissionsAppIds integer pairs of uids and the permission granted to it. If the
- * permission is 0, revoke all permissions of that uid.
- *
- * @hide
- */
- @VisibleForTesting
- void sendPackagePermissionsToNetd(SparseIntArray netdPermissionsAppIds) {
- if (mNetd == null) {
- Log.e(TAG, "Failed to get the netd service");
- return;
- }
- ArrayList<Integer> allPermissionAppIds = new ArrayList<>();
- ArrayList<Integer> internetPermissionAppIds = new ArrayList<>();
- ArrayList<Integer> updateStatsPermissionAppIds = new ArrayList<>();
- ArrayList<Integer> noPermissionAppIds = new ArrayList<>();
- ArrayList<Integer> uninstalledAppIds = new ArrayList<>();
- for (int i = 0; i < netdPermissionsAppIds.size(); i++) {
- int permissions = netdPermissionsAppIds.valueAt(i);
- switch(permissions) {
- case (INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS):
- allPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
- break;
- case INetd.PERMISSION_INTERNET:
- internetPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
- break;
- case INetd.PERMISSION_UPDATE_DEVICE_STATS:
- updateStatsPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
- break;
- case INetd.PERMISSION_NONE:
- noPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
- break;
- case INetd.PERMISSION_UNINSTALLED:
- uninstalledAppIds.add(netdPermissionsAppIds.keyAt(i));
- break;
- default:
- Log.e(TAG, "unknown permission type: " + permissions + "for uid: "
- + netdPermissionsAppIds.keyAt(i));
- }
- }
- try {
- // TODO: add a lock inside netd to protect IPC trafficSetNetPermForUids()
- if (allPermissionAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(
- INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
- toIntArray(allPermissionAppIds));
- }
- if (internetPermissionAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(INetd.PERMISSION_INTERNET,
- toIntArray(internetPermissionAppIds));
- }
- if (updateStatsPermissionAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UPDATE_DEVICE_STATS,
- toIntArray(updateStatsPermissionAppIds));
- }
- if (noPermissionAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(INetd.PERMISSION_NONE,
- toIntArray(noPermissionAppIds));
- }
- if (uninstalledAppIds.size() != 0) {
- mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UNINSTALLED,
- toIntArray(uninstalledAppIds));
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Pass appId list of special permission failed." + e);
- }
- }
-
- /** Should only be used by unit tests */
- @VisibleForTesting
- public Set<UidRange> getVpnUidRanges(String iface) {
- return mVpnUidRanges.get(iface);
- }
-
- private synchronized void onSettingChanged() {
- // Step1. Update apps allowed to use restricted networks and compute the set of packages to
- // update.
- final Set<String> packagesToUpdate = new ArraySet<>(mAppsAllowedOnRestrictedNetworks);
- updateAppsAllowedOnRestrictedNetworks(mDeps.getAppsAllowedOnRestrictedNetworks(mContext));
- packagesToUpdate.addAll(mAppsAllowedOnRestrictedNetworks);
-
- final Map<Integer, Boolean> updatedApps = new HashMap<>();
- final Map<Integer, Boolean> removedApps = new HashMap<>();
-
- // Step2. For each package to update, find out its new permission.
- for (String app : packagesToUpdate) {
- final PackageInfo info = getPackageInfo(app);
- if (info == null || info.applicationInfo == null) continue;
-
- final int uid = info.applicationInfo.uid;
- final Boolean permission = highestUidNetworkPermission(uid);
-
- if (null == permission) {
- removedApps.put(uid, NETWORK); // Doesn't matter which permission is set here.
- mApps.remove(uid);
- } else {
- updatedApps.put(uid, permission);
- mApps.put(uid, permission);
- }
- }
-
- // Step3. Update or revoke permission for uids with netd.
- update(mUsers, updatedApps, true /* add */);
- update(mUsers, removedApps, false /* add */);
- }
-
- /** Dump info to dumpsys */
- public void dump(IndentingPrintWriter pw) {
- pw.println("Interface filtering rules:");
- pw.increaseIndent();
- for (Map.Entry<String, Set<UidRange>> vpn : mVpnUidRanges.entrySet()) {
- pw.println("Interface: " + vpn.getKey());
- pw.println("UIDs: " + vpn.getValue().toString());
- pw.println();
- }
- pw.decreaseIndent();
- }
-
- private static void log(String s) {
- if (DBG) {
- Log.d(TAG, s);
- }
- }
-
- private static void loge(String s) {
- Log.e(TAG, s);
- }
-
- private static void loge(String s, Throwable e) {
- Log.e(TAG, s, e);
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/ProfileNetworkPreferences.java b/packages/Connectivity/service/src/com/android/server/connectivity/ProfileNetworkPreferences.java
deleted file mode 100644
index dd2815d..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/ProfileNetworkPreferences.java
+++ /dev/null
@@ -1,87 +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.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.NetworkCapabilities;
-import android.os.UserHandle;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A data class containing all the per-profile network preferences.
- *
- * A given profile can only have one preference.
- */
-public class ProfileNetworkPreferences {
- /**
- * A single preference, as it applies to a given user profile.
- */
- public static class Preference {
- @NonNull public final UserHandle user;
- // Capabilities are only null when sending an object to remove the setting for a user
- @Nullable public final NetworkCapabilities capabilities;
-
- public Preference(@NonNull final UserHandle user,
- @Nullable final NetworkCapabilities capabilities) {
- this.user = user;
- this.capabilities = null == capabilities ? null : new NetworkCapabilities(capabilities);
- }
-
- /** toString */
- public String toString() {
- return "[ProfileNetworkPreference user=" + user + " caps=" + capabilities + "]";
- }
- }
-
- @NonNull public final List<Preference> preferences;
-
- public ProfileNetworkPreferences() {
- preferences = Collections.EMPTY_LIST;
- }
-
- private ProfileNetworkPreferences(@NonNull final List<Preference> list) {
- preferences = Collections.unmodifiableList(list);
- }
-
- /**
- * Returns a new object consisting of this object plus the passed preference.
- *
- * If a preference already exists for the same user, it will be replaced by the passed
- * preference. Passing a Preference object containing a null capabilities object is equivalent
- * to (and indeed, implemented as) removing the preference for this user.
- */
- public ProfileNetworkPreferences plus(@NonNull final Preference pref) {
- final ArrayList<Preference> newPrefs = new ArrayList<>();
- for (final Preference existingPref : preferences) {
- if (!existingPref.user.equals(pref.user)) {
- newPrefs.add(existingPref);
- }
- }
- if (null != pref.capabilities) {
- newPrefs.add(pref);
- }
- return new ProfileNetworkPreferences(newPrefs);
- }
-
- public boolean isEmpty() {
- return preferences.isEmpty();
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/ProxyTracker.java b/packages/Connectivity/service/src/com/android/server/connectivity/ProxyTracker.java
deleted file mode 100644
index bc0929c..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/ProxyTracker.java
+++ /dev/null
@@ -1,358 +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.GLOBAL_HTTP_PROXY_EXCLUSION_LIST;
-import static android.net.ConnectivitySettingsManager.GLOBAL_HTTP_PROXY_HOST;
-import static android.net.ConnectivitySettingsManager.GLOBAL_HTTP_PROXY_PAC;
-import static android.net.ConnectivitySettingsManager.GLOBAL_HTTP_PROXY_PORT;
-import static android.provider.Settings.Global.HTTP_PROXY;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Network;
-import android.net.PacProxyManager;
-import android.net.Proxy;
-import android.net.ProxyInfo;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.net.module.util.ProxyUtils;
-
-import java.util.Collections;
-import java.util.Objects;
-
-/**
- * A class to handle proxy for ConnectivityService.
- *
- * @hide
- */
-public class ProxyTracker {
- private static final String TAG = ProxyTracker.class.getSimpleName();
- private static final boolean DBG = true;
-
- // EXTRA_PROXY_INFO is now @removed. In order to continue sending it, hardcode its value here.
- // The Proxy.EXTRA_PROXY_INFO constant is not visible to this code because android.net.Proxy
- // a hidden platform constant not visible to mainline modules.
- private static final String EXTRA_PROXY_INFO = "android.intent.extra.PROXY_INFO";
-
- @NonNull
- private final Context mContext;
-
- @NonNull
- private final Object mProxyLock = new Object();
- // The global proxy is the proxy that is set device-wide, overriding any network-specific
- // proxy. Note however that proxies are hints ; the system does not enforce their use. Hence
- // this value is only for querying.
- @Nullable
- @GuardedBy("mProxyLock")
- private ProxyInfo mGlobalProxy = null;
- // The default proxy is the proxy that applies to no particular network if the global proxy
- // is not set. Individual networks have their own settings that override this. This member
- // is set through setDefaultProxy, which is called when the default network changes proxies
- // in its LinkProperties, or when ConnectivityService switches to a new default network, or
- // when PacProxyService resolves the proxy.
- @Nullable
- @GuardedBy("mProxyLock")
- private volatile ProxyInfo mDefaultProxy = null;
- // Whether the default proxy is enabled.
- @GuardedBy("mProxyLock")
- private boolean mDefaultProxyEnabled = true;
-
- private final Handler mConnectivityServiceHandler;
-
- private final PacProxyManager mPacProxyManager;
-
- private class PacProxyInstalledListener implements PacProxyManager.PacProxyInstalledListener {
- private final int mEvent;
-
- PacProxyInstalledListener(int event) {
- mEvent = event;
- }
-
- public void onPacProxyInstalled(@Nullable Network network, @NonNull ProxyInfo proxy) {
- mConnectivityServiceHandler
- .sendMessage(mConnectivityServiceHandler
- .obtainMessage(mEvent, new Pair<>(network, proxy)));
- }
- }
-
- public ProxyTracker(@NonNull final Context context,
- @NonNull final Handler connectivityServiceInternalHandler, final int pacChangedEvent) {
- mContext = context;
- mConnectivityServiceHandler = connectivityServiceInternalHandler;
- mPacProxyManager = context.getSystemService(PacProxyManager.class);
-
- PacProxyInstalledListener listener = new PacProxyInstalledListener(pacChangedEvent);
- mPacProxyManager.addPacProxyInstalledListener(
- mConnectivityServiceHandler::post, listener);
- }
-
- // Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present
- // (e.g. if mGlobalProxy==null fall back to network-specific proxy, if network-specific
- // proxy is null then there is no proxy in place).
- @Nullable
- private static ProxyInfo canonicalizeProxyInfo(@Nullable final ProxyInfo proxy) {
- if (proxy != null && TextUtils.isEmpty(proxy.getHost())
- && Uri.EMPTY.equals(proxy.getPacFileUrl())) {
- return null;
- }
- return proxy;
- }
-
- // ProxyInfo equality functions with a couple modifications over ProxyInfo.equals() to make it
- // better for determining if a new proxy broadcast is necessary:
- // 1. Canonicalize empty ProxyInfos to null so an empty proxy compares equal to null so as to
- // avoid unnecessary broadcasts.
- // 2. Make sure all parts of the ProxyInfo's compare true, including the host when a PAC URL
- // is in place. This is important so legacy PAC resolver (see com.android.proxyhandler)
- // changes aren't missed. The legacy PAC resolver pretends to be a simple HTTP proxy but
- // actually uses the PAC to resolve; this results in ProxyInfo's with PAC URL, host and port
- // all set.
- public static boolean proxyInfoEqual(@Nullable final ProxyInfo a, @Nullable final ProxyInfo b) {
- final ProxyInfo pa = canonicalizeProxyInfo(a);
- final ProxyInfo pb = canonicalizeProxyInfo(b);
- // ProxyInfo.equals() doesn't check hosts when PAC URLs are present, but we need to check
- // hosts even when PAC URLs are present to account for the legacy PAC resolver.
- return Objects.equals(pa, pb) && (pa == null || Objects.equals(pa.getHost(), pb.getHost()));
- }
-
- /**
- * Gets the default system-wide proxy.
- *
- * This will return the global proxy if set, otherwise the default proxy if in use. Note
- * that this is not necessarily the proxy that any given process should use, as the right
- * proxy for a process is the proxy for the network this process will use, which may be
- * different from this value. This value is simply the default in case there is no proxy set
- * in the network that will be used by a specific process.
- * @return The default system-wide proxy or null if none.
- */
- @Nullable
- public ProxyInfo getDefaultProxy() {
- // This information is already available as a world read/writable jvm property.
- synchronized (mProxyLock) {
- if (mGlobalProxy != null) return mGlobalProxy;
- if (mDefaultProxyEnabled) return mDefaultProxy;
- return null;
- }
- }
-
- /**
- * Gets the global proxy.
- *
- * @return The global proxy or null if none.
- */
- @Nullable
- public ProxyInfo getGlobalProxy() {
- // This information is already available as a world read/writable jvm property.
- synchronized (mProxyLock) {
- return mGlobalProxy;
- }
- }
-
- /**
- * Read the global proxy settings and cache them in memory.
- */
- public void loadGlobalProxy() {
- if (loadDeprecatedGlobalHttpProxy()) {
- return;
- }
- ContentResolver res = mContext.getContentResolver();
- String host = Settings.Global.getString(res, GLOBAL_HTTP_PROXY_HOST);
- int port = Settings.Global.getInt(res, GLOBAL_HTTP_PROXY_PORT, 0);
- String exclList = Settings.Global.getString(res, GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
- String pacFileUrl = Settings.Global.getString(res, GLOBAL_HTTP_PROXY_PAC);
- if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) {
- ProxyInfo proxyProperties;
- if (!TextUtils.isEmpty(pacFileUrl)) {
- proxyProperties = ProxyInfo.buildPacProxy(Uri.parse(pacFileUrl));
- } else {
- proxyProperties = ProxyInfo.buildDirectProxy(host, port,
- ProxyUtils.exclusionStringAsList(exclList));
- }
- if (!proxyProperties.isValid()) {
- if (DBG) Log.d(TAG, "Invalid proxy properties, ignoring: " + proxyProperties);
- return;
- }
-
- synchronized (mProxyLock) {
- mGlobalProxy = proxyProperties;
- }
-
- if (!TextUtils.isEmpty(pacFileUrl)) {
- mConnectivityServiceHandler.post(
- () -> mPacProxyManager.setCurrentProxyScriptUrl(proxyProperties));
- }
- }
- }
-
- /**
- * Read the global proxy from the deprecated Settings.Global.HTTP_PROXY setting and apply it.
- * Returns {@code true} when global proxy was set successfully from deprecated setting.
- */
- public boolean loadDeprecatedGlobalHttpProxy() {
- final String proxy = Settings.Global.getString(mContext.getContentResolver(), HTTP_PROXY);
- if (!TextUtils.isEmpty(proxy)) {
- String data[] = proxy.split(":");
- if (data.length == 0) {
- return false;
- }
-
- final String proxyHost = data[0];
- int proxyPort = 8080;
- if (data.length > 1) {
- try {
- proxyPort = Integer.parseInt(data[1]);
- } catch (NumberFormatException e) {
- return false;
- }
- }
- final ProxyInfo p = ProxyInfo.buildDirectProxy(proxyHost, proxyPort,
- Collections.emptyList());
- setGlobalProxy(p);
- return true;
- }
- return false;
- }
-
- /**
- * Sends the system broadcast informing apps about a new proxy configuration.
- *
- * Confusingly this method also sets the PAC file URL. TODO : separate this, it has nothing
- * to do in a "sendProxyBroadcast" method.
- */
- public void sendProxyBroadcast() {
- final ProxyInfo defaultProxy = getDefaultProxy();
- final ProxyInfo proxyInfo = null != defaultProxy ?
- defaultProxy : ProxyInfo.buildDirectProxy("", 0, Collections.emptyList());
- mPacProxyManager.setCurrentProxyScriptUrl(proxyInfo);
-
- if (!shouldSendBroadcast(proxyInfo)) {
- return;
- }
- if (DBG) Log.d(TAG, "sending Proxy Broadcast for " + proxyInfo);
- Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
- Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- intent.putExtra(EXTRA_PROXY_INFO, proxyInfo);
- final long ident = Binder.clearCallingIdentity();
- try {
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- private boolean shouldSendBroadcast(ProxyInfo proxy) {
- return Uri.EMPTY.equals(proxy.getPacFileUrl()) || proxy.getPort() > 0;
- }
-
- /**
- * Sets the global proxy in memory. Also writes the values to the global settings of the device.
- *
- * @param proxyInfo the proxy spec, or null for no proxy.
- */
- public void setGlobalProxy(@Nullable ProxyInfo proxyInfo) {
- synchronized (mProxyLock) {
- // ProxyInfo#equals is not commutative :( and is public API, so it can't be fixed.
- if (proxyInfo == mGlobalProxy) return;
- if (proxyInfo != null && proxyInfo.equals(mGlobalProxy)) return;
- if (mGlobalProxy != null && mGlobalProxy.equals(proxyInfo)) return;
-
- final String host;
- final int port;
- final String exclList;
- final String pacFileUrl;
- if (proxyInfo != null && (!TextUtils.isEmpty(proxyInfo.getHost()) ||
- !Uri.EMPTY.equals(proxyInfo.getPacFileUrl()))) {
- if (!proxyInfo.isValid()) {
- if (DBG) Log.d(TAG, "Invalid proxy properties, ignoring: " + proxyInfo);
- return;
- }
- mGlobalProxy = new ProxyInfo(proxyInfo);
- host = mGlobalProxy.getHost();
- port = mGlobalProxy.getPort();
- exclList = ProxyUtils.exclusionListAsString(mGlobalProxy.getExclusionList());
- pacFileUrl = Uri.EMPTY.equals(proxyInfo.getPacFileUrl())
- ? "" : proxyInfo.getPacFileUrl().toString();
- } else {
- host = "";
- port = 0;
- exclList = "";
- pacFileUrl = "";
- mGlobalProxy = null;
- }
- final ContentResolver res = mContext.getContentResolver();
- final long token = Binder.clearCallingIdentity();
- try {
- Settings.Global.putString(res, GLOBAL_HTTP_PROXY_HOST, host);
- Settings.Global.putInt(res, GLOBAL_HTTP_PROXY_PORT, port);
- Settings.Global.putString(res, GLOBAL_HTTP_PROXY_EXCLUSION_LIST, exclList);
- Settings.Global.putString(res, GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
-
- sendProxyBroadcast();
- }
- }
-
- /**
- * Sets the default proxy for the device.
- *
- * The default proxy is the proxy used for networks that do not have a specific proxy.
- * @param proxyInfo the proxy spec, or null for no proxy.
- */
- public void setDefaultProxy(@Nullable ProxyInfo proxyInfo) {
- synchronized (mProxyLock) {
- if (Objects.equals(mDefaultProxy, proxyInfo)) return;
- if (proxyInfo != null && !proxyInfo.isValid()) {
- if (DBG) Log.d(TAG, "Invalid proxy properties, ignoring: " + proxyInfo);
- return;
- }
-
- // This call could be coming from the PacProxyService, containing the port of the
- // local proxy. If this new proxy matches the global proxy then copy this proxy to the
- // global (to get the correct local port), and send a broadcast.
- // TODO: Switch PacProxyService to have its own message to send back rather than
- // reusing EVENT_HAS_CHANGED_PROXY and this call to handleApplyDefaultProxy.
- if ((mGlobalProxy != null) && (proxyInfo != null)
- && (!Uri.EMPTY.equals(proxyInfo.getPacFileUrl()))
- && proxyInfo.getPacFileUrl().equals(mGlobalProxy.getPacFileUrl())) {
- mGlobalProxy = proxyInfo;
- sendProxyBroadcast();
- return;
- }
- mDefaultProxy = proxyInfo;
-
- if (mGlobalProxy != null) return;
- if (mDefaultProxyEnabled) {
- sendProxyBroadcast();
- }
- }
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/QosCallbackAgentConnection.java b/packages/Connectivity/service/src/com/android/server/connectivity/QosCallbackAgentConnection.java
deleted file mode 100644
index 534dbe7..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/QosCallbackAgentConnection.java
+++ /dev/null
@@ -1,199 +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 static android.net.QosCallbackException.EX_TYPE_FILTER_NONE;
-
-import android.annotation.NonNull;
-import android.net.IQosCallback;
-import android.net.Network;
-import android.net.QosCallbackException;
-import android.net.QosFilter;
-import android.net.QosSession;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.telephony.data.EpsBearerQosSessionAttributes;
-import android.telephony.data.NrQosSessionAttributes;
-import android.util.Log;
-
-import java.util.Objects;
-
-/**
- * Wraps callback related information and sends messages between network agent and the application.
- * <p/>
- * This is a satellite class of {@link com.android.server.ConnectivityService} and not meant
- * to be used in other contexts.
- *
- * @hide
- */
-class QosCallbackAgentConnection implements IBinder.DeathRecipient {
- private static final String TAG = QosCallbackAgentConnection.class.getSimpleName();
- private static final boolean DBG = false;
-
- private final int mAgentCallbackId;
- @NonNull private final QosCallbackTracker mQosCallbackTracker;
- @NonNull private final IQosCallback mCallback;
- @NonNull private final IBinder mBinder;
- @NonNull private final QosFilter mFilter;
- @NonNull private final NetworkAgentInfo mNetworkAgentInfo;
-
- private final int mUid;
-
- /**
- * Gets the uid
- * @return uid
- */
- int getUid() {
- return mUid;
- }
-
- /**
- * Gets the binder
- * @return binder
- */
- @NonNull
- IBinder getBinder() {
- return mBinder;
- }
-
- /**
- * Gets the callback id
- *
- * @return callback id
- */
- int getAgentCallbackId() {
- return mAgentCallbackId;
- }
-
- /**
- * Gets the network tied to the callback of this connection
- *
- * @return network
- */
- @NonNull
- Network getNetwork() {
- return mFilter.getNetwork();
- }
-
- QosCallbackAgentConnection(@NonNull final QosCallbackTracker qosCallbackTracker,
- final int agentCallbackId,
- @NonNull final IQosCallback callback,
- @NonNull final QosFilter filter,
- final int uid,
- @NonNull final NetworkAgentInfo networkAgentInfo) {
- Objects.requireNonNull(qosCallbackTracker, "qosCallbackTracker must be non-null");
- Objects.requireNonNull(callback, "callback must be non-null");
- Objects.requireNonNull(filter, "filter must be non-null");
- Objects.requireNonNull(networkAgentInfo, "networkAgentInfo must be non-null");
-
- mQosCallbackTracker = qosCallbackTracker;
- mAgentCallbackId = agentCallbackId;
- mCallback = callback;
- mFilter = filter;
- mUid = uid;
- mBinder = mCallback.asBinder();
- mNetworkAgentInfo = networkAgentInfo;
- }
-
- @Override
- public void binderDied() {
- logw("binderDied: binder died with callback id: " + mAgentCallbackId);
- mQosCallbackTracker.unregisterCallback(mCallback);
- }
-
- void unlinkToDeathRecipient() {
- mBinder.unlinkToDeath(this, 0);
- }
-
- // Returns false if the NetworkAgent was never notified.
- boolean sendCmdRegisterCallback() {
- final int exceptionType = mFilter.validate();
- if (exceptionType != EX_TYPE_FILTER_NONE) {
- try {
- if (DBG) log("sendCmdRegisterCallback: filter validation failed");
- mCallback.onError(exceptionType);
- } catch (final RemoteException e) {
- loge("sendCmdRegisterCallback:", e);
- }
- return false;
- }
-
- try {
- mBinder.linkToDeath(this, 0);
- } catch (final RemoteException e) {
- loge("failed linking to death recipient", e);
- return false;
- }
- mNetworkAgentInfo.onQosFilterCallbackRegistered(mAgentCallbackId, mFilter);
- return true;
- }
-
- void sendCmdUnregisterCallback() {
- if (DBG) log("sendCmdUnregisterCallback: unregistering");
- mNetworkAgentInfo.onQosCallbackUnregistered(mAgentCallbackId);
- }
-
- void sendEventEpsQosSessionAvailable(final QosSession session,
- final EpsBearerQosSessionAttributes attributes) {
- try {
- if (DBG) log("sendEventEpsQosSessionAvailable: sending...");
- mCallback.onQosEpsBearerSessionAvailable(session, attributes);
- } catch (final RemoteException e) {
- loge("sendEventEpsQosSessionAvailable: remote exception", e);
- }
- }
-
- void sendEventNrQosSessionAvailable(final QosSession session,
- final NrQosSessionAttributes attributes) {
- try {
- if (DBG) log("sendEventNrQosSessionAvailable: sending...");
- mCallback.onNrQosSessionAvailable(session, attributes);
- } catch (final RemoteException e) {
- loge("sendEventNrQosSessionAvailable: remote exception", e);
- }
- }
-
- void sendEventQosSessionLost(@NonNull final QosSession session) {
- try {
- if (DBG) log("sendEventQosSessionLost: sending...");
- mCallback.onQosSessionLost(session);
- } catch (final RemoteException e) {
- loge("sendEventQosSessionLost: remote exception", e);
- }
- }
-
- void sendEventQosCallbackError(@QosCallbackException.ExceptionType final int exceptionType) {
- try {
- if (DBG) log("sendEventQosCallbackError: sending...");
- mCallback.onError(exceptionType);
- } catch (final RemoteException e) {
- loge("sendEventQosCallbackError: remote exception", e);
- }
- }
-
- private static void log(@NonNull final String msg) {
- Log.d(TAG, msg);
- }
-
- private static void logw(@NonNull final String msg) {
- Log.w(TAG, msg);
- }
-
- private static void loge(@NonNull final String msg, final Throwable t) {
- Log.e(TAG, msg, t);
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/QosCallbackTracker.java b/packages/Connectivity/service/src/com/android/server/connectivity/QosCallbackTracker.java
deleted file mode 100644
index b6ab47b..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/QosCallbackTracker.java
+++ /dev/null
@@ -1,292 +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.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.IQosCallback;
-import android.net.Network;
-import android.net.QosCallbackException;
-import android.net.QosFilter;
-import android.net.QosSession;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IBinder;
-import android.telephony.data.EpsBearerQosSessionAttributes;
-import android.telephony.data.NrQosSessionAttributes;
-import android.util.Log;
-
-import com.android.net.module.util.CollectionUtils;
-import com.android.server.ConnectivityService;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Tracks qos callbacks and handles the communication between the network agent and application.
- * <p/>
- * Any method prefixed by handle must be called from the
- * {@link com.android.server.ConnectivityService} handler thread.
- *
- * @hide
- */
-public class QosCallbackTracker {
- private static final String TAG = QosCallbackTracker.class.getSimpleName();
- private static final boolean DBG = true;
-
- @NonNull
- private final Handler mConnectivityServiceHandler;
-
- @NonNull
- private final ConnectivityService.PerUidCounter mNetworkRequestCounter;
-
- /**
- * Each agent gets a unique callback id that is used to proxy messages back to the original
- * callback.
- * <p/>
- * Note: The fact that this is initialized to 0 is to ensure that the thread running
- * {@link #handleRegisterCallback(IQosCallback, QosFilter, int, NetworkAgentInfo)} sees the
- * initialized value. This would not necessarily be the case if the value was initialized to
- * the non-default value.
- * <p/>
- * Note: The term previous does not apply to the first callback id that is assigned.
- */
- private int mPreviousAgentCallbackId = 0;
-
- @NonNull
- private final List<QosCallbackAgentConnection> mConnections = new ArrayList<>();
-
- /**
- *
- * @param connectivityServiceHandler must be the same handler used with
- * {@link com.android.server.ConnectivityService}
- * @param networkRequestCounter keeps track of the number of open requests under a given
- * uid
- */
- public QosCallbackTracker(@NonNull final Handler connectivityServiceHandler,
- final ConnectivityService.PerUidCounter networkRequestCounter) {
- mConnectivityServiceHandler = connectivityServiceHandler;
- mNetworkRequestCounter = networkRequestCounter;
- }
-
- /**
- * Registers the callback with the tracker
- *
- * @param callback the callback to register
- * @param filter the filter being registered alongside the callback
- */
- public void registerCallback(@NonNull final IQosCallback callback,
- @NonNull final QosFilter filter, @NonNull final NetworkAgentInfo networkAgentInfo) {
- final int uid = Binder.getCallingUid();
-
- // Enforce that the number of requests under this uid has exceeded the allowed number
- mNetworkRequestCounter.incrementCountOrThrow(uid);
-
- mConnectivityServiceHandler.post(
- () -> handleRegisterCallback(callback, filter, uid, networkAgentInfo));
- }
-
- private void handleRegisterCallback(@NonNull final IQosCallback callback,
- @NonNull final QosFilter filter, final int uid,
- @NonNull final NetworkAgentInfo networkAgentInfo) {
- final QosCallbackAgentConnection ac =
- handleRegisterCallbackInternal(callback, filter, uid, networkAgentInfo);
- if (ac != null) {
- if (DBG) log("handleRegisterCallback: added callback " + ac.getAgentCallbackId());
- mConnections.add(ac);
- } else {
- mNetworkRequestCounter.decrementCount(uid);
- }
- }
-
- private QosCallbackAgentConnection handleRegisterCallbackInternal(
- @NonNull final IQosCallback callback,
- @NonNull final QosFilter filter, final int uid,
- @NonNull final NetworkAgentInfo networkAgentInfo) {
- final IBinder binder = callback.asBinder();
- if (CollectionUtils.any(mConnections, c -> c.getBinder().equals(binder))) {
- // A duplicate registration would have only made this far due to a programming error.
- logwtf("handleRegisterCallback: Callbacks can only be register once.");
- return null;
- }
-
- mPreviousAgentCallbackId = mPreviousAgentCallbackId + 1;
- final int newCallbackId = mPreviousAgentCallbackId;
-
- final QosCallbackAgentConnection ac =
- new QosCallbackAgentConnection(this, newCallbackId, callback,
- filter, uid, networkAgentInfo);
-
- final int exceptionType = filter.validate();
- if (exceptionType != QosCallbackException.EX_TYPE_FILTER_NONE) {
- ac.sendEventQosCallbackError(exceptionType);
- return null;
- }
-
- // Only add to the callback maps if the NetworkAgent successfully registered it
- if (!ac.sendCmdRegisterCallback()) {
- // There was an issue when registering the agent
- if (DBG) log("handleRegisterCallback: error sending register callback");
- mNetworkRequestCounter.decrementCount(uid);
- return null;
- }
- return ac;
- }
-
- /**
- * Unregisters callback
- * @param callback callback to unregister
- */
- public void unregisterCallback(@NonNull final IQosCallback callback) {
- mConnectivityServiceHandler.post(() -> handleUnregisterCallback(callback.asBinder(), true));
- }
-
- private void handleUnregisterCallback(@NonNull final IBinder binder,
- final boolean sendToNetworkAgent) {
- final int connIndex =
- CollectionUtils.indexOf(mConnections, c -> c.getBinder().equals(binder));
- if (connIndex < 0) {
- logw("handleUnregisterCallback: no matching agentConnection");
- return;
- }
- final QosCallbackAgentConnection agentConnection = mConnections.get(connIndex);
-
- if (DBG) {
- log("handleUnregisterCallback: unregister "
- + agentConnection.getAgentCallbackId());
- }
-
- mNetworkRequestCounter.decrementCount(agentConnection.getUid());
- mConnections.remove(agentConnection);
-
- if (sendToNetworkAgent) {
- agentConnection.sendCmdUnregisterCallback();
- }
- agentConnection.unlinkToDeathRecipient();
- }
-
- /**
- * Called when the NetworkAgent sends the qos session available event for EPS
- *
- * @param qosCallbackId the callback id that the qos session is now available to
- * @param session the qos session that is now available
- * @param attributes the qos attributes that are now available on the qos session
- */
- public void sendEventEpsQosSessionAvailable(final int qosCallbackId,
- final QosSession session,
- final EpsBearerQosSessionAttributes attributes) {
- runOnAgentConnection(qosCallbackId, "sendEventEpsQosSessionAvailable: ",
- ac -> ac.sendEventEpsQosSessionAvailable(session, attributes));
- }
-
- /**
- * Called when the NetworkAgent sends the qos session available event for NR
- *
- * @param qosCallbackId the callback id that the qos session is now available to
- * @param session the qos session that is now available
- * @param attributes the qos attributes that are now available on the qos session
- */
- public void sendEventNrQosSessionAvailable(final int qosCallbackId,
- final QosSession session,
- final NrQosSessionAttributes attributes) {
- runOnAgentConnection(qosCallbackId, "sendEventNrQosSessionAvailable: ",
- ac -> ac.sendEventNrQosSessionAvailable(session, attributes));
- }
-
- /**
- * Called when the NetworkAgent sends the qos session lost event
- *
- * @param qosCallbackId the callback id that lost the qos session
- * @param session the corresponding qos session
- */
- public void sendEventQosSessionLost(final int qosCallbackId,
- final QosSession session) {
- runOnAgentConnection(qosCallbackId, "sendEventQosSessionLost: ",
- ac -> ac.sendEventQosSessionLost(session));
- }
-
- /**
- * Called when the NetworkAgent sends the qos session on error event
- *
- * @param qosCallbackId the callback id that should receive the exception
- * @param exceptionType the type of exception that caused the callback to error
- */
- public void sendEventQosCallbackError(final int qosCallbackId,
- @QosCallbackException.ExceptionType final int exceptionType) {
- runOnAgentConnection(qosCallbackId, "sendEventQosCallbackError: ",
- ac -> {
- ac.sendEventQosCallbackError(exceptionType);
- handleUnregisterCallback(ac.getBinder(), false);
- });
- }
-
- /**
- * Unregisters all callbacks associated to this network agent
- *
- * Note: Must be called on the connectivity service handler thread
- *
- * @param network the network that was released
- */
- public void handleNetworkReleased(@Nullable final Network network) {
- // Iterate in reverse order as agent connections will be removed when unregistering
- for (int i = mConnections.size() - 1; i >= 0; i--) {
- final QosCallbackAgentConnection agentConnection = mConnections.get(i);
- if (!agentConnection.getNetwork().equals(network)) continue;
- agentConnection.sendEventQosCallbackError(
- QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED);
-
- // Call unregister workflow w\o sending anything to agent since it is disconnected.
- handleUnregisterCallback(agentConnection.getBinder(), false);
- }
- }
-
- private interface AgentConnectionAction {
- void execute(@NonNull QosCallbackAgentConnection agentConnection);
- }
-
- @Nullable
- private void runOnAgentConnection(final int qosCallbackId,
- @NonNull final String logPrefix,
- @NonNull final AgentConnectionAction action) {
- mConnectivityServiceHandler.post(() -> {
- final int acIndex = CollectionUtils.indexOf(mConnections,
- c -> c.getAgentCallbackId() == qosCallbackId);
- if (acIndex == -1) {
- loge(logPrefix + ": " + qosCallbackId + " missing callback id");
- return;
- }
-
- action.execute(mConnections.get(acIndex));
- });
- }
-
- private static void log(final String msg) {
- Log.d(TAG, msg);
- }
-
- private static void logw(final String msg) {
- Log.w(TAG, msg);
- }
-
- private static void loge(final String msg) {
- Log.e(TAG, msg);
- }
-
- private static void logwtf(final String msg) {
- Log.wtf(TAG, msg);
- }
-}
diff --git a/packages/Connectivity/service/src/com/android/server/connectivity/TcpKeepaliveController.java b/packages/Connectivity/service/src/com/android/server/connectivity/TcpKeepaliveController.java
deleted file mode 100644
index 73f3475..0000000
--- a/packages/Connectivity/service/src/com/android/server/connectivity/TcpKeepaliveController.java
+++ /dev/null
@@ -1,340 +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.connectivity;
-
-import static android.net.SocketKeepalive.DATA_RECEIVED;
-import static android.net.SocketKeepalive.ERROR_INVALID_SOCKET;
-import static android.net.SocketKeepalive.ERROR_SOCKET_NOT_IDLE;
-import static android.net.SocketKeepalive.ERROR_UNSUPPORTED;
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
-import static android.system.OsConstants.ENOPROTOOPT;
-import static android.system.OsConstants.FIONREAD;
-import static android.system.OsConstants.IPPROTO_IP;
-import static android.system.OsConstants.IPPROTO_TCP;
-import static android.system.OsConstants.IP_TOS;
-import static android.system.OsConstants.IP_TTL;
-
-import static com.android.server.connectivity.OsCompat.TIOCOUTQ;
-
-import android.annotation.NonNull;
-import android.net.InvalidPacketException;
-import android.net.NetworkUtils;
-import android.net.SocketKeepalive.InvalidSocketException;
-import android.net.TcpKeepalivePacketData;
-import android.net.TcpKeepalivePacketDataParcelable;
-import android.net.TcpRepairWindow;
-import android.net.util.KeepalivePacketDataUtil;
-import android.os.Handler;
-import android.os.MessageQueue;
-import android.os.Messenger;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.server.connectivity.KeepaliveTracker.KeepaliveInfo;
-
-import java.io.FileDescriptor;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.net.SocketException;
-
-/**
- * Manage tcp socket which offloads tcp keepalive.
- *
- * The input socket will be changed to repair mode and the application
- * will not have permission to read/write data. If the application wants
- * to write data, it must stop tcp keepalive offload to leave repair mode
- * first. If a remote packet arrives, repair mode will be turned off and
- * offload will be stopped. The application will receive a callback to know
- * it can start reading data.
- *
- * {start,stop}SocketMonitor are thread-safe, but care must be taken in the
- * order in which they are called. Please note that while calling
- * {@link #startSocketMonitor(FileDescriptor, Messenger, int)} multiple times
- * with either the same slot or the same FileDescriptor without stopping it in
- * between will result in an exception, calling {@link #stopSocketMonitor(int)}
- * multiple times with the same int is explicitly a no-op.
- * Please also note that switching the socket to repair mode is not synchronized
- * with either of these operations and has to be done in an orderly fashion
- * with stopSocketMonitor. Take care in calling these in the right order.
- * @hide
- */
-public class TcpKeepaliveController {
- private static final String TAG = "TcpKeepaliveController";
- private static final boolean DBG = false;
-
- private final MessageQueue mFdHandlerQueue;
-
- private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR;
-
- // Reference include/uapi/linux/tcp.h
- private static final int TCP_REPAIR = 19;
- private static final int TCP_REPAIR_QUEUE = 20;
- private static final int TCP_QUEUE_SEQ = 21;
- private static final int TCP_NO_QUEUE = 0;
- private static final int TCP_RECV_QUEUE = 1;
- private static final int TCP_SEND_QUEUE = 2;
- private static final int TCP_REPAIR_OFF = 0;
- private static final int TCP_REPAIR_ON = 1;
- // Reference include/uapi/linux/sockios.h
- private static final int SIOCINQ = FIONREAD;
- private static final int SIOCOUTQ = TIOCOUTQ;
-
- /**
- * Keeps track of packet listeners.
- * Key: slot number of keepalive offload.
- * Value: {@link FileDescriptor} being listened to.
- */
- @GuardedBy("mListeners")
- private final SparseArray<FileDescriptor> mListeners = new SparseArray<>();
-
- public TcpKeepaliveController(final Handler connectivityServiceHandler) {
- mFdHandlerQueue = connectivityServiceHandler.getLooper().getQueue();
- }
-
- /** Build tcp keepalive packet. */
- public static TcpKeepalivePacketData getTcpKeepalivePacket(@NonNull FileDescriptor fd)
- throws InvalidPacketException, InvalidSocketException {
- try {
- final TcpKeepalivePacketDataParcelable tcpDetails = switchToRepairMode(fd);
- return KeepalivePacketDataUtil.fromStableParcelable(tcpDetails);
- } catch (InvalidPacketException | InvalidSocketException e) {
- switchOutOfRepairMode(fd);
- throw e;
- }
- }
- /**
- * Switch the tcp socket to repair mode and query detail tcp information.
- *
- * @param fd the fd of socket on which to use keepalive offload.
- * @return a {@link TcpKeepalivePacketDataParcelable} object for current
- * tcp/ip information.
- */
- private static TcpKeepalivePacketDataParcelable switchToRepairMode(FileDescriptor fd)
- throws InvalidSocketException {
- if (DBG) Log.i(TAG, "switchToRepairMode to start tcp keepalive : " + fd);
- final TcpKeepalivePacketDataParcelable tcpDetails = new TcpKeepalivePacketDataParcelable();
- final SocketAddress srcSockAddr;
- final SocketAddress dstSockAddr;
- final TcpRepairWindow trw;
-
- // Query source address and port.
- try {
- srcSockAddr = Os.getsockname(fd);
- } catch (ErrnoException e) {
- Log.e(TAG, "Get sockname fail: ", e);
- throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
- }
- if (srcSockAddr instanceof InetSocketAddress) {
- tcpDetails.srcAddress = getAddress((InetSocketAddress) srcSockAddr);
- tcpDetails.srcPort = getPort((InetSocketAddress) srcSockAddr);
- } else {
- Log.e(TAG, "Invalid or mismatched SocketAddress");
- throw new InvalidSocketException(ERROR_INVALID_SOCKET);
- }
- // Query destination address and port.
- try {
- dstSockAddr = Os.getpeername(fd);
- } catch (ErrnoException e) {
- Log.e(TAG, "Get peername fail: ", e);
- throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
- }
- if (dstSockAddr instanceof InetSocketAddress) {
- tcpDetails.dstAddress = getAddress((InetSocketAddress) dstSockAddr);
- tcpDetails.dstPort = getPort((InetSocketAddress) dstSockAddr);
- } else {
- Log.e(TAG, "Invalid or mismatched peer SocketAddress");
- throw new InvalidSocketException(ERROR_INVALID_SOCKET);
- }
-
- // Query sequence and ack number
- dropAllIncomingPackets(fd, true);
- try {
- // Switch to tcp repair mode.
- Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR, TCP_REPAIR_ON);
-
- // Check if socket is idle.
- if (!isSocketIdle(fd)) {
- Log.e(TAG, "Socket is not idle");
- throw new InvalidSocketException(ERROR_SOCKET_NOT_IDLE);
- }
- // Query write sequence number from SEND_QUEUE.
- Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_SEND_QUEUE);
- tcpDetails.seq = OsCompat.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
- // Query read sequence number from RECV_QUEUE.
- Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_RECV_QUEUE);
- tcpDetails.ack = OsCompat.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
- // Switch to NO_QUEUE to prevent illegal socket read/write in repair mode.
- Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_NO_QUEUE);
- // Finally, check if socket is still idle. TODO : this check needs to move to
- // after starting polling to prevent a race.
- if (!isReceiveQueueEmpty(fd)) {
- Log.e(TAG, "Fatal: receive queue of this socket is not empty");
- throw new InvalidSocketException(ERROR_INVALID_SOCKET);
- }
- if (!isSendQueueEmpty(fd)) {
- Log.e(TAG, "Socket is not idle");
- throw new InvalidSocketException(ERROR_SOCKET_NOT_IDLE);
- }
-
- // Query tcp window size.
- trw = NetworkUtils.getTcpRepairWindow(fd);
- tcpDetails.rcvWnd = trw.rcvWnd;
- tcpDetails.rcvWndScale = trw.rcvWndScale;
- if (tcpDetails.srcAddress.length == 4 /* V4 address length */) {
- // Query TOS.
- tcpDetails.tos = OsCompat.getsockoptInt(fd, IPPROTO_IP, IP_TOS);
- // Query TTL.
- tcpDetails.ttl = OsCompat.getsockoptInt(fd, IPPROTO_IP, IP_TTL);
- }
- } catch (ErrnoException e) {
- Log.e(TAG, "Exception reading TCP state from socket", e);
- if (e.errno == ENOPROTOOPT) {
- // ENOPROTOOPT may happen in kernel version lower than 4.8.
- // Treat it as ERROR_UNSUPPORTED.
- throw new InvalidSocketException(ERROR_UNSUPPORTED, e);
- } else {
- throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
- }
- } finally {
- dropAllIncomingPackets(fd, false);
- }
-
- // Keepalive sequence number is last sequence number - 1. If it couldn't be retrieved,
- // then it must be set to -1, so decrement in all cases.
- tcpDetails.seq = tcpDetails.seq - 1;
-
- return tcpDetails;
- }
-
- /**
- * Switch the tcp socket out of repair mode.
- *
- * @param fd the fd of socket to switch back to normal.
- */
- private static void switchOutOfRepairMode(@NonNull final FileDescriptor fd) {
- try {
- Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR, TCP_REPAIR_OFF);
- } catch (ErrnoException e) {
- Log.e(TAG, "Cannot switch socket out of repair mode", e);
- // Well, there is not much to do here to recover
- }
- }
-
- /**
- * Start monitoring incoming packets.
- *
- * @param fd socket fd to monitor.
- * @param ki a {@link KeepaliveInfo} that tracks information about a socket keepalive.
- * @param slot keepalive slot.
- */
- public void startSocketMonitor(@NonNull final FileDescriptor fd,
- @NonNull final KeepaliveInfo ki, final int slot)
- throws IllegalArgumentException, InvalidSocketException {
- synchronized (mListeners) {
- if (null != mListeners.get(slot)) {
- throw new IllegalArgumentException("This slot is already taken");
- }
- for (int i = 0; i < mListeners.size(); ++i) {
- if (fd.equals(mListeners.valueAt(i))) {
- Log.e(TAG, "This fd is already registered.");
- throw new InvalidSocketException(ERROR_INVALID_SOCKET);
- }
- }
- mFdHandlerQueue.addOnFileDescriptorEventListener(fd, FD_EVENTS, (readyFd, events) -> {
- // This can't be called twice because the queue guarantees that once the listener
- // is unregistered it can't be called again, even for a message that arrived
- // before it was unregistered.
- final int reason;
- if (0 != (events & EVENT_ERROR)) {
- reason = ERROR_INVALID_SOCKET;
- } else {
- reason = DATA_RECEIVED;
- }
- ki.onFileDescriptorInitiatedStop(reason);
- // The listener returns the new set of events to listen to. Because 0 means no
- // event, the listener gets unregistered.
- return 0;
- });
- mListeners.put(slot, fd);
- }
- }
-
- /** Stop socket monitor */
- // This slot may have been stopped automatically already because the socket received data,
- // was closed on the other end or otherwise suffered some error. In this case, this function
- // is a no-op.
- public void stopSocketMonitor(final int slot) {
- final FileDescriptor fd;
- synchronized (mListeners) {
- fd = mListeners.get(slot);
- if (null == fd) return;
- mListeners.remove(slot);
- }
- mFdHandlerQueue.removeOnFileDescriptorEventListener(fd);
- if (DBG) Log.d(TAG, "Moving socket out of repair mode for stop : " + fd);
- switchOutOfRepairMode(fd);
- }
-
- private static byte [] getAddress(InetSocketAddress inetAddr) {
- return inetAddr.getAddress().getAddress();
- }
-
- private static int getPort(InetSocketAddress inetAddr) {
- return inetAddr.getPort();
- }
-
- private static boolean isSocketIdle(FileDescriptor fd) throws ErrnoException {
- return isReceiveQueueEmpty(fd) && isSendQueueEmpty(fd);
- }
-
- private static boolean isReceiveQueueEmpty(FileDescriptor fd)
- throws ErrnoException {
- final int result = OsCompat.ioctlInt(fd, SIOCINQ);
- if (result != 0) {
- Log.e(TAG, "Read queue has data");
- return false;
- }
- return true;
- }
-
- private static boolean isSendQueueEmpty(FileDescriptor fd)
- throws ErrnoException {
- final int result = OsCompat.ioctlInt(fd, SIOCOUTQ);
- if (result != 0) {
- Log.e(TAG, "Write queue has data");
- return false;
- }
- return true;
- }
-
- private static void dropAllIncomingPackets(FileDescriptor fd, boolean enable)
- throws InvalidSocketException {
- try {
- if (enable) {
- NetworkUtils.attachDropAllBPFFilter(fd);
- } else {
- NetworkUtils.detachBPFFilter(fd);
- }
- } catch (SocketException e) {
- Log.e(TAG, "Socket Exception: ", e);
- throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
- }
- }
-}
diff --git a/packages/Connectivity/tests/OWNERS b/packages/Connectivity/tests/OWNERS
deleted file mode 100644
index d3836d4..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/TEST_MAPPING b/packages/Connectivity/tests/TEST_MAPPING
deleted file mode 100644
index 502f885..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/Android.bp b/packages/Connectivity/tests/common/Android.bp
deleted file mode 100644
index 7331453..0000000
--- a/packages/Connectivity/tests/common/Android.bp
+++ /dev/null
@@ -1,67 +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",
- ],
-}
-
-// defaults for tests that need to build against framework-connectivity's @hide APIs
-// Only usable from targets that have visibility on framework-connectivity.impl.
-// Instead of using this, consider avoiding to depend on hidden connectivity APIs in
-// tests.
-java_defaults {
- name: "framework-connectivity-test-defaults",
- sdk_version: "core_platform", // tests can use @CorePlatformApi's
- libs: [
- // order matters: classes in framework-connectivity are resolved before framework,
- // meaning @hide APIs in framework-connectivity are resolved before @SystemApi
- // stubs in framework
- "framework-connectivity.impl",
- "framework",
-
- // if sdk_version="" this gets automatically included, but here we need to add manually.
- "framework-res",
- ],
-}
diff --git a/packages/Connectivity/tests/common/java/ParseExceptionTest.kt b/packages/Connectivity/tests/common/java/ParseExceptionTest.kt
deleted file mode 100644
index b702d61..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/CaptivePortalDataTest.kt b/packages/Connectivity/tests/common/java/android/net/CaptivePortalDataTest.kt
deleted file mode 100644
index 18a9331..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/CaptivePortalTest.java b/packages/Connectivity/tests/common/java/android/net/CaptivePortalTest.java
deleted file mode 100644
index 15d3398..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/DependenciesTest.java b/packages/Connectivity/tests/common/java/android/net/DependenciesTest.java
deleted file mode 100644
index ac1c28a..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/DhcpInfoTest.java b/packages/Connectivity/tests/common/java/android/net/DhcpInfoTest.java
deleted file mode 100644
index ab4726b..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/IpPrefixTest.java b/packages/Connectivity/tests/common/java/android/net/IpPrefixTest.java
deleted file mode 100644
index 50ecb42..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/KeepalivePacketDataTest.kt b/packages/Connectivity/tests/common/java/android/net/KeepalivePacketDataTest.kt
deleted file mode 100644
index f464ec6..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/LinkAddressTest.java b/packages/Connectivity/tests/common/java/android/net/LinkAddressTest.java
deleted file mode 100644
index 2cf3cf9..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/LinkPropertiesTest.java b/packages/Connectivity/tests/common/java/android/net/LinkPropertiesTest.java
deleted file mode 100644
index 550953d..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/MatchAllNetworkSpecifierTest.kt b/packages/Connectivity/tests/common/java/android/net/MatchAllNetworkSpecifierTest.kt
deleted file mode 100644
index a5e44d5..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/NattKeepalivePacketDataTest.kt b/packages/Connectivity/tests/common/java/android/net/NattKeepalivePacketDataTest.kt
deleted file mode 100644
index 46f39dd..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/NetworkAgentConfigTest.kt b/packages/Connectivity/tests/common/java/android/net/NetworkAgentConfigTest.kt
deleted file mode 100644
index 2b45b3d..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/NetworkCapabilitiesTest.java b/packages/Connectivity/tests/common/java/android/net/NetworkCapabilitiesTest.java
deleted file mode 100644
index 9537786..0000000
--- a/packages/Connectivity/tests/common/java/android/net/NetworkCapabilitiesTest.java
+++ /dev/null
@@ -1,1170 +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_TRUSTED;
-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());
- }
- }
-
- @Test @IgnoreUpTo(Build.VERSION_CODES.R)
- public void testBuilderWithoutDefaultCap() {
- final NetworkCapabilities nc =
- NetworkCapabilities.Builder.withoutDefaultCapabilities().build();
- assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
- assertFalse(nc.hasCapability(NET_CAPABILITY_TRUSTED));
- assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_VPN));
- // Ensure test case fails if new net cap is added into default cap but no update here.
- assertEquals(0, nc.getCapabilities().length);
- }
-}
diff --git a/packages/Connectivity/tests/common/java/android/net/NetworkProviderTest.kt b/packages/Connectivity/tests/common/java/android/net/NetworkProviderTest.kt
deleted file mode 100644
index 7424157..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/NetworkSpecifierTest.kt b/packages/Connectivity/tests/common/java/android/net/NetworkSpecifierTest.kt
deleted file mode 100644
index f3409f5..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/NetworkStackTest.java b/packages/Connectivity/tests/common/java/android/net/NetworkStackTest.java
deleted file mode 100644
index f8f9c72..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/NetworkStateSnapshotTest.kt b/packages/Connectivity/tests/common/java/android/net/NetworkStateSnapshotTest.kt
deleted file mode 100644
index 0ca4d95..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/NetworkTest.java b/packages/Connectivity/tests/common/java/android/net/NetworkTest.java
deleted file mode 100644
index 7423c73..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/OemNetworkPreferencesTest.java b/packages/Connectivity/tests/common/java/android/net/OemNetworkPreferencesTest.java
deleted file mode 100644
index fd29a95..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/RouteInfoTest.java b/packages/Connectivity/tests/common/java/android/net/RouteInfoTest.java
deleted file mode 100644
index 71689f9..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/StaticIpConfigurationTest.java b/packages/Connectivity/tests/common/java/android/net/StaticIpConfigurationTest.java
deleted file mode 100644
index b5f23bf..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/TcpKeepalivePacketDataTest.kt b/packages/Connectivity/tests/common/java/android/net/TcpKeepalivePacketDataTest.kt
deleted file mode 100644
index 7a18bb0..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/UidRangeTest.java b/packages/Connectivity/tests/common/java/android/net/UidRangeTest.java
deleted file mode 100644
index 1b1c954..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/UnderlyingNetworkInfoTest.kt b/packages/Connectivity/tests/common/java/android/net/UnderlyingNetworkInfoTest.kt
deleted file mode 100644
index f23ba26..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/apf/ApfCapabilitiesTest.java b/packages/Connectivity/tests/common/java/android/net/apf/ApfCapabilitiesTest.java
deleted file mode 100644
index 88996d9..0000000
--- a/packages/Connectivity/tests/common/java/android/net/apf/ApfCapabilitiesTest.java
+++ /dev/null
@@ -1,132 +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.assertArrayEquals;
-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 android.os.Build;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-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 java.util.Arrays;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ApfCapabilitiesTest {
- @Rule
- public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
-
- 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 @IgnoreUpTo(Build.VERSION_CODES.R)
- public void testGetApfDrop8023Frames_S() {
- // IpClient does not call getApfDrop8023Frames() since S, so any customization of the return
- // value on S+ is a configuration error as it will not be used by IpClient.
- assertTrue("android.R.bool.config_apfDrop802_3Frames has been modified to false, but "
- + "starting from S its value is not used by IpClient. If the modification is "
- + "intentional, use a runtime resource overlay for the NetworkStack package to "
- + "overlay com.android.networkstack.R.bool.config_apfDrop802_3Frames instead.",
- ApfCapabilities.getApfDrop8023Frames());
- }
-
- @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));
- }
-
- @Test @IgnoreUpTo(Build.VERSION_CODES.R)
- public void testGetApfEtherTypeBlackList_S() {
- // IpClient does not call getApfEtherTypeBlackList() since S, so any customization of the
- // return value on S+ is a configuration error as it will not be used by IpClient.
- assertArrayEquals("android.R.array.config_apfEthTypeBlackList has been modified, but "
- + "starting from S its value is not used by IpClient. If the modification "
- + "is intentional, use a runtime resource overlay for the NetworkStack "
- + "package to overlay "
- + "com.android.networkstack.R.array.config_apfEthTypeDenyList instead.",
- new int[] { 0x88a2, 0x88a4, 0x88b8, 0x88cd, 0x88e3 },
- ApfCapabilities.getApfEtherTypeBlackList());
- }
-}
diff --git a/packages/Connectivity/tests/common/java/android/net/metrics/ApfProgramEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/ApfProgramEventTest.kt
deleted file mode 100644
index 0b7b740..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/metrics/ApfStatsTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/ApfStatsTest.kt
deleted file mode 100644
index 46a8c8e..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/metrics/DhcpClientEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/DhcpClientEventTest.kt
deleted file mode 100644
index 8d7a9c4..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/metrics/DhcpErrorEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/DhcpErrorEventTest.kt
deleted file mode 100644
index 236f72e..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/metrics/IpConnectivityLogTest.java b/packages/Connectivity/tests/common/java/android/net/metrics/IpConnectivityLogTest.java
deleted file mode 100644
index d4780d3..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/metrics/IpManagerEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/IpManagerEventTest.kt
deleted file mode 100644
index 64be508..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/metrics/IpReachabilityEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/IpReachabilityEventTest.kt
deleted file mode 100644
index 55b5e49..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/metrics/NetworkEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/NetworkEventTest.kt
deleted file mode 100644
index 41430b0..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/metrics/RaEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/RaEventTest.kt
deleted file mode 100644
index d9b7203..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/metrics/ValidationProbeEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/ValidationProbeEventTest.kt
deleted file mode 100644
index 51c0d41..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/netstats/NetworkStatsApiTest.kt b/packages/Connectivity/tests/common/java/android/net/netstats/NetworkStatsApiTest.kt
deleted file mode 100644
index 7b22e45..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/common/java/android/net/util/SocketUtilsTest.kt b/packages/Connectivity/tests/common/java/android/net/util/SocketUtilsTest.kt
deleted file mode 100644
index aaf97f3..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/deflake/Android.bp b/packages/Connectivity/tests/deflake/Android.bp
deleted file mode 100644
index 58ece37..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/deflake/src/com/android/server/net/FrameworksNetDeflakeTest.kt b/packages/Connectivity/tests/deflake/src/com/android/server/net/FrameworksNetDeflakeTest.kt
deleted file mode 100644
index 6285525..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/integration/Android.bp b/packages/Connectivity/tests/integration/Android.bp
deleted file mode 100644
index 39c424e..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/integration/AndroidManifest.xml b/packages/Connectivity/tests/integration/AndroidManifest.xml
deleted file mode 100644
index 2e13689..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/integration/res/values/config.xml b/packages/Connectivity/tests/integration/res/values/config.xml
deleted file mode 100644
index 2c8046f..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/integration/src/android/net/TestNetworkStackClient.kt b/packages/Connectivity/tests/integration/src/android/net/TestNetworkStackClient.kt
deleted file mode 100644
index 61ef5bd..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
deleted file mode 100644
index e039ef0..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/HttpResponse.aidl b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/HttpResponse.aidl
deleted file mode 100644
index 9a2bcfe..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/HttpResponse.kt b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/HttpResponse.kt
deleted file mode 100644
index e206313..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/INetworkStackInstrumentation.aidl b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/INetworkStackInstrumentation.aidl
deleted file mode 100644
index efc58ad..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt
deleted file mode 100644
index e807952..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
deleted file mode 100644
index eff6658..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/integration/util/com/android/server/ConnectivityServiceTestUtils.kt b/packages/Connectivity/tests/integration/util/com/android/server/ConnectivityServiceTestUtils.kt
deleted file mode 100644
index 165fd37..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/integration/util/com/android/server/NetworkAgentWrapper.java b/packages/Connectivity/tests/integration/util/com/android/server/NetworkAgentWrapper.java
deleted file mode 100644
index 17db179..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/integration/util/com/android/server/TestNetIdManager.kt b/packages/Connectivity/tests/integration/util/com/android/server/TestNetIdManager.kt
deleted file mode 100644
index 938a694..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/smoketest/Android.bp b/packages/Connectivity/tests/smoketest/Android.bp
deleted file mode 100644
index 1535f3d..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/smoketest/AndroidManifest.xml b/packages/Connectivity/tests/smoketest/AndroidManifest.xml
deleted file mode 100644
index f1b9feb..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/smoketest/AndroidTest.xml b/packages/Connectivity/tests/smoketest/AndroidTest.xml
deleted file mode 100644
index ac366e4..0000000
--- a/packages/Connectivity/tests/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/packages/Connectivity/tests/smoketest/java/SmokeTest.java b/packages/Connectivity/tests/smoketest/java/SmokeTest.java
deleted file mode 100644
index 7d6655f..0000000
--- a/packages/Connectivity/tests/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);
- }
-}
diff --git a/packages/Connectivity/tests/unit/Android.bp b/packages/Connectivity/tests/unit/Android.bp
deleted file mode 100644
index 6f503ac..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/AndroidManifest.xml b/packages/Connectivity/tests/unit/AndroidManifest.xml
deleted file mode 100644
index 4c60ccf..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/AndroidTest.xml b/packages/Connectivity/tests/unit/AndroidTest.xml
deleted file mode 100644
index 939ae49..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/jarjar-rules.txt b/packages/Connectivity/tests/unit/jarjar-rules.txt
deleted file mode 100644
index ca88672..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java b/packages/Connectivity/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
deleted file mode 100644
index 899295a..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/ConnectivityDiagnosticsManagerTest.java b/packages/Connectivity/tests/unit/java/android/net/ConnectivityDiagnosticsManagerTest.java
deleted file mode 100644
index 06e9405..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/ConnectivityManagerTest.java b/packages/Connectivity/tests/unit/java/android/net/ConnectivityManagerTest.java
deleted file mode 100644
index c804e10..0000000
--- a/packages/Connectivity/tests/unit/java/android/net/ConnectivityManagerTest.java
+++ /dev/null
@@ -1,438 +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.requestBackgroundNetwork(null, callback, handler));
- mustFail(() -> manager.requestBackgroundNetwork(request, null, handler));
- mustFail(() -> manager.requestBackgroundNetwork(request, callback, null));
-
- 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.registerBestMatchingNetworkCallback(null, callback, handler));
- mustFail(() -> manager.registerBestMatchingNetworkCallback(request, null, handler));
- mustFail(() -> manager.registerBestMatchingNetworkCallback(request, 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/packages/Connectivity/tests/unit/java/android/net/Ikev2VpnProfileTest.java b/packages/Connectivity/tests/unit/java/android/net/Ikev2VpnProfileTest.java
deleted file mode 100644
index 0707ef3..0000000
--- a/packages/Connectivity/tests/unit/java/android/net/Ikev2VpnProfileTest.java
+++ /dev/null
@@ -1,447 +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.internal.org.bouncycastle.x509.X509V1CertificateGenerator;
-import com.android.net.module.util.ProxyUtils;
-
-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,
- IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305);
- 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.AUTH_AES_XCBC,
- IpSecAlgorithm.AUTH_AES_CMAC,
- IpSecAlgorithm.CRYPT_AES_CBC,
- IpSecAlgorithm.CRYPT_AES_CTR);
- 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/packages/Connectivity/tests/unit/java/android/net/IpMemoryStoreTest.java b/packages/Connectivity/tests/unit/java/android/net/IpMemoryStoreTest.java
deleted file mode 100644
index 0b13800..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/IpSecAlgorithmTest.java b/packages/Connectivity/tests/unit/java/android/net/IpSecAlgorithmTest.java
deleted file mode 100644
index 5bd2214..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/IpSecConfigTest.java b/packages/Connectivity/tests/unit/java/android/net/IpSecConfigTest.java
deleted file mode 100644
index 25e225e..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/IpSecManagerTest.java b/packages/Connectivity/tests/unit/java/android/net/IpSecManagerTest.java
deleted file mode 100644
index 730e2d5..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/IpSecTransformTest.java b/packages/Connectivity/tests/unit/java/android/net/IpSecTransformTest.java
deleted file mode 100644
index 424f23d..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/KeepalivePacketDataUtilTest.java b/packages/Connectivity/tests/unit/java/android/net/KeepalivePacketDataUtilTest.java
deleted file mode 100644
index fc739fb..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/MacAddressTest.java b/packages/Connectivity/tests/unit/java/android/net/MacAddressTest.java
deleted file mode 100644
index 6de31f6..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/NetworkIdentityTest.kt b/packages/Connectivity/tests/unit/java/android/net/NetworkIdentityTest.kt
deleted file mode 100644
index eb2b85c..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/NetworkStatsHistoryTest.java b/packages/Connectivity/tests/unit/java/android/net/NetworkStatsHistoryTest.java
deleted file mode 100644
index 13558cd..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/NetworkStatsTest.java b/packages/Connectivity/tests/unit/java/android/net/NetworkStatsTest.java
deleted file mode 100644
index 23d5a7e..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/NetworkTemplateTest.kt b/packages/Connectivity/tests/unit/java/android/net/NetworkTemplateTest.kt
deleted file mode 100644
index cb39a0c..0000000
--- a/packages/Connectivity/tests/unit/java/android/net/NetworkTemplateTest.kt
+++ /dev/null
@@ -1,365 +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.buildTemplateCarrierMetered
-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,
- metered: Boolean = true
- ): NetworkStateSnapshot {
- val lp = LinkProperties()
- val caps = NetworkCapabilities().apply {
- setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !metered)
- 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 testCarrierMeteredMatches() {
- val templateCarrierImsi1Metered = buildTemplateCarrierMetered(TEST_IMSI1)
-
- val mobileImsi1 = buildMobileNetworkState(TEST_IMSI1)
- val mobileImsi1Unmetered = buildNetworkState(TYPE_MOBILE, TEST_IMSI1, null /* ssid */,
- OEM_NONE, false /* metered */)
- val mobileImsi2 = buildMobileNetworkState(TEST_IMSI2)
- val wifiSsid1 = buildWifiNetworkState(null /* subscriberId */, TEST_SSID1)
- val wifiImsi1Ssid1 = buildWifiNetworkState(TEST_IMSI1, TEST_SSID1)
- val wifiImsi1Ssid1Unmetered = buildNetworkState(TYPE_WIFI, TEST_IMSI1, TEST_SSID1,
- OEM_NONE, false /* metered */)
-
- val identMobileImsi1Metered = buildNetworkIdentity(mockContext,
- mobileImsi1, false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
- val identMobileImsi1Unmetered = buildNetworkIdentity(mockContext,
- mobileImsi1Unmetered, false /* defaultNetwork */,
- TelephonyManager.NETWORK_TYPE_UMTS)
- val identMobileImsi2Metered = buildNetworkIdentity(mockContext,
- mobileImsi2, false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
- val identWifiSsid1Metered = buildNetworkIdentity(
- mockContext, wifiSsid1, true /* defaultNetwork */, 0 /* subType */)
- val identCarrierWifiImsi1Metered = buildNetworkIdentity(
- mockContext, wifiImsi1Ssid1, true /* defaultNetwork */, 0 /* subType */)
- val identCarrierWifiImsi1NonMetered = buildNetworkIdentity(mockContext,
- wifiImsi1Ssid1Unmetered, true /* defaultNetwork */, 0 /* subType */)
-
- templateCarrierImsi1Metered.assertMatches(identMobileImsi1Metered)
- templateCarrierImsi1Metered.assertDoesNotMatch(identMobileImsi1Unmetered)
- templateCarrierImsi1Metered.assertDoesNotMatch(identMobileImsi2Metered)
- templateCarrierImsi1Metered.assertDoesNotMatch(identWifiSsid1Metered)
- templateCarrierImsi1Metered.assertMatches(identCarrierWifiImsi1Metered)
- templateCarrierImsi1Metered.assertDoesNotMatch(identCarrierWifiImsi1NonMetered)
- }
-
- @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/packages/Connectivity/tests/unit/java/android/net/NetworkUtilsTest.java b/packages/Connectivity/tests/unit/java/android/net/NetworkUtilsTest.java
deleted file mode 100644
index 7748288..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/QosSocketFilterTest.java b/packages/Connectivity/tests/unit/java/android/net/QosSocketFilterTest.java
deleted file mode 100644
index 40f8f1b..0000000
--- a/packages/Connectivity/tests/unit/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.matchesAddress(
- 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.matchesAddress(
- 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.matchesAddress(
- 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.matchesAddress(
- 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.matchesAddress(
- new InetSocketAddress(addressA, 10), addressB, 10, 10));
- }
-}
-
diff --git a/packages/Connectivity/tests/unit/java/android/net/TelephonyNetworkSpecifierTest.java b/packages/Connectivity/tests/unit/java/android/net/TelephonyNetworkSpecifierTest.java
deleted file mode 100644
index 6714bb1..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/VpnManagerTest.java b/packages/Connectivity/tests/unit/java/android/net/VpnManagerTest.java
deleted file mode 100644
index 3135062..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/VpnTransportInfoTest.java b/packages/Connectivity/tests/unit/java/android/net/VpnTransportInfoTest.java
deleted file mode 100644
index ccaa5cf..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/ipmemorystore/ParcelableTests.java b/packages/Connectivity/tests/unit/java/android/net/ipmemorystore/ParcelableTests.java
deleted file mode 100644
index 603c875..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/nsd/NsdManagerTest.java b/packages/Connectivity/tests/unit/java/android/net/nsd/NsdManagerTest.java
deleted file mode 100644
index b0a9b8a..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/nsd/NsdServiceInfoTest.java b/packages/Connectivity/tests/unit/java/android/net/nsd/NsdServiceInfoTest.java
deleted file mode 100644
index 94dfc75..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/util/DnsUtilsTest.java b/packages/Connectivity/tests/unit/java/android/net/util/DnsUtilsTest.java
deleted file mode 100644
index b626db8..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/util/KeepaliveUtilsTest.kt b/packages/Connectivity/tests/unit/java/android/net/util/KeepaliveUtilsTest.kt
deleted file mode 100644
index 5006d53..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/android/net/util/MultinetworkPolicyTrackerTest.kt b/packages/Connectivity/tests/unit/java/android/net/util/MultinetworkPolicyTrackerTest.kt
deleted file mode 100644
index 25aa626..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/internal/net/NetworkUtilsInternalTest.java b/packages/Connectivity/tests/unit/java/com/android/internal/net/NetworkUtilsInternalTest.java
deleted file mode 100644
index 3cfecd5..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/internal/net/VpnProfileTest.java b/packages/Connectivity/tests/unit/java/com/android/internal/net/VpnProfileTest.java
deleted file mode 100644
index cb0f071..0000000
--- a/packages/Connectivity/tests/unit/java/com/android/internal/net/VpnProfileTest.java
+++ /dev/null
@@ -1,194 +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 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_CRYPT_CHACHA20_POLY1305,
- 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 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/packages/Connectivity/tests/unit/java/com/android/internal/util/BitUtilsTest.java b/packages/Connectivity/tests/unit/java/com/android/internal/util/BitUtilsTest.java
deleted file mode 100644
index d2fbdce..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/internal/util/RingBufferTest.java b/packages/Connectivity/tests/unit/java/com/android/internal/util/RingBufferTest.java
deleted file mode 100644
index d06095a..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/ConnectivityServiceTest.java
deleted file mode 100644
index 4661385..0000000
--- a/packages/Connectivity/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ /dev/null
@@ -1,12901 +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.assertSameElements;
-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);
- }
-
- @Test
- public void testNetworkCallbackWithNullUids() throws Exception {
- final NetworkRequest request = new NetworkRequest.Builder()
- .removeCapability(NET_CAPABILITY_NOT_VPN)
- .build();
- final TestNetworkCallback callback = new TestNetworkCallback();
- mCm.registerNetworkCallback(request, callback);
-
- // Attempt to file a callback for networks applying to another UID. This does not actually
- // work, because this code does not currently have permission to do so. The callback behaves
- // exactly the same as the one registered just above.
- final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID);
- final NetworkRequest otherUidRequest = new NetworkRequest.Builder()
- .removeCapability(NET_CAPABILITY_NOT_VPN)
- .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid)))
- .build();
- final TestNetworkCallback otherUidCallback = new TestNetworkCallback();
- mCm.registerNetworkCallback(otherUidRequest, otherUidCallback);
-
- final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder()
- .removeCapability(NET_CAPABILITY_NOT_VPN)
- .setIncludeOtherUidNetworks(true)
- .build();
- final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback();
- mCm.registerNetworkCallback(includeOtherUidsRequest, includeOtherUidsCallback);
-
- // Both callbacks see a network with no specifier that applies to their UID.
- mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
- mWiFiNetworkAgent.connect(false /* validated */);
- callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- includeOtherUidsCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- otherUidCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- includeOtherUidsCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
-
- // Only the includeOtherUidsCallback sees a VPN that does not apply to its UID.
- final UidRange range = UidRange.createForUser(UserHandle.of(RESTRICTED_USER));
- final Set<UidRange> vpnRanges = Collections.singleton(range);
- mMockVpn.establish(new LinkProperties(), VPN_UID, vpnRanges);
- includeOtherUidsCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
- callback.assertNoCallback();
- otherUidCallback.assertNoCallback();
-
- mMockVpn.disconnect();
- includeOtherUidsCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
- callback.assertNoCallback();
- otherUidCallback.assertNoCallback();
- }
-
- private static class RedactableNetworkSpecifier extends NetworkSpecifier {
- public static final int ID_INVALID = -1;
-
- public final int networkId;
-
- RedactableNetworkSpecifier(int networkId) {
- this.networkId = networkId;
- }
-
- @Override
- public boolean canBeSatisfiedBy(NetworkSpecifier other) {
- return other instanceof RedactableNetworkSpecifier
- && this.networkId == ((RedactableNetworkSpecifier) other).networkId;
- }
-
- @Override
- public NetworkSpecifier redact() {
- return new RedactableNetworkSpecifier(ID_INVALID);
- }
- }
-
- @Test
- public void testNetworkCallbackWithNullUidsRedactsSpecifier() throws Exception {
- final RedactableNetworkSpecifier specifier = new RedactableNetworkSpecifier(42);
- final NetworkRequest request = new NetworkRequest.Builder()
- .addCapability(NET_CAPABILITY_INTERNET)
- .addTransportType(TRANSPORT_WIFI)
- .setNetworkSpecifier(specifier)
- .build();
- final TestNetworkCallback callback = new TestNetworkCallback();
- mCm.registerNetworkCallback(request, callback);
-
- // Attempt to file a callback for networks applying to another UID. This does not actually
- // work, because this code does not currently have permission to do so. The callback behaves
- // exactly the same as the one registered just above.
- final int otherUid = UserHandle.getUid(RESTRICTED_USER, VPN_UID);
- final NetworkRequest otherUidRequest = new NetworkRequest.Builder()
- .addCapability(NET_CAPABILITY_INTERNET)
- .addTransportType(TRANSPORT_WIFI)
- .setNetworkSpecifier(specifier)
- .setUids(UidRange.toIntRanges(uidRangesForUids(otherUid)))
- .build();
- final TestNetworkCallback otherUidCallback = new TestNetworkCallback();
- mCm.registerNetworkCallback(otherUidRequest, otherUidCallback);
-
- final NetworkRequest includeOtherUidsRequest = new NetworkRequest.Builder()
- .addCapability(NET_CAPABILITY_INTERNET)
- .addTransportType(TRANSPORT_WIFI)
- .setNetworkSpecifier(specifier)
- .setIncludeOtherUidNetworks(true)
- .build();
- final TestNetworkCallback includeOtherUidsCallback = new TestNetworkCallback();
- mCm.registerNetworkCallback(includeOtherUidsRequest, callback);
-
- // Only the regular callback sees the network, because callbacks filed with no UID have
- // their specifiers redacted.
- final LinkProperties emptyLp = new LinkProperties();
- final NetworkCapabilities ncTemplate = new NetworkCapabilities()
- .addTransportType(TRANSPORT_WIFI)
- .setNetworkSpecifier(specifier);
- mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, emptyLp, ncTemplate);
- mWiFiNetworkAgent.connect(false /* validated */);
- callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- includeOtherUidsCallback.assertNoCallback();
- }
-
- 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 void expectNotifyNetworkStatus(List<Network> networks, String defaultIface,
- Integer vpnUid, String vpnIfname, List<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());
-
- assertSameElements(networksCaptor.getValue(), networks);
-
- List<UnderlyingNetworkInfo> infos = vpnInfosCaptor.getValue();
- if (vpnUid != null) {
- assertEquals("Should have exactly one VPN:", 1, infos.size());
- UnderlyingNetworkInfo info = infos.get(0);
- assertEquals("Unexpected VPN owner:", (int) vpnUid, info.getOwnerUid());
- assertEquals("Unexpected VPN interface:", vpnIfname, info.getInterface());
- assertSameElements(underlyingIfaces, info.getUnderlyingInterfaces());
- } else {
- assertEquals(0, infos.size());
- return;
- }
- }
-
- private void expectNotifyNetworkStatus(
- List<Network> networks, String defaultIface) throws Exception {
- expectNotifyNetworkStatus(networks, defaultIface, null, null, List.of());
- }
-
- @Test
- public void testStatsIfacesChanged() throws Exception {
- mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
- mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
-
- final List<Network> onlyCell = List.of(mCellNetworkAgent.getNetwork());
- final List<Network> onlyWifi = List.of(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();
- expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME);
- reset(mStatsManager);
-
- // Default network switch should update ifaces.
- mWiFiNetworkAgent.connect(false);
- mWiFiNetworkAgent.sendLinkProperties(wifiLp);
- waitForIdle();
- assertEquals(wifiLp, mService.getActiveLinkProperties());
- expectNotifyNetworkStatus(onlyWifi, WIFI_IFNAME);
- reset(mStatsManager);
-
- // Disconnect should update ifaces.
- mWiFiNetworkAgent.disconnect();
- waitForIdle();
- expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME);
- reset(mStatsManager);
-
- // Metered change should update ifaces
- mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
- waitForIdle();
- expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME);
- reset(mStatsManager);
-
- mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
- waitForIdle();
- expectNotifyNetworkStatus(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(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();
- expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME);
- reset(mStatsManager);
-
- // Test VPNs.
- final LinkProperties lp = new LinkProperties();
- lp.setInterfaceName(VPN_IFNAME);
-
- mMockVpn.establishForMyUid(lp);
- assertUidRangesUpdatedForMyUid(true);
-
- final List<Network> cellAndVpn =
- List.of(mCellNetworkAgent.getNetwork(), mMockVpn.getNetwork());
-
- // A VPN with default (null) underlying networks sets the underlying network's interfaces...
- expectNotifyNetworkStatus(cellAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
- List.of(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 List<Network> wifiAndVpn =
- List.of(mWiFiNetworkAgent.getNetwork(), mMockVpn.getNetwork());
- final List<Network> cellAndWifi =
- List.of(mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork());
- final Network[] cellNullAndWifi =
- new Network[]{mCellNetworkAgent.getNetwork(), null, mWiFiNetworkAgent.getNetwork()};
-
- waitForIdle();
- assertEquals(wifiLp, mService.getActiveLinkProperties());
- expectNotifyNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
- List.of(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.toArray(new Network[0]));
- waitForIdle();
- expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
- List.of(MOBILE_IFNAME));
- reset(mStatsManager);
-
- mMockVpn.setUnderlyingNetworks(cellAndWifi.toArray(new Network[0]));
- waitForIdle();
- expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
- List.of(MOBILE_IFNAME, WIFI_IFNAME));
- reset(mStatsManager);
-
- // Null underlying networks are ignored.
- mMockVpn.setUnderlyingNetworks(cellNullAndWifi);
- waitForIdle();
- expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
- List.of(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()));
- expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
- List.of(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();
- expectNotifyNetworkStatus(wifiAndVpn, null);
- reset(mStatsManager);
-
- // Specifying only a null underlying network is the same as no networks.
- mMockVpn.setUnderlyingNetworks(onlyNull);
- waitForIdle();
- expectNotifyNetworkStatus(wifiAndVpn, null);
- reset(mStatsManager);
-
- // Specifying networks that are all disconnected is the same as specifying no networks.
- mMockVpn.setUnderlyingNetworks(onlyCell.toArray(new Network[0]));
- waitForIdle();
- expectNotifyNetworkStatus(wifiAndVpn, null);
- reset(mStatsManager);
-
- // Passing in null again means follow the default network again.
- mMockVpn.setUnderlyingNetworks(null);
- waitForIdle();
- expectNotifyNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
- List.of(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 int wrongUid = Process.myUid() + 1;
-
- final NetworkCapabilities nc = new NetworkCapabilities();
- nc.setAdministratorUids(new int[] {wrongUid});
- final NetworkAgentInfo naiWithUid = fakeMobileNai(nc);
-
- 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, wrongUid, naiWithUid, mContext.getOpPackageName()));
- }
-
- @Test
- public void testCheckConnectivityDiagnosticsPermissionsNoLocationPermission() throws Exception {
- final NetworkCapabilities nc = new NetworkCapabilities();
- nc.setAdministratorUids(new int[] {Process.myUid()});
- final NetworkAgentInfo naiWithUid = fakeMobileNai(nc);
-
- mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
-
- assertFalse(
- "ACCESS_FINE_LOCATION permission necessary for Connectivity Diagnostics",
- mService.checkConnectivityDiagnosticsPermissions(
- Process.myPid(), Process.myUid(), naiWithUid, 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/packages/Connectivity/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java b/packages/Connectivity/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java
deleted file mode 100644
index cf2c9c7..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/IpSecServiceRefcountedResourceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/IpSecServiceRefcountedResourceTest.java
deleted file mode 100644
index 22a2c94..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/IpSecServiceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/IpSecServiceTest.java
deleted file mode 100644
index 6232423..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/LegacyTypeTrackerTest.kt b/packages/Connectivity/tests/unit/java/com/android/server/LegacyTypeTrackerTest.kt
deleted file mode 100644
index 5ec1119..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/NetIdManagerTest.kt b/packages/Connectivity/tests/unit/java/com/android/server/NetIdManagerTest.kt
deleted file mode 100644
index 6f5e740..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/NetworkManagementServiceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/NetworkManagementServiceTest.java
deleted file mode 100644
index 13516d7..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/NsdServiceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/NsdServiceTest.java
deleted file mode 100644
index a90fa68..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
deleted file mode 100644
index 0ffeec9..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt
deleted file mode 100644
index 45b575a..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
deleted file mode 100644
index 70495cc..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
deleted file mode 100644
index 8b072c4..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/connectivity/LingerMonitorTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/LingerMonitorTest.java
deleted file mode 100644
index 36e229d..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/connectivity/MetricsTestUtil.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/MetricsTestUtil.java
deleted file mode 100644
index 5064b9b..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
deleted file mode 100644
index 38f6d7f..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/connectivity/Nat464XlatTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/Nat464XlatTest.java
deleted file mode 100644
index 9b2a638..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
deleted file mode 100644
index 50aaaee..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
deleted file mode 100644
index c353cea..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetworkOfferTest.kt b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetworkOfferTest.kt
deleted file mode 100644
index 409f8c3..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetworkRankerTest.kt b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetworkRankerTest.kt
deleted file mode 100644
index 4408958..0000000
--- a/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetworkRankerTest.kt
+++ /dev/null
@@ -1,172 +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.NetworkCapabilities
-import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
-import android.net.NetworkCapabilities.TRANSPORT_WIFI
-import android.net.NetworkScore.KEEP_CONNECTED_NONE
-import android.net.NetworkScore.POLICY_EXITING
-import android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY
-import android.net.NetworkScore.POLICY_YIELD_TO_BAD_WIFI
-import android.os.Build
-import androidx.test.filters.SmallTest
-import com.android.server.connectivity.FullScore.POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD
-import com.android.server.connectivity.FullScore.POLICY_IS_VALIDATED
-import com.android.testutils.DevSdkIgnoreRule
-import com.android.testutils.DevSdkIgnoreRunner
-import org.junit.Test
-import org.junit.runner.RunWith
-import kotlin.test.assertEquals
-
-private fun score(vararg policies: Int) = FullScore(0,
- policies.fold(0L) { acc, e -> acc or (1L shl e) }, KEEP_CONNECTED_NONE)
-private fun caps(transport: Int) = NetworkCapabilities.Builder().addTransportType(transport).build()
-
-@SmallTest
-@RunWith(DevSdkIgnoreRunner::class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
-class NetworkRankerTest {
- private val mRanker = NetworkRanker()
-
- private class TestScore(private val sc: FullScore, private val nc: NetworkCapabilities)
- : NetworkRanker.Scoreable {
- override fun getScore() = sc
- override fun getCapsNoCopy(): NetworkCapabilities = nc
- }
-
- @Test
- fun testYieldToBadWiFiOneCell() {
- // Only cell, it wins
- val winner = TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- val scores = listOf(winner)
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
- }
-
- @Test
- fun testYieldToBadWiFiOneCellOneBadWiFi() {
- // Bad wifi wins against yielding validated cell
- val winner = TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD),
- caps(TRANSPORT_WIFI))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
- }
-
- @Test
- fun testYieldToBadWiFiOneCellTwoBadWiFi() {
- // Bad wifi wins against yielding validated cell. Prefer the one that's primary.
- val winner = TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
- POLICY_TRANSPORT_PRIMARY), caps(TRANSPORT_WIFI))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD),
- caps(TRANSPORT_WIFI)),
- TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
- }
-
- @Test
- fun testYieldToBadWiFiOneCellTwoBadWiFiOneNotAvoided() {
- // Bad wifi ever validated wins against bad wifi that never was validated (or was
- // avoided when bad).
- val winner = TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD),
- caps(TRANSPORT_WIFI))
- val scores = listOf(
- winner,
- TestScore(score(), caps(TRANSPORT_WIFI)),
- TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
- }
-
- @Test
- fun testYieldToBadWiFiOneCellOneBadWiFiOneGoodWiFi() {
- // Good wifi wins
- val winner = TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
- POLICY_IS_VALIDATED), caps(TRANSPORT_WIFI))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
- POLICY_TRANSPORT_PRIMARY), caps(TRANSPORT_WIFI)),
- TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
- }
-
- @Test
- fun testYieldToBadWiFiTwoCellsOneBadWiFi() {
- // Cell that doesn't yield wins over cell that yields and bad wifi
- val winner = TestScore(score(POLICY_IS_VALIDATED), caps(TRANSPORT_CELLULAR))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
- POLICY_TRANSPORT_PRIMARY), caps(TRANSPORT_WIFI)),
- TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
- }
-
- @Test
- fun testYieldToBadWiFiTwoCellsOneBadWiFiOneGoodWiFi() {
- // Good wifi wins over cell that doesn't yield and cell that yields
- val winner = TestScore(score(POLICY_IS_VALIDATED), caps(TRANSPORT_WIFI))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
- POLICY_TRANSPORT_PRIMARY), caps(TRANSPORT_WIFI)),
- TestScore(score(POLICY_IS_VALIDATED), caps(TRANSPORT_CELLULAR)),
- TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
- }
-
- @Test
- fun testYieldToBadWiFiOneExitingGoodWiFi() {
- // Yielding cell wins over good exiting wifi
- val winner = TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_IS_VALIDATED, POLICY_EXITING), caps(TRANSPORT_WIFI))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
- }
-
- @Test
- fun testYieldToBadWiFiOneExitingBadWiFi() {
- // Yielding cell wins over bad exiting wifi
- val winner = TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
- POLICY_EXITING), caps(TRANSPORT_WIFI))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
- }
-}
diff --git a/packages/Connectivity/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
deleted file mode 100644
index c75618f..0000000
--- a/packages/Connectivity/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ /dev/null
@@ -1,1001 +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.net.ConnectivitySettingsManager.APPS_ALLOWED_ON_RESTRICTED_NETWORKS;
-import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
-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.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.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.database.ContentObserver;
-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.ArraySet;
-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);
- when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>());
-
- 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) {
- return hasRestrictedNetworkPermission(
- partition, targetSdkVersion, "" /* packageName */, uid, permissions);
- }
-
- private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion,
- String packageName, int uid, String... permissions) {
- final PackageInfo packageInfo =
- packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, permissions, partition);
- packageInfo.packageName = packageName;
- 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));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_P, MOCK_UID1, PERMISSION_MAINLINE_NETWORK_STACK));
-
- 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));
- }
-
- @Test
- public void testHasRestrictedNetworkPermissionAppAllowedOnRestrictedNetworks() {
- mPermissionMonitor.updateAppsAllowedOnRestrictedNetworks(
- new ArraySet<>(new String[] { MOCK_PACKAGE1 }));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1, CHANGE_NETWORK_STATE));
- assertTrue(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1, CONNECTIVITY_INTERNAL));
-
- assertFalse(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID1));
- assertFalse(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID1, CHANGE_NETWORK_STATE));
- assertFalse(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID1, CONNECTIVITY_INTERNAL));
-
- }
-
- private boolean wouldBeCarryoverPackage(String partition, int targetSdkVersion, int uid) {
- final PackageInfo packageInfo = packageInfoWithPermissions(
- REQUESTED_PERMISSION_GRANTED, new String[] {}, partition);
- packageInfo.applicationInfo.targetSdkVersion = targetSdkVersion;
- packageInfo.applicationInfo.uid = uid;
- return mPermissionMonitor.isCarryoverPackage(packageInfo.applicationInfo);
- }
-
- @Test
- public void testIsCarryoverPackage() {
- doReturn(VERSION_P).when(mDeps).getDeviceFirstSdkInt();
- assertTrue(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
- assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, SYSTEM_UID));
- assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, MOCK_UID1));
- assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, MOCK_UID1));
- assertTrue(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
- assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, SYSTEM_UID));
- assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1));
- assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, MOCK_UID1));
-
- doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt();
- assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
- assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, SYSTEM_UID));
- assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, MOCK_UID1));
- assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, MOCK_UID1));
- assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
- assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, SYSTEM_UID));
- assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1));
- assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, MOCK_UID1));
-
- assertFalse(wouldBeCarryoverPackage(PARTITION_OEM, VERSION_Q, SYSTEM_UID));
- assertFalse(wouldBeCarryoverPackage(PARTITION_PRODUCT, VERSION_Q, SYSTEM_UID));
- assertFalse(wouldBeCarryoverPackage(PARTITION_OEM, VERSION_Q, MOCK_UID1));
- assertFalse(wouldBeCarryoverPackage(PARTITION_PRODUCT, VERSION_Q, MOCK_UID1));
- }
-
- private boolean wouldBeAppAllowedOnRestrictedNetworks(String packageName) {
- final PackageInfo packageInfo = new PackageInfo();
- packageInfo.packageName = packageName;
- return mPermissionMonitor.isAppAllowedOnRestrictedNetworks(packageInfo);
- }
-
- @Test
- public void testIsAppAllowedOnRestrictedNetworks() {
- mPermissionMonitor.updateAppsAllowedOnRestrictedNetworks(new ArraySet<>());
- assertFalse(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE1));
- assertFalse(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE2));
-
- mPermissionMonitor.updateAppsAllowedOnRestrictedNetworks(
- new ArraySet<>(new String[] { MOCK_PACKAGE1 }));
- assertTrue(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE1));
- assertFalse(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE2));
-
- mPermissionMonitor.updateAppsAllowedOnRestrictedNetworks(
- new ArraySet<>(new String[] { MOCK_PACKAGE2 }));
- assertFalse(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE1));
- assertTrue(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE2));
-
- mPermissionMonitor.updateAppsAllowedOnRestrictedNetworks(
- new ArraySet<>(new String[] { "com.android.test" }));
- assertFalse(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE1));
- assertFalse(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE2));
- }
-
- 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 });
- }
-
- @Test
- public void testAppsAllowedOnRestrictedNetworksChanged() throws Exception {
- final NetdMonitor mNetdMonitor = new NetdMonitor(mNetdService);
- final ArgumentCaptor<ContentObserver> captor =
- ArgumentCaptor.forClass(ContentObserver.class);
- verify(mDeps, times(1)).registerContentObserver(any(),
- argThat(uri -> uri.getEncodedPath().contains(APPS_ALLOWED_ON_RESTRICTED_NETWORKS)),
- anyBoolean(), captor.capture());
- final ContentObserver contentObserver = captor.getValue();
-
- mPermissionMonitor.onUserAdded(MOCK_USER1);
- // Prepare PackageInfo for MOCK_PACKAGE1
- final PackageInfo packageInfo = buildPackageInfo(
- false /* hasSystemPermission */, MOCK_UID1, MOCK_USER1);
- packageInfo.packageName = MOCK_PACKAGE1;
- when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), anyInt())).thenReturn(packageInfo);
- when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{MOCK_PACKAGE1});
- // Prepare PackageInfo for MOCK_PACKAGE2
- final PackageInfo packageInfo2 = buildPackageInfo(
- false /* hasSystemPermission */, MOCK_UID2, MOCK_USER1);
- packageInfo2.packageName = MOCK_PACKAGE2;
- when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
- when(mPackageManager.getPackagesForUid(MOCK_UID2)).thenReturn(new String[]{MOCK_PACKAGE2});
-
- // MOCK_PACKAGE1 is listed in setting that allow to use restricted networks, MOCK_UID1
- // should have SYSTEM permission.
- when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn(
- new ArraySet<>(new String[] { MOCK_PACKAGE1 }));
- contentObserver.onChange(true /* selfChange */);
- mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
- mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
-
- // MOCK_PACKAGE2 is listed in setting that allow to use restricted networks, MOCK_UID2
- // should have SYSTEM permission but MOCK_UID1 should revoke permission.
- when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn(
- new ArraySet<>(new String[] { MOCK_PACKAGE2 }));
- contentObserver.onChange(true /* selfChange */);
- mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
- mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
-
- // No app lists in setting, should revoke permission from all uids.
- when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>());
- contentObserver.onChange(true /* selfChange */);
- mNetdMonitor.expectNoPermission(
- new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1, MOCK_UID2});
- }
-
- @Test
- public void testAppsAllowedOnRestrictedNetworksChangedWithSharedUid() throws Exception {
- final NetdMonitor mNetdMonitor = new NetdMonitor(mNetdService);
- final ArgumentCaptor<ContentObserver> captor =
- ArgumentCaptor.forClass(ContentObserver.class);
- verify(mDeps, times(1)).registerContentObserver(any(),
- argThat(uri -> uri.getEncodedPath().contains(APPS_ALLOWED_ON_RESTRICTED_NETWORKS)),
- anyBoolean(), captor.capture());
- final ContentObserver contentObserver = captor.getValue();
-
- mPermissionMonitor.onUserAdded(MOCK_USER1);
- // Prepare PackageInfo for MOCK_PACKAGE1 and MOCK_PACKAGE2 with shared uid MOCK_UID1.
- final PackageInfo packageInfo = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
- packageInfo.applicationInfo.uid = MOCK_USER1.getUid(MOCK_UID1);
- packageInfo.packageName = MOCK_PACKAGE1;
- final PackageInfo packageInfo2 = buildPackageInfo(
- false /* hasSystemPermission */, MOCK_UID1, MOCK_USER1);
- packageInfo2.packageName = MOCK_PACKAGE2;
- when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), anyInt())).thenReturn(packageInfo);
- when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
- when(mPackageManager.getPackagesForUid(MOCK_UID1))
- .thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2});
-
- // MOCK_PACKAGE1 have CHANGE_NETWORK_STATE, MOCK_UID1 should have NETWORK permission.
- addPackageForUsers(new UserHandle[]{MOCK_USER1}, MOCK_PACKAGE1, MOCK_UID1);
- mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
-
- // MOCK_PACKAGE2 is listed in setting that allow to use restricted networks, MOCK_UID1
- // should upgrade to SYSTEM permission.
- when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn(
- new ArraySet<>(new String[] { MOCK_PACKAGE2 }));
- contentObserver.onChange(true /* selfChange */);
- mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
-
- // MOCK_PACKAGE1 is listed in setting that allow to use restricted networks, MOCK_UID1
- // should still have SYSTEM permission.
- when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn(
- new ArraySet<>(new String[] { MOCK_PACKAGE1 }));
- contentObserver.onChange(true /* selfChange */);
- mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
-
- // No app lists in setting, MOCK_UID1 should downgrade to NETWORK permission.
- when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>());
- contentObserver.onChange(true /* selfChange */);
- mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
-
- // MOCK_PACKAGE1 removed, should revoke permission from MOCK_UID1.
- when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{MOCK_PACKAGE2});
- removePackageForUsers(new UserHandle[]{MOCK_USER1}, MOCK_PACKAGE1, MOCK_UID1);
- mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
- }
-}
\ No newline at end of file
diff --git a/packages/Connectivity/tests/unit/java/com/android/server/connectivity/VpnTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/VpnTest.java
deleted file mode 100644
index b725b82..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsAccessTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsAccessTest.java
deleted file mode 100644
index 8b730af..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsBaseTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsBaseTest.java
deleted file mode 100644
index a058a46..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsCollectionTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsCollectionTest.java
deleted file mode 100644
index 505ff9b..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
deleted file mode 100644
index 93599f3..0000000
--- a/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
+++ /dev/null
@@ -1,579 +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 com.android.internal.util.test.FsUtil;
-
-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()) {
- FsUtil.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()) {
- FsUtil.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/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
deleted file mode 100644
index 9fa1c50..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
deleted file mode 100644
index 0ba5f7d..0000000
--- a/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ /dev/null
@@ -1,1811 +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.internal.util.test.FsUtil;
-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 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 sTemplateCarrierWifi1 =
- buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL, IMSI_1);
- 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()) {
- FsUtil.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 {
- FsUtil.deleteContents(mStatsDir);
-
- mServiceContext = null;
- mStatsDir = null;
-
- mNetManager = null;
- mSettings = null;
-
- mSession.close();
- mService = null;
-
- mHandlerThread.quitSafely();
- }
-
- private void initWifiStats(NetworkStateSnapshot snapshot) 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[] {snapshot};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
-
- mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
- new UnderlyingNetworkInfo[0]);
- }
-
- private void incrementWifiStats(long durationMillis, String iface,
- long rxb, long rxp, long txb, long txp) throws Exception {
- incrementCurrentTime(durationMillis);
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .insertEntry(iface, rxb, rxp, txb, txp));
- expectNetworkStatsUidDetail(buildEmptyStats());
- forcePollAndWaitForIdle();
- }
-
- @Test
- public void testNetworkStatsCarrierWifi() throws Exception {
- initWifiStats(buildWifiState(true, TEST_IFACE, IMSI_1));
- // verify service has empty history for carrier merged wifi and non-carrier wifi
- assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
- assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
-
- // modify some number on wifi, and trigger poll event
- incrementWifiStats(HOUR_IN_MILLIS, TEST_IFACE, 1024L, 1L, 2048L, 2L);
-
- // verify service recorded history
- assertNetworkTotal(sTemplateCarrierWifi1, 1024L, 1L, 2048L, 2L, 0);
-
- // verify service recorded history for wifi with SSID filter
- 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.
- incrementWifiStats(DAY_IN_MILLIS, TEST_IFACE, 4096L, 4L, 8192L, 8L);
-
- // verify service recorded history
- assertNetworkTotal(sTemplateCarrierWifi1, 4096L, 4L, 8192L, 8L, 0);
- // verify service recorded history for wifi with SSID filter
- assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
- }
-
- @Test
- public void testNetworkStatsNonCarrierWifi() throws Exception {
- initWifiStats(buildWifiState());
-
- // verify service has empty history for wifi
- assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
- // verify service has empty history for carrier merged wifi
- assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
-
- // modify some number on wifi, and trigger poll event
- incrementWifiStats(HOUR_IN_MILLIS, TEST_IFACE, 1024L, 1L, 2048L, 2L);
-
- // verify service recorded history
- assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
- // verify service has empty history for carrier wifi since current network is non carrier
- // wifi
- assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
-
- // and bump forward again, with counters going higher. this is
- // important, since polling should correctly subtract last snapshot.
- incrementWifiStats(DAY_IN_MILLIS, TEST_IFACE, 4096L, 4L, 8192L, 8L);
-
- // verify service recorded history
- assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
- // verify service has empty history for carrier wifi since current network is non carrier
- // wifi
- assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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#notifyNetworkStatus 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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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.notifyNetworkStatus(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
- // handleNotifyNetworkStatus.
- 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.notifyNetworkStatus(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, null);
- }
-
- private static NetworkStateSnapshot buildWifiState(boolean isMetered, @NonNull String iface) {
- return buildWifiState(isMetered, iface, null);
- }
-
- private static NetworkStateSnapshot buildWifiState(boolean isMetered, @NonNull String iface,
- String subscriberId) {
- 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, subscriberId, 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/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java
deleted file mode 100644
index 6d2c7dc..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java
deleted file mode 100644
index ebbc0ef..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/jni/Android.bp b/packages/Connectivity/tests/unit/jni/Android.bp
deleted file mode 100644
index 22a04f5..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/jni/test_onload.cpp b/packages/Connectivity/tests/unit/jni/test_onload.cpp
deleted file mode 100644
index 5194ddb..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/history_v1 b/packages/Connectivity/tests/unit/res/raw/history_v1
deleted file mode 100644
index de79491..0000000
--- a/packages/Connectivity/tests/unit/res/raw/history_v1
+++ /dev/null
Binary files differ
diff --git a/packages/Connectivity/tests/unit/res/raw/net_dev_typical b/packages/Connectivity/tests/unit/res/raw/net_dev_typical
deleted file mode 100644
index 290bf03..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/netstats_uid_v4 b/packages/Connectivity/tests/unit/res/raw/netstats_uid_v4
deleted file mode 100644
index e75fc1c..0000000
--- a/packages/Connectivity/tests/unit/res/raw/netstats_uid_v4
+++ /dev/null
Binary files differ
diff --git a/packages/Connectivity/tests/unit/res/raw/netstats_v1 b/packages/Connectivity/tests/unit/res/raw/netstats_v1
deleted file mode 100644
index e80860a..0000000
--- a/packages/Connectivity/tests/unit/res/raw/netstats_v1
+++ /dev/null
Binary files differ
diff --git a/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_iface_fmt_typical b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_iface_fmt_typical
deleted file mode 100644
index 656d5bb..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_iface_typical b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_iface_typical
deleted file mode 100644
index 610723a..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_typical b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_typical
deleted file mode 100644
index c1b0d25..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_incorrect_iface b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_incorrect_iface
deleted file mode 100644
index fc92715..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying
deleted file mode 100644
index 1ef1889..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying_compression b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying_compression
deleted file mode 100644
index 6d6bf55..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying_own_traffic b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying_own_traffic
deleted file mode 100644
index 2c2e5d2..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn
deleted file mode 100644
index eb0513b..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_rewrite_through_self b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_rewrite_through_self
deleted file mode 100644
index afcdd71..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_two_underlying_duplication b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_two_underlying_duplication
deleted file mode 100644
index d7c7eb9..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_two_underlying_split b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_two_underlying_split
deleted file mode 100644
index 38a3dce..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_two_underlying_split_compression b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_two_underlying_split_compression
deleted file mode 100644
index d35244b..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_with_clat b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_with_clat
deleted file mode 100644
index 0d893d5..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat
deleted file mode 100644
index f04b32f..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat_100mb_download_after b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat_100mb_download_after
deleted file mode 100644
index 12d98ca..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat_100mb_download_before b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat_100mb_download_before
deleted file mode 100644
index ce4bcc3..0000000
--- a/packages/Connectivity/tests/unit/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/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat_simple b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat_simple
deleted file mode 100644
index a1d6d411..0000000
--- a/packages/Connectivity/tests/unit/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