Merge history of packages/Connectivity
Modified Visibility / Includes for: - Tethering/common/TetheringLib/Android.bp Modified License Import for: - framework/Android.bp - service/Android.bp - tests/common/Android.bp - tests/deflake/Android.bp - tests/integration/Android.bp - tests/smoketest/Android.bp - tests/unit/Android.bp - tests/unit/jni/Android.bp Modified Lint mapping for: - framework/lint-baseline.xml - service/lint-baseline.xml BUG: 186628461 TEST: TH Merged-In: Ie82d0fb34bda77543e31c82660c6f315efa87f62 Change-Id: I3c2563d4ae4e3715d0c6270344ba8f7ef067872f
This commit is contained in:
17
TEST_MAPPING
17
TEST_MAPPING
@@ -31,5 +31,22 @@
|
||||
"name": "CtsNetTestCasesLatestSdk[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex]",
|
||||
"keywords": ["sim"]
|
||||
}
|
||||
],
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ java_sdk_library {
|
||||
name: "framework-tethering",
|
||||
defaults: ["framework-module-defaults"],
|
||||
impl_library_visibility: [
|
||||
"//frameworks/base/packages/Tethering:__subpackages__",
|
||||
"//packages/modules/Connectivity/Tethering:__subpackages__",
|
||||
],
|
||||
|
||||
@@ -30,7 +29,7 @@ java_sdk_library {
|
||||
stub_only_libs: ["framework-connectivity.stubs.module_lib"],
|
||||
aidl: {
|
||||
include_dirs: [
|
||||
"frameworks/base/packages/Connectivity/framework/aidl-export",
|
||||
"packages/modules/Connectivity/framework/aidl-export",
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
161
framework/Android.bp
Normal file
161
framework/Android.bp
Normal file
@@ -0,0 +1,161 @@
|
||||
//
|
||||
// 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
|
||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||
}
|
||||
|
||||
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",
|
||||
],
|
||||
}
|
||||
19
framework/aidl-export/android/net/CaptivePortalData.aidl
Normal file
19
framework/aidl-export/android/net/CaptivePortalData.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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;
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
*
|
||||
* 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;
|
||||
19
framework/aidl-export/android/net/DhcpInfo.aidl
Normal file
19
framework/aidl-export/android/net/DhcpInfo.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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;
|
||||
19
framework/aidl-export/android/net/IpConfiguration.aidl
Normal file
19
framework/aidl-export/android/net/IpConfiguration.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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;
|
||||
22
framework/aidl-export/android/net/IpPrefix.aidl
Normal file
22
framework/aidl-export/android/net/IpPrefix.aidl
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
*
|
||||
* 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;
|
||||
19
framework/aidl-export/android/net/KeepalivePacketData.aidl
Normal file
19
framework/aidl-export/android/net/KeepalivePacketData.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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;
|
||||
21
framework/aidl-export/android/net/LinkAddress.aidl
Normal file
21
framework/aidl-export/android/net/LinkAddress.aidl
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
*
|
||||
* 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;
|
||||
|
||||
20
framework/aidl-export/android/net/LinkProperties.aidl
Normal file
20
framework/aidl-export/android/net/LinkProperties.aidl
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
**
|
||||
** 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;
|
||||
20
framework/aidl-export/android/net/MacAddress.aidl
Normal file
20
framework/aidl-export/android/net/MacAddress.aidl
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
*
|
||||
* 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;
|
||||
20
framework/aidl-export/android/net/Network.aidl
Normal file
20
framework/aidl-export/android/net/Network.aidl
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
**
|
||||
** 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;
|
||||
19
framework/aidl-export/android/net/NetworkAgentConfig.aidl
Normal file
19
framework/aidl-export/android/net/NetworkAgentConfig.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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;
|
||||
21
framework/aidl-export/android/net/NetworkCapabilities.aidl
Normal file
21
framework/aidl-export/android/net/NetworkCapabilities.aidl
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
**
|
||||
** 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;
|
||||
|
||||
19
framework/aidl-export/android/net/NetworkInfo.aidl
Normal file
19
framework/aidl-export/android/net/NetworkInfo.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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;
|
||||
20
framework/aidl-export/android/net/NetworkRequest.aidl
Normal file
20
framework/aidl-export/android/net/NetworkRequest.aidl
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
20
framework/aidl-export/android/net/NetworkScore.aidl
Normal file
20
framework/aidl-export/android/net/NetworkScore.aidl
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
19
framework/aidl-export/android/net/OemNetworkPreferences.aidl
Normal file
19
framework/aidl-export/android/net/OemNetworkPreferences.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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;
|
||||
21
framework/aidl-export/android/net/ProxyInfo.aidl
Normal file
21
framework/aidl-export/android/net/ProxyInfo.aidl
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
**
|
||||
** 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;
|
||||
|
||||
21
framework/aidl-export/android/net/QosFilterParcelable.aidl
Normal file
21
framework/aidl-export/android/net/QosFilterParcelable.aidl
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
**
|
||||
** 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;
|
||||
|
||||
21
framework/aidl-export/android/net/QosSession.aidl
Normal file
21
framework/aidl-export/android/net/QosSession.aidl
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
**
|
||||
** 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;
|
||||
|
||||
21
framework/aidl-export/android/net/QosSocketInfo.aidl
Normal file
21
framework/aidl-export/android/net/QosSocketInfo.aidl
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
**
|
||||
** 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;
|
||||
|
||||
19
framework/aidl-export/android/net/RouteInfo.aidl
Normal file
19
framework/aidl-export/android/net/RouteInfo.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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;
|
||||
20
framework/aidl-export/android/net/StaticIpConfiguration.aidl
Normal file
20
framework/aidl-export/android/net/StaticIpConfiguration.aidl
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
**
|
||||
** 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;
|
||||
20
framework/aidl-export/android/net/TestNetworkInterface.aidl
Normal file
20
framework/aidl-export/android/net/TestNetworkInterface.aidl
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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;
|
||||
20
framework/aidl-export/android/net/apf/ApfCapabilities.aidl
Normal file
20
framework/aidl-export/android/net/apf/ApfCapabilities.aidl
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
**
|
||||
** 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;
|
||||
476
framework/api/current.txt
Normal file
476
framework/api/current.txt
Normal file
@@ -0,0 +1,476 @@
|
||||
// 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 {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
4
framework/api/lint-baseline.txt
Normal file
4
framework/api/lint-baseline.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
// 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()
|
||||
179
framework/api/module-lib-current.txt
Normal file
179
framework/api/module-lib-current.txt
Normal file
@@ -0,0 +1,179 @@
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
1
framework/api/module-lib-removed.txt
Normal file
1
framework/api/module-lib-removed.txt
Normal file
@@ -0,0 +1 @@
|
||||
// Signature format: 2.0
|
||||
11
framework/api/removed.txt
Normal file
11
framework/api/removed.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
// 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
505
framework/api/system-current.txt
Normal file
505
framework/api/system-current.txt
Normal file
@@ -0,0 +1,505 @@
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
1
framework/api/system-lint-baseline.txt
Normal file
1
framework/api/system-lint-baseline.txt
Normal file
@@ -0,0 +1 @@
|
||||
// Baseline format: 1.0
|
||||
1
framework/api/system-removed.txt
Normal file
1
framework/api/system-removed.txt
Normal file
@@ -0,0 +1 @@
|
||||
// Signature format: 2.0
|
||||
2
framework/jarjar-rules.txt
Normal file
2
framework/jarjar-rules.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
rule com.android.net.module.util.** android.net.connectivity.framework.util.@1
|
||||
rule android.net.NetworkFactory* android.net.connectivity.framework.NetworkFactory@1
|
||||
271
framework/jni/android_net_NetworkUtils.cpp
Normal file
271
framework/jni/android_net_NetworkUtils.cpp
Normal file
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* 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
|
||||
38
framework/jni/onload.cpp
Normal file
38
framework/jni/onload.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
};
|
||||
48
framework/lint-baseline.xml
Normal file
48
framework/lint-baseline.xml
Normal file
@@ -0,0 +1,48 @@
|
||||
<?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="packages/modules/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="packages/modules/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="packages/modules/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="packages/modules/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java"
|
||||
line="126"
|
||||
column="54"/>
|
||||
</issue>
|
||||
|
||||
</issues>
|
||||
170
framework/src/android/net/CaptivePortal.java
Normal file
170
framework/src/android/net/CaptivePortal.java
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* 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) {
|
||||
}
|
||||
}
|
||||
379
framework/src/android/net/CaptivePortalData.java
Normal file
379
framework/src/android/net/CaptivePortalData.java
Normal file
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* 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
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
20
framework/src/android/net/ConnectionInfo.aidl
Normal file
20
framework/src/android/net/ConnectionInfo.aidl
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
**
|
||||
** 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;
|
||||
83
framework/src/android/net/ConnectionInfo.java
Normal file
83
framework/src/android/net/ConnectionInfo.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
51
framework/src/android/net/ConnectivityAnnotations.java
Normal file
51
framework/src/android/net/ConnectivityAnnotations.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Type annotations for constants used in the connectivity API surface.
|
||||
*
|
||||
* The annotations are maintained in a separate class so that it can be built as
|
||||
* a separate library that other modules can build against, as Typedef should not
|
||||
* be exposed as SystemApi.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class ConnectivityAnnotations {
|
||||
private ConnectivityAnnotations() {}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(flag = true, value = {
|
||||
ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER,
|
||||
ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY,
|
||||
ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE,
|
||||
})
|
||||
public @interface MultipathPreference {}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(flag = false, value = {
|
||||
ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED,
|
||||
ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED,
|
||||
ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED,
|
||||
})
|
||||
public @interface RestrictBackgroundStatus {}
|
||||
}
|
||||
778
framework/src/android/net/ConnectivityDiagnosticsManager.java
Normal file
778
framework/src/android/net/ConnectivityDiagnosticsManager.java
Normal file
@@ -0,0 +1,778 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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)
|
||||
);
|
||||
}
|
||||
}
|
||||
5459
framework/src/android/net/ConnectivityManager.java
Normal file
5459
framework/src/android/net/ConnectivityManager.java
Normal file
File diff suppressed because it is too large
Load Diff
108
framework/src/android/net/ConnectivityResources.java
Normal file
108
framework/src/android/net/ConnectivityResources.java
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
1087
framework/src/android/net/ConnectivitySettingsManager.java
Normal file
1087
framework/src/android/net/ConnectivitySettingsManager.java
Normal file
File diff suppressed because it is too large
Load Diff
56
framework/src/android/net/ConnectivityThread.java
Normal file
56
framework/src/android/net/ConnectivityThread.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
105
framework/src/android/net/DhcpInfo.java
Normal file
105
framework/src/android/net/DhcpInfo.java
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
577
framework/src/android/net/DnsResolver.java
Normal file
577
framework/src/android/net/DnsResolver.java
Normal file
@@ -0,0 +1,577 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
45
framework/src/android/net/DnsResolverServiceManager.java
Normal file
45
framework/src/android/net/DnsResolverServiceManager.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
26
framework/src/android/net/ICaptivePortal.aidl
Normal file
26
framework/src/android/net/ICaptivePortal.aidl
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
229
framework/src/android/net/IConnectivityManager.aidl
Normal file
229
framework/src/android/net/IConnectivityManager.aidl
Normal file
@@ -0,0 +1,229 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
24
framework/src/android/net/INetworkActivityListener.aidl
Normal file
24
framework/src/android/net/INetworkActivityListener.aidl
Normal file
@@ -0,0 +1,24 @@
|
||||
/* 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();
|
||||
}
|
||||
51
framework/src/android/net/INetworkAgent.aidl
Normal file
51
framework/src/android/net/INetworkAgent.aidl
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
46
framework/src/android/net/INetworkAgentRegistry.aidl
Normal file
46
framework/src/android/net/INetworkAgentRegistry.aidl
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
61
framework/src/android/net/INetworkOfferCallback.aidl
Normal file
61
framework/src/android/net/INetworkOfferCallback.aidl
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
23
framework/src/android/net/IOnCompleteListener.aidl
Normal file
23
framework/src/android/net/IOnCompleteListener.aidl
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
*
|
||||
* 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();
|
||||
}
|
||||
37
framework/src/android/net/IQosCallback.aidl
Normal file
37
framework/src/android/net/IQosCallback.aidl
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
34
framework/src/android/net/ISocketKeepaliveCallback.aidl
Normal file
34
framework/src/android/net/ISocketKeepaliveCallback.aidl
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
39
framework/src/android/net/ITestNetworkManager.aidl
Normal file
39
framework/src/android/net/ITestNetworkManager.aidl
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
88
framework/src/android/net/InetAddressCompat.java
Normal file
88
framework/src/android/net/InetAddressCompat.java
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
65
framework/src/android/net/InetAddresses.java
Normal file
65
framework/src/android/net/InetAddresses.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
66
framework/src/android/net/InvalidPacketException.java
Normal file
66
framework/src/android/net/InvalidPacketException.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
223
framework/src/android/net/IpConfiguration.java
Normal file
223
framework/src/android/net/IpConfiguration.java
Normal file
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
303
framework/src/android/net/IpPrefix.java
Normal file
303
framework/src/android/net/IpPrefix.java
Normal file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
119
framework/src/android/net/KeepalivePacketData.java
Normal file
119
framework/src/android/net/KeepalivePacketData.java
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
|
||||
}
|
||||
549
framework/src/android/net/LinkAddress.java
Normal file
549
framework/src/android/net/LinkAddress.java
Normal file
@@ -0,0 +1,549 @@
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
1823
framework/src/android/net/LinkProperties.java
Normal file
1823
framework/src/android/net/LinkProperties.java
Normal file
File diff suppressed because it is too large
Load Diff
400
framework/src/android/net/MacAddress.java
Normal file
400
framework/src/android/net/MacAddress.java
Normal file
@@ -0,0 +1,400 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
144
framework/src/android/net/NattKeepalivePacketData.java
Normal file
144
framework/src/android/net/NattKeepalivePacketData.java
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
77
framework/src/android/net/NattSocketKeepalive.java
Normal file
77
framework/src/android/net/NattSocketKeepalive.java
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
530
framework/src/android/net/Network.java
Normal file
530
framework/src/android/net/Network.java
Normal file
@@ -0,0 +1,530 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
1324
framework/src/android/net/NetworkAgent.java
Normal file
1324
framework/src/android/net/NetworkAgent.java
Normal file
File diff suppressed because it is too large
Load Diff
505
framework/src/android/net/NetworkAgentConfig.java
Normal file
505
framework/src/android/net/NetworkAgentConfig.java
Normal file
@@ -0,0 +1,505 @@
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
2779
framework/src/android/net/NetworkCapabilities.java
Normal file
2779
framework/src/android/net/NetworkCapabilities.java
Normal file
File diff suppressed because it is too large
Load Diff
80
framework/src/android/net/NetworkConfig.java
Normal file
80
framework/src/android/net/NetworkConfig.java
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
625
framework/src/android/net/NetworkInfo.java
Normal file
625
framework/src/android/net/NetworkInfo.java
Normal file
@@ -0,0 +1,625 @@
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
332
framework/src/android/net/NetworkProvider.java
Normal file
332
framework/src/android/net/NetworkProvider.java
Normal file
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
32
framework/src/android/net/NetworkReleasedException.java
Normal file
32
framework/src/android/net/NetworkReleasedException.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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");
|
||||
}
|
||||
}
|
||||
753
framework/src/android/net/NetworkRequest.java
Normal file
753
framework/src/android/net/NetworkRequest.java
Normal file
@@ -0,0 +1,753 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
328
framework/src/android/net/NetworkScore.java
Normal file
328
framework/src/android/net/NetworkScore.java
Normal file
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
130
framework/src/android/net/NetworkState.java
Normal file
130
framework/src/android/net/NetworkState.java
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
429
framework/src/android/net/NetworkUtils.java
Normal file
429
framework/src/android/net/NetworkUtils.java
Normal file
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
276
framework/src/android/net/OemNetworkPreferences.java
Normal file
276
framework/src/android/net/OemNetworkPreferences.java
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* 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()));
|
||||
}
|
||||
};
|
||||
}
|
||||
37
framework/src/android/net/ParseException.java
Normal file
37
framework/src/android/net/ParseException.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
370
framework/src/android/net/ProxyInfo.java
Normal file
370
framework/src/android/net/ProxyInfo.java
Normal file
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
91
framework/src/android/net/QosCallback.java
Normal file
91
framework/src/android/net/QosCallback.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
148
framework/src/android/net/QosCallbackConnection.java
Normal file
148
framework/src/android/net/QosCallbackConnection.java
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
110
framework/src/android/net/QosCallbackException.java
Normal file
110
framework/src/android/net/QosCallbackException.java
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
86
framework/src/android/net/QosFilter.java
Normal file
86
framework/src/android/net/QosFilter.java
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
113
framework/src/android/net/QosFilterParcelable.java
Normal file
113
framework/src/android/net/QosFilterParcelable.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
142
framework/src/android/net/QosSession.java
Normal file
142
framework/src/android/net/QosSession.java
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
30
framework/src/android/net/QosSessionAttributes.java
Normal file
30
framework/src/android/net/QosSessionAttributes.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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 {
|
||||
}
|
||||
179
framework/src/android/net/QosSocketFilter.java
Normal file
179
framework/src/android/net/QosSocketFilter.java
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
190
framework/src/android/net/QosSocketInfo.java
Normal file
190
framework/src/android/net/QosSocketInfo.java
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
659
framework/src/android/net/RouteInfo.java
Normal file
659
framework/src/android/net/RouteInfo.java
Normal file
@@ -0,0 +1,659 @@
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user