diff options
57 files changed, 1017 insertions, 272 deletions
diff --git a/StubLibraries.bp b/StubLibraries.bp index 1644a550aca5..ba9c250f2975 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -268,6 +268,36 @@ droidstubs { // 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_defaults { 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 { 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 { 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 a52223792b7a..5487e8788b9a 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 @@ public final class ConnectivityController extends RestrictingController implemen 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 @@ public final class ConnectivityController extends RestrictingController implemen 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 ea8e7bc4ab06..a346812ff5f5 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 @@ public final class JobStatus { 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 @@ public final class JobStatus { } } - 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 000000000000..c023b312b471 --- /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 001038d139c4..0691dbc4dcb0 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 5a2b8bdd3c0a..cc425f01b926 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -29284,7 +29284,6 @@ package android.os { 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 fe8b9d6e4fa0..e7a7fd2ea7a1 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -27,10 +27,6 @@ package android.content { 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 @@ package android.os { 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 e31f17497323..db50f0b7ab2e 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -8123,7 +8123,7 @@ package android.security.keystore { } 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 @@ package android.uwb { 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 @@ package android.uwb { 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 @@ package android.uwb { 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 0c57f4e3b557..f7b101d56c27 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1022,6 +1022,7 @@ package android.os { 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 7713e25d5ecd..74018a8ab1f8 100644 --- a/core/java/android/app/IUidObserver.aidl +++ b/core/java/android/app/IUidObserver.aidl @@ -24,7 +24,7 @@ oneway interface IUidObserver { // 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 4d68e90437be..0fad63f192bb 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2324,14 +2324,6 @@ public class Intent implements Parcelable, Cloneable { @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 e1685887e806..62c576144221 100644 --- a/core/java/android/net/EthernetNetworkSpecifier.java +++ b/core/java/android/net/EthernetNetworkSpecifier.java @@ -42,15 +42,22 @@ public final class EthernetNetworkSpecifier extends NetworkSpecifier implements @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 03caafda2b13..e47ffcc4ff4c 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -1309,10 +1309,25 @@ public class Build { * 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 2a9bbdf3ec5d..98565536e64a 100644 --- a/core/java/android/uwb/DistanceMeasurement.java +++ b/core/java/android/uwb/DistanceMeasurement.java @@ -60,6 +60,7 @@ public final class DistanceMeasurement implements Parcelable { * * @return error of distance measurement in meters */ + @FloatRange(from = 0.0) public double getErrorMeters() { return mErrorMeters; } @@ -162,7 +163,7 @@ public final class DistanceMeasurement implements Parcelable { * @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 @@ public final class DistanceMeasurement implements Parcelable { * @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 4036892fb9e7..30da248e9e87 100644 --- a/core/java/android/uwb/IUwbAdapter.aidl +++ b/core/java/android/uwb/IUwbAdapter.aidl @@ -160,14 +160,4 @@ interface IUwbAdapter { * 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 f71f3ff7ad44..f15debbf3e6f 100644 --- a/core/java/android/uwb/IUwbRangingCallbacks.aidl +++ b/core/java/android/uwb/IUwbRangingCallbacks.aidl @@ -92,9 +92,13 @@ interface IUwbRangingCallbacks { * 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 85f2c1ccc180..e2c64a709922 100644 --- a/core/java/android/uwb/RangingManager.java +++ b/core/java/android/uwb/RangingManager.java @@ -165,7 +165,8 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub { } @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 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub { } 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 52ec5bde0dac..345b69df84d5 100644 --- a/core/java/android/uwb/RangingSession.java +++ b/core/java/android/uwb/RangingSession.java @@ -191,8 +191,11 @@ public final class RangingSession implements AutoCloseable { /** * 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 @@ public final class RangingSession implements AutoCloseable { /** * @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 24ade39f9834..cc4e2bb59787 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 e41805dd3a59..21ef083bcdbc 100644 --- a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java +++ b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java @@ -123,8 +123,8 @@ public class RangingManagerTest { 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 43fdedc41e9f..aef68d0fd097 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -410,6 +410,7 @@ applications that come with the platform <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 1f9022b4ad3d..a6aa4f21e53b 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -353,7 +353,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu boolean userPresenceRequired, byte[] attestationChallenge, boolean devicePropertiesAttestationIncluded, - int[] attestationIds, + @NonNull int[] attestationIds, boolean uniqueIdIncluded, boolean userAuthenticationValidWhileOnBody, boolean invalidatedByBiometricEnrollment, @@ -779,9 +779,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu * @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 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu 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 c26d9f583fd4..dc7f3dda35c0 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -655,7 +655,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } 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 d1dddbd52265..34b9fced5bee 100644 --- a/native/android/Android.bp +++ b/native/android/Android.bp @@ -77,6 +77,7 @@ cc_library_shared { "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 ab290f9d706a..7692e30c31fb 100644 --- a/packages/Connectivity/framework/api/current.txt +++ b/packages/Connectivity/framework/api/current.txt @@ -410,6 +410,8 @@ package android.net { } 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 513b6308f372..caf7f49efcd8 100644 --- a/packages/Connectivity/framework/api/module-lib-current.txt +++ b/packages/Connectivity/framework/api/module-lib-current.txt @@ -26,6 +26,7 @@ package android.net { 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 @@ package android.net { 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 @@ package android.net { } 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 0a82cb7cfee1..d6d38889e93f 100644 --- a/packages/Connectivity/framework/api/system-current.txt +++ b/packages/Connectivity/framework/api/system-current.txt @@ -455,14 +455,14 @@ package android.net { 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 82dbd0fb1f87..53aa1b92edca 100644 --- a/packages/Connectivity/framework/src/android/net/CaptivePortalData.java +++ b/packages/Connectivity/framework/src/android/net/CaptivePortalData.java @@ -42,7 +42,7 @@ public final class CaptivePortalData implements Parcelable { 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 @@ public final class CaptivePortalData implements Parcelable { 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 @@ public final class CaptivePortalData implements Parcelable { 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 84914a1aeeab..0418450ccda9 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.ComponentName; 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 @@ public class ConnectivityManager { "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 @@ public class ConnectivityManager { * * <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 @@ public class ConnectivityManager { @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 0741414ab3aa..41fad6317a20 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.os.Parcelable; 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 class Network implements Parcelable { 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 9a75f0bf18bf..a43dd15a8765 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.os.Process; 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 @@ public final class NetworkCapabilities implements Parcelable { } } - /** @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 5d40417440d4..3a8a07a55ad4 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.Parcelable; 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 @@ public class NetworkRequest implements Parcelable { } } - /** @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 5a76cd6d6b0f..2bb006df82e0 100644 --- a/packages/Connectivity/framework/src/android/net/OemNetworkPreferences.java +++ b/packages/Connectivity/framework/src/android/net/OemNetworkPreferences.java @@ -40,6 +40,23 @@ import java.util.Objects; */ @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 final class OemNetworkPreferences implements Parcelable { */ 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 @@ public final class OemNetworkPreferences implements Parcelable { @Override public String toString() { - return "OemNetworkPreferences{" + "mNetworkMappings=" + mNetworkMappings + '}'; + return "OemNetworkPreferences{" + "mNetworkMappings=" + getNetworkPreferences() + '}'; } @Override @@ -185,6 +208,8 @@ public final class OemNetworkPreferences implements Parcelable { /** @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 @@ public final class OemNetworkPreferences implements Parcelable { @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 ca6d012dfe7c..9d4727a84bc0 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 @@ import android.annotation.SystemApi; 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 ddb3a6a72fb4..c2c4f32ca673 100644 --- a/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java +++ b/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java @@ -32,22 +32,39 @@ import java.util.Objects; 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 @@ public final class TcpKeepalivePacketData extends KeepalivePacketData implements 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 a7a62351e5be..9ddd2f57679b 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 @@ public class TestNetworkManager { * @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 @@ public class TestNetworkManager { * @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 @@ public class TestNetworkManager { * 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 @@ public class TestNetworkManager { * 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 d0dc987b81ae..bd5f8ab26bd9 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 cc36b47029a2..852c689ae020 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 5aa3e5be2ae9..2e974aeb0ae1 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -2884,13 +2884,13 @@ public class ConnectivityService extends IConnectivityManager.Stub 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 @@ public class ConnectivityService extends IConnectivityManager.Stub 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 @@ public class ConnectivityService extends IConnectivityManager.Stub } } pw.decreaseIndent(); + pw.decreaseIndent(); + pw.println(); + pw.println("mOemNetworkPreferencesLogs (most recent first):"); + pw.increaseIndent(); + mOemNetworkPreferencesLogs.reverseDump(pw); pw.decreaseIndent(); } @@ -6205,6 +6210,12 @@ public class ConnectivityService extends IConnectivityManager.Stub @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 @@ public class ConnectivityService extends IConnectivityManager.Stub } 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 @@ public class ConnectivityService extends IConnectivityManager.Stub 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 8796516c1064..9c10658e7c0e 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 android.util.Slog; 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.VcnContext; 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 @@ public class VcnManagementService extends IVcnManagementService.Stub { } } + /** + * 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 cc5a25a57e38..2744f11f1c4e 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.graphics.Rect; 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 @@ public class ActivityManagerService extends IActivityManager.Stub 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 ffeb77d1d109..cf4fe1ef9f97 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 @@ public class DnsManager { /* * 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 58a702527e5f..8bb5204ee083 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 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { 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 0e4a2ee076c2..ca9c75f71504 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 @@ public class PackageDexOptimizer { 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 ae806aa500a6..7bc6056f91f3 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 android.util.Slog; 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 @@ public class Vcn extends Handler { 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 @@ public class Vcn extends Handler { 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 20c08eb2ce92..83ac36f9e0f6 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 android.util.Slog; 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.TelephonySubscriptionTracker.TelephonySubscription 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 @@ public class VcnGatewayConnection extends StateMachine { */ 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 @@ public class VcnGatewayConnection extends StateMachine { * <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 @@ public class VcnGatewayConnection extends StateMachine { 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 @@ public class VcnGatewayConnection extends StateMachine { 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 @@ public class VcnGatewayConnection extends StateMachine { 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 @@ public class VcnGatewayConnection extends StateMachine { 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 @@ public class VcnGatewayConnection extends StateMachine { 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 @@ public class VcnGatewayConnection extends StateMachine { 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 @@ public class VcnGatewayConnection extends StateMachine { 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 @@ public class VcnGatewayConnection extends StateMachine { @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 @@ public class VcnGatewayConnection extends StateMachine { } } + /** + * 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 @@ public class VcnGatewayConnection extends StateMachine { } @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 @@ public class VcnGatewayConnection extends StateMachine { 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 @@ public class VcnGatewayConnection extends StateMachine { @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 @@ public class VcnGatewayConnection extends StateMachine { 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 a90969599159..be0deb57ee76 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 android.util.Slog; 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 @@ public class VcnNetworkProvider extends NetworkProvider { 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 000000000000..49c1a02215e3 --- /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 6e539bbaf9fe..566698576026 100644 --- a/services/net/java/android/net/util/KeepalivePacketDataUtil.java +++ b/services/net/java/android/net/util/KeepalivePacketDataUtil.java @@ -80,12 +80,12 @@ public final class KeepalivePacketDataUtil { 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 38fa9077f188..3c3df51aa4e8 100644 --- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java +++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java @@ -525,7 +525,7 @@ public final class TelephonyPermissions { * * @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 @@ public final class TelephonyPermissions { * * @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 @@ public final class TelephonyPermissions { * * @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 677006692f84..7a18bb08faa8 100644 --- a/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt +++ b/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt @@ -92,12 +92,12 @@ class TcpKeepalivePacketDataTest { 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 e050495bfd0d..790f3be13293 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -18,6 +18,7 @@ package com.android.server; import static android.Manifest.permission.CHANGE_NETWORK_STATE; import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; +import static android.Manifest.permission.DUMP; import static android.Manifest.permission.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.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import kotlin.reflect.KClass; @@ -9950,6 +9953,7 @@ public class ConnectivityServiceTest { @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 @@ public class ConnectivityServiceTest { } @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 34c00182f855..bb67593d84ba 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 android.net.vcn.VcnManager.VCN_ERROR_CODE_NETWORK_ERROR; 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.LinkAddress; 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 @@ import java.util.function.Consumer; @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 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection } @Test - public void testMigratedTransformsAreApplied() throws Exception { + public void testMigration() throws Exception { + triggerChildOpened(); + getChildSessionCallback() .onIpSecTransformsMigrated(makeDummyIpSecTransform(), makeDummyIpSecTransform()); mTestLooper.dispatchAll(); @@ -170,6 +177,17 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection } 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 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection .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 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection 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 c5ed8f6ddcc7..dc73be25ffa3 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 @@ package com.android.server.vcn; 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.IpSecTunnelInterfaceResponse; 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 @@ public class VcnGatewayConnectionTestBase { 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 @@ public class VcnGatewayConnectionTestBase { 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 @@ public class VcnGatewayConnectionTestBase { 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 000000000000..29511f780bf6 --- /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 ceb705f4e42a..451fed6be353 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 2924e0109830..822aba4ee43b 100755 --- a/tools/hiddenapi/exclude.sh +++ b/tools/hiddenapi/exclude.sh @@ -48,7 +48,7 @@ SHA=$1 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" |