Implement INetworkMonitorCallbacks#notifyNetworkTestedWithExtras.
INetworkMonitorCallbacks defines notifyNetworkTestedWithExtras() for notifying ConnectivityService of networks being tested along with a PersistableBundle of extras. A new event is introduced for NetworkStateTrackerHandler to notify the ConnectivityDiagnosticsHandler before continuing with the normal processing for "network tested" notifications. The event is also used in the ConnectivityDiagnosticsHandler. Bug: 143187964 Bug: 147391402 Test: compiles. Test: atest CtsNetTestCases FrameworksNetTests Change-Id: Iab29da790c0f5faae68227770bc3a84bbc94f124 (cherry picked from commit c5326407d592490783259a48a8ca653c4ff13122)
This commit is contained in:
@@ -23,6 +23,7 @@ import static android.content.pm.PackageManager.GET_PERMISSIONS;
|
||||
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.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN;
|
||||
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
|
||||
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL;
|
||||
@@ -119,6 +120,7 @@ import static org.mockito.Mockito.when;
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -132,6 +134,7 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.location.LocationManager;
|
||||
import android.net.CaptivePortalData;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.ConnectivityManager.NetworkCallback;
|
||||
@@ -177,6 +180,7 @@ import android.net.shared.PrivateDnsConfig;
|
||||
import android.net.util.MultinetworkPolicyTracker;
|
||||
import android.os.BadParcelableException;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.ConditionVariable;
|
||||
import android.os.Handler;
|
||||
@@ -187,6 +191,7 @@ import android.os.Looper;
|
||||
import android.os.Parcel;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.Parcelable;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
@@ -218,6 +223,7 @@ import com.android.server.connectivity.DefaultNetworkMetrics;
|
||||
import com.android.server.connectivity.IpConnectivityMetrics;
|
||||
import com.android.server.connectivity.MockableSystemProperties;
|
||||
import com.android.server.connectivity.Nat464Xlat;
|
||||
import com.android.server.connectivity.NetworkAgentInfo;
|
||||
import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
|
||||
import com.android.server.connectivity.ProxyTracker;
|
||||
import com.android.server.connectivity.Vpn;
|
||||
@@ -292,6 +298,8 @@ public class ConnectivityServiceTest {
|
||||
|
||||
private static final int UNREASONABLY_LONG_ALARM_WAIT_MS = 1000;
|
||||
|
||||
private static final long TIMESTAMP = 1234L;
|
||||
|
||||
private static final String CLAT_PREFIX = "v4-";
|
||||
private static final String MOBILE_IFNAME = "test_rmnet_data0";
|
||||
private static final String WIFI_IFNAME = "test_wlan0";
|
||||
@@ -327,6 +335,8 @@ public class ConnectivityServiceTest {
|
||||
@Mock AlarmManager mAlarmManager;
|
||||
@Mock IConnectivityDiagnosticsCallback mConnectivityDiagnosticsCallback;
|
||||
@Mock IBinder mIBinder;
|
||||
@Mock LocationManager mLocationManager;
|
||||
@Mock AppOpsManager mAppOpsManager;
|
||||
|
||||
private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor =
|
||||
ArgumentCaptor.forClass(ResolverParamsParcel.class);
|
||||
@@ -412,6 +422,8 @@ public class ConnectivityServiceTest {
|
||||
if (Context.NETWORK_STACK_SERVICE.equals(name)) return mNetworkStack;
|
||||
if (Context.USER_SERVICE.equals(name)) return mUserManager;
|
||||
if (Context.ALARM_SERVICE.equals(name)) return mAlarmManager;
|
||||
if (Context.LOCATION_SERVICE.equals(name)) return mLocationManager;
|
||||
if (Context.APP_OPS_SERVICE.equals(name)) return mAppOpsManager;
|
||||
return super.getSystemService(name);
|
||||
}
|
||||
|
||||
@@ -564,6 +576,7 @@ public class ConnectivityServiceTest {
|
||||
private int mProbesCompleted;
|
||||
private int mProbesSucceeded;
|
||||
private String mNmValidationRedirectUrl = null;
|
||||
private PersistableBundle mValidationExtras = PersistableBundle.EMPTY;
|
||||
private boolean mNmProvNotificationRequested = false;
|
||||
|
||||
private final ConditionVariable mNetworkStatusReceived = new ConditionVariable();
|
||||
@@ -631,8 +644,8 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
|
||||
mNmCallbacks.notifyProbeStatusChanged(mProbesCompleted, mProbesSucceeded);
|
||||
mNmCallbacks.notifyNetworkTested(
|
||||
mNmValidationResult, mNmValidationRedirectUrl);
|
||||
mNmCallbacks.notifyNetworkTestedWithExtras(
|
||||
mNmValidationResult, mNmValidationRedirectUrl, TIMESTAMP, mValidationExtras);
|
||||
|
||||
if (mNmValidationRedirectUrl != null) {
|
||||
mNmCallbacks.showProvisioningNotification(
|
||||
@@ -970,6 +983,8 @@ public class ConnectivityServiceTest {
|
||||
// not inherit from NetworkAgent.
|
||||
private TestNetworkAgentWrapper mMockNetworkAgent;
|
||||
|
||||
private VpnInfo mVpnInfo;
|
||||
|
||||
public MockVpn(int userId) {
|
||||
super(startHandlerThreadAndReturnLooper(), mServiceContext, mNetworkManagementService,
|
||||
userId);
|
||||
@@ -1041,6 +1056,17 @@ public class ConnectivityServiceTest {
|
||||
mConnected = false;
|
||||
mConfig = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized VpnInfo getVpnInfo() {
|
||||
if (mVpnInfo != null) return mVpnInfo;
|
||||
|
||||
return super.getVpnInfo();
|
||||
}
|
||||
|
||||
private void setVpnInfo(VpnInfo vpnInfo) {
|
||||
mVpnInfo = vpnInfo;
|
||||
}
|
||||
}
|
||||
|
||||
private void mockVpn(int uid) {
|
||||
@@ -6402,7 +6428,7 @@ public class ConnectivityServiceTest {
|
||||
new NetworkCapabilities(), TYPE_ETHERNET, 0, NetworkRequest.Type.NONE);
|
||||
try {
|
||||
mService.registerConnectivityDiagnosticsCallback(
|
||||
mConnectivityDiagnosticsCallback, request);
|
||||
mConnectivityDiagnosticsCallback, request, mContext.getPackageName());
|
||||
fail("registerConnectivityDiagnosticsCallback should throw on invalid NetworkRequest");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
@@ -6416,7 +6442,7 @@ public class ConnectivityServiceTest {
|
||||
when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder);
|
||||
|
||||
mService.registerConnectivityDiagnosticsCallback(
|
||||
mConnectivityDiagnosticsCallback, wifiRequest);
|
||||
mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName());
|
||||
|
||||
verify(mIBinder, timeout(TIMEOUT_MS))
|
||||
.linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt());
|
||||
@@ -6440,7 +6466,7 @@ public class ConnectivityServiceTest {
|
||||
when(mConnectivityDiagnosticsCallback.asBinder()).thenReturn(mIBinder);
|
||||
|
||||
mService.registerConnectivityDiagnosticsCallback(
|
||||
mConnectivityDiagnosticsCallback, wifiRequest);
|
||||
mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName());
|
||||
|
||||
verify(mIBinder, timeout(TIMEOUT_MS))
|
||||
.linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt());
|
||||
@@ -6451,7 +6477,7 @@ public class ConnectivityServiceTest {
|
||||
|
||||
// Register the same callback again
|
||||
mService.registerConnectivityDiagnosticsCallback(
|
||||
mConnectivityDiagnosticsCallback, wifiRequest);
|
||||
mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName());
|
||||
|
||||
// Block until all other events are done processing.
|
||||
HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
|
||||
@@ -6460,4 +6486,145 @@ public class ConnectivityServiceTest {
|
||||
mService.mConnectivityDiagnosticsCallbacks.containsKey(
|
||||
mConnectivityDiagnosticsCallback));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckConnectivityDiagnosticsPermissionsNetworkStack() throws Exception {
|
||||
final NetworkAgentInfo naiWithoutUid =
|
||||
new NetworkAgentInfo(
|
||||
null, null, null, null, null, new NetworkCapabilities(), null,
|
||||
mServiceContext, null, null, mService, null, null, null, 0);
|
||||
|
||||
mServiceContext.setPermission(
|
||||
android.Manifest.permission.NETWORK_STACK, PERMISSION_GRANTED);
|
||||
assertTrue(
|
||||
"NetworkStack permission not applied",
|
||||
mService.checkConnectivityDiagnosticsPermissions(
|
||||
Process.myPid(), Process.myUid(), naiWithoutUid,
|
||||
mContext.getOpPackageName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckConnectivityDiagnosticsPermissionsNoLocationPermission() throws Exception {
|
||||
final NetworkAgentInfo naiWithoutUid =
|
||||
new NetworkAgentInfo(
|
||||
null, null, null, null, null, new NetworkCapabilities(), null,
|
||||
mServiceContext, null, null, mService, null, null, null, 0);
|
||||
|
||||
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
|
||||
|
||||
assertFalse(
|
||||
"ACCESS_FINE_LOCATION permission necessary for Connectivity Diagnostics",
|
||||
mService.checkConnectivityDiagnosticsPermissions(
|
||||
Process.myPid(), Process.myUid(), naiWithoutUid,
|
||||
mContext.getOpPackageName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception {
|
||||
final NetworkAgentInfo naiWithoutUid =
|
||||
new NetworkAgentInfo(
|
||||
null, null, null, null, null, new NetworkCapabilities(), null,
|
||||
mServiceContext, null, null, mService, null, null, null, 0);
|
||||
|
||||
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION);
|
||||
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
|
||||
|
||||
// setUp() calls mockVpn() which adds a VPN with the Test Runner's uid. Configure it to be
|
||||
// active
|
||||
final VpnInfo info = new VpnInfo();
|
||||
info.ownerUid = Process.myUid();
|
||||
info.vpnIface = "interface";
|
||||
mMockVpn.setVpnInfo(info);
|
||||
assertTrue(
|
||||
"Active VPN permission not applied",
|
||||
mService.checkConnectivityDiagnosticsPermissions(
|
||||
Process.myPid(), Process.myUid(), naiWithoutUid,
|
||||
mContext.getOpPackageName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckConnectivityDiagnosticsPermissionsNetworkAdministrator() throws Exception {
|
||||
final NetworkCapabilities nc = new NetworkCapabilities();
|
||||
nc.setAdministratorUids(Arrays.asList(Process.myUid()));
|
||||
final NetworkAgentInfo naiWithUid =
|
||||
new NetworkAgentInfo(
|
||||
null, null, null, null, null, nc, null, mServiceContext, null, null,
|
||||
mService, null, null, null, 0);
|
||||
|
||||
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION);
|
||||
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
|
||||
|
||||
// Disconnect mock vpn so the uid check on NetworkAgentInfo is tested
|
||||
mMockVpn.disconnect();
|
||||
assertTrue(
|
||||
"NetworkCapabilities administrator uid permission not applied",
|
||||
mService.checkConnectivityDiagnosticsPermissions(
|
||||
Process.myPid(), Process.myUid(), naiWithUid, mContext.getOpPackageName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckConnectivityDiagnosticsPermissionsFails() throws Exception {
|
||||
final NetworkCapabilities nc = new NetworkCapabilities();
|
||||
nc.setOwnerUid(Process.myUid());
|
||||
nc.setAdministratorUids(Arrays.asList(Process.myUid()));
|
||||
final NetworkAgentInfo naiWithUid =
|
||||
new NetworkAgentInfo(
|
||||
null, null, null, null, null, nc, null, mServiceContext, null, null,
|
||||
mService, null, null, null, 0);
|
||||
|
||||
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION);
|
||||
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
|
||||
|
||||
// Use wrong pid and uid
|
||||
assertFalse(
|
||||
"Permissions allowed when they shouldn't be granted",
|
||||
mService.checkConnectivityDiagnosticsPermissions(
|
||||
Process.myPid() + 1, Process.myUid() + 1, naiWithUid,
|
||||
mContext.getOpPackageName()));
|
||||
}
|
||||
|
||||
private void setupLocationPermissions(
|
||||
int targetSdk, boolean locationToggle, String op, String perm) throws Exception {
|
||||
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
applicationInfo.targetSdkVersion = targetSdk;
|
||||
when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
|
||||
.thenReturn(applicationInfo);
|
||||
|
||||
when(mLocationManager.isLocationEnabledForUser(any())).thenReturn(locationToggle);
|
||||
|
||||
when(mAppOpsManager.noteOp(eq(op), eq(Process.myUid()), eq(mContext.getPackageName())))
|
||||
.thenReturn(AppOpsManager.MODE_ALLOWED);
|
||||
|
||||
mServiceContext.setPermission(perm, PERMISSION_GRANTED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectivityDiagnosticsCallbackOnConnectivityReport() 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();
|
||||
|
||||
// Wait for onConnectivityReport to fire
|
||||
verify(mConnectivityDiagnosticsCallback, timeout(TIMEOUT_MS))
|
||||
.onConnectivityReport(any(ConnectivityReport.class));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user