From 9ddf8a5953d62eefff73303bba6db40c6ac04388 Mon Sep 17 00:00:00 2001 From: Automerger Merge Worker Date: Tue, 12 May 2020 18:48:04 +0000 Subject: [PATCH] Create TestApi for simulating a Data Stall on ConnectivityService. This change adds a TestApi for simulating a Data Stall to ConnectivityService. This allows for Data Stalls to be triggered without having to manipulate the signals used by NetworkMonitor . This also allows NetworkMonitor to update the ways it detects Data Stalls without affecting CTS tests for ConnectivityDiagnosticsManager. Bug: 148032944 Test: atest ConnectivityDiagnosticsManagerTest Change-Id: Icad439efa2ab4c872c21d3ee6ceaae8c5b49f18d Merged-In: Icad439efa2ab4c872c21d3ee6ceaae8c5b49f18d (cherry picked from commit b06463a002eb6215e9dda64e599eabd74cb56382) --- .../java/android/net/ConnectivityManager.java | 25 +++++++++++ .../android/net/IConnectivityManager.aidl | 5 +++ .../android/server/ConnectivityService.java | 44 +++++++++++++++---- 3 files changed, 65 insertions(+), 9 deletions(-) diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 7332ede0b9..36ffe50ef8 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -48,6 +48,7 @@ import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.ParcelFileDescriptor; +import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; @@ -4693,4 +4694,28 @@ public class ConnectivityManager { Log.d(TAG, "StackLog:" + sb.toString()); } } + + /** + * Simulates a Data Stall for the specified Network. + * + *

The caller must be the owner of the specified Network. + * + * @param detectionMethod The detection method used to identify the Data Stall. + * @param timestampMillis The timestamp at which the stall 'occurred', in milliseconds. + * @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. + * @hide + */ + @TestApi + @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_TEST_NETWORKS, + android.Manifest.permission.NETWORK_STACK}) + public void simulateDataStall(int detectionMethod, long timestampMillis, + @NonNull Network network, @NonNull PersistableBundle extras) { + try { + mService.simulateDataStall(detectionMethod, timestampMillis, network, extras); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 14345608e9..69a47f24a0 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -18,6 +18,7 @@ package android.net; import android.app.PendingIntent; import android.net.ConnectionInfo; +import android.net.ConnectivityDiagnosticsManager; import android.net.IConnectivityDiagnosticsCallback; import android.net.LinkProperties; import android.net.Network; @@ -33,6 +34,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.Messenger; import android.os.ParcelFileDescriptor; +import android.os.PersistableBundle; import android.os.ResultReceiver; import com.android.internal.net.LegacyVpnInfo; @@ -227,4 +229,7 @@ interface IConnectivityManager void unregisterConnectivityDiagnosticsCallback(in IConnectivityDiagnosticsCallback callback); IBinder startOrGetTestNetworkService(); + + void simulateDataStall(int detectionMethod, long timestampMillis, in Network network, + in PersistableBundle extras); } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 8ca6951aef..629c580afc 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -3087,10 +3087,6 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public void notifyDataStallSuspected(DataStallReportParcelable p) { - final Message msg = mConnectivityDiagnosticsHandler.obtainMessage( - ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, - p.detectionMethod, mNetId, p.timestampMillis); - final PersistableBundle extras = new PersistableBundle(); switch (p.detectionMethod) { case DETECTION_METHOD_DNS_EVENTS: @@ -3105,12 +3101,9 @@ public class ConnectivityService extends IConnectivityManager.Stub log("Unknown data stall detection method, ignoring: " + p.detectionMethod); return; } - msg.setData(new Bundle(extras)); - // NetworkStateTrackerHandler currently doesn't take any actions based on data - // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid - // the cost of going through two handlers. - mConnectivityDiagnosticsHandler.sendMessage(msg); + proxyDataStallToConnectivityDiagnosticsHandler( + p.detectionMethod, mNetId, p.timestampMillis, extras); } @Override @@ -3124,6 +3117,19 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + private void proxyDataStallToConnectivityDiagnosticsHandler(int detectionMethod, int netId, + long timestampMillis, @NonNull PersistableBundle extras) { + final Message msg = mConnectivityDiagnosticsHandler.obtainMessage( + ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, + detectionMethod, netId, timestampMillis); + msg.setData(new Bundle(extras)); + + // NetworkStateTrackerHandler currently doesn't take any actions based on data + // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid + // the cost of going through two handlers. + mConnectivityDiagnosticsHandler.sendMessage(msg); + } + private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) { return isPrivateDnsValidationRequired(nai.networkCapabilities); } @@ -8151,4 +8157,24 @@ public class ConnectivityService extends IConnectivityManager.Stub 0, callback)); } + + @Override + public void simulateDataStall(int detectionMethod, long timestampMillis, + @NonNull Network network, @NonNull PersistableBundle extras) { + enforceAnyPermissionOf(android.Manifest.permission.MANAGE_TEST_NETWORKS, + android.Manifest.permission.NETWORK_STACK); + final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network); + if (!nc.hasTransport(TRANSPORT_TEST)) { + throw new SecurityException("Data Stall simluation is only possible for test networks"); + } + + final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); + if (nai == null || nai.creatorUid != Binder.getCallingUid()) { + throw new SecurityException("Data Stall simulation is only possible for network " + + "creators"); + } + + proxyDataStallToConnectivityDiagnosticsHandler( + detectionMethod, network.netId, timestampMillis, extras); + } }