diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 403b44d6d7..f1e4f64ef8 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -219,4 +219,6 @@ interface IConnectivityManager void registerTetheringEventCallback(ITetheringEventCallback callback, String callerPkg); void unregisterTetheringEventCallback(ITetheringEventCallback callback, String callerPkg); + + IBinder startOrGetTestNetworkService(); } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 72f7a68ad2..3ed294845d 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -299,6 +299,15 @@ public class ConnectivityService extends IConnectivityManager.Stub private INetworkPolicyManager mPolicyManager; private NetworkPolicyManagerInternal mPolicyManagerInternal; + /** + * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple + * instances. + */ + @GuardedBy("mTNSLock") + private TestNetworkService mTNS; + + private final Object mTNSLock = new Object(); + private String mCurrentTcpBufferSizes; private static final SparseArray sMagicDecoderRing = MessageUtils.findMessageNames( @@ -6958,4 +6967,22 @@ public class ConnectivityService extends IConnectivityManager.Stub return vpn != null && vpn.getLockdown(); } } + + /** + * Returns a IBinder to a TestNetworkService. Will be lazily created as needed. + * + *

The TestNetworkService must be run in the system server due to TUN creation. + */ + @Override + public IBinder startOrGetTestNetworkService() { + synchronized (mTNSLock) { + TestNetworkService.enforceTestNetworkPermissions(mContext); + + if (mTNS == null) { + mTNS = new TestNetworkService(mContext, mNMS); + } + + return mTNS; + } + } }