Merge "Remove location-permission check from VcnStatusCallbacks."
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 1644a55..ba9c250 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -268,6 +268,36 @@
// from stub sources
/////////////////////////////////////////////////////////////////////
+modules_public_stubs = [
+ "android.net.ipsec.ike.stubs",
+ "art.module.public.api.stubs",
+ "conscrypt.module.public.api.stubs",
+ "framework-connectivity.stubs",
+ "framework-media.stubs",
+ "framework-mediaprovider.stubs",
+ "framework-permission.stubs",
+ "framework-sdkextensions.stubs",
+ "framework-statsd.stubs",
+ "framework-tethering.stubs",
+ "framework-wifi.stubs",
+ "i18n.module.public.api.stubs",
+]
+
+modules_system_stubs = [
+ "android.net.ipsec.ike.stubs.system",
+ "art.module.public.api.stubs", // Only has public stubs
+ "conscrypt.module.public.api.stubs", // Only has public stubs
+ "framework-connectivity.stubs.system",
+ "framework-media.stubs.system",
+ "framework-mediaprovider.stubs.system",
+ "framework-permission.stubs.system",
+ "framework-sdkextensions.stubs.system",
+ "framework-statsd.stubs.system",
+ "framework-tethering.stubs.system",
+ "framework-wifi.stubs.system",
+ "i18n.module.public.api.stubs", // Only has public stubs
+]
+
java_defaults {
name: "android_defaults_stubs_current",
libs: [ "stub-annotations" ],
@@ -299,19 +329,7 @@
java_library_static {
name: "android_stubs_current",
srcs: [ ":api-stubs-docs-non-updatable" ],
- static_libs: [
- "android.net.ipsec.ike.stubs",
- "art.module.public.api.stubs",
- "conscrypt.module.public.api.stubs",
- "framework-connectivity.stubs",
- "framework-media.stubs",
- "framework-mediaprovider.stubs",
- "framework-permission.stubs",
- "framework-sdkextensions.stubs",
- "framework-statsd.stubs",
- "framework-tethering.stubs",
- "framework-wifi.stubs",
- "i18n.module.public.api.stubs",
+ static_libs: modules_public_stubs + [
"private-stub-annotations-jar",
],
defaults: ["android_defaults_stubs_current"],
@@ -320,19 +338,7 @@
java_library_static {
name: "android_system_stubs_current",
srcs: [ ":system-api-stubs-docs-non-updatable" ],
- static_libs: [
- "android.net.ipsec.ike.stubs.system",
- "art.module.public.api.stubs",
- "conscrypt.module.public.api.stubs",
- "framework-connectivity.stubs.system",
- "framework-media.stubs.system",
- "framework-mediaprovider.stubs.system",
- "framework-permission.stubs.system",
- "framework-sdkextensions.stubs.system",
- "framework-statsd.stubs.system",
- "framework-tethering.stubs.system",
- "framework-wifi.stubs.system",
- "i18n.module.public.api.stubs",
+ static_libs: modules_system_stubs + [
"private-stub-annotations-jar",
],
defaults: [
@@ -355,21 +361,9 @@
java_library_static {
name: "android_test_stubs_current",
srcs: [ ":test-api-stubs-docs-non-updatable" ],
- static_libs: [
- // Modules do not have test APIs, but we want to include their SystemApis, like we include
- // the SystemApi of framework-non-updatable-sources.
- "android.net.ipsec.ike.stubs.system",
- "art.module.public.api.stubs",
- "conscrypt.module.public.api.stubs",
- "framework-connectivity.stubs.system",
- "framework-media.stubs.system",
- "framework-mediaprovider.stubs.system",
- "framework-permission.stubs.system",
- "framework-sdkextensions.stubs.system",
- "framework-statsd.stubs.system",
- "framework-tethering.stubs.system",
- "framework-wifi.stubs.system",
- "i18n.module.public.api.stubs",
+ // Modules do not have test APIs, but we want to include their SystemApis, like we include
+ // the SystemApi of framework-non-updatable-sources.
+ static_libs: modules_system_stubs + [
"private-stub-annotations-jar",
],
defaults: [
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index a522237..5487e87 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -693,13 +693,6 @@
StateControllerProto.ConnectivityController.REQUESTED_STANDBY_EXCEPTION_UIDS,
mRequestedWhitelistJobs.keyAt(i));
}
- for (int i = 0; i < mAvailableNetworks.size(); i++) {
- Network network = mAvailableNetworks.keyAt(i);
- if (network != null) {
- network.dumpDebug(proto,
- StateControllerProto.ConnectivityController.AVAILABLE_NETWORKS);
- }
- }
for (int i = 0; i < mTrackedJobs.size(); i++) {
final ArraySet<JobStatus> jobs = mTrackedJobs.valueAt(i);
for (int j = 0; j < jobs.size(); j++) {
@@ -713,12 +706,6 @@
StateControllerProto.ConnectivityController.TrackedJob.INFO);
proto.write(StateControllerProto.ConnectivityController.TrackedJob.SOURCE_UID,
js.getSourceUid());
- NetworkRequest rn = js.getJob().getRequiredNetwork();
- if (rn != null) {
- rn.dumpDebug(proto,
- StateControllerProto.ConnectivityController.TrackedJob
- .REQUIRED_NETWORK);
- }
proto.end(jsToken);
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index ea8e7bc..a346812 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -1911,9 +1911,6 @@
if (uriPerms != null) {
uriPerms.dump(proto, JobStatusDumpProto.JobInfo.GRANTED_URI_PERMISSIONS);
}
- if (job.getRequiredNetwork() != null) {
- job.getRequiredNetwork().dumpDebug(proto, JobStatusDumpProto.JobInfo.REQUIRED_NETWORK);
- }
if (mTotalNetworkDownloadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
proto.write(JobStatusDumpProto.JobInfo.TOTAL_NETWORK_DOWNLOAD_BYTES,
mTotalNetworkDownloadBytes);
@@ -2002,10 +1999,6 @@
}
}
- if (network != null) {
- network.dumpDebug(proto, JobStatusDumpProto.NETWORK);
- }
-
if (pendingWork != null) {
for (int i = 0; i < pendingWork.size(); i++) {
dumpJobWorkItem(proto, JobStatusDumpProto.PENDING_WORK, pendingWork.get(i));
diff --git a/api/dump_api_shas.sh b/api/dump_api_shas.sh
new file mode 100755
index 0000000..c023b31
--- /dev/null
+++ b/api/dump_api_shas.sh
@@ -0,0 +1,56 @@
+#!/bin/bash -e
+# This script dumps the git SHAs of all commits inside api tracking directories.
+# It can used by tools wanting to track API changes, and the primary original
+# purpose is to verify verify all API change SHAs have been tracked by the
+# server-side API-council tools.
+#
+# The only argument is used to specify a git commit range to filter by.
+#
+# Example invocation (API changes between O and P):
+# frameworks/base/api/dump_api_shas.sh origin/oreo-dev..origin/pie-dev
+
+set -o pipefail
+
+eecho() { echo $@ >&2 ; }
+
+if [[ $1 == *..* ]]; then
+ exclude=${1/..*}
+ include=${1/*..}
+else
+ eecho No range or invalid range specified, defaulting to all commits from HEAD.
+ exclude=
+ include=HEAD
+fi
+
+eecho -n building queryview...
+{ source build/envsetup.sh && lunch aosp_arm && m queryview; } >/dev/null 2>&1 \
+ || { eecho failed; exit 1; }
+eecho "done"
+
+# This finds the directories where the dependant java_sdk_libs are defined
+bpdirs=$(
+ bazel query --config=queryview --output=package \
+ 'kind(java_sdk_library, deps(//frameworks/base/api/..., 1))' 2>/dev/null
+ echo frameworks/base/core/api # Not a java_sdk_library.
+ echo frameworks/base/services/api # Not a java_sdk_library.
+)
+
+# Find relevant api subdirectories
+apidirs=$(
+ find $bpdirs -type f -name '*current.txt' -path '*/api/*' \
+ | xargs realpath --relative-to=$(pwd) | xargs dirname | sort | uniq
+)
+
+# Dump sorted SHAs of commits in these directories
+{ for d in $apidirs; do
+ ( cd $d
+ eecho inspecting $d
+ exclude_arg=$(test -n "$exclude" && {
+ git rev-parse -q --verify $exclude > /dev/null && echo "--not $exclude" \
+ || eecho "$d has no revision $exclude, including all commits"; } || true)
+ for f in $(find . -name '*current.txt'); do
+ git --no-pager log --pretty=format:%H --no-merges --follow $include $exclude_arg -- $f
+ echo # No trailing newline with --no-pager
+ done
+ )
+done; } | sort | uniq
diff --git a/config/OWNERS b/config/OWNERS
index 001038d..0691dbc 100644
--- a/config/OWNERS
+++ b/config/OWNERS
@@ -1,14 +1,8 @@
include /ZYGOTE_OWNERS
-# compat-team@ for changes to hiddenapi files
-
-per-file hiddenapi-* = andreionea@google.com, mathewi@google.com, satayev@google.com
-
# art-team@ manages the boot image profiles
per-file boot-* = calin@google.com, mathieuc@google.com, ngeoffray@google.com
per-file dirty-image-objects = calin@google.com, mathieuc@google.com, ngeoffray@google.com
per-file generate-preloaded-classes.sh = calin@google.com, mathieuc@google.com, ngeoffray@google.com
per-file preloaded-classes* = calin@google.com, mathieuc@google.com, ngeoffray@google.com
-# Escalations:
-per-file hiddenapi-* = bdc@google.com, narayan@google.com
diff --git a/core/api/current.txt b/core/api/current.txt
index 5a2b8bd..cc425f0 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -29284,7 +29284,6 @@
field public static final String HARDWARE;
field public static final String HOST;
field public static final String ID;
- field public static final boolean IS_DEBUGGABLE;
field public static final String MANUFACTURER;
field public static final String MODEL;
field @NonNull public static final String ODM_SKU;
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index fe8b9d6..e7a7fd2 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -27,10 +27,6 @@
field public static final String TEST_NETWORK_SERVICE = "test_network";
}
- public class Intent implements java.lang.Cloneable android.os.Parcelable {
- field public static final String ACTION_CLEAR_DNS_CACHE = "android.intent.action.CLEAR_DNS_CACHE";
- }
-
}
package android.net {
@@ -121,6 +117,10 @@
method public final void markVintfStability();
}
+ public class Build {
+ method public static boolean isDebuggable();
+ }
+
public static class Build.VERSION {
field public static final int FIRST_SDK_INT;
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index e31f174..db50f0b 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -8123,7 +8123,7 @@
}
public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
- method @Nullable public int[] getAttestationIds();
+ method @NonNull public int[] getAttestationIds();
method public int getNamespace();
}
@@ -12499,7 +12499,7 @@
public final class DistanceMeasurement implements android.os.Parcelable {
method public int describeContents();
method @FloatRange(from=0.0, to=1.0) public double getConfidenceLevel();
- method public double getErrorMeters();
+ method @FloatRange(from=0.0) public double getErrorMeters();
method public double getMeters();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.uwb.DistanceMeasurement> CREATOR;
@@ -12508,8 +12508,8 @@
public static final class DistanceMeasurement.Builder {
ctor public DistanceMeasurement.Builder();
method @NonNull public android.uwb.DistanceMeasurement build();
- method @NonNull public android.uwb.DistanceMeasurement.Builder setConfidenceLevel(double);
- method @NonNull public android.uwb.DistanceMeasurement.Builder setErrorMeters(double);
+ method @NonNull public android.uwb.DistanceMeasurement.Builder setConfidenceLevel(@FloatRange(from=0.0, to=1.0) double);
+ method @NonNull public android.uwb.DistanceMeasurement.Builder setErrorMeters(@FloatRange(from=0.0) double);
method @NonNull public android.uwb.DistanceMeasurement.Builder setMeters(double);
}
@@ -12568,7 +12568,7 @@
method public void onStartFailed(int, @NonNull android.os.PersistableBundle);
method public void onStarted(@NonNull android.os.PersistableBundle);
method public void onStopFailed(int, @NonNull android.os.PersistableBundle);
- method public void onStopped();
+ method public void onStopped(int, @NonNull android.os.PersistableBundle);
field public static final int REASON_BAD_PARAMETERS = 3; // 0x3
field public static final int REASON_GENERIC_ERROR = 4; // 0x4
field public static final int REASON_LOCAL_REQUEST = 1; // 0x1
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 0c57f4e..f7b101d 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1022,6 +1022,7 @@
public class Build {
method public static boolean is64BitAbi(String);
+ method public static boolean isDebuggable();
field public static final boolean IS_EMULATOR;
}
diff --git a/core/java/android/app/IUidObserver.aidl b/core/java/android/app/IUidObserver.aidl
index 7713e25..74018a8 100644
--- a/core/java/android/app/IUidObserver.aidl
+++ b/core/java/android/app/IUidObserver.aidl
@@ -24,7 +24,7 @@
// below block of transactions.
// Since these transactions are also called from native code, these must be kept in sync with
- // the ones in frameworks/native/include/binder/IActivityManager.h
+ // the ones in frameworks/native/include_activitymanager/binder/IActivityManager.h
// =============== Beginning of transactions used on native side as well ======================
/**
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 4d68e90..0fad63f 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2324,14 +2324,6 @@
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_TIMEZONE_CHANGED = "android.intent.action.TIMEZONE_CHANGED";
/**
- * Clear DNS Cache Action: This is broadcast when networks have changed and old
- * DNS entries should be tossed.
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static final String ACTION_CLEAR_DNS_CACHE = "android.intent.action.CLEAR_DNS_CACHE";
- /**
* Alarm Changed Action: This is broadcast when the AlarmClock
* application's alarm is set or unset. It is used by the
* AlarmClock application and the StatusBar service.
diff --git a/core/java/android/net/EthernetNetworkSpecifier.java b/core/java/android/net/EthernetNetworkSpecifier.java
index e168588..62c5761 100644
--- a/core/java/android/net/EthernetNetworkSpecifier.java
+++ b/core/java/android/net/EthernetNetworkSpecifier.java
@@ -42,15 +42,22 @@
@NonNull
private final String mInterfaceName;
+ /**
+ * Create a new EthernetNetworkSpecifier.
+ * @param interfaceName Name of the ethernet interface the specifier refers to.
+ */
public EthernetNetworkSpecifier(@NonNull String interfaceName) {
Preconditions.checkStringNotEmpty(interfaceName);
mInterfaceName = interfaceName;
}
- // This may be null in the future to support specifiers based on data other than the interface
- // name.
+ /**
+ * Get the name of the ethernet interface the specifier refers to.
+ */
@Nullable
public String getInterfaceName() {
+ // This may be null in the future to support specifiers based on data other than the
+ // interface name.
return mInterfaceName;
}
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 03caafd..e47ffcc 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1309,10 +1309,25 @@
* Debuggable builds allow users to gain root access via local shell, attach debuggers to any
* application regardless of whether they have the "debuggable" attribute set, or downgrade
* selinux into "permissive" mode in particular.
+ * @hide
*/
public static final boolean IS_DEBUGGABLE =
SystemProperties.getInt("ro.debuggable", 0) == 1;
+ /**
+ * Returns true if the device is running a debuggable build such as "userdebug" or "eng".
+ *
+ * Debuggable builds allow users to gain root access via local shell, attach debuggers to any
+ * application regardless of whether they have the "debuggable" attribute set, or downgrade
+ * selinux into "permissive" mode in particular.
+ * @hide
+ */
+ @TestApi
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static boolean isDebuggable() {
+ return IS_DEBUGGABLE;
+ }
+
/** {@hide} */
public static final boolean IS_ENG = "eng".equals(TYPE);
/** {@hide} */
diff --git a/core/java/android/uwb/DistanceMeasurement.java b/core/java/android/uwb/DistanceMeasurement.java
index 2a9bbdf..9856553 100644
--- a/core/java/android/uwb/DistanceMeasurement.java
+++ b/core/java/android/uwb/DistanceMeasurement.java
@@ -60,6 +60,7 @@
*
* @return error of distance measurement in meters
*/
+ @FloatRange(from = 0.0)
public double getErrorMeters() {
return mErrorMeters;
}
@@ -162,7 +163,7 @@
* @throws IllegalArgumentException if error is negative or NaN
*/
@NonNull
- public Builder setErrorMeters(double errorMeters) {
+ public Builder setErrorMeters(@FloatRange(from = 0.0) double errorMeters) {
if (Double.isNaN(errorMeters) || errorMeters < 0.0) {
throw new IllegalArgumentException(
"errorMeters must be >= 0.0 and not NaN: " + errorMeters);
@@ -178,7 +179,8 @@
* @throws IllegalArgumentException if confidence level is not in the range of [0.0, 1.0]
*/
@NonNull
- public Builder setConfidenceLevel(double confidenceLevel) {
+ public Builder setConfidenceLevel(
+ @FloatRange(from = 0.0, to = 1.0) double confidenceLevel) {
if (confidenceLevel < 0.0 || confidenceLevel > 1.0) {
throw new IllegalArgumentException(
"confidenceLevel must be in the range [0.0, 1.0]: " + confidenceLevel);
diff --git a/core/java/android/uwb/IUwbAdapter.aidl b/core/java/android/uwb/IUwbAdapter.aidl
index 4036892..30da248 100644
--- a/core/java/android/uwb/IUwbAdapter.aidl
+++ b/core/java/android/uwb/IUwbAdapter.aidl
@@ -160,14 +160,4 @@
* closed.
*/
const int RANGING_SESSION_CLOSE_THRESHOLD_MS = 3000; // Value TBD
-
- /**
- * Ranging scheduling time unit (RSTU) for High Rate Pulse (HRP) PHY
- */
- const int HIGH_RATE_PULSE_CHIRPS_PER_RSTU = 416;
-
- /**
- * Ranging scheduling time unit (RSTU) for Low Rate Pulse (LRP) PHY
- */
- const int LOW_RATE_PULSE_CHIRPS_PER_RSTU = 1;
}
diff --git a/core/java/android/uwb/IUwbRangingCallbacks.aidl b/core/java/android/uwb/IUwbRangingCallbacks.aidl
index f71f3ff..f15debb 100644
--- a/core/java/android/uwb/IUwbRangingCallbacks.aidl
+++ b/core/java/android/uwb/IUwbRangingCallbacks.aidl
@@ -92,9 +92,13 @@
* Called when the ranging session has been stopped
*
* @param sessionHandle the session the callback is being invoked for
+ * @param reason the reason the session was stopped
+ * @param parameters protocol specific parameters
*/
- void onRangingStopped(in SessionHandle sessionHandle);
+ void onRangingStopped(in SessionHandle sessionHandle,
+ RangingChangeReason reason,
+ in PersistableBundle parameters);
/**
* Called when a ranging session fails to stop
diff --git a/core/java/android/uwb/RangingManager.java b/core/java/android/uwb/RangingManager.java
index 85f2c1c..e2c64a7 100644
--- a/core/java/android/uwb/RangingManager.java
+++ b/core/java/android/uwb/RangingManager.java
@@ -165,7 +165,8 @@
}
@Override
- public void onRangingStopped(SessionHandle sessionHandle) {
+ public void onRangingStopped(SessionHandle sessionHandle, @RangingChangeReason int reason,
+ PersistableBundle params) {
synchronized (this) {
if (!hasSession(sessionHandle)) {
Log.w(TAG, "onRangingStopped - received unexpected SessionHandle: "
@@ -174,7 +175,7 @@
}
RangingSession session = mRangingSessionTable.get(sessionHandle);
- session.onRangingStopped();
+ session.onRangingStopped(convertToReason(reason), params);
}
}
diff --git a/core/java/android/uwb/RangingSession.java b/core/java/android/uwb/RangingSession.java
index 52ec5bd..345b69d 100644
--- a/core/java/android/uwb/RangingSession.java
+++ b/core/java/android/uwb/RangingSession.java
@@ -191,8 +191,11 @@
/**
* Invoked when a request to stop the session succeeds
+ *
+ * @param reason reason for the session stop
+ * @param parameters protocol specific parameters related to the stop reason
*/
- void onStopped();
+ void onStopped(@Reason int reason, @NonNull PersistableBundle parameters);
/**
* Invoked when a request to stop the session fails
@@ -434,14 +437,15 @@
/**
* @hide
*/
- public void onRangingStopped() {
+ public void onRangingStopped(@Callback.Reason int reason,
+ @NonNull PersistableBundle params) {
if (mState == State.CLOSED) {
Log.w(TAG, "onRangingStopped invoked for a closed session");
return;
}
mState = State.IDLE;
- executeCallback(() -> mCallback.onStopped());
+ executeCallback(() -> mCallback.onStopped(reason, params));
}
/**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 24ade39..cc4e2bb 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -332,7 +332,7 @@
<protected-broadcast android:name="android.nfc.handover.intent.action.HANDOVER_SEND_MULTIPLE" />
<protected-broadcast android:name="com.android.nfc.handover.action.CANCEL_HANDOVER_TRANSFER" />
- <protected-broadcast android:name="android.intent.action.CLEAR_DNS_CACHE" />
+ <protected-broadcast android:name="android.net.action.CLEAR_DNS_CACHE" />
<protected-broadcast android:name="android.intent.action.PROXY_CHANGE" />
<protected-broadcast android:name="android.os.UpdateLock.UPDATE_LOCK_CHANGED" />
diff --git a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
index e41805d..21ef083 100644
--- a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
+++ b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
@@ -123,8 +123,8 @@
rangingManager.onRangingReconfigureFailed(handle, REASON, PARAMS);
verify(callback, times(1)).onReconfigureFailed(eq(REASON), eq(PARAMS));
- rangingManager.onRangingStopped(handle);
- verify(callback, times(1)).onStopped();
+ rangingManager.onRangingStopped(handle, REASON, PARAMS);
+ verify(callback, times(1)).onStopped(eq(REASON), eq(PARAMS));
rangingManager.onRangingStopFailed(handle, REASON, PARAMS);
verify(callback, times(1)).onStopFailed(eq(REASON), eq(PARAMS));
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 43fdedc..aef68d0 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -410,6 +410,7 @@
<permission name="android.permission.LOG_COMPAT_CHANGE" />
<permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
<permission name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG" />
+ <permission name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD" />
<!-- Permissions required to test ambient display. -->
<permission name="android.permission.READ_DREAM_STATE" />
<permission name="android.permission.WRITE_DREAM_STATE" />
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 1f9022b..a6aa4f2 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -353,7 +353,7 @@
boolean userPresenceRequired,
byte[] attestationChallenge,
boolean devicePropertiesAttestationIncluded,
- int[] attestationIds,
+ @NonNull int[] attestationIds,
boolean uniqueIdIncluded,
boolean userAuthenticationValidWhileOnBody,
boolean invalidatedByBiometricEnrollment,
@@ -779,9 +779,8 @@
* @return integer array representing the requested device IDs to attest.
*/
@SystemApi
- @Nullable
- public int[] getAttestationIds() {
- return Utils.cloneIfNotNull(mAttestationIds);
+ public @NonNull int[] getAttestationIds() {
+ return mAttestationIds.clone();
}
/**
@@ -911,7 +910,7 @@
private boolean mUserPresenceRequired = false;
private byte[] mAttestationChallenge = null;
private boolean mDevicePropertiesAttestationIncluded = false;
- private int[] mAttestationIds = null;
+ private int[] mAttestationIds = new int[0];
private boolean mUniqueIdIncluded = false;
private boolean mUserAuthenticationValidWhileOnBody;
private boolean mInvalidatedByBiometricEnrollment = true;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index c26d9f583..dc7f3dd 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -655,7 +655,7 @@
}
int[] idTypes = mSpec.getAttestationIds();
- if (idTypes == null) {
+ if (idTypes.length == 0) {
return;
}
final Set<Integer> idTypesSet = new ArraySet<>(idTypes.length);
diff --git a/native/android/Android.bp b/native/android/Android.bp
index d1dddbd..34b9fce 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -77,6 +77,7 @@
"libgui",
"libharfbuzz_ng", // Only for including hb.h via minikin
"libsensor",
+ "libactivitymanager_aidl",
"libandroid_runtime",
"libminikin",
"libnetd_client",
diff --git a/packages/Connectivity/framework/api/current.txt b/packages/Connectivity/framework/api/current.txt
index ab290f9..7692e30 100644
--- a/packages/Connectivity/framework/api/current.txt
+++ b/packages/Connectivity/framework/api/current.txt
@@ -410,6 +410,8 @@
}
public class ParseException extends java.lang.RuntimeException {
+ ctor public ParseException(@NonNull String);
+ ctor public ParseException(@NonNull String, @NonNull Throwable);
field public String response;
}
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
index 513b630..caf7f49 100644
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -26,6 +26,7 @@
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";
@@ -132,11 +133,6 @@
method @NonNull public android.net.NetworkRequest.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
}
- public class ParseException extends java.lang.RuntimeException {
- ctor public ParseException(@NonNull String);
- ctor public ParseException(@NonNull String, @NonNull Throwable);
- }
-
public final class TcpRepairWindow {
ctor public TcpRepairWindow(int, int, int, int, int, int);
field public final int maxWindow;
@@ -157,10 +153,10 @@
}
public class TestNetworkManager {
- method @NonNull public android.net.TestNetworkInterface createTapInterface();
- method @NonNull public android.net.TestNetworkInterface createTunInterface(@NonNull java.util.Collection<android.net.LinkAddress>);
- method public void setupTestNetwork(@NonNull String, @NonNull android.os.IBinder);
- method public void teardownTestNetwork(@NonNull android.net.Network);
+ 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";
}
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
index 0a82cb7..d6d3888 100644
--- a/packages/Connectivity/framework/api/system-current.txt
+++ b/packages/Connectivity/framework/api/system-current.txt
@@ -455,14 +455,14 @@
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;
- field public final int ipTos;
- field public final int ipTtl;
- field public final int tcpAck;
- field public final int tcpSeq;
- field public final int tcpWindow;
- field public final int tcpWindowScale;
}
}
diff --git a/packages/Connectivity/framework/src/android/net/CaptivePortalData.java b/packages/Connectivity/framework/src/android/net/CaptivePortalData.java
index 82dbd0f..53aa1b9 100644
--- a/packages/Connectivity/framework/src/android/net/CaptivePortalData.java
+++ b/packages/Connectivity/framework/src/android/net/CaptivePortalData.java
@@ -42,7 +42,7 @@
private final long mByteLimit;
private final long mExpiryTimeMillis;
private final boolean mCaptive;
- private final CharSequence mVenueFriendlyName;
+ private final String mVenueFriendlyName;
private final int mVenueInfoUrlSource;
private final int mUserPortalUrlSource;
@@ -73,14 +73,14 @@
mByteLimit = byteLimit;
mExpiryTimeMillis = expiryTimeMillis;
mCaptive = captive;
- mVenueFriendlyName = venueFriendlyName;
+ 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.readCharSequence(), p.readInt(),
+ p.readLong(), p.readLong(), p.readBoolean(), p.readString(), p.readInt(),
p.readInt());
}
@@ -98,7 +98,7 @@
dest.writeLong(mByteLimit);
dest.writeLong(mExpiryTimeMillis);
dest.writeBoolean(mCaptive);
- dest.writeCharSequence(mVenueFriendlyName);
+ dest.writeString(mVenueFriendlyName);
dest.writeInt(mVenueInfoUrlSource);
dest.writeInt(mUserPortalUrlSource);
}
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index 84914a1..0418450 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -44,6 +44,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.net.ConnectivityDiagnosticsManager.DataStallReport.DetectionMethod;
import android.net.IpSecManager.UdpEncapsulationSocket;
import android.net.SocketKeepalive.Callback;
import android.net.TetheringManager.StartTetheringCallback;
@@ -450,6 +451,15 @@
"android.net.action.PROMPT_PARTIAL_CONNECTIVITY";
/**
+ * Clear DNS Cache Action: This is broadcast when networks have changed and old
+ * DNS entries should be cleared.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final String ACTION_CLEAR_DNS_CACHE = "android.net.action.CLEAR_DNS_CACHE";
+
+ /**
* Invalid tethering type.
* @see #startTethering(int, boolean, OnStartTetheringCallback)
* @hide
@@ -5095,10 +5105,13 @@
*
* <p>This method should only be used for tests.
*
- * <p>The caller must be the owner of the specified Network.
+ * <p>The caller must be the owner of the specified Network. This simulates a data stall to
+ * have the system behave as if it had happened, but does not actually stall connectivity.
*
* @param detectionMethod The detection method used to identify the Data Stall.
- * @param timestampMillis The timestamp at which the stall 'occurred', in milliseconds.
+ * See ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_*.
+ * @param timestampMillis The timestamp at which the stall 'occurred', in milliseconds, as per
+ * SystemClock.elapsedRealtime.
* @param network The Network for which a Data Stall is being simluated.
* @param extras The PersistableBundle of extras included in the Data Stall notification.
* @throws SecurityException if the caller is not the owner of the given network.
@@ -5107,7 +5120,7 @@
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_TEST_NETWORKS,
android.Manifest.permission.NETWORK_STACK})
- public void simulateDataStall(int detectionMethod, long timestampMillis,
+ public void simulateDataStall(@DetectionMethod int detectionMethod, long timestampMillis,
@NonNull Network network, @NonNull PersistableBundle extras) {
try {
mService.simulateDataStall(detectionMethod, timestampMillis, network, extras);
diff --git a/packages/Connectivity/framework/src/android/net/Network.java b/packages/Connectivity/framework/src/android/net/Network.java
index 0741414..41fad63 100644
--- a/packages/Connectivity/framework/src/android/net/Network.java
+++ b/packages/Connectivity/framework/src/android/net/Network.java
@@ -27,7 +27,6 @@
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
-import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.GuardedBy;
@@ -526,11 +525,4 @@
public String toString() {
return Integer.toString(netId);
}
-
- /** @hide */
- public void dumpDebug(ProtoOutputStream proto, long fieldId) {
- final long token = proto.start(fieldId);
- proto.write(NetworkProto.NET_ID, netId);
- proto.end(token);
- }
}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
index 9a75f0b..a43dd15 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
@@ -35,7 +35,6 @@
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Range;
-import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import com.android.net.module.util.CollectionUtils;
@@ -2060,34 +2059,6 @@
}
}
- /** @hide */
- public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
- final long token = proto.start(fieldId);
-
- for (int transport : getTransportTypes()) {
- proto.write(NetworkCapabilitiesProto.TRANSPORTS, transport);
- }
-
- for (int capability : getCapabilities()) {
- proto.write(NetworkCapabilitiesProto.CAPABILITIES, capability);
- }
-
- proto.write(NetworkCapabilitiesProto.LINK_UP_BANDWIDTH_KBPS, mLinkUpBandwidthKbps);
- proto.write(NetworkCapabilitiesProto.LINK_DOWN_BANDWIDTH_KBPS, mLinkDownBandwidthKbps);
-
- if (mNetworkSpecifier != null) {
- proto.write(NetworkCapabilitiesProto.NETWORK_SPECIFIER, mNetworkSpecifier.toString());
- }
- if (mTransportInfo != null) {
- // TODO b/120653863: write transport-specific info to proto?
- }
-
- proto.write(NetworkCapabilitiesProto.CAN_REPORT_SIGNAL_STRENGTH, hasSignalStrength());
- proto.write(NetworkCapabilitiesProto.SIGNAL_STRENGTH, mSignalStrength);
-
- proto.end(token);
- }
-
/**
* @hide
*/
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index 5d40417..3a8a07a 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
@@ -47,7 +47,6 @@
import android.os.Process;
import android.text.TextUtils;
import android.util.Range;
-import android.util.proto.ProtoOutputStream;
import java.util.Arrays;
import java.util.List;
@@ -680,18 +679,6 @@
}
}
- /** @hide */
- public void dumpDebug(ProtoOutputStream proto, long fieldId) {
- final long token = proto.start(fieldId);
-
- proto.write(NetworkRequestProto.TYPE, typeToProtoEnum(type));
- proto.write(NetworkRequestProto.REQUEST_ID, requestId);
- proto.write(NetworkRequestProto.LEGACY_TYPE, legacyType);
- networkCapabilities.dumpDebug(proto, NetworkRequestProto.NETWORK_CAPABILITIES);
-
- proto.end(token);
- }
-
public boolean equals(@Nullable Object obj) {
if (obj instanceof NetworkRequest == false) return false;
NetworkRequest that = (NetworkRequest)obj;
diff --git a/packages/Connectivity/framework/src/android/net/OemNetworkPreferences.java b/packages/Connectivity/framework/src/android/net/OemNetworkPreferences.java
index 5a76cd6..2bb006d 100644
--- a/packages/Connectivity/framework/src/android/net/OemNetworkPreferences.java
+++ b/packages/Connectivity/framework/src/android/net/OemNetworkPreferences.java
@@ -40,6 +40,23 @@
*/
@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.
*/
@@ -69,6 +86,12 @@
*/
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;
@@ -96,7 +119,7 @@
@Override
public String toString() {
- return "OemNetworkPreferences{" + "mNetworkMappings=" + mNetworkMappings + '}';
+ return "OemNetworkPreferences{" + "mNetworkMappings=" + getNetworkPreferences() + '}';
}
@Override
@@ -185,6 +208,8 @@
/** @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,
@@ -205,6 +230,10 @@
@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:
diff --git a/packages/Connectivity/framework/src/android/net/ParseException.java b/packages/Connectivity/framework/src/android/net/ParseException.java
index ca6d012..9d4727a 100644
--- a/packages/Connectivity/framework/src/android/net/ParseException.java
+++ b/packages/Connectivity/framework/src/android/net/ParseException.java
@@ -17,7 +17,6 @@
package android.net;
import android.annotation.NonNull;
-import android.annotation.SystemApi;
/**
* Thrown when parsing failed.
@@ -26,15 +25,11 @@
public class ParseException extends RuntimeException {
public String response;
- /** @hide */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public ParseException(@NonNull String response) {
super(response);
this.response = response;
}
- /** @hide */
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public ParseException(@NonNull String response, @NonNull Throwable cause) {
super(response, cause);
this.response = response;
diff --git a/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java b/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java
index ddb3a6a7..c2c4f32 100644
--- a/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java
+++ b/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java
@@ -32,22 +32,39 @@
public final class TcpKeepalivePacketData extends KeepalivePacketData implements Parcelable {
private static final String TAG = "TcpKeepalivePacketData";
- /** TCP sequence number. */
+ /**
+ * TCP sequence number.
+ * @hide
+ */
public final int tcpSeq;
- /** TCP ACK number. */
+ /**
+ * TCP ACK number.
+ * @hide
+ */
public final int tcpAck;
- /** TCP RCV window. */
+ /**
+ * TCP RCV window.
+ * @hide
+ */
public final int tcpWindow;
- /** TCP RCV window scale. */
+ /** TCP RCV window scale.
+ * @hide
+ */
public final int tcpWindowScale;
- /** IP TOS. */
+ /**
+ * IP TOS.
+ * @hide
+ */
public final int ipTos;
- /** IP TTL. */
+ /**
+ * IP TTL.
+ * @hide
+ */
public final int ipTtl;
public TcpKeepalivePacketData(@NonNull final InetAddress srcAddress, int srcPort,
@@ -63,6 +80,56 @@
this.ipTtl = ipTtl;
}
+ /**
+ * Get the TCP sequence number.
+ *
+ * See https://tools.ietf.org/html/rfc793#page-15.
+ */
+ public int getTcpSeq() {
+ return tcpSeq;
+ }
+
+ /**
+ * Get the TCP ACK number.
+ *
+ * See https://tools.ietf.org/html/rfc793#page-15.
+ */
+ public int getTcpAck() {
+ return tcpAck;
+ }
+
+ /**
+ * Get the TCP RCV window.
+ *
+ * See https://tools.ietf.org/html/rfc793#page-15.
+ */
+ public int getTcpWindow() {
+ return tcpWindow;
+ }
+
+ /**
+ * Get the TCP RCV window scale.
+ *
+ * See https://tools.ietf.org/html/rfc793#page-15.
+ */
+ public int getTcpWindowScale() {
+ return tcpWindowScale;
+ }
+
+ /**
+ * Get the IP type of service.
+ */
+ public int getIpTos() {
+ return ipTos;
+ }
+
+ /**
+ * Get the IP TTL.
+ */
+ public int getIpTtl() {
+ return ipTtl;
+ }
+
@Override
public boolean equals(@Nullable final Object o) {
if (!(o instanceof TcpKeepalivePacketData)) return false;
diff --git a/packages/Connectivity/framework/src/android/net/TestNetworkManager.java b/packages/Connectivity/framework/src/android/net/TestNetworkManager.java
index a7a6235..9ddd2f5 100644
--- a/packages/Connectivity/framework/src/android/net/TestNetworkManager.java
+++ b/packages/Connectivity/framework/src/android/net/TestNetworkManager.java
@@ -15,8 +15,10 @@
*/
package android.net;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.os.IBinder;
import android.os.RemoteException;
@@ -58,6 +60,7 @@
* @param network The test network that should be torn down
* @hide
*/
+ @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public void teardownTestNetwork(@NonNull Network network) {
try {
@@ -103,6 +106,7 @@
* @param binder A binder object guarding the lifecycle of this test network.
* @hide
*/
+ @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public void setupTestNetwork(@NonNull String iface, @NonNull IBinder binder) {
setupTestNetwork(iface, null, true, new int[0], binder);
@@ -145,6 +149,7 @@
* TUN interface.
* @hide
*/
+ @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@NonNull
public TestNetworkInterface createTunInterface(@NonNull Collection<LinkAddress> linkAddrs) {
@@ -163,6 +168,7 @@
* TAP interface.
* @hide
*/
+ @RequiresPermission(Manifest.permission.MANAGE_TEST_NETWORKS)
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@NonNull
public TestNetworkInterface createTapInterface() {
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index d0dc987..bd5f8ab 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -251,10 +251,11 @@
<!-- permissions required for CTS test - PhoneStateListenerTest -->
<uses-permission android:name="android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH" />
- <!-- Permissions required for ganting and logging -->
+ <!-- Permissions required for granting and logging -->
<uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/>
<uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
<uses-permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"/>
+ <uses-permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/>
<!-- Permission required for CTS test - BatterySaverTest -->
<uses-permission android:name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
diff --git a/services/backup/OWNERS b/services/backup/OWNERS
index cc36b47..852c689 100644
--- a/services/backup/OWNERS
+++ b/services/backup/OWNERS
@@ -1,6 +1,5 @@
# Bug component: 656484
-aabhinav@google.com
bryanmawhinney@google.com
jstemmer@google.com
millmore@google.com
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 5aa3e5b..2e974ae 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2884,13 +2884,13 @@
pw.println();
pw.println("mNetworkRequestInfoLogs (most recent first):");
pw.increaseIndent();
- mNetworkRequestInfoLogs.reverseDump(fd, pw, args);
+ mNetworkRequestInfoLogs.reverseDump(pw);
pw.decreaseIndent();
pw.println();
pw.println("mNetworkInfoBlockingLogs (most recent first):");
pw.increaseIndent();
- mNetworkInfoBlockingLogs.reverseDump(fd, pw, args);
+ mNetworkInfoBlockingLogs.reverseDump(pw);
pw.decreaseIndent();
pw.println();
@@ -2904,7 +2904,7 @@
long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
pw.println("currently holding WakeLock for: " + (duration / 1000) + "s");
}
- mWakelockLogs.reverseDump(fd, pw, args);
+ mWakelockLogs.reverseDump(pw);
pw.println();
pw.println("bandwidth update requests (by uid):");
@@ -2916,7 +2916,12 @@
}
}
pw.decreaseIndent();
+ pw.decreaseIndent();
+ pw.println();
+ pw.println("mOemNetworkPreferencesLogs (most recent first):");
+ pw.increaseIndent();
+ mOemNetworkPreferencesLogs.reverseDump(pw);
pw.decreaseIndent();
}
@@ -6205,6 +6210,12 @@
@NonNull
private ProfileNetworkPreferences mProfileNetworkPreferences = new ProfileNetworkPreferences();
+ // OemNetworkPreferences activity String log entries.
+ private static final int MAX_OEM_NETWORK_PREFERENCE_LOGS = 20;
+ @NonNull
+ private final LocalLog mOemNetworkPreferencesLogs =
+ new LocalLog(MAX_OEM_NETWORK_PREFERENCE_LOGS);
+
/**
* Determine whether a given package has a mapping in the current OemNetworkPreferences.
* @param packageName the package name to check existence of a mapping for.
@@ -7677,7 +7688,7 @@
}
void addRequestReassignment(@NonNull final RequestReassignment reassignment) {
- if (Build.IS_DEBUGGABLE) {
+ if (Build.isDebuggable()) {
// The code is never supposed to add two reassignments of the same request. Make
// sure this stays true, but without imposing this expensive check on all
// reassignments on all user devices.
@@ -9637,6 +9648,7 @@
return;
}
+ mOemNetworkPreferencesLogs.log("UPDATE INITIATED: " + preference);
final ArraySet<NetworkRequestInfo> nris =
new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(preference);
replaceDefaultNetworkRequestsForPreference(nris);
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 8796516..9c10658 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import static android.Manifest.permission.DUMP;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
@@ -69,6 +70,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.net.module.util.LocationPermissionChecker;
import com.android.server.vcn.TelephonySubscriptionTracker;
import com.android.server.vcn.Vcn;
@@ -76,7 +78,9 @@
import com.android.server.vcn.VcnNetworkProvider;
import com.android.server.vcn.util.PersistableBundleUtils;
+import java.io.FileDescriptor;
import java.io.IOException;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -918,6 +922,33 @@
}
}
+ /**
+ * Dumps the state of the VcnManagementService for logging and debugging purposes.
+ *
+ * <p>PII and credentials MUST NEVER be dumped here.
+ */
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ mContext.enforceCallingOrSelfPermission(DUMP, TAG);
+
+ final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
+
+ pw.println("VcnManagementService dump:");
+ pw.increaseIndent();
+
+ mNetworkProvider.dump(pw);
+
+ synchronized (mLock) {
+ pw.println("mVcns:");
+ for (Vcn vcn : mVcns.values()) {
+ vcn.dump(pw);
+ }
+ pw.println();
+ }
+
+ pw.decreaseIndent();
+ }
+
// TODO(b/180452282): Make name more generic and implement directly with VcnManagementService
/** Callback for Vcn signals sent up to VcnManagementService. */
public interface VcnCallback {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index cc5a25a..2744f11 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -236,6 +236,7 @@
import android.hardware.display.DisplayManagerInternal;
import android.location.LocationManager;
import android.media.audiofx.AudioEffect;
+import android.net.ConnectivityManager;
import android.net.Proxy;
import android.net.Uri;
import android.os.AppZygote;
@@ -16458,7 +16459,7 @@
stats.noteCurrentTimeChangedLocked();
}
break;
- case Intent.ACTION_CLEAR_DNS_CACHE:
+ case ConnectivityManager.ACTION_CLEAR_DNS_CACHE:
mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
break;
case Proxy.PROXY_CHANGE_ACTION:
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index ffeb77d..cf4fe1e 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -420,7 +420,7 @@
/*
* Tell the VMs to toss their DNS caches
*/
- final Intent intent = new Intent(Intent.ACTION_CLEAR_DNS_CACHE);
+ final Intent intent = new Intent(ConnectivityManager.ACTION_CLEAR_DNS_CACHE);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
/*
* Connectivity events can happen before boot has completed ...
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 58a7025..8bb5204 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -800,7 +800,9 @@
assertRunOnServiceThread();
if (!mService.isPowerStandbyOrTransient()) {
addAndStartAction(new SystemAudioAutoInitiationAction(this, avr.getLogicalAddress()));
- if (isConnected(avr.getPortId()) && isArcFeatureEnabled(avr.getPortId())
+ if (!isDirectConnectAddress(avr.getPhysicalAddress())) {
+ startArcAction(false);
+ } else if (isConnected(avr.getPortId()) && isArcFeatureEnabled(avr.getPortId())
&& !hasAction(SetArcTransmissionStateAction.class)) {
startArcAction(true);
}
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 0e4a2ee..ca9c75f 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -267,7 +267,7 @@
mArtStatsLogger,
sessionId,
compilerFilter,
- sharedGid,
+ pkg.getUid(),
packageStats.getCompileTime(path),
dexMetadataPath,
options.getCompilationReason(),
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index ae806aa..7bc6056 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -38,6 +38,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.server.VcnManagementService.VcnCallback;
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
@@ -328,6 +329,8 @@
private void handleNetworkRequested(
@NonNull NetworkRequest request, int score, int providerId) {
+ Slog.v(getLogTag(), "Received request " + request);
+
if (score > getNetworkScore()) {
if (VDBG) {
Slog.v(
@@ -409,6 +412,26 @@
return TAG + " [" + mSubscriptionGroup.hashCode() + "]";
}
+ /**
+ * Dumps the state of this Vcn for logging and debugging purposes.
+ *
+ * <p>PII and credentials MUST NEVER be dumped here.
+ */
+ public void dump(IndentingPrintWriter pw) {
+ pw.println("Vcn (" + mSubscriptionGroup + "):");
+ pw.increaseIndent();
+
+ pw.println("mCurrentStatus: " + mCurrentStatus);
+
+ pw.println("mVcnGatewayConnections:");
+ for (VcnGatewayConnection gw : mVcnGatewayConnections.values()) {
+ gw.dump(pw);
+ }
+ pw.println();
+
+ pw.decreaseIndent();
+ }
+
/** Retrieves the network score for a VCN Network */
// Package visibility for use in VcnGatewayConnection
static int getNetworkScore() {
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 20c08eb..83ac36f 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -77,6 +77,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.internal.util.WakeupMessage;
@@ -84,6 +85,7 @@
import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord;
import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkTrackerCallback;
import com.android.server.vcn.Vcn.VcnGatewayStatusCallback;
+import com.android.server.vcn.util.MtuUtils;
import java.io.IOException;
import java.net.Inet4Address;
@@ -448,6 +450,44 @@
*/
private static final int EVENT_SAFE_MODE_TIMEOUT_EXCEEDED = 10;
+ /**
+ * Sent when an IKE has completed migration, and created updated transforms for application.
+ *
+ * <p>Only relevant in the Connected state.
+ *
+ * @param arg1 The session token for the IKE Session that completed migration, used to prevent
+ * out-of-date signals from propagating.
+ * @param obj @NonNull An EventMigrationCompletedInfo instance with relevant data.
+ */
+ private static final int EVENT_MIGRATION_COMPLETED = 11;
+
+ private static class EventMigrationCompletedInfo implements EventInfo {
+ @NonNull public final IpSecTransform inTransform;
+ @NonNull public final IpSecTransform outTransform;
+
+ EventMigrationCompletedInfo(
+ @NonNull IpSecTransform inTransform, @NonNull IpSecTransform outTransform) {
+ this.inTransform = Objects.requireNonNull(inTransform);
+ this.outTransform = Objects.requireNonNull(outTransform);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(inTransform, outTransform);
+ }
+
+ @Override
+ public boolean equals(@Nullable Object other) {
+ if (!(other instanceof EventMigrationCompletedInfo)) {
+ return false;
+ }
+
+ final EventMigrationCompletedInfo rhs = (EventMigrationCompletedInfo) other;
+ return Objects.equals(inTransform, rhs.inTransform)
+ && Objects.equals(outTransform, rhs.outTransform);
+ }
+ }
+
@VisibleForTesting(visibility = Visibility.PRIVATE)
@NonNull
final DisconnectedState mDisconnectedState = new DisconnectedState();
@@ -574,7 +614,7 @@
* <p>Set in Connected state, always @NonNull in Connected, Migrating states, @Nullable
* otherwise.
*/
- private NetworkAgent mNetworkAgent;
+ private VcnNetworkAgent mNetworkAgent;
@Nullable private WakeupMessage mTeardownTimeoutAlarm;
@Nullable private WakeupMessage mDisconnectRequestAlarm;
@@ -1053,6 +1093,14 @@
sendMessageAndAcquireWakeLock(EVENT_SESSION_CLOSED, token);
}
+ private void migrationCompleted(
+ int token, @NonNull IpSecTransform inTransform, @NonNull IpSecTransform outTransform) {
+ sendMessageAndAcquireWakeLock(
+ EVENT_MIGRATION_COMPLETED,
+ token,
+ new EventMigrationCompletedInfo(inTransform, outTransform));
+ }
+
private void childTransformCreated(
int token, @NonNull IpSecTransform transform, int direction) {
sendMessageAndAcquireWakeLock(
@@ -1148,7 +1196,9 @@
case EVENT_SETUP_COMPLETED: // Fallthrough
case EVENT_DISCONNECT_REQUESTED: // Fallthrough
case EVENT_TEARDOWN_TIMEOUT_EXPIRED: // Fallthrough
- case EVENT_SUBSCRIPTIONS_CHANGED:
+ case EVENT_SUBSCRIPTIONS_CHANGED: // Fallthrough
+ case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED: // Fallthrough
+ case EVENT_MIGRATION_COMPLETED:
logUnexpectedEvent(msg.what);
break;
default:
@@ -1440,30 +1490,32 @@
private abstract class ConnectedStateBase extends ActiveBaseState {
protected void updateNetworkAgent(
@NonNull IpSecTunnelInterface tunnelIface,
- @NonNull NetworkAgent agent,
+ @NonNull VcnNetworkAgent agent,
@NonNull VcnChildSessionConfiguration childConfig) {
final NetworkCapabilities caps =
buildNetworkCapabilities(mConnectionConfig, mUnderlying);
final LinkProperties lp =
- buildConnectedLinkProperties(mConnectionConfig, tunnelIface, childConfig);
+ buildConnectedLinkProperties(
+ mConnectionConfig, tunnelIface, childConfig, mUnderlying);
agent.sendNetworkCapabilities(caps);
agent.sendLinkProperties(lp);
}
- protected NetworkAgent buildNetworkAgent(
+ protected VcnNetworkAgent buildNetworkAgent(
@NonNull IpSecTunnelInterface tunnelIface,
@NonNull VcnChildSessionConfiguration childConfig) {
final NetworkCapabilities caps =
buildNetworkCapabilities(mConnectionConfig, mUnderlying);
final LinkProperties lp =
- buildConnectedLinkProperties(mConnectionConfig, tunnelIface, childConfig);
+ buildConnectedLinkProperties(
+ mConnectionConfig, tunnelIface, childConfig, mUnderlying);
final NetworkAgentConfig nac =
new NetworkAgentConfig.Builder()
.setLegacyType(ConnectivityManager.TYPE_MOBILE)
.build();
- final NetworkAgent agent =
+ final VcnNetworkAgent agent =
mDeps.newNetworkAgent(
mVcnContext,
TAG,
@@ -1472,15 +1524,21 @@
Vcn.getNetworkScore(),
nac,
mVcnContext.getVcnNetworkProvider(),
- () -> {
- Slog.d(TAG, "NetworkAgent was unwanted");
- // If network agent has already been torn down, skip sending the
- // disconnect. Unwanted() is always called, even when networkAgents
- // are unregistered in teardownNetwork(), so prevent duplicate
- // notifications.
- if (mNetworkAgent != null) {
- teardownAsynchronously();
+ (agentRef) -> {
+ // Only trigger teardown if the NetworkAgent hasn't been replaced or
+ // changed. This guards against two cases - the first where
+ // unwanted() may be called as a result of the
+ // NetworkAgent.unregister() call, which might trigger a teardown
+ // instead of just a Network disconnect, as well as the case where a
+ // new NetworkAgent replaces an old one before the unwanted() call
+ // is processed.
+ if (mNetworkAgent != agentRef) {
+ Slog.d(TAG, "unwanted() called on stale NetworkAgent");
+ return;
}
+
+ Slog.d(TAG, "NetworkAgent was unwanted");
+ teardownAsynchronously();
} /* networkUnwantedCallback */,
(status) -> {
if (status == NetworkAgent.VALIDATION_STATUS_VALID) {
@@ -1620,12 +1678,36 @@
case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED:
handleSafeModeTimeoutExceeded();
break;
+ case EVENT_MIGRATION_COMPLETED:
+ final EventMigrationCompletedInfo migrationCompletedInfo =
+ (EventMigrationCompletedInfo) msg.obj;
+
+ handleMigrationCompleted(migrationCompletedInfo);
+ break;
default:
logUnhandledMessage(msg);
break;
}
}
+ private void handleMigrationCompleted(EventMigrationCompletedInfo migrationCompletedInfo) {
+ applyTransform(
+ mCurrentToken,
+ mTunnelIface,
+ mUnderlying.network,
+ migrationCompletedInfo.inTransform,
+ IpSecManager.DIRECTION_IN);
+
+ applyTransform(
+ mCurrentToken,
+ mTunnelIface,
+ mUnderlying.network,
+ migrationCompletedInfo.outTransform,
+ IpSecManager.DIRECTION_OUT);
+
+ updateNetworkAgent(mTunnelIface, mNetworkAgent, mChildConfig);
+ }
+
private void handleUnderlyingNetworkChanged(@NonNull Message msg) {
final UnderlyingNetworkRecord oldUnderlying = mUnderlying;
mUnderlying = ((EventUnderlyingNetworkChangedInfo) msg.obj).newUnderlying;
@@ -1815,7 +1897,10 @@
private static LinkProperties buildConnectedLinkProperties(
@NonNull VcnGatewayConnectionConfig gatewayConnectionConfig,
@NonNull IpSecTunnelInterface tunnelIface,
- @NonNull VcnChildSessionConfiguration childConfig) {
+ @NonNull VcnChildSessionConfiguration childConfig,
+ @Nullable UnderlyingNetworkRecord underlying) {
+ final VcnControlPlaneIkeConfig controlPlaneConfig =
+ (VcnControlPlaneIkeConfig) gatewayConnectionConfig.getControlPlaneConfig();
final LinkProperties lp = new LinkProperties();
lp.setInterfaceName(tunnelIface.getInterfaceName());
@@ -1831,7 +1916,12 @@
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null /*gateway*/,
null /*iface*/, RouteInfo.RTN_UNICAST));
- lp.setMtu(gatewayConnectionConfig.getMaxMtu());
+ final int underlyingMtu = (underlying == null) ? 0 : underlying.linkProperties.getMtu();
+ lp.setMtu(
+ MtuUtils.getMtu(
+ controlPlaneConfig.getChildSessionParams().getSaProposals(),
+ gatewayConnectionConfig.getMaxMtu(),
+ underlyingMtu));
return lp;
}
@@ -1912,8 +2002,7 @@
@NonNull IpSecTransform inIpSecTransform,
@NonNull IpSecTransform outIpSecTransform) {
Slog.v(TAG, "ChildTransformsMigrated; token " + mToken);
- onIpSecTransformCreated(inIpSecTransform, IpSecManager.DIRECTION_IN);
- onIpSecTransformCreated(outIpSecTransform, IpSecManager.DIRECTION_OUT);
+ migrationCompleted(mToken, inIpSecTransform, outIpSecTransform);
}
@Override
@@ -1924,6 +2013,27 @@
}
}
+ /**
+ * Dumps the state of this VcnGatewayConnection for logging and debugging purposes.
+ *
+ * <p>PII and credentials MUST NEVER be dumped here.
+ */
+ public void dump(IndentingPrintWriter pw) {
+ pw.println("VcnGatewayConnection (" + mConnectionConfig.getGatewayConnectionName() + "):");
+ pw.increaseIndent();
+
+ pw.println("Current state: " + getCurrentState().getClass().getSimpleName());
+ pw.println("mIsQuitting: " + mIsQuitting);
+ pw.println("mIsInSafeMode: " + mIsInSafeMode);
+ pw.println("mCurrentToken: " + mCurrentToken);
+ pw.println("mFailedAttempts: " + mFailedAttempts);
+ pw.println(
+ "mNetworkAgent.getNetwork(): "
+ + (mNetworkAgent == null ? null : mNetworkAgent.getNetwork()));
+
+ pw.decreaseIndent();
+ }
+
@VisibleForTesting(visibility = Visibility.PRIVATE)
void setTunnelInterface(IpSecTunnelInterface tunnelIface) {
mTunnelIface = tunnelIface;
@@ -1965,12 +2075,12 @@
}
@VisibleForTesting(visibility = Visibility.PRIVATE)
- NetworkAgent getNetworkAgent() {
+ VcnNetworkAgent getNetworkAgent() {
return mNetworkAgent;
}
@VisibleForTesting(visibility = Visibility.PRIVATE)
- void setNetworkAgent(@Nullable NetworkAgent networkAgent) {
+ void setNetworkAgent(@Nullable VcnNetworkAgent networkAgent) {
mNetworkAgent = networkAgent;
}
@@ -2058,8 +2168,8 @@
return new WakeupMessage(vcnContext.getContext(), handler, tag, runnable);
}
- /** Builds a new NetworkAgent. */
- public NetworkAgent newNetworkAgent(
+ /** Builds a new VcnNetworkAgent. */
+ public VcnNetworkAgent newNetworkAgent(
@NonNull VcnContext vcnContext,
@NonNull String tag,
@NonNull NetworkCapabilities caps,
@@ -2067,27 +2177,18 @@
@NonNull int score,
@NonNull NetworkAgentConfig nac,
@NonNull NetworkProvider provider,
- @NonNull Runnable networkUnwantedCallback,
+ @NonNull Consumer<VcnNetworkAgent> networkUnwantedCallback,
@NonNull Consumer<Integer> validationStatusCallback) {
- return new NetworkAgent(
- vcnContext.getContext(),
- vcnContext.getLooper(),
+ return new VcnNetworkAgent(
+ vcnContext,
tag,
caps,
lp,
score,
nac,
- provider) {
- @Override
- public void onNetworkUnwanted() {
- networkUnwantedCallback.run();
- }
-
- @Override
- public void onValidationStatus(int status, @Nullable Uri redirectUri) {
- validationStatusCallback.accept(status);
- }
- };
+ provider,
+ networkUnwantedCallback,
+ validationStatusCallback);
}
/** Gets the elapsed real time since boot, in millis. */
@@ -2203,4 +2304,73 @@
mImpl.release();
}
}
+
+ /** Proxy Implementation of NetworkAgent, used for testing. */
+ @VisibleForTesting(visibility = Visibility.PRIVATE)
+ public static class VcnNetworkAgent {
+ private final NetworkAgent mImpl;
+
+ public VcnNetworkAgent(
+ @NonNull VcnContext vcnContext,
+ @NonNull String tag,
+ @NonNull NetworkCapabilities caps,
+ @NonNull LinkProperties lp,
+ @NonNull int score,
+ @NonNull NetworkAgentConfig nac,
+ @NonNull NetworkProvider provider,
+ @NonNull Consumer<VcnNetworkAgent> networkUnwantedCallback,
+ @NonNull Consumer<Integer> validationStatusCallback) {
+ mImpl =
+ new NetworkAgent(
+ vcnContext.getContext(),
+ vcnContext.getLooper(),
+ tag,
+ caps,
+ lp,
+ score,
+ nac,
+ provider) {
+ @Override
+ public void onNetworkUnwanted() {
+ networkUnwantedCallback.accept(VcnNetworkAgent.this);
+ }
+
+ @Override
+ public void onValidationStatus(int status, @Nullable Uri redirectUri) {
+ validationStatusCallback.accept(status);
+ }
+ };
+ }
+
+ /** Registers the underlying NetworkAgent */
+ public void register() {
+ mImpl.register();
+ }
+
+ /** Marks the underlying NetworkAgent as connected */
+ public void markConnected() {
+ mImpl.markConnected();
+ }
+
+ /** Unregisters the underlying NetworkAgent */
+ public void unregister() {
+ mImpl.unregister();
+ }
+
+ /** Sends new NetworkCapabilities for the underlying NetworkAgent */
+ public void sendNetworkCapabilities(@NonNull NetworkCapabilities caps) {
+ mImpl.sendNetworkCapabilities(caps);
+ }
+
+ /** Sends new LinkProperties for the underlying NetworkAgent */
+ public void sendLinkProperties(@NonNull LinkProperties lp) {
+ mImpl.sendLinkProperties(lp);
+ }
+
+ /** Retrieves the Network for the underlying NetworkAgent */
+ @Nullable
+ public Network getNetwork() {
+ return mImpl.getNetwork();
+ }
+ }
}
diff --git a/services/core/java/com/android/server/vcn/VcnNetworkProvider.java b/services/core/java/com/android/server/vcn/VcnNetworkProvider.java
index a909695..be0deb5 100644
--- a/services/core/java/com/android/server/vcn/VcnNetworkProvider.java
+++ b/services/core/java/com/android/server/vcn/VcnNetworkProvider.java
@@ -29,6 +29,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
+import com.android.internal.util.IndentingPrintWriter;
import java.util.Objects;
import java.util.Set;
@@ -129,10 +130,50 @@
mScore = score;
mProviderId = providerId;
}
+
+ /**
+ * Dumps the state of this NetworkRequestEntry for logging and debugging purposes.
+ *
+ * <p>PII and credentials MUST NEVER be dumped here.
+ */
+ public void dump(IndentingPrintWriter pw) {
+ pw.println("NetworkRequestEntry:");
+ pw.increaseIndent();
+
+ pw.println("mRequest: " + mRequest);
+ pw.println("mScore: " + mScore);
+ pw.println("mProviderId: " + mProviderId);
+
+ pw.decreaseIndent();
+ }
}
// package-private
interface NetworkRequestListener {
void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId);
}
+
+ /**
+ * Dumps the state of this VcnNetworkProvider for logging and debugging purposes.
+ *
+ * <p>PII and credentials MUST NEVER be dumped here.
+ */
+ public void dump(IndentingPrintWriter pw) {
+ pw.println("VcnNetworkProvider:");
+ pw.increaseIndent();
+
+ pw.println("mListeners:");
+ for (NetworkRequestListener listener : mListeners) {
+ pw.println(listener);
+ }
+ pw.println();
+
+ pw.println("mRequests.values:");
+ for (NetworkRequestEntry entry : mRequests.values()) {
+ entry.dump(pw);
+ }
+ pw.println();
+
+ pw.decreaseIndent();
+ }
}
diff --git a/services/core/java/com/android/server/vcn/util/MtuUtils.java b/services/core/java/com/android/server/vcn/util/MtuUtils.java
new file mode 100644
index 0000000..49c1a02
--- /dev/null
+++ b/services/core/java/com/android/server/vcn/util/MtuUtils.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vcn.util;
+
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_3DES;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CTR;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_CHACHA20_POLY1305;
+import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_AES_CMAC_96;
+import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96;
+import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96;
+import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128;
+import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192;
+import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256;
+import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_NONE;
+
+import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
+
+import static java.lang.Math.max;
+import static java.util.Collections.unmodifiableMap;
+
+import android.annotation.NonNull;
+import android.net.ipsec.ike.ChildSaProposal;
+import android.util.ArrayMap;
+import android.util.Pair;
+import android.util.Slog;
+
+import java.util.List;
+import java.util.Map;
+
+/** @hide */
+public class MtuUtils {
+ private static final String TAG = MtuUtils.class.getSimpleName();
+ /**
+ * Max ESP overhead possible
+ *
+ * <p>60 (Outer IPv4 + options) + 8 (UDP encap) + 4 (SPI) + 4 (Seq) + 2 (Pad + NextHeader)
+ */
+ private static final int GENERIC_ESP_OVERHEAD_MAX = 78;
+
+ /** Maximum overheads of authentication algorithms, keyed on IANA-defined constants */
+ private static final Map<Integer, Integer> AUTH_ALGORITHM_OVERHEAD;
+
+ static {
+ final Map<Integer, Integer> map = new ArrayMap<>();
+ map.put(INTEGRITY_ALGORITHM_NONE, 0);
+ map.put(INTEGRITY_ALGORITHM_HMAC_SHA1_96, 12);
+ map.put(INTEGRITY_ALGORITHM_AES_XCBC_96, 12);
+ map.put(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128, 32);
+ map.put(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192, 48);
+ map.put(INTEGRITY_ALGORITHM_HMAC_SHA2_512_256, 64);
+ map.put(INTEGRITY_ALGORITHM_AES_CMAC_96, 12);
+
+ AUTH_ALGORITHM_OVERHEAD = unmodifiableMap(map);
+ }
+
+ /** Maximum overheads of encryption algorithms, keyed on IANA-defined constants */
+ private static final Map<Integer, Integer> CRYPT_ALGORITHM_OVERHEAD;
+
+ static {
+ final Map<Integer, Integer> map = new ArrayMap<>();
+ map.put(ENCRYPTION_ALGORITHM_3DES, 15); // 8 (IV) + 7 (Max pad)
+ map.put(ENCRYPTION_ALGORITHM_AES_CBC, 31); // 16 (IV) + 15 (Max pad)
+ map.put(ENCRYPTION_ALGORITHM_AES_CTR, 11); // 8 (IV) + 3 (Max pad)
+
+ CRYPT_ALGORITHM_OVERHEAD = unmodifiableMap(map);
+ }
+
+ /** Maximum overheads of combined mode algorithms, keyed on IANA-defined constants */
+ private static final Map<Integer, Integer> AUTHCRYPT_ALGORITHM_OVERHEAD;
+
+ static {
+ final Map<Integer, Integer> map = new ArrayMap<>();
+ map.put(ENCRYPTION_ALGORITHM_AES_GCM_8, 19); // 8 (IV) + 3 (Max pad) + 8 (ICV)
+ map.put(ENCRYPTION_ALGORITHM_AES_GCM_12, 23); // 8 (IV) + 3 (Max pad) + 12 (ICV)
+ map.put(ENCRYPTION_ALGORITHM_AES_GCM_16, 27); // 8 (IV) + 3 (Max pad) + 16 (ICV)
+ map.put(ENCRYPTION_ALGORITHM_CHACHA20_POLY1305, 27); // 8 (IV) + 3 (Max pad) + 16 (ICV)
+
+ AUTHCRYPT_ALGORITHM_OVERHEAD = unmodifiableMap(map);
+ }
+
+ /**
+ * Calculates the MTU of the inner interface based on the parameters provided
+ *
+ * <p>The MTU of the inner interface will be the minimum of the following:
+ *
+ * <ul>
+ * <li>The MTU of the outer interface, minus the greatest ESP overhead (based on proposed
+ * algorithms).
+ * <li>The maximum MTU as provided in the arguments.
+ * </ul>
+ */
+ public static int getMtu(
+ @NonNull List<ChildSaProposal> childProposals, int maxMtu, int underlyingMtu) {
+ if (underlyingMtu <= 0) {
+ return IPV6_MIN_MTU;
+ }
+
+ boolean hasUnknownAlgorithm = false;
+ int maxAuthOverhead = 0;
+ int maxCryptOverhead = 0;
+ int maxAuthCryptOverhead = 0;
+
+ for (ChildSaProposal proposal : childProposals) {
+ for (Pair<Integer, Integer> encryptionAlgoPair : proposal.getEncryptionAlgorithms()) {
+ final int algo = encryptionAlgoPair.first;
+
+ if (AUTHCRYPT_ALGORITHM_OVERHEAD.containsKey(algo)) {
+ maxAuthCryptOverhead =
+ max(maxAuthCryptOverhead, AUTHCRYPT_ALGORITHM_OVERHEAD.get(algo));
+ continue;
+ } else if (CRYPT_ALGORITHM_OVERHEAD.containsKey(algo)) {
+ maxCryptOverhead = max(maxCryptOverhead, CRYPT_ALGORITHM_OVERHEAD.get(algo));
+ continue;
+ }
+
+ Slog.wtf(TAG, "Unknown encryption algorithm requested: " + algo);
+ return IPV6_MIN_MTU;
+ }
+
+ for (int algo : proposal.getIntegrityAlgorithms()) {
+ if (AUTH_ALGORITHM_OVERHEAD.containsKey(algo)) {
+ maxAuthOverhead = max(maxAuthOverhead, AUTH_ALGORITHM_OVERHEAD.get(algo));
+ continue;
+ }
+
+ Slog.wtf(TAG, "Unknown integrity algorithm requested: " + algo);
+ return IPV6_MIN_MTU;
+ }
+ }
+
+ // Return minimum of maxMtu, and the adjusted MTUs based on algorithms.
+ final int combinedModeMtu = underlyingMtu - maxAuthCryptOverhead - GENERIC_ESP_OVERHEAD_MAX;
+ final int normalModeMtu =
+ underlyingMtu - maxCryptOverhead - maxAuthOverhead - GENERIC_ESP_OVERHEAD_MAX;
+ return Math.min(Math.min(maxMtu, combinedModeMtu), normalModeMtu);
+ }
+}
diff --git a/services/net/java/android/net/util/KeepalivePacketDataUtil.java b/services/net/java/android/net/util/KeepalivePacketDataUtil.java
index 6e539bb..5666985 100644
--- a/services/net/java/android/net/util/KeepalivePacketDataUtil.java
+++ b/services/net/java/android/net/util/KeepalivePacketDataUtil.java
@@ -80,12 +80,12 @@
parcel.srcPort = pkt.getSrcPort();
parcel.dstAddress = dstAddress.getAddress();
parcel.dstPort = pkt.getDstPort();
- parcel.seq = pkt.tcpSeq;
- parcel.ack = pkt.tcpAck;
- parcel.rcvWnd = pkt.tcpWindow;
- parcel.rcvWndScale = pkt.tcpWindowScale;
- parcel.tos = pkt.ipTos;
- parcel.ttl = pkt.ipTtl;
+ parcel.seq = pkt.getTcpSeq();
+ parcel.ack = pkt.getTcpAck();
+ parcel.rcvWnd = pkt.getTcpWindow();
+ parcel.rcvWndScale = pkt.getTcpWindowScale();
+ parcel.tos = pkt.getIpTos();
+ parcel.ttl = pkt.getIpTtl();
return parcel;
}
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index 38fa907..3c3df51 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -525,7 +525,7 @@
*
* @throws SecurityException if the caller does not have the required permission/privileges
*/
- public static void enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
+ public static void enforceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
Context context, int subId, String message) {
if (context.checkCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE)
== PERMISSION_GRANTED) {
@@ -545,7 +545,7 @@
*
* @throws SecurityException if the caller does not have the required permission/privileges
*/
- public static void enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
+ public static void enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Context context, int subId, String message) {
if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
== PERMISSION_GRANTED) {
@@ -567,7 +567,7 @@
*
* @throws SecurityException if the caller does not have the required permission/privileges
*/
- public static void enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+ public static void enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Context context, int subId, String message) {
if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
== PERMISSION_GRANTED) {
diff --git a/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt b/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt
index 6770066..7a18bb0 100644
--- a/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt
+++ b/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt
@@ -92,12 +92,12 @@
assertTrue(str.contains(data.dstAddress.hostAddress))
assertTrue(str.contains(data.dstPort.toString()))
// .packet not included in toString()
- assertTrue(str.contains(data.tcpSeq.toString()))
- assertTrue(str.contains(data.tcpAck.toString()))
- assertTrue(str.contains(data.tcpWindow.toString()))
- assertTrue(str.contains(data.tcpWindowScale.toString()))
- assertTrue(str.contains(data.ipTos.toString()))
- assertTrue(str.contains(data.ipTtl.toString()))
+ assertTrue(str.contains(data.getTcpSeq().toString()))
+ assertTrue(str.contains(data.getTcpAck().toString()))
+ assertTrue(str.contains(data.getTcpWindow().toString()))
+ assertTrue(str.contains(data.getTcpWindowScale().toString()))
+ assertTrue(str.contains(data.getIpTos().toString()))
+ assertTrue(str.contains(data.getIpTtl().toString()))
// Update above assertions if field is added
assertFieldCountEquals(5, KeepalivePacketData::class.java)
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index e050495..790f3be 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -18,6 +18,7 @@
import static android.Manifest.permission.CHANGE_NETWORK_STATE;
import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
+import static android.Manifest.permission.DUMP;
import static android.Manifest.permission.NETWORK_FACTORY;
import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.app.PendingIntent.FLAG_IMMUTABLE;
@@ -356,6 +357,8 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
import java.util.function.Supplier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
import kotlin.reflect.KClass;
@@ -9950,6 +9953,7 @@
@Test
public void testDumpDoesNotCrash() {
+ mServiceContext.setPermission(DUMP, PERMISSION_GRANTED);
// Filing a couple requests prior to testing the dump.
final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
@@ -11706,6 +11710,33 @@
}
@Test
+ public void testSetOemNetworkPreferenceLogsRequest() throws Exception {
+ mServiceContext.setPermission(DUMP, PERMISSION_GRANTED);
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OEM_NETWORK_PREFERENCE_OEM_PAID;
+ final StringWriter stringWriter = new StringWriter();
+ final String logIdentifier = "UPDATE INITIATED: OemNetworkPreferences";
+ final Pattern pattern = Pattern.compile(logIdentifier);
+
+ final int expectedNumLogs = 2;
+ final UidRangeParcel[] uidRanges =
+ toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID));
+
+ // Call twice to generate two logs.
+ setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME);
+ setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME);
+ mService.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]);
+
+ final String dumpOutput = stringWriter.toString();
+ final Matcher matcher = pattern.matcher(dumpOutput);
+ int count = 0;
+ while (matcher.find()) {
+ count++;
+ }
+ assertEquals(expectedNumLogs, count);
+ }
+
+ @Test
public void testGetAllNetworkStateSnapshot() throws Exception {
verifyNoNetwork();
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 34c0018..bb67593 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -26,6 +26,7 @@
import static com.android.server.vcn.VcnGatewayConnection.VcnChildSessionConfiguration;
import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession;
+import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -46,15 +47,19 @@
import android.net.LinkProperties;
import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
+import android.net.ipsec.ike.ChildSaProposal;
import android.net.ipsec.ike.exceptions.AuthenticationFailedException;
import android.net.ipsec.ike.exceptions.IkeException;
import android.net.ipsec.ike.exceptions.IkeInternalException;
import android.net.ipsec.ike.exceptions.TemporaryFailureException;
+import android.net.vcn.VcnControlPlaneIkeConfig;
import android.net.vcn.VcnManager.VcnErrorCode;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.server.vcn.util.MtuUtils;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -73,13 +78,13 @@
@SmallTest
public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnectionTestBase {
private VcnIkeSession mIkeSession;
- private NetworkAgent mNetworkAgent;
+ private VcnNetworkAgent mNetworkAgent;
@Before
public void setUp() throws Exception {
super.setUp();
- mNetworkAgent = mock(NetworkAgent.class);
+ mNetworkAgent = mock(VcnNetworkAgent.class);
doReturn(mNetworkAgent)
.when(mDeps)
.newNetworkAgent(any(), any(), any(), any(), anyInt(), any(), any(), any(), any());
@@ -152,7 +157,9 @@
}
@Test
- public void testMigratedTransformsAreApplied() throws Exception {
+ public void testMigration() throws Exception {
+ triggerChildOpened();
+
getChildSessionCallback()
.onIpSecTransformsMigrated(makeDummyIpSecTransform(), makeDummyIpSecTransform());
mTestLooper.dispatchAll();
@@ -170,6 +177,17 @@
}
assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
+
+ final List<ChildSaProposal> saProposals =
+ ((VcnControlPlaneIkeConfig) mConfig.getControlPlaneConfig())
+ .getChildSessionParams()
+ .getSaProposals();
+ final int expectedMtu =
+ MtuUtils.getMtu(
+ saProposals,
+ mConfig.getMaxMtu(),
+ TEST_UNDERLYING_NETWORK_RECORD_1.linkProperties.getMtu());
+ verify(mNetworkAgent).sendLinkProperties(argThat(lp -> expectedMtu == lp.getMtu()));
}
private void triggerChildOpened() {
@@ -299,8 +317,9 @@
.removeAddressFromTunnelInterface(
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(TEST_INTERNAL_ADDR), any());
- // TODO(b/184579891): Also verify link properties updated and sent when sendLinkProperties
- // is mockable
+ verify(mNetworkAgent).sendLinkProperties(argThat(
+ lp -> newInternalAddrs.equals(lp.getLinkAddresses())
+ && Collections.singletonList(TEST_DNS_ADDR_2).equals(lp.getDnsServers())));
// Verify that IpSecTunnelInterface only created once
verify(mIpSecSvc).createTunnelInterface(any(), any(), any(), any(), any());
@@ -323,6 +342,66 @@
assertFalse(mGatewayConnection.isInSafeMode());
}
+ private Consumer<VcnNetworkAgent> setupNetworkAndGetUnwantedCallback() {
+ triggerChildOpened();
+ mTestLooper.dispatchAll();
+
+ final ArgumentCaptor<Consumer<VcnNetworkAgent>> unwantedCallbackCaptor =
+ ArgumentCaptor.forClass(Consumer.class);
+ verify(mDeps)
+ .newNetworkAgent(
+ any(),
+ any(),
+ any(),
+ any(),
+ anyInt(),
+ any(),
+ any(),
+ unwantedCallbackCaptor.capture(),
+ any());
+
+ return unwantedCallbackCaptor.getValue();
+ }
+
+ @Test
+ public void testUnwantedNetworkAgentTriggersTeardown() throws Exception {
+ final Consumer<VcnNetworkAgent> unwantedCallback = setupNetworkAndGetUnwantedCallback();
+
+ unwantedCallback.accept(mNetworkAgent);
+ mTestLooper.dispatchAll();
+
+ assertTrue(mGatewayConnection.isQuitting());
+ assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
+ }
+
+ @Test
+ public void testUnwantedNetworkAgentWithDisconnectedNetworkAgent() throws Exception {
+ final Consumer<VcnNetworkAgent> unwantedCallback = setupNetworkAndGetUnwantedCallback();
+
+ mGatewayConnection.setNetworkAgent(null);
+ unwantedCallback.accept(mNetworkAgent);
+ mTestLooper.dispatchAll();
+
+ // Verify that the call was ignored; the state machine is still running, and the state has
+ // not changed.
+ assertFalse(mGatewayConnection.isQuitting());
+ assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
+ }
+
+ @Test
+ public void testUnwantedNetworkAgentWithNewNetworkAgent() throws Exception {
+ final Consumer<VcnNetworkAgent> unwantedCallback = setupNetworkAndGetUnwantedCallback();
+ final VcnNetworkAgent testAgent = mock(VcnNetworkAgent.class);
+
+ mGatewayConnection.setNetworkAgent(testAgent);
+ unwantedCallback.accept(mNetworkAgent);
+ mTestLooper.dispatchAll();
+
+ assertFalse(mGatewayConnection.isQuitting());
+ assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
+ assertEquals(testAgent, mGatewayConnection.getNetworkAgent());
+ }
+
@Test
public void testChildSessionClosedTriggersDisconnect() throws Exception {
// Verify scheduled but not canceled when entering ConnectedState
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
index c5ed8f6..dc73be2 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
@@ -18,6 +18,7 @@
import static com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord;
import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession;
+import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent;
import static com.android.server.vcn.VcnTestUtils.setupIpSecManager;
import static org.junit.Assert.assertEquals;
@@ -44,7 +45,6 @@
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
-import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
import android.net.ipsec.ike.ChildSessionCallback;
import android.net.ipsec.ike.IkeSessionCallback;
@@ -90,12 +90,18 @@
protected static final int TEST_SUB_ID = 5;
protected static final long ELAPSED_REAL_TIME = 123456789L;
protected static final String TEST_IPSEC_TUNNEL_IFACE = "IPSEC_IFACE";
+
protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_1 =
new UnderlyingNetworkRecord(
new Network(0),
new NetworkCapabilities(),
new LinkProperties(),
false /* blocked */);
+
+ static {
+ TEST_UNDERLYING_NETWORK_RECORD_1.linkProperties.setMtu(1500);
+ }
+
protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_2 =
new UnderlyingNetworkRecord(
new Network(1),
@@ -103,6 +109,10 @@
new LinkProperties(),
false /* blocked */);
+ static {
+ TEST_UNDERLYING_NETWORK_RECORD_2.linkProperties.setMtu(1460);
+ }
+
protected static final TelephonySubscriptionSnapshot TEST_SUBSCRIPTION_SNAPSHOT =
new TelephonySubscriptionSnapshot(
Collections.singletonMap(TEST_SUB_ID, TEST_SUB_GRP), Collections.EMPTY_MAP);
@@ -278,8 +288,8 @@
protected void verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent(
@NonNull State expectedState) {
- // Set a NetworkAgent, and expect it to be unregistered and cleared
- final NetworkAgent mockNetworkAgent = mock(NetworkAgent.class);
+ // Set a VcnNetworkAgent, and expect it to be unregistered and cleared
+ final VcnNetworkAgent mockNetworkAgent = mock(VcnNetworkAgent.class);
mGatewayConnection.setNetworkAgent(mockNetworkAgent);
// SafeMode timer starts when VcnGatewayConnection exits DisconnectedState (the initial
diff --git a/tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java b/tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java
new file mode 100644
index 0000000..29511f7
--- /dev/null
+++ b/tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vcn.util;
+
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8;
+import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128;
+import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_256;
+
+import static com.android.net.module.util.NetworkStackConstants.ETHER_MTU;
+import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
+import static com.android.server.vcn.util.MtuUtils.getMtu;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import static java.util.Collections.emptyList;
+
+import android.net.ipsec.ike.ChildSaProposal;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MtuUtilsTest {
+ @Test
+ public void testUnderlyingMtuZero() {
+ assertEquals(
+ IPV6_MIN_MTU, getMtu(emptyList(), ETHER_MTU /* maxMtu */, 0 /* underlyingMtu */));
+ }
+
+ @Test
+ public void testClampsToMaxMtu() {
+ assertEquals(0, getMtu(emptyList(), 0 /* maxMtu */, IPV6_MIN_MTU /* underlyingMtu */));
+ }
+
+ @Test
+ public void testNormalModeAlgorithmLessThanUnderlyingMtu() {
+ final List<ChildSaProposal> saProposals =
+ Arrays.asList(
+ new ChildSaProposal.Builder()
+ .addEncryptionAlgorithm(
+ ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256)
+ .addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128)
+ .build());
+
+ final int actualMtu =
+ getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */);
+ assertTrue(ETHER_MTU > actualMtu);
+ }
+
+ @Test
+ public void testCombinedModeAlgorithmLessThanUnderlyingMtu() {
+ final List<ChildSaProposal> saProposals =
+ Arrays.asList(
+ new ChildSaProposal.Builder()
+ .addEncryptionAlgorithm(
+ ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256)
+ .addEncryptionAlgorithm(
+ ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_256)
+ .addEncryptionAlgorithm(
+ ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_256)
+ .build());
+
+ final int actualMtu =
+ getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */);
+ assertTrue(ETHER_MTU > actualMtu);
+ }
+}
diff --git a/tools/hiddenapi/checksorted_sha.sh b/tools/hiddenapi/checksorted_sha.sh
index ceb705f..451fed6 100755
--- a/tools/hiddenapi/checksorted_sha.sh
+++ b/tools/hiddenapi/checksorted_sha.sh
@@ -1,7 +1,7 @@
#!/bin/bash
set -e
LOCAL_DIR="$( dirname ${BASH_SOURCE} )"
-git show --name-only --pretty=format: $1 | grep "config/hiddenapi-.*txt" | while read file; do
+git show --name-only --pretty=format: $1 | grep "boot/hiddenapi/hiddenapi-.*txt" | while read file; do
diff <(git show $1:$file) <(git show $1:$file | $LOCAL_DIR/sort_api.sh ) || {
echo -e "\e[1m\e[31m$file $1 is not sorted or contains duplicates. To sort it correctly:\e[0m"
echo -e "\e[33m${LOCAL_DIR}/sort_api.sh $2/frameworks/base/$file\e[0m"
diff --git a/tools/hiddenapi/exclude.sh b/tools/hiddenapi/exclude.sh
index 2924e01..822aba4 100755
--- a/tools/hiddenapi/exclude.sh
+++ b/tools/hiddenapi/exclude.sh
@@ -48,7 +48,7 @@
PACKAGES=$(for t in $TEAMS; do echo $(eval echo \${${t}_PACKAGES}); done)
RE=$(echo ${PACKAGES} | sed "s/ /|/g")
EXIT_CODE=0
-for file in $(git show --name-only --pretty=format: $SHA | grep "config/hiddenapi-.*txt"); do
+for file in $(git show --name-only --pretty=format: $SHA | grep "boot/hiddenapi/hiddenapi-.*txt"); do
ENTRIES=$(grep -E "^\+L(${RE})/" <(git diff ${SHA}~1 ${SHA} $file) | sed "s|^\+||" || echo)
if [[ -n "${ENTRIES}" ]]; then
echo -e "\e[1m\e[31m$file $SHA contains the following entries\e[0m"