Implement INetworkMonitorCallbacks#notifyDataStallSuspected.

INetworkMonitorCallbacks defines notifyDataStallSuspected() for
notifying ConnectivityService of networks encountering a potential data
stall. A new event is introduced for ConnectivityDiagnosticsHandler to
process the notification and invoke the relevant
ConnectivityDiagnosticsCallbacks.

Bug: 143187964
Test: compiles
Test: atest CtsNetTestCases FrameworksNetTests
Change-Id: I70320bdda9855dced31e08e6a0b25329fb5cb535
Merged-In: I70320bdda9855dced31e08e6a0b25329fb5cb535
This commit is contained in:
Cody Kesting
2020-01-06 16:55:35 -08:00
parent e10545c736
commit b12ad4ca3a
2 changed files with 94 additions and 0 deletions

View File

@@ -68,6 +68,7 @@ import android.database.ContentObserver;
import android.net.CaptivePortal; import android.net.CaptivePortal;
import android.net.ConnectionInfo; import android.net.ConnectionInfo;
import android.net.ConnectivityDiagnosticsManager.ConnectivityReport; import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
import android.net.ConnectivityDiagnosticsManager.DataStallReport;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.ICaptivePortal; import android.net.ICaptivePortal;
import android.net.IConnectivityDiagnosticsCallback; import android.net.IConnectivityDiagnosticsCallback;
@@ -3008,6 +3009,21 @@ public class ConnectivityService extends IConnectivityManager.Stub
EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId)); EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId));
} }
@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 @Override
public int getInterfaceVersion() { public int getInterfaceVersion() {
return this.VERSION; return this.VERSION;
@@ -7555,6 +7571,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/ */
private static final int EVENT_NETWORK_TESTED = ConnectivityService.EVENT_NETWORK_TESTED; 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) { private ConnectivityDiagnosticsHandler(Looper looper) {
super(looper); super(looper);
} }
@@ -7585,6 +7611,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
handleNetworkTestedWithExtras(reportEvent, extras); handleNetworkTestedWithExtras(reportEvent, extras);
break; 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;
}
} }
} }
} }
@@ -7714,6 +7751,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( private List<IConnectivityDiagnosticsCallback> getMatchingPermissionedCallbacks(
@NonNull NetworkAgentInfo nai) { @NonNull NetworkAgentInfo nai) {
final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>(); final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>();

View File

@@ -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_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport; 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.ACTION_CAPTIVE_PORTAL_SIGN_IN;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL;
@@ -570,6 +571,9 @@ public class ConnectivityServiceTest {
| NETWORK_VALIDATION_RESULT_PARTIAL; | NETWORK_VALIDATION_RESULT_PARTIAL;
private static final int VALIDATION_RESULT_INVALID = 0; 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 INetworkMonitor mNetworkMonitor;
private INetworkMonitorCallbacks mNmCallbacks; private INetworkMonitorCallbacks mNmCallbacks;
private int mNmValidationResult = VALIDATION_RESULT_BASE; private int mNmValidationResult = VALIDATION_RESULT_BASE;
@@ -577,6 +581,7 @@ public class ConnectivityServiceTest {
private int mProbesSucceeded; private int mProbesSucceeded;
private String mNmValidationRedirectUrl = null; private String mNmValidationRedirectUrl = null;
private PersistableBundle mValidationExtras = PersistableBundle.EMPTY; private PersistableBundle mValidationExtras = PersistableBundle.EMPTY;
private PersistableBundle mDataStallExtras = PersistableBundle.EMPTY;
private boolean mNmProvNotificationRequested = false; private boolean mNmProvNotificationRequested = false;
private final ConditionVariable mNetworkStatusReceived = new ConditionVariable(); private final ConditionVariable mNetworkStatusReceived = new ConditionVariable();
@@ -804,6 +809,11 @@ public class ConnectivityServiceTest {
public void expectPreventReconnectReceived() { public void expectPreventReconnectReceived() {
expectPreventReconnectReceived(TIMEOUT_MS); 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)) verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS))
.onConnectivityReport(any(ConnectivityReport.class)); .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));
}
} }