diff options
| author | 2020-02-06 15:47:26 +0000 | |
|---|---|---|
| committer | 2020-02-06 15:47:26 +0000 | |
| commit | 960dd65d4972f6135828a23e92bb78655c999529 (patch) | |
| tree | ba3ce8a18d61a1e5ab0b2f6e39f8218985fc9b6c | |
| parent | 7202e904c9e2338b011d59d99200a9551f450f3d (diff) | |
| parent | 7d4c82788afe7c851b0b794a929366970f609d2f (diff) | |
Merge "Implement INetworkMonitorCallbacks#notifyDataStallSuspected."
| -rw-r--r-- | services/core/java/com/android/server/ConnectivityService.java | 53 | ||||
| -rw-r--r-- | tests/net/java/com/android/server/ConnectivityServiceTest.java | 41 |
2 files changed, 94 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 9e8ab4f20db1..fe2fc1bced9c 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -68,6 +68,7 @@ import android.database.ContentObserver; import android.net.CaptivePortal; import android.net.ConnectionInfo; import android.net.ConnectivityDiagnosticsManager.ConnectivityReport; +import android.net.ConnectivityDiagnosticsManager.DataStallReport; import android.net.ConnectivityManager; import android.net.ICaptivePortal; import android.net.IConnectivityDiagnosticsCallback; @@ -3009,6 +3010,21 @@ public class ConnectivityService extends IConnectivityManager.Stub } @Override + public void notifyDataStallSuspected( + long timestampMillis, int detectionMethod, PersistableBundle extras) { + final Message msg = + mConnectivityDiagnosticsHandler.obtainMessage( + ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, + detectionMethod, mNetId, 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); + } + + @Override public int getInterfaceVersion() { return this.VERSION; } @@ -7559,6 +7575,16 @@ public class ConnectivityService extends IConnectivityManager.Stub */ private static final int EVENT_NETWORK_TESTED = ConnectivityService.EVENT_NETWORK_TESTED; + /** + * Event for NetworkMonitor to inform ConnectivityService that a potential data stall has + * been detected on the network. + * obj = Long the timestamp (in millis) for when the suspected data stall was detected. + * arg1 = {@link DataStallReport#DetectionMethod} indicating the detection method. + * arg2 = NetID. + * data = PersistableBundle of extras passed from NetworkMonitor. + */ + private static final int EVENT_DATA_STALL_SUSPECTED = 4; + private ConnectivityDiagnosticsHandler(Looper looper) { super(looper); } @@ -7589,6 +7615,17 @@ public class ConnectivityService extends IConnectivityManager.Stub handleNetworkTestedWithExtras(reportEvent, extras); break; } + case EVENT_DATA_STALL_SUSPECTED: { + final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2); + if (nai == null) break; + + // This is safe because NetworkMonitorCallbacks#notifyDataStallSuspected + // receives a PersistableBundle and converts it to the Bundle in the incoming + // Message. + final PersistableBundle extras = new PersistableBundle(msg.getData()); + handleDataStallSuspected(nai, (long) msg.obj, msg.arg1, extras); + break; + } } } } @@ -7718,6 +7755,22 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + private void handleDataStallSuspected( + @NonNull NetworkAgentInfo nai, long timestampMillis, int detectionMethod, + @NonNull PersistableBundle extras) { + final DataStallReport report = + new DataStallReport(nai.network, timestampMillis, detectionMethod, extras); + final List<IConnectivityDiagnosticsCallback> results = + getMatchingPermissionedCallbacks(nai); + for (final IConnectivityDiagnosticsCallback cb : results) { + try { + cb.onDataStallSuspected(report); + } catch (RemoteException ex) { + loge("Error invoking onDataStallSuspected", ex); + } + } + } + private List<IConnectivityDiagnosticsCallback> getMatchingPermissionedCallbacks( @NonNull NetworkAgentInfo nai) { final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>(); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 8162843d9823..760ebf61ffd1 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -24,6 +24,7 @@ import static android.content.pm.PackageManager.MATCH_ANY_USER; import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport; +import static android.net.ConnectivityDiagnosticsManager.DataStallReport; import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL; @@ -570,6 +571,9 @@ public class ConnectivityServiceTest { | NETWORK_VALIDATION_RESULT_PARTIAL; private static final int VALIDATION_RESULT_INVALID = 0; + private static final long DATA_STALL_TIMESTAMP = 10L; + private static final int DATA_STALL_DETECTION_METHOD = 1; + private INetworkMonitor mNetworkMonitor; private INetworkMonitorCallbacks mNmCallbacks; private int mNmValidationResult = VALIDATION_RESULT_BASE; @@ -577,6 +581,7 @@ public class ConnectivityServiceTest { private int mProbesSucceeded; private String mNmValidationRedirectUrl = null; private PersistableBundle mValidationExtras = PersistableBundle.EMPTY; + private PersistableBundle mDataStallExtras = PersistableBundle.EMPTY; private boolean mNmProvNotificationRequested = false; private final ConditionVariable mNetworkStatusReceived = new ConditionVariable(); @@ -804,6 +809,11 @@ public class ConnectivityServiceTest { public void expectPreventReconnectReceived() { expectPreventReconnectReceived(TIMEOUT_MS); } + + void notifyDataStallSuspected() throws Exception { + mNmCallbacks.notifyDataStallSuspected( + DATA_STALL_TIMESTAMP, DATA_STALL_DETECTION_METHOD, mDataStallExtras); + } } /** @@ -6625,4 +6635,35 @@ public class ConnectivityServiceTest { verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) .onConnectivityReport(any(ConnectivityReport.class)); } + + @Test + public void testConnectivityDiagnosticsCallbackOnDataStallSuspected() throws Exception { + final NetworkRequest request = new NetworkRequest.Builder().build(); + when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder); + + mServiceContext.setPermission( + android.Manifest.permission.NETWORK_STACK, PERMISSION_GRANTED); + + mService.registerConnectivityDiagnosticsCallback( + mConnectivityDiagnosticsCallback, request, mContext.getPackageName()); + + // Block until all other events are done processing. + HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); + + // Connect the cell agent verify that it notifies TestNetworkCallback that it is available + final TestNetworkCallback callback = new TestNetworkCallback(); + mCm.registerDefaultNetworkCallback(callback); + mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); + mCellNetworkAgent.connect(true); + callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); + callback.assertNoCallback(); + + // Trigger notifyDataStallSuspected() on the INetworkMonitorCallbacks instance in the + // cellular network agent + mCellNetworkAgent.notifyDataStallSuspected(); + + // Wait for onDataStallSuspected to fire + verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS)) + .onDataStallSuspected(any(DataStallReport.class)); + } } |