summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt15
-rw-r--r--core/api/system-current.txt15
-rw-r--r--core/java/android/app/AppOpsManager.java24
-rw-r--r--core/java/android/net/IIpSecService.aidl3
-rw-r--r--core/java/android/net/IpSecManager.java36
-rw-r--r--core/java/android/os/Debug.java7
-rw-r--r--core/jni/Android.bp1
-rw-r--r--core/jni/android_os_Debug.cpp45
-rw-r--r--core/res/res/values/config.xml2
-rw-r--r--core/tests/coretests/src/com/android/internal/widget/OWNERS3
-rw-r--r--services/core/java/com/android/server/IpSecService.java54
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java92
-rw-r--r--services/core/java/com/android/server/connectivity/QosCallbackTracker.java10
-rw-r--r--services/core/java/com/android/server/vcn/VcnGatewayConnection.java40
-rw-r--r--services/tests/servicestests/test-apps/ConnTestApp/OWNERS1
-rw-r--r--telephony/java/android/telephony/ims/ImsRegistrationAttributes.aidl19
-rw-r--r--telephony/java/android/telephony/ims/ImsRegistrationAttributes.java219
-rw-r--r--telephony/java/android/telephony/ims/RegistrationManager.java68
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl5
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java82
-rw-r--r--tests/net/java/com/android/server/IpSecServiceParameterizedTest.java152
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java11
22 files changed, 752 insertions, 152 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 7d30edee3a13..34d4be9a0d2d 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -42166,6 +42166,15 @@ package android.telephony.ims {
field public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; // 0x2
}
+ public final class ImsRegistrationAttributes implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getAttributeFlags();
+ method @NonNull public java.util.Set<java.lang.String> getFeatureTags();
+ method public int getTransportType();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsRegistrationAttributes> CREATOR;
+ }
+
public class RcsUceAdapter {
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isUceSettingEnabled() throws android.telephony.ims.ImsException;
}
@@ -42182,8 +42191,10 @@ package android.telephony.ims {
public static class RegistrationManager.RegistrationCallback {
ctor public RegistrationManager.RegistrationCallback();
- method public void onRegistered(int);
- method public void onRegistering(int);
+ method @Deprecated public void onRegistered(int);
+ method public void onRegistered(@NonNull android.telephony.ims.ImsRegistrationAttributes);
+ method @Deprecated public void onRegistering(int);
+ method public void onRegistering(@NonNull android.telephony.ims.ImsRegistrationAttributes);
method public void onTechnologyChangeFailed(int, @NonNull android.telephony.ims.ImsReasonInfo);
method public void onUnregistered(@NonNull android.telephony.ims.ImsReasonInfo);
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 4e23275f81cd..0d012264c162 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -6156,6 +6156,7 @@ package android.net {
method public void close();
method @NonNull public String getInterfaceName();
method @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void removeAddress(@NonNull java.net.InetAddress, int) throws java.io.IOException;
+ method @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void setUnderlyingNetwork(@NonNull android.net.Network) throws java.io.IOException;
}
public static class IpSecTransform.Builder {
@@ -11578,6 +11579,8 @@ package android.telephony.ims {
@Deprecated public static class ImsMmTelManager.RegistrationCallback extends android.telephony.ims.RegistrationManager.RegistrationCallback {
ctor @Deprecated public ImsMmTelManager.RegistrationCallback();
+ method @Deprecated public void onRegistered(int);
+ method @Deprecated public void onRegistering(int);
}
public class ImsRcsManager {
@@ -11595,6 +11598,16 @@ package android.telephony.ims {
field public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service";
}
+ public final class ImsRegistrationAttributes implements android.os.Parcelable {
+ method public int getRegistrationTechnology();
+ }
+
+ public static final class ImsRegistrationAttributes.Builder {
+ ctor public ImsRegistrationAttributes.Builder(int);
+ method @NonNull public android.telephony.ims.ImsRegistrationAttributes build();
+ method @NonNull public android.telephony.ims.ImsRegistrationAttributes.Builder setFeatureTags(@NonNull java.util.Set<java.lang.String>);
+ }
+
public class ImsService extends android.app.Service {
ctor public ImsService();
method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int);
@@ -12378,7 +12391,9 @@ package android.telephony.ims.stub {
ctor public ImsRegistrationImplBase();
method public final void onDeregistered(android.telephony.ims.ImsReasonInfo);
method public final void onRegistered(int);
+ method public final void onRegistered(@NonNull android.telephony.ims.ImsRegistrationAttributes);
method public final void onRegistering(int);
+ method public final void onRegistering(@NonNull android.telephony.ims.ImsRegistrationAttributes);
method public final void onSubscriberAssociatedUriChanged(android.net.Uri[]);
method public final void onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo);
method public void triggerFullNetworkRegistration(@IntRange(from=100, to=699) int, @Nullable String);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 31ab2248236d..797253af394b 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1136,9 +1136,16 @@ public class AppOpsManager {
// TODO: Add as AppProtoEnums
public static final int OP_RECORD_AUDIO_HOTWORD = 102;
+ /**
+ * Manage credentials in the system KeyChain.
+ *
+ * @hide
+ */
+ public static final int OP_MANAGE_CREDENTIALS = AppProtoEnums.APP_OP_MANAGE_CREDENTIALS;
+
/** @hide */
@UnsupportedAppUsage
- public static final int _NUM_OP = 104;
+ public static final int _NUM_OP = 105;
/** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -1485,6 +1492,13 @@ public class AppOpsManager {
*/
public static final String OPSTR_RECORD_AUDIO_HOTWORD = "android:record_audio_hotword";
+ /**
+ * Manage credentials in the system KeyChain.
+ *
+ * @hide
+ */
+ public static final String OPSTR_MANAGE_CREDENTIALS = "android:manage_credentials";
+
/** {@link #sAppOpsToNote} not initialized yet for this op */
private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
/** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
@@ -1679,6 +1693,7 @@ public class AppOpsManager {
OP_PHONE_CALL_CAMERA, // OP_PHONE_CALL_CAMERA
OP_RECORD_AUDIO_HOTWORD, // RECORD_AUDIO_HOTWORD
OP_MANAGE_ONGOING_CALLS, // MANAGE_ONGOING_CALLS
+ OP_MANAGE_CREDENTIALS, // MANAGE_CREDENTIALS
};
/**
@@ -1789,6 +1804,7 @@ public class AppOpsManager {
OPSTR_PHONE_CALL_CAMERA,
OPSTR_RECORD_AUDIO_HOTWORD,
OPSTR_MANAGE_ONGOING_CALLS,
+ OPSTR_MANAGE_CREDENTIALS,
};
/**
@@ -1900,6 +1916,7 @@ public class AppOpsManager {
"PHONE_CALL_CAMERA",
"RECORD_AUDIO_HOTWORD",
"MANAGE_ONGOING_CALLS",
+ "MANAGE_CREDENTIALS",
};
/**
@@ -2012,6 +2029,7 @@ public class AppOpsManager {
null, // no permission for OP_PHONE_CALL_CAMERA
null, // no permission for OP_RECORD_AUDIO_HOTWORD
Manifest.permission.MANAGE_ONGOING_CALLS,
+ null, // no permission for OP_MANAGE_CREDENTIALS
};
/**
@@ -2124,6 +2142,7 @@ public class AppOpsManager {
null, // PHONE_CALL_MICROPHONE
null, // RECORD_AUDIO_HOTWORD
null, // MANAGE_ONGOING_CALLS
+ null, // MANAGE_CREDENTIALS
};
/**
@@ -2235,6 +2254,7 @@ public class AppOpsManager {
null, // PHONE_CALL_CAMERA
null, // RECORD_AUDIO_HOTWORD
null, // MANAGE_ONGOING_CALLS
+ null, // MANAGE_CREDENTIALS
};
/**
@@ -2345,6 +2365,7 @@ public class AppOpsManager {
AppOpsManager.MODE_ALLOWED, // PHONE_CALL_CAMERA
AppOpsManager.MODE_ALLOWED, // OP_RECORD_AUDIO_HOTWORD
AppOpsManager.MODE_DEFAULT, // MANAGE_ONGOING_CALLS
+ AppOpsManager.MODE_DEFAULT, // MANAGE_CREDENTIALS
};
/**
@@ -2459,6 +2480,7 @@ public class AppOpsManager {
false, // PHONE_CALL_CAMERA
false, // RECORD_AUDIO_HOTWORD
true, // MANAGE_ONGOING_CALLS
+ false, // MANAGE_CREDENTIALS
};
/**
diff --git a/core/java/android/net/IIpSecService.aidl b/core/java/android/net/IIpSecService.aidl
index d6774d47b49e..933256a3b475 100644
--- a/core/java/android/net/IIpSecService.aidl
+++ b/core/java/android/net/IIpSecService.aidl
@@ -58,6 +58,9 @@ interface IIpSecService
in LinkAddress localAddr,
in String callingPackage);
+ void setNetworkForTunnelInterface(
+ int tunnelResourceId, in Network underlyingNetwork, in String callingPackage);
+
void deleteTunnelInterface(int resourceId, in String callingPackage);
IpSecTransformResponse createTransform(
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index 70bca3019818..98acd98cc465 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -782,6 +782,42 @@ public final class IpSecManager {
}
}
+ /**
+ * Update the underlying network for this IpSecTunnelInterface.
+ *
+ * <p>This new underlying network will be used for all transforms applied AFTER this call is
+ * complete. Before new {@link IpSecTransform}(s) with matching addresses are applied to
+ * this tunnel interface, traffic will still use the old SA, and be routed on the old
+ * underlying network.
+ *
+ * <p>To migrate IPsec tunnel mode traffic, a caller should:
+ *
+ * <ol>
+ * <li>Update the IpSecTunnelInterface’s underlying network.
+ * <li>Apply {@link IpSecTransform}(s) with matching addresses to this
+ * IpSecTunnelInterface.
+ * </ol>
+ *
+ * @param underlyingNetwork the new {@link Network} that will carry traffic for this tunnel.
+ * This network MUST never be the network exposing this IpSecTunnelInterface, otherwise
+ * this method will throw an {@link IllegalArgumentException}.
+ */
+ // TODO: b/169171001 Update the documentation when transform migration is supported.
+ // The purpose of making updating network and applying transforms separate is to leave open
+ // the possibility to support lossless migration procedures. To do that, Android platform
+ // will need to support multiple inbound tunnel mode transforms, just like it can support
+ // multiple transport mode transforms.
+ @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
+ @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
+ public void setUnderlyingNetwork(@NonNull Network underlyingNetwork) throws IOException {
+ try {
+ mService.setNetworkForTunnelInterface(
+ mResourceId, underlyingNetwork, mOpPackageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
private IpSecTunnelInterface(@NonNull Context ctx, @NonNull IIpSecService service,
@NonNull InetAddress localAddress, @NonNull InetAddress remoteAddress,
@NonNull Network underlyingNetwork)
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index a2cf1aee3250..ea282afb8b8e 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -2584,6 +2584,13 @@ public final class Debug
public static native long getIonPoolsSizeKb();
/**
+ * Return GPU DMA buffer usage in kB or -1 on error.
+ *
+ * @hide
+ */
+ public static native long getGpuDmaBufUsageKb();
+
+ /**
* Return DMA-BUF memory mapped by processes in kB.
* Notes:
* * Warning: Might impact performance as it reads /proc/<pid>/maps files for each process.
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 79a0dfd61e9f..088682c9f2d8 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -206,6 +206,7 @@ cc_library_shared {
],
shared_libs: [
+ "android.hardware.memtrack-unstable-ndk_platform",
"libandroidicu",
"libbpf_android",
"libnetdbpf",
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index b5373f7347ae..223b4dcc0549 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -33,6 +33,7 @@
#include <string>
#include <vector>
+#include <aidl/android/hardware/memtrack/DeviceInfo.h>
#include <android-base/logging.h>
#include <bionic/malloc.h>
#include <debuggerd/client.h>
@@ -45,6 +46,7 @@
#include "jni.h"
#include <dmabufinfo/dmabuf_sysfs_stats.h>
#include <dmabufinfo/dmabufinfo.h>
+#include <dmabufinfo/dmabuf_sysfs_stats.h>
#include <meminfo/procmeminfo.h>
#include <meminfo/sysmeminfo.h>
#include <memtrack/memtrack.h>
@@ -520,14 +522,15 @@ static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid,
}
if (outUssSwapPssRss != NULL) {
- if (env->GetArrayLength(outUssSwapPssRss) >= 1) {
+ int outLen = env->GetArrayLength(outUssSwapPssRss);
+ if (outLen >= 1) {
jlong* outUssSwapPssRssArray = env->GetLongArrayElements(outUssSwapPssRss, 0);
if (outUssSwapPssRssArray != NULL) {
outUssSwapPssRssArray[0] = uss;
- if (env->GetArrayLength(outUssSwapPssRss) >= 2) {
+ if (outLen >= 2) {
outUssSwapPssRssArray[1] = swapPss;
}
- if (env->GetArrayLength(outUssSwapPssRss) >= 3) {
+ if (outLen >= 3) {
outUssSwapPssRssArray[2] = rss;
}
}
@@ -536,17 +539,18 @@ static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid,
}
if (outMemtrack != NULL) {
- if (env->GetArrayLength(outMemtrack) >= 1) {
+ int outLen = env->GetArrayLength(outMemtrack);
+ if (outLen >= 1) {
jlong* outMemtrackArray = env->GetLongArrayElements(outMemtrack, 0);
if (outMemtrackArray != NULL) {
outMemtrackArray[0] = memtrack;
- if (env->GetArrayLength(outMemtrack) >= 2) {
+ if (outLen >= 2) {
outMemtrackArray[1] = graphics_mem.graphics;
}
- if (env->GetArrayLength(outMemtrack) >= 3) {
+ if (outLen >= 3) {
outMemtrackArray[2] = graphics_mem.gl;
}
- if (env->GetArrayLength(outMemtrack) >= 4) {
+ if (outLen >= 4) {
outMemtrackArray[3] = graphics_mem.other;
}
}
@@ -844,6 +848,31 @@ static jlong android_os_Debug_getDmabufHeapPoolsSizeKb(JNIEnv* env, jobject claz
return poolsSizeKb;
}
+static jlong android_os_Debug_getGpuDmaBufUsageKb(JNIEnv* env, jobject clazz) {
+ std::vector<aidl::android::hardware::memtrack::DeviceInfo> gpu_device_info;
+ if (!memtrack_gpu_device_info(&gpu_device_info)) {
+ return -1;
+ }
+
+ dmabufinfo::DmabufSysfsStats stats;
+ if (!GetDmabufSysfsStats(&stats)) {
+ return -1;
+ }
+
+ jlong sizeKb = 0;
+ const auto& importer_stats = stats.importer_info();
+ for (const auto& dev_info : gpu_device_info) {
+ const auto& importer_info = importer_stats.find(dev_info.name);
+ if (importer_info == importer_stats.end()) {
+ continue;
+ }
+
+ sizeKb += importer_info->second.size;
+ }
+
+ return sizeKb;
+}
+
static jlong android_os_Debug_getDmabufMappedSizeKb(JNIEnv* env, jobject clazz) {
jlong dmabufPss = 0;
std::vector<dmabufinfo::DmaBuffer> dmabufs;
@@ -952,6 +981,8 @@ static const JNINativeMethod gMethods[] = {
(void*)android_os_Debug_getIonHeapsSizeKb },
{ "getDmabufTotalExportedKb", "()J",
(void*)android_os_Debug_getDmabufTotalExportedKb },
+ { "getGpuDmaBufUsageKb", "()J",
+ (void*)android_os_Debug_getGpuDmaBufUsageKb },
{ "getIonPoolsSizeKb", "()J",
(void*)android_os_Debug_getIonPoolsSizeKb },
{ "getDmabufMappedSizeKb", "()J",
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 20cb27085661..ee45249c2030 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1547,8 +1547,8 @@
take precedence over lower ones.
See com.android.server.timedetector.TimeDetectorStrategy for available sources. -->
<string-array name="config_autoTimeSourcesPriority">
- <item>telephony</item>
<item>network</item>
+ <item>telephony</item>
</string-array>
<!-- Enables the TimeZoneRuleManager service. This is the global switch for the updateable time
diff --git a/core/tests/coretests/src/com/android/internal/widget/OWNERS b/core/tests/coretests/src/com/android/internal/widget/OWNERS
new file mode 100644
index 000000000000..b40fe240d80c
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/widget/OWNERS
@@ -0,0 +1,3 @@
+# LockSettings related
+per-file *LockPattern* = file:/services/core/java/com/android/server/locksettings/OWNERS
+per-file *Lockscreen* = file:/services/core/java/com/android/server/locksettings/OWNERS
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index f648c3e146de..b48bc900aa84 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -29,6 +29,7 @@ import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
import android.net.IIpSecService;
import android.net.INetd;
import android.net.InetAddresses;
@@ -41,6 +42,7 @@ import android.net.IpSecTransformResponse;
import android.net.IpSecTunnelInterfaceResponse;
import android.net.IpSecUdpEncapResponse;
import android.net.LinkAddress;
+import android.net.LinkProperties;
import android.net.Network;
import android.net.TrafficStats;
import android.net.util.NetdService;
@@ -797,9 +799,15 @@ public class IpSecService extends IIpSecService.Stub {
}
}
- private final class TunnelInterfaceRecord extends OwnedResourceRecord {
+ /**
+ * Tracks an tunnel interface, and manages cleanup paths.
+ *
+ * <p>This class is not thread-safe, and expects that that users of this class will ensure
+ * synchronization and thread safety by holding the IpSecService.this instance lock
+ */
+ @VisibleForTesting
+ final class TunnelInterfaceRecord extends OwnedResourceRecord {
private final String mInterfaceName;
- private final Network mUnderlyingNetwork;
// outer addresses
private final String mLocalAddress;
@@ -810,6 +818,8 @@ public class IpSecService extends IIpSecService.Stub {
private final int mIfId;
+ private Network mUnderlyingNetwork;
+
TunnelInterfaceRecord(
int resourceId,
String interfaceName,
@@ -870,14 +880,22 @@ public class IpSecService extends IIpSecService.Stub {
releaseNetId(mOkey);
}
- public String getInterfaceName() {
- return mInterfaceName;
+ @GuardedBy("IpSecService.this")
+ public void setUnderlyingNetwork(Network underlyingNetwork) {
+ // When #applyTunnelModeTransform is called, this new underlying network will be used to
+ // update the output mark of the input transform.
+ mUnderlyingNetwork = underlyingNetwork;
}
+ @GuardedBy("IpSecService.this")
public Network getUnderlyingNetwork() {
return mUnderlyingNetwork;
}
+ public String getInterfaceName() {
+ return mInterfaceName;
+ }
+
/** Returns the local, outer address for the tunnelInterface */
public String getLocalAddress() {
return mLocalAddress;
@@ -1429,6 +1447,34 @@ public class IpSecService extends IIpSecService.Stub {
}
}
+ /** Set TunnelInterface to use a specific underlying network. */
+ @Override
+ public synchronized void setNetworkForTunnelInterface(
+ int tunnelResourceId, Network underlyingNetwork, String callingPackage) {
+ enforceTunnelFeatureAndPermissions(callingPackage);
+ Objects.requireNonNull(underlyingNetwork, "No underlying network was specified");
+
+ final UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+
+ // Get tunnelInterface record; if no such interface is found, will throw
+ // IllegalArgumentException. userRecord.mTunnelInterfaceRecords is never null
+ final TunnelInterfaceRecord tunnelInterfaceInfo =
+ userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelResourceId);
+
+ final ConnectivityManager connectivityManager =
+ mContext.getSystemService(ConnectivityManager.class);
+ final LinkProperties lp = connectivityManager.getLinkProperties(underlyingNetwork);
+ if (tunnelInterfaceInfo.getInterfaceName().equals(lp.getInterfaceName())) {
+ throw new IllegalArgumentException(
+ "Underlying network cannot be the network being exposed by this tunnel");
+ }
+
+ // It is meaningless to check if the network exists or is valid because the network might
+ // disconnect at any time after it passes the check.
+
+ tunnelInterfaceInfo.setUnderlyingNetwork(underlyingNetwork);
+ }
+
/**
* Delete a TunnelInterface that has been been allocated by and registered with the system
* server
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f5df87eefafd..126d04f794f5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -13318,6 +13318,7 @@ public class ActivityManagerService extends IActivityManager.Stub
long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
long[] miscRss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
+ long[] memtrackTmp = new long[4];
long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
@@ -13330,6 +13331,8 @@ public class ActivityManagerService extends IActivityManager.Stub
long totalRss = 0;
long cachedPss = 0;
long cachedSwapPss = 0;
+ long totalMemtrackGraphics = 0;
+ long totalMemtrackGl = 0;
boolean hasSwapPss = false;
Debug.MemoryInfo mi = null;
@@ -13352,6 +13355,8 @@ public class ActivityManagerService extends IActivityManager.Stub
final int reportType;
final long startTime;
final long endTime;
+ long memtrackGraphics = 0;
+ long memtrackGl = 0;
if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
startTime = SystemClock.currentThreadTimeMillis();
@@ -13363,7 +13368,7 @@ public class ActivityManagerService extends IActivityManager.Stub
} else {
reportType = ProcessStats.ADD_PSS_EXTERNAL;
startTime = SystemClock.currentThreadTimeMillis();
- long pss = Debug.getPss(pid, tmpLong, null);
+ long pss = Debug.getPss(pid, tmpLong, memtrackTmp);
if (pss == 0) {
continue;
}
@@ -13371,6 +13376,8 @@ public class ActivityManagerService extends IActivityManager.Stub
endTime = SystemClock.currentThreadTimeMillis();
mi.dalvikPrivateDirty = (int) tmpLong[0];
mi.dalvikRss = (int) tmpLong[2];
+ memtrackGraphics = memtrackTmp[1];
+ memtrackGl = memtrackTmp[2];
}
if (!opts.isCheckinRequest && opts.dumpDetails) {
pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
@@ -13435,6 +13442,8 @@ public class ActivityManagerService extends IActivityManager.Stub
totalPss += myTotalPss;
totalSwapPss += myTotalSwapPss;
totalRss += myTotalRss;
+ totalMemtrackGraphics += memtrackGraphics;
+ totalMemtrackGl += memtrackGl;
MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
(hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
myTotalSwapPss, myTotalRss, pid, hasActivities);
@@ -13500,6 +13509,8 @@ public class ActivityManagerService extends IActivityManager.Stub
for (int i=0; i<N; i++) {
ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
+ long memtrackGraphics = 0;
+ long memtrackGl = 0;
if (mi == null) {
mi = new Debug.MemoryInfo();
}
@@ -13508,13 +13519,15 @@ public class ActivityManagerService extends IActivityManager.Stub
continue;
}
} else {
- long pss = Debug.getPss(st.pid, tmpLong, null);
+ long pss = Debug.getPss(st.pid, tmpLong, memtrackTmp);
if (pss == 0) {
continue;
}
mi.nativePss = (int) pss;
mi.nativePrivateDirty = (int) tmpLong[0];
mi.nativeRss = (int) tmpLong[2];
+ memtrackGraphics = memtrackTmp[1];
+ memtrackGl = memtrackTmp[2];
}
final long myTotalPss = mi.getTotalPss();
@@ -13524,6 +13537,8 @@ public class ActivityManagerService extends IActivityManager.Stub
totalSwapPss += myTotalSwapPss;
totalRss += myTotalRss;
nativeProcTotalPss += myTotalPss;
+ totalMemtrackGraphics += memtrackGraphics;
+ totalMemtrackGl += memtrackGl;
MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
st.name, myTotalPss, mi.getSummaryTotalSwapPss(), myTotalRss,
@@ -13746,7 +13761,11 @@ public class ActivityManagerService extends IActivityManager.Stub
pw.print(" mapped + ");
pw.print(stringifyKBSize(dmabufUnmapped));
pw.println(" unmapped)");
- kernelUsed += totalExportedDmabuf;
+ // Account unmapped dmabufs as part of kernel memory allocations
+ kernelUsed += dmabufUnmapped;
+ // Replace memtrack HAL reported Graphics category with mapped dmabufs
+ totalPss -= totalMemtrackGraphics;
+ totalPss += dmabufMapped;
}
final long totalDmabufHeapPool = Debug.getDmabufHeapPoolsSizeKb();
if (totalDmabufHeapPool >= 0) {
@@ -13756,13 +13775,27 @@ public class ActivityManagerService extends IActivityManager.Stub
}
final long gpuUsage = Debug.getGpuTotalUsageKb();
if (gpuUsage >= 0) {
- pw.print(" GPU: "); pw.println(stringifyKBSize(gpuUsage));
+ final long gpuDmaBufUsage = Debug.getGpuDmaBufUsageKb();
+ if (gpuDmaBufUsage >= 0) {
+ final long gpuPrivateUsage = gpuUsage - gpuDmaBufUsage;
+ pw.print(" GPU: ");
+ pw.print(stringifyKBSize(gpuUsage));
+ pw.print(" (");
+ pw.print(stringifyKBSize(gpuDmaBufUsage));
+ pw.print(" dmabuf + ");
+ pw.print(stringifyKBSize(gpuPrivateUsage));
+ pw.println(" private)");
+ // Replace memtrack HAL reported GL category with private GPU allocations and
+ // account it as part of kernel memory allocations
+ totalPss -= totalMemtrackGl;
+ kernelUsed += gpuPrivateUsage;
+ } else {
+ pw.print(" GPU: "); pw.println(stringifyKBSize(gpuUsage));
+ }
}
- /*
- * Note: ION/DMA-BUF heap pools are reclaimable and hence, they are included as part of
- * memInfo.getCachedSizeKb().
- */
+ // Note: ION/DMA-BUF heap pools are reclaimable and hence, they are included as part of
+ // memInfo.getCachedSizeKb().
final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- kernelUsed - memInfo.getZramTotalSizeKb();
@@ -14366,7 +14399,7 @@ public class ActivityManagerService extends IActivityManager.Stub
infoMap.put(mi.pid, mi);
}
updateCpuStatsNow();
- long[] memtrackTmp = new long[1];
+ long[] memtrackTmp = new long[4];
long[] swaptrackTmp = new long[2];
final List<ProcessCpuTracker.Stats> stats;
// Get a list of Stats that have vsize > 0
@@ -14394,6 +14427,8 @@ public class ActivityManagerService extends IActivityManager.Stub
long totalPss = 0;
long totalSwapPss = 0;
long totalMemtrack = 0;
+ long totalMemtrackGraphics = 0;
+ long totalMemtrackGl = 0;
for (int i=0, N=memInfos.size(); i<N; i++) {
ProcessMemInfo mi = memInfos.get(i);
if (mi.pss == 0) {
@@ -14404,6 +14439,8 @@ public class ActivityManagerService extends IActivityManager.Stub
totalPss += mi.pss;
totalSwapPss += mi.swapPss;
totalMemtrack += mi.memtrack;
+ totalMemtrackGraphics += memtrackTmp[1];
+ totalMemtrackGl += memtrackTmp[2];
}
Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
@Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
@@ -14571,10 +14608,16 @@ public class ActivityManagerService extends IActivityManager.Stub
} else {
final long totalExportedDmabuf = Debug.getDmabufTotalExportedKb();
if (totalExportedDmabuf >= 0) {
+ final long dmabufMapped = Debug.getDmabufMappedSizeKb();
+ final long dmabufUnmapped = totalExportedDmabuf - dmabufMapped;
memInfoBuilder.append("DMA-BUF: ");
memInfoBuilder.append(stringifyKBSize(totalExportedDmabuf));
memInfoBuilder.append("\n");
- kernelUsed += totalExportedDmabuf;
+ // Account unmapped dmabufs as part of kernel memory allocations
+ kernelUsed += dmabufUnmapped;
+ // Replace memtrack HAL reported Graphics category with mapped dmabufs
+ totalPss -= totalMemtrackGraphics;
+ totalPss += dmabufMapped;
}
final long totalDmabufHeapPool = Debug.getDmabufHeapPoolsSizeKb();
if (totalDmabufHeapPool >= 0) {
@@ -14586,19 +14629,34 @@ public class ActivityManagerService extends IActivityManager.Stub
final long gpuUsage = Debug.getGpuTotalUsageKb();
if (gpuUsage >= 0) {
- memInfoBuilder.append(" GPU: ");
- memInfoBuilder.append(stringifyKBSize(gpuUsage));
- memInfoBuilder.append("\n");
+ final long gpuDmaBufUsage = Debug.getGpuDmaBufUsageKb();
+ if (gpuDmaBufUsage >= 0) {
+ final long gpuPrivateUsage = gpuUsage - gpuDmaBufUsage;
+ memInfoBuilder.append(" GPU: ");
+ memInfoBuilder.append(stringifyKBSize(gpuUsage));
+ memInfoBuilder.append(" (");
+ memInfoBuilder.append(stringifyKBSize(gpuDmaBufUsage));
+ memInfoBuilder.append(" dmabuf + ");
+ memInfoBuilder.append(stringifyKBSize(gpuPrivateUsage));
+ memInfoBuilder.append(" private)\n");
+ // Replace memtrack HAL reported GL category with private GPU allocations and
+ // account it as part of kernel memory allocations
+ totalPss -= totalMemtrackGl;
+ kernelUsed += gpuPrivateUsage;
+ } else {
+ memInfoBuilder.append(" GPU: ");
+ memInfoBuilder.append(stringifyKBSize(gpuUsage));
+ memInfoBuilder.append("\n");
+ }
+
}
memInfoBuilder.append(" Used RAM: ");
memInfoBuilder.append(stringifyKBSize(
totalPss - cachedPss + kernelUsed));
memInfoBuilder.append("\n");
- /*
- * Note: ION/DMA-BUF heap pools are reclaimable and hence, they are included as part of
- * memInfo.getCachedSizeKb().
- */
+ // Note: ION/DMA-BUF heap pools are reclaimable and hence, they are included as part of
+ // memInfo.getCachedSizeKb().
memInfoBuilder.append(" Lost RAM: ");
memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
- (totalPss - totalSwapPss) - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
diff --git a/services/core/java/com/android/server/connectivity/QosCallbackTracker.java b/services/core/java/com/android/server/connectivity/QosCallbackTracker.java
index 87b4c162a2cc..7ef315c469ae 100644
--- a/services/core/java/com/android/server/connectivity/QosCallbackTracker.java
+++ b/services/core/java/com/android/server/connectivity/QosCallbackTracker.java
@@ -27,7 +27,7 @@ import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.data.EpsBearerQosSessionAttributes;
-import android.util.Slog;
+import android.util.Log;
import com.android.internal.util.CollectionUtils;
import com.android.server.ConnectivityService;
@@ -260,18 +260,18 @@ public class QosCallbackTracker {
}
private static void log(final String msg) {
- Slog.d(TAG, msg);
+ Log.d(TAG, msg);
}
private static void logw(final String msg) {
- Slog.w(TAG, msg);
+ Log.w(TAG, msg);
}
private static void loge(final String msg) {
- Slog.e(TAG, msg);
+ Log.e(TAG, msg);
}
private static void logwtf(final String msg) {
- Slog.wtf(TAG, msg);
+ Log.wtf(TAG, msg);
}
}
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 2503e812f9e1..37d13fb86dc0 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -125,10 +125,11 @@ import java.util.concurrent.TimeUnit;
public class VcnGatewayConnection extends StateMachine {
private static final String TAG = VcnGatewayConnection.class.getSimpleName();
+ @VisibleForTesting(visibility = Visibility.PRIVATE)
+ static final InetAddress DUMMY_ADDR = InetAddresses.parseNumericAddress("192.0.2.0");
+
private static final int[] MERGED_CAPABILITIES =
new int[] {NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_NOT_ROAMING};
-
- private static final InetAddress DUMMY_ADDR = InetAddresses.parseNumericAddress("192.0.2.0");
private static final int ARG_NOT_PRESENT = Integer.MIN_VALUE;
private static final String DISCONNECT_REASON_INTERNAL_ERROR = "Uncaught exception: ";
@@ -412,11 +413,11 @@ public class VcnGatewayConnection extends StateMachine {
@NonNull private final VcnGatewayConnectionConfig mConnectionConfig;
@NonNull private final VcnGatewayStatusCallback mGatewayStatusCallback;
@NonNull private final Dependencies mDeps;
-
@NonNull private final VcnUnderlyingNetworkTrackerCallback mUnderlyingNetworkTrackerCallback;
@NonNull private final IpSecManager mIpSecManager;
- @NonNull private final IpSecTunnelInterface mTunnelIface;
+
+ @Nullable private IpSecTunnelInterface mTunnelIface = null;
/** Running state of this VcnGatewayConnection. */
private boolean mIsRunning = true;
@@ -526,20 +527,6 @@ public class VcnGatewayConnection extends StateMachine {
mUnderlyingNetworkTrackerCallback);
mIpSecManager = mVcnContext.getContext().getSystemService(IpSecManager.class);
- IpSecTunnelInterface iface;
- try {
- iface =
- mIpSecManager.createIpSecTunnelInterface(
- DUMMY_ADDR, DUMMY_ADDR, new Network(-1));
- } catch (IOException | ResourceUnavailableException e) {
- teardownAsynchronously();
- mTunnelIface = null;
-
- return;
- }
-
- mTunnelIface = iface;
-
addState(mDisconnectedState);
addState(mDisconnectingState);
addState(mConnectingState);
@@ -1117,6 +1104,18 @@ public class VcnGatewayConnection extends StateMachine {
class ConnectedState extends ConnectedStateBase {
@Override
protected void enterState() throws Exception {
+ if (mTunnelIface == null) {
+ try {
+ // Requires a real Network object in order to be created; doing this any earlier
+ // means not having a real Network object, or picking an incorrect Network.
+ mTunnelIface =
+ mIpSecManager.createIpSecTunnelInterface(
+ DUMMY_ADDR, DUMMY_ADDR, mUnderlying.network);
+ } catch (IOException | ResourceUnavailableException e) {
+ teardownAsynchronously();
+ }
+ }
+
// Successful connection, clear failed attempt counter
mFailedAttempts = 0;
}
@@ -1434,6 +1433,11 @@ public class VcnGatewayConnection extends StateMachine {
}
@VisibleForTesting(visibility = Visibility.PRIVATE)
+ void setTunnelInterface(IpSecTunnelInterface tunnelIface) {
+ mTunnelIface = tunnelIface;
+ }
+
+ @VisibleForTesting(visibility = Visibility.PRIVATE)
UnderlyingNetworkTrackerCallback getUnderlyingNetworkTrackerCallback() {
return mUnderlyingNetworkTrackerCallback;
}
diff --git a/services/tests/servicestests/test-apps/ConnTestApp/OWNERS b/services/tests/servicestests/test-apps/ConnTestApp/OWNERS
new file mode 100644
index 000000000000..aa87958f1d53
--- /dev/null
+++ b/services/tests/servicestests/test-apps/ConnTestApp/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/telephony/java/android/telephony/ims/ImsRegistrationAttributes.aidl b/telephony/java/android/telephony/ims/ImsRegistrationAttributes.aidl
new file mode 100644
index 000000000000..0830ff2ff050
--- /dev/null
+++ b/telephony/java/android/telephony/ims/ImsRegistrationAttributes.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+parcelable ImsRegistrationAttributes;
diff --git a/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java b/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java
new file mode 100644
index 000000000000..a36f54953e63
--- /dev/null
+++ b/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.util.ArraySet;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Contains the attributes associated with the current IMS registration.
+ */
+public final class ImsRegistrationAttributes implements Parcelable {
+
+ /**
+ * Builder for creating {@link ImsRegistrationAttributes} instances.
+ * @hide
+ */
+ @SystemApi
+ public static final class Builder {
+ private final int mRegistrationTech;
+ private Set<String> mFeatureTags = Collections.emptySet();
+
+ /**
+ * Build a new instance of {@link ImsRegistrationAttributes}.
+ *
+ * @param registrationTech The Radio Access Technology that IMS is registered on.
+ */
+ public Builder(@ImsRegistrationImplBase.ImsRegistrationTech int registrationTech) {
+ mRegistrationTech = registrationTech;
+ }
+
+ /**
+ * Optional IMS feature tags included in this IMS registration.
+ * @param tags A set of Strings containing the MMTEL and RCS feature tags associated with
+ * the IMS registration. This information is used for services such as the UCE
+ * service to ascertain the complete IMS registration state to ensure the SIP
+ * PUBLISH is accurate. The format of the set of feature tags must be one feature
+ * tag key and value per entry. Each feature tag will contain the feature tag name
+ * and string value (if applicable), even if they have the same feature tag name.
+ * For example,
+ * {@code +g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg,
+ * urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session", +g.gsma.callcomposer} must
+ * be split into three feature tag entries:
+ * {@code {+g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg",
+ * +g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session",
+ * +g.gsma.callcomposer}}.
+ */
+ public @NonNull Builder setFeatureTags(@NonNull Set<String> tags) {
+ if (tags == null) {
+ throw new IllegalArgumentException("feature tag set must not be null");
+ }
+ mFeatureTags = new ArraySet<>(tags);
+ return this;
+ }
+
+ /**
+ * @return A new instance created from this builder.
+ */
+ public @NonNull ImsRegistrationAttributes build() {
+ return new ImsRegistrationAttributes(mRegistrationTech,
+ RegistrationManager.getAccessType(mRegistrationTech),
+ 0 /* No attributes in AOSP */, mFeatureTags);
+ }
+
+ }
+
+ private final int mRegistrationTech;
+ private final int mTransportType;
+ private final int mImsAttributeFlags;
+ private final ArrayList<String> mFeatureTags;
+
+ /**
+ * Create a new {@link ImsRegistrationAttributes} instance.
+ *
+ * @param registrationTech The technology that IMS has been registered on.
+ * @param transportType The transport type that IMS has been registered on.
+ * @param imsAttributeFlags The attributes associated with the IMS registration.
+ * @param featureTags The feature tags included in the IMS registration.
+ * @see Builder
+ * @hide
+ */
+ public ImsRegistrationAttributes(
+ @ImsRegistrationImplBase.ImsRegistrationTech int registrationTech,
+ @AccessNetworkConstants.TransportType int transportType,
+ int imsAttributeFlags,
+ @Nullable Set<String> featureTags) {
+ mRegistrationTech = registrationTech;
+ mTransportType = transportType;
+ mImsAttributeFlags = imsAttributeFlags;
+ mFeatureTags = new ArrayList<>(featureTags);
+ }
+
+ /**@hide*/
+ public ImsRegistrationAttributes(Parcel source) {
+ mRegistrationTech = source.readInt();
+ mTransportType = source.readInt();
+ mImsAttributeFlags = source.readInt();
+ mFeatureTags = new ArrayList<>();
+ source.readList(mFeatureTags, null /*classloader*/);
+ }
+
+ /**
+ * @return The Radio Access Technology that the IMS registration has been registered over.
+ * @hide
+ */
+ @SystemApi
+ public @ImsRegistrationImplBase.ImsRegistrationTech int getRegistrationTechnology() {
+ return mRegistrationTech;
+ }
+
+ /**
+ * @return The access network transport type that IMS has been registered over.
+ */
+ public @AccessNetworkConstants.TransportType int getTransportType() {
+ return mTransportType;
+ }
+
+ /**
+ * @return A bit-mask containing attributes associated with the IMS registration.
+ */
+ public int getAttributeFlags() {
+ return mImsAttributeFlags;
+ }
+
+ /**
+ * Gets the Set of feature tags associated with the current IMS registration, if the IMS
+ * service supports supplying this information.
+ * <p>
+ * The format of the set of feature tags will be one feature tag key and value per entry and
+ * will potentially contain MMTEL and RCS feature tags, depending the configuration of the IMS
+ * service associated with the registration indications. Each feature tag will contain the
+ * feature tag name and string value (if applicable), even if they have the same feature tag
+ * name. For example, {@code +g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg,
+ * urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session", +g.gsma.callcomposer} will be split
+ * into three feature tag entries:
+ * {@code {+g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg",
+ * +g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session",
+ * +g.gsma.callcomposer}}.
+ * @return The Set of feature tags associated with the current IMS registration.
+ */
+ public @NonNull Set<String> getFeatureTags() {
+ if (mFeatureTags == null) {
+ return Collections.emptySet();
+ }
+ return new ArraySet<>(mFeatureTags);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mRegistrationTech);
+ dest.writeInt(mTransportType);
+ dest.writeInt(mImsAttributeFlags);
+ dest.writeList(mFeatureTags);
+ }
+
+ public static final @NonNull Creator<ImsRegistrationAttributes> CREATOR =
+ new Creator<ImsRegistrationAttributes>() {
+ @Override
+ public ImsRegistrationAttributes createFromParcel(Parcel source) {
+ return new ImsRegistrationAttributes(source);
+ }
+
+ @Override
+ public ImsRegistrationAttributes[] newArray(int size) {
+ return new ImsRegistrationAttributes[size];
+ }
+ };
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ImsRegistrationAttributes that = (ImsRegistrationAttributes) o;
+ return mRegistrationTech == that.mRegistrationTech
+ && mTransportType == that.mTransportType
+ && mImsAttributeFlags == that.mImsAttributeFlags
+ && Objects.equals(mFeatureTags, that.mFeatureTags);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mRegistrationTech, mTransportType, mImsAttributeFlags, mFeatureTags);
+ }
+
+ @Override
+ public String toString() {
+ return "ImsRegistrationAttributes { transportType= " + mTransportType + ", attributeFlags="
+ + mImsAttributeFlags + ", featureTags=[" + mFeatureTags + "]}";
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
index 2c75368b86bf..c49121f4dc5d 100644
--- a/telephony/java/android/telephony/ims/RegistrationManager.java
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -71,7 +71,6 @@ public interface RegistrationManager {
*/
int REGISTRATION_STATE_REGISTERED = 2;
-
/**@hide*/
// Translate ImsRegistrationImplBase API to new AccessNetworkConstant because WLAN
// and WWAN are more accurate constants.
@@ -79,7 +78,8 @@ public interface RegistrationManager {
new HashMap<Integer, Integer>() {{
// Map NONE to -1 to make sure that we handle the REGISTRATION_TECH_NONE
// case, since it is defined.
- put(ImsRegistrationImplBase.REGISTRATION_TECH_NONE, -1);
+ put(ImsRegistrationImplBase.REGISTRATION_TECH_NONE,
+ AccessNetworkConstants.TRANSPORT_TYPE_INVALID);
put(ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
put(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
@@ -103,6 +103,20 @@ public interface RegistrationManager {
}
/**
+ * @param regtech The registration technology.
+ * @return The Access Network type from registration technology.
+ * @hide
+ */
+ static int getAccessType(int regtech) {
+ if (!RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.containsKey(regtech)) {
+ Log.w("RegistrationManager", "getAccessType - invalid regType returned: "
+ + regtech);
+ return AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+ }
+ return RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(regtech);
+ }
+
+ /**
* Callback class for receiving IMS network Registration callback events.
* @see #registerImsRegistrationCallback(Executor, RegistrationCallback)
* @see #unregisterImsRegistrationCallback(RegistrationCallback)
@@ -119,26 +133,24 @@ public interface RegistrationManager {
}
@Override
- public void onRegistered(int imsRadioTech) {
+ public void onRegistered(ImsRegistrationAttributes attr) {
if (mLocalCallback == null) return;
long callingIdentity = Binder.clearCallingIdentity();
try {
- mExecutor.execute(() ->
- mLocalCallback.onRegistered(getAccessType(imsRadioTech)));
+ mExecutor.execute(() -> mLocalCallback.onRegistered(attr));
} finally {
restoreCallingIdentity(callingIdentity);
}
}
@Override
- public void onRegistering(int imsRadioTech) {
+ public void onRegistering(ImsRegistrationAttributes attr) {
if (mLocalCallback == null) return;
long callingIdentity = Binder.clearCallingIdentity();
try {
- mExecutor.execute(() ->
- mLocalCallback.onRegistering(getAccessType(imsRadioTech)));
+ mExecutor.execute(() -> mLocalCallback.onRegistering(attr));
} finally {
restoreCallingIdentity(callingIdentity);
}
@@ -183,15 +195,6 @@ public interface RegistrationManager {
private void setExecutor(Executor executor) {
mExecutor = executor;
}
-
- private static int getAccessType(int regType) {
- if (!RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.containsKey(regType)) {
- Log.w("RegistrationManager", "RegistrationBinder - invalid regType returned: "
- + regType);
- return -1;
- }
- return RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(regType);
- }
}
private final RegistrationBinder mBinder = new RegistrationBinder(this);
@@ -200,19 +203,42 @@ public interface RegistrationManager {
* Notifies the framework when the IMS Provider is registered to the IMS network.
*
* @param imsTransportType the radio access technology.
+ * @deprecated Use {@link #onRegistered(ImsRegistrationAttributes)} instead.
*/
public void onRegistered(@AccessNetworkConstants.TransportType int imsTransportType) {
}
/**
+ * Notifies the framework when the IMS Provider is registered to the IMS network
+ * with corresponding attributes.
+ *
+ * @param attributes The attributes associated with this IMS registration.
+ */
+ public void onRegistered(@NonNull ImsRegistrationAttributes attributes) {
+ // Default impl to keep backwards compatibility with old implementations
+ onRegistered(attributes.getTransportType());
+ }
+
+ /**
* Notifies the framework when the IMS Provider is trying to register the IMS network.
*
* @param imsTransportType the radio access technology.
+ * @deprecated Use {@link #onRegistering(ImsRegistrationAttributes)} instead.
*/
public void onRegistering(@AccessNetworkConstants.TransportType int imsTransportType) {
}
/**
+ * Notifies the framework when the IMS Provider is trying to register the IMS network.
+ *
+ * @param attributes The attributes associated with this IMS registration.
+ */
+ public void onRegistering(@NonNull ImsRegistrationAttributes attributes) {
+ // Default impl to keep backwards compatibility with old implementations
+ onRegistering(attributes.getTransportType());
+ }
+
+ /**
* Notifies the framework when the IMS Provider is unregistered from the IMS network.
*
* @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
@@ -298,10 +324,10 @@ public interface RegistrationManager {
* @param executor The {@link Executor} that will be used to call the IMS registration state
* callback.
* @param stateCallback A callback called on the supplied {@link Executor} that will contain the
- * registration state of the IMS service, which will be one of the
- * following: {@link #REGISTRATION_STATE_NOT_REGISTERED},
- * {@link #REGISTRATION_STATE_REGISTERING}, or
- * {@link #REGISTRATION_STATE_REGISTERED}.
+ * registration state of the IMS service, which will be one of the
+ * following: {@link #REGISTRATION_STATE_NOT_REGISTERED},
+ * {@link #REGISTRATION_STATE_REGISTERING}, or
+ * {@link #REGISTRATION_STATE_REGISTERED}.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
void getRegistrationState(@NonNull @CallbackExecutor Executor executor,
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl
index 749b1916962e..179407c983e5 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl
@@ -21,6 +21,7 @@ import android.net.Uri;
import android.telephony.ims.stub.ImsFeatureConfiguration;
import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
/**
* See {@link ImsManager#RegistrationCallback} for more information.
@@ -28,8 +29,8 @@ import android.telephony.ims.ImsReasonInfo;
* {@hide}
*/
oneway interface IImsRegistrationCallback {
- void onRegistered(int imsRadioTech);
- void onRegistering(int imsRadioTech);
+ void onRegistered(in ImsRegistrationAttributes attr);
+ void onRegistering(in ImsRegistrationAttributes attr);
void onDeregistered(in ImsReasonInfo info);
void onTechnologyChangeFailed(int imsRadioTech, in ImsReasonInfo info);
void onSubscriberAssociatedUriChanged(in Uri[] uris);
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index 088a7e26a9d0..23032f0c4d38 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -18,17 +18,18 @@ package android.telephony.ims.stub;
import android.annotation.IntDef;
import android.annotation.IntRange;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.Uri;
import android.os.RemoteException;
import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
import android.telephony.ims.RegistrationManager;
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.util.Log;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.util.RemoteCallbackListExt;
import com.android.internal.util.ArrayUtils;
@@ -83,7 +84,10 @@ public class ImsRegistrationImplBase {
@Override
public @ImsRegistrationTech int getRegistrationTechnology() throws RemoteException {
- return getConnectionType();
+ synchronized (mLock) {
+ return (mRegistrationAttributes == null) ? REGISTRATION_TECH_NONE
+ : mRegistrationAttributes.getRegistrationTechnology();
+ }
}
@Override
@@ -116,8 +120,7 @@ public class ImsRegistrationImplBase {
new RemoteCallbackListExt<>();
private final Object mLock = new Object();
// Locked on mLock
- private @ImsRegistrationTech
- int mConnectionType = REGISTRATION_TECH_NONE;
+ private ImsRegistrationAttributes mRegistrationAttributes;
// Locked on mLock
private int mRegistrationState = REGISTRATION_STATE_UNKNOWN;
// Locked on mLock, create unspecified disconnect cause.
@@ -195,17 +198,24 @@ public class ImsRegistrationImplBase {
/**
* Notify the framework that the device is connected to the IMS network.
*
- * @param imsRadioTech the radio access technology. Valid values are defined as
- * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}.
+ * @param imsRadioTech the radio access technology.
*/
public final void onRegistered(@ImsRegistrationTech int imsRadioTech) {
- updateToState(imsRadioTech, RegistrationManager.REGISTRATION_STATE_REGISTERED);
+ onRegistered(new ImsRegistrationAttributes.Builder(imsRadioTech).build());
+ }
+
+ /**
+ * Notify the framework that the device is connected to the IMS network.
+ *
+ * @param attributes The attributes associated with the IMS registration.
+ */
+ public final void onRegistered(@NonNull ImsRegistrationAttributes attributes) {
+ updateToState(attributes, RegistrationManager.REGISTRATION_STATE_REGISTERED);
mCallbacks.broadcastAction((c) -> {
try {
- c.onRegistered(imsRadioTech);
+ c.onRegistered(attributes);
} catch (RemoteException e) {
- Log.w(LOG_TAG, e + " " + "onRegistrationConnected() - Skipping " +
- "callback.");
+ Log.w(LOG_TAG, e + "onRegistered(int, Set) - Skipping callback.");
}
});
}
@@ -213,17 +223,24 @@ public class ImsRegistrationImplBase {
/**
* Notify the framework that the device is trying to connect the IMS network.
*
- * @param imsRadioTech the radio access technology. Valid values are defined as
- * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}.
+ * @param imsRadioTech the radio access technology.
*/
public final void onRegistering(@ImsRegistrationTech int imsRadioTech) {
- updateToState(imsRadioTech, RegistrationManager.REGISTRATION_STATE_REGISTERING);
+ onRegistering(new ImsRegistrationAttributes.Builder(imsRadioTech).build());
+ }
+
+ /**
+ * Notify the framework that the device is trying to connect the IMS network.
+ *
+ * @param attributes The attributes associated with the IMS registration.
+ */
+ public final void onRegistering(@NonNull ImsRegistrationAttributes attributes) {
+ updateToState(attributes, RegistrationManager.REGISTRATION_STATE_REGISTERING);
mCallbacks.broadcastAction((c) -> {
try {
- c.onRegistering(imsRadioTech);
+ c.onRegistering(attributes);
} catch (RemoteException e) {
- Log.w(LOG_TAG, e + " " + "onRegistrationProcessing() - Skipping " +
- "callback.");
+ Log.w(LOG_TAG, e + "onRegistering(int, Set) - Skipping callback.");
}
});
}
@@ -252,8 +269,7 @@ public class ImsRegistrationImplBase {
try {
c.onDeregistered(reasonInfo);
} catch (RemoteException e) {
- Log.w(LOG_TAG, e + " " + "onRegistrationDisconnected() - Skipping " +
- "callback.");
+ Log.w(LOG_TAG, e + "onDeregistered() - Skipping callback.");
}
});
}
@@ -272,8 +288,7 @@ public class ImsRegistrationImplBase {
try {
c.onTechnologyChangeFailed(imsRadioTech, reasonInfo);
} catch (RemoteException e) {
- Log.w(LOG_TAG, e + " " + "onRegistrationChangeFailed() - Skipping " +
- "callback.");
+ Log.w(LOG_TAG, e + "onTechnologyChangeFailed() - Skipping callback.");
}
});
}
@@ -297,14 +312,13 @@ public class ImsRegistrationImplBase {
try {
callback.onSubscriberAssociatedUriChanged(uris);
} catch (RemoteException e) {
- Log.w(LOG_TAG, e + " " + "onSubscriberAssociatedUriChanged() - Skipping "
- + "callback.");
+ Log.w(LOG_TAG, e + "onSubscriberAssociatedUriChanged() - Skipping callback.");
}
}
- private void updateToState(@ImsRegistrationTech int connType, int newState) {
+ private void updateToState(ImsRegistrationAttributes attributes, int newState) {
synchronized (mLock) {
- mConnectionType = connType;
+ mRegistrationAttributes = attributes;
mRegistrationState = newState;
mLastDisconnectCause = null;
}
@@ -316,7 +330,7 @@ public class ImsRegistrationImplBase {
mUrisSet = false;
mUris = null;
- updateToState(REGISTRATION_TECH_NONE,
+ updateToState(new ImsRegistrationAttributes.Builder(REGISTRATION_TECH_NONE).build(),
RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED);
if (info != null) {
mLastDisconnectCause = info;
@@ -328,29 +342,19 @@ public class ImsRegistrationImplBase {
}
/**
- * @return the current registration connection type. Valid values are
- * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}
- * @hide
- */
- @VisibleForTesting
- public final @ImsRegistrationTech int getConnectionType() {
- synchronized (mLock) {
- return mConnectionType;
- }
- }
-
- /**
* @param c the newly registered callback that will be updated with the current registration
* state.
*/
private void updateNewCallbackWithState(IImsRegistrationCallback c)
throws RemoteException {
int state;
+ ImsRegistrationAttributes attributes;
ImsReasonInfo disconnectInfo;
boolean urisSet;
Uri[] uris;
synchronized (mLock) {
state = mRegistrationState;
+ attributes = mRegistrationAttributes;
disconnectInfo = mLastDisconnectCause;
urisSet = mUrisSet;
uris = mUris;
@@ -361,11 +365,11 @@ public class ImsRegistrationImplBase {
break;
}
case RegistrationManager.REGISTRATION_STATE_REGISTERING: {
- c.onRegistering(getConnectionType());
+ c.onRegistering(attributes);
break;
}
case RegistrationManager.REGISTRATION_STATE_REGISTERED: {
- c.onRegistered(getConnectionType());
+ c.onRegistered(attributes);
break;
}
case REGISTRATION_STATE_UNKNOWN: {
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 799bcc82d2a9..c86224a71978 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -33,6 +33,7 @@ import static org.mockito.Mockito.when;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
import android.net.INetd;
import android.net.InetAddresses;
import android.net.IpSecAlgorithm;
@@ -44,6 +45,7 @@ import android.net.IpSecTransformResponse;
import android.net.IpSecTunnelInterfaceResponse;
import android.net.IpSecUdpEncapResponse;
import android.net.LinkAddress;
+import android.net.LinkProperties;
import android.net.Network;
import android.os.Binder;
import android.os.INetworkManagementService;
@@ -53,6 +55,8 @@ import android.test.mock.MockContext;
import androidx.test.filters.SmallTest;
+import com.android.server.IpSecService.TunnelInterfaceRecord;
+
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -109,6 +113,7 @@ public class IpSecServiceParameterizedTest {
};
AppOpsManager mMockAppOps = mock(AppOpsManager.class);
+ ConnectivityManager mMockConnectivityMgr = mock(ConnectivityManager.class);
MockContext mMockContext = new MockContext() {
@Override
@@ -116,12 +121,22 @@ public class IpSecServiceParameterizedTest {
switch(name) {
case Context.APP_OPS_SERVICE:
return mMockAppOps;
+ case Context.CONNECTIVITY_SERVICE:
+ return mMockConnectivityMgr;
default:
return null;
}
}
@Override
+ public String getSystemServiceName(Class<?> serviceClass) {
+ if (ConnectivityManager.class == serviceClass) {
+ return Context.CONNECTIVITY_SERVICE;
+ }
+ return null;
+ }
+
+ @Override
public PackageManager getPackageManager() {
return mMockPkgMgr;
}
@@ -151,6 +166,10 @@ public class IpSecServiceParameterizedTest {
new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
private static final int REMOTE_ENCAP_PORT = 4500;
+ private static final String BLESSED_PACKAGE = "blessedPackage";
+ private static final String SYSTEM_PACKAGE = "systemPackage";
+ private static final String BAD_PACKAGE = "badPackage";
+
public IpSecServiceParameterizedTest(
String sourceAddr, String destAddr, String localInnerAddr, int family) {
mSourceAddr = sourceAddr;
@@ -174,15 +193,15 @@ public class IpSecServiceParameterizedTest {
when(mMockPkgMgr.hasSystemFeature(anyString())).thenReturn(true);
// A package granted the AppOp for MANAGE_IPSEC_TUNNELS will be MODE_ALLOWED.
- when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("blessedPackage")))
- .thenReturn(AppOpsManager.MODE_ALLOWED);
+ when(mMockAppOps.noteOp(anyInt(), anyInt(), eq(BLESSED_PACKAGE)))
+ .thenReturn(AppOpsManager.MODE_ALLOWED);
// A system package will not be granted the app op, so this should fall back to
// a permissions check, which should pass.
- when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("systemPackage")))
- .thenReturn(AppOpsManager.MODE_DEFAULT);
+ when(mMockAppOps.noteOp(anyInt(), anyInt(), eq(SYSTEM_PACKAGE)))
+ .thenReturn(AppOpsManager.MODE_DEFAULT);
// A mismatch between the package name and the UID will return MODE_IGNORED.
- when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("badPackage")))
- .thenReturn(AppOpsManager.MODE_IGNORED);
+ when(mMockAppOps.noteOp(anyInt(), anyInt(), eq(BAD_PACKAGE)))
+ .thenReturn(AppOpsManager.MODE_IGNORED);
}
//TODO: Add a test to verify SPI.
@@ -338,7 +357,7 @@ public class IpSecServiceParameterizedTest {
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
assertEquals(IpSecManager.Status.OK, createTransformResp.status);
verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
@@ -352,7 +371,7 @@ public class IpSecServiceParameterizedTest {
ipSecConfig.setAuthenticatedEncryption(AEAD_ALGO);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
assertEquals(IpSecManager.Status.OK, createTransformResp.status);
verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
@@ -370,14 +389,14 @@ public class IpSecServiceParameterizedTest {
if (mFamily == AF_INET) {
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
assertEquals(IpSecManager.Status.OK, createTransformResp.status);
verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port);
} else {
try {
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6");
} catch (IllegalArgumentException expected) {
}
@@ -396,14 +415,14 @@ public class IpSecServiceParameterizedTest {
if (mFamily == AF_INET) {
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
assertEquals(IpSecManager.Status.OK, createTransformResp.status);
verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port);
} else {
try {
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6");
} catch (IllegalArgumentException expected) {
}
@@ -417,12 +436,12 @@ public class IpSecServiceParameterizedTest {
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
assertEquals(IpSecManager.Status.OK, createTransformResp.status);
// Attempting to create transform a second time with the same SPIs should throw an error...
try {
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
fail("IpSecService should have thrown an error for reuse of SPI");
} catch (IllegalStateException expected) {
}
@@ -430,7 +449,7 @@ public class IpSecServiceParameterizedTest {
// ... even if the transform is deleted
mIpSecService.deleteTransform(createTransformResp.resourceId);
try {
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
fail("IpSecService should have thrown an error for reuse of SPI");
} catch (IllegalStateException expected) {
}
@@ -443,7 +462,7 @@ public class IpSecServiceParameterizedTest {
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
@@ -467,7 +486,7 @@ public class IpSecServiceParameterizedTest {
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
mIpSecService.deleteTransform(createTransformResp.resourceId);
verify(mMockNetd, times(1))
@@ -515,7 +534,7 @@ public class IpSecServiceParameterizedTest {
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
IpSecService.RefcountedResource refcountedRecord =
@@ -562,7 +581,7 @@ public class IpSecServiceParameterizedTest {
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
if (closeSpiBeforeApply) {
mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
@@ -592,7 +611,7 @@ public class IpSecServiceParameterizedTest {
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
// Close SPI record
mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
@@ -638,7 +657,7 @@ public class IpSecServiceParameterizedTest {
@Test
public void testCreateTunnelInterface() throws Exception {
IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
// Check that we have stored the tracking object, and retrieve it
IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
@@ -661,11 +680,11 @@ public class IpSecServiceParameterizedTest {
@Test
public void testDeleteTunnelInterface() throws Exception {
IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
- mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, "blessedPackage");
+ mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, BLESSED_PACKAGE);
// Verify quota and RefcountedResource objects cleaned up
assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent);
@@ -678,10 +697,73 @@ public class IpSecServiceParameterizedTest {
}
}
+ private Network createFakeUnderlyingNetwork(String interfaceName) {
+ final Network fakeNetwork = new Network(1000);
+ final LinkProperties fakeLp = new LinkProperties();
+ fakeLp.setInterfaceName(interfaceName);
+ when(mMockConnectivityMgr.getLinkProperties(eq(fakeNetwork))).thenReturn(fakeLp);
+ return fakeNetwork;
+ }
+
+ @Test
+ public void testSetNetworkForTunnelInterface() throws Exception {
+ final IpSecTunnelInterfaceResponse createTunnelResp =
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
+ final Network newFakeNetwork = createFakeUnderlyingNetwork("newFakeNetworkInterface");
+ final int tunnelIfaceResourceId = createTunnelResp.resourceId;
+ mIpSecService.setNetworkForTunnelInterface(
+ tunnelIfaceResourceId, newFakeNetwork, BLESSED_PACKAGE);
+
+ final IpSecService.UserRecord userRecord =
+ mIpSecService.mUserResourceTracker.getUserRecord(mUid);
+ assertEquals(1, userRecord.mTunnelQuotaTracker.mCurrent);
+
+ final TunnelInterfaceRecord tunnelInterfaceInfo =
+ userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelIfaceResourceId);
+ assertEquals(newFakeNetwork, tunnelInterfaceInfo.getUnderlyingNetwork());
+ }
+
+ @Test
+ public void testSetNetworkForTunnelInterfaceFailsForInvalidResourceId() throws Exception {
+ final IpSecTunnelInterfaceResponse createTunnelResp =
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
+ final Network newFakeNetwork = new Network(1000);
+
+ try {
+ mIpSecService.setNetworkForTunnelInterface(
+ IpSecManager.INVALID_RESOURCE_ID, newFakeNetwork, BLESSED_PACKAGE);
+ fail("Expected an IllegalArgumentException for invalid resource ID.");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testSetNetworkForTunnelInterfaceFailsWhenSettingTunnelNetwork() throws Exception {
+ final IpSecTunnelInterfaceResponse createTunnelResp =
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
+ final int tunnelIfaceResourceId = createTunnelResp.resourceId;
+ final IpSecService.UserRecord userRecord =
+ mIpSecService.mUserResourceTracker.getUserRecord(mUid);
+ final TunnelInterfaceRecord tunnelInterfaceInfo =
+ userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelIfaceResourceId);
+
+ final Network newFakeNetwork =
+ createFakeUnderlyingNetwork(tunnelInterfaceInfo.getInterfaceName());
+
+ try {
+ mIpSecService.setNetworkForTunnelInterface(
+ tunnelIfaceResourceId, newFakeNetwork, BLESSED_PACKAGE);
+ fail(
+ "Expected an IllegalArgumentException because the underlying network is the"
+ + " network being exposed by this tunnel.");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
@Test
public void testTunnelInterfaceBinderDeath() throws Exception {
IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
IpSecService.RefcountedResource refcountedRecord =
@@ -718,9 +800,9 @@ public class IpSecServiceParameterizedTest {
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
if (closeSpiBeforeApply) {
mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
@@ -728,8 +810,8 @@ public class IpSecServiceParameterizedTest {
int transformResourceId = createTransformResp.resourceId;
int tunnelResourceId = createTunnelResp.resourceId;
- mIpSecService.applyTunnelModeTransform(tunnelResourceId, IpSecManager.DIRECTION_OUT,
- transformResourceId, "blessedPackage");
+ mIpSecService.applyTunnelModeTransform(
+ tunnelResourceId, IpSecManager.DIRECTION_OUT, transformResourceId, BLESSED_PACKAGE);
for (int selAddrFamily : ADDRESS_FAMILIES) {
verify(mMockNetd)
@@ -758,17 +840,17 @@ public class IpSecServiceParameterizedTest {
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+ mIpSecService.createTransform(ipSecConfig, new Binder(), BLESSED_PACKAGE);
IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, BLESSED_PACKAGE);
// Close SPI record
mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
int transformResourceId = createTransformResp.resourceId;
int tunnelResourceId = createTunnelResp.resourceId;
- mIpSecService.applyTunnelModeTransform(tunnelResourceId, IpSecManager.DIRECTION_OUT,
- transformResourceId, "blessedPackage");
+ mIpSecService.applyTunnelModeTransform(
+ tunnelResourceId, IpSecManager.DIRECTION_OUT, transformResourceId, BLESSED_PACKAGE);
for (int selAddrFamily : ADDRESS_FAMILIES) {
verify(mMockNetd)
@@ -790,7 +872,7 @@ public class IpSecServiceParameterizedTest {
@Test
public void testAddRemoveAddressFromTunnelInterface() throws Exception {
- for (String pkgName : new String[]{"blessedPackage", "systemPackage"}) {
+ for (String pkgName : new String[] {BLESSED_PACKAGE, SYSTEM_PACKAGE}) {
IpSecTunnelInterfaceResponse createTunnelResp =
createAndValidateTunnel(mSourceAddr, mDestinationAddr, pkgName);
mIpSecService.addAddressToTunnelInterface(
@@ -816,7 +898,7 @@ public class IpSecServiceParameterizedTest {
public void testAddTunnelFailsForBadPackageName() throws Exception {
try {
IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr, "badPackage");
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, BAD_PACKAGE);
fail("Expected a SecurityException for badPackage.");
} catch (SecurityException expected) {
}
@@ -830,7 +912,7 @@ public class IpSecServiceParameterizedTest {
try {
String addr = Inet4Address.getLoopbackAddress().getHostAddress();
mIpSecService.createTunnelInterface(
- addr, addr, new Network(0), new Binder(), "blessedPackage");
+ addr, addr, new Network(0), new Binder(), BLESSED_PACKAGE);
fail("Expected UnsupportedOperationException for disabled feature");
} catch (UnsupportedOperationException expected) {
}
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
index 8643d8a2ea8a..16181b6f839a 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
@@ -16,12 +16,18 @@
package com.android.server.vcn;
+import static android.net.IpSecManager.IpSecTunnelInterface;
+
+import static com.android.server.vcn.VcnGatewayConnection.DUMMY_ADDR;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
+import android.net.IpSecManager;
+
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -37,6 +43,11 @@ public class VcnGatewayConnectionDisconnectedStateTest extends VcnGatewayConnect
public void setUp() throws Exception {
super.setUp();
+ final IpSecTunnelInterface tunnelIface =
+ mContext.getSystemService(IpSecManager.class)
+ .createIpSecTunnelInterface(
+ DUMMY_ADDR, DUMMY_ADDR, TEST_UNDERLYING_NETWORK_RECORD_1.network);
+ mGatewayConnection.setTunnelInterface(tunnelIface);
mGatewayConnection.transitionTo(mGatewayConnection.mDisconnectedState);
mTestLooper.dispatchAll();
}