Merge changes I4256ca5f,I91528e1a,I48bd594c
* changes: Change ConnectivityServiceTest to prepare for VPN code move. Add to VpnManager the VPN APIs used by Settings and SystemUI. Remove temporary hack in VpnTest.
This commit is contained in:
@@ -21,6 +21,7 @@ import static com.android.internal.util.Preconditions.checkNotNull;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -28,6 +29,8 @@ import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import com.android.internal.net.LegacyVpnInfo;
|
||||
import com.android.internal.net.VpnConfig;
|
||||
import com.android.internal.net.VpnProfile;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -161,4 +164,104 @@ public class VpnManager {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the VPN configuration for the given user ID.
|
||||
* @hide
|
||||
*/
|
||||
@Nullable
|
||||
public VpnConfig getVpnConfig(@UserIdInt int userId) {
|
||||
try {
|
||||
return mService.getVpnConfig(userId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare for a VPN application.
|
||||
* VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId},
|
||||
* {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
|
||||
*
|
||||
* @param oldPackage Package name of the application which currently controls VPN, which will
|
||||
* be replaced. If there is no such application, this should should either be
|
||||
* {@code null} or {@link VpnConfig.LEGACY_VPN}.
|
||||
* @param newPackage Package name of the application which should gain control of VPN, or
|
||||
* {@code null} to disable.
|
||||
* @param userId User for whom to prepare the new VPN.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean prepareVpn(@Nullable String oldPackage, @Nullable String newPackage,
|
||||
int userId) {
|
||||
try {
|
||||
return mService.prepareVpn(oldPackage, newPackage, userId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the VPN package has the ability to launch VPNs without user intervention. This
|
||||
* method is used by system-privileged apps. VPN permissions are checked in the {@link Vpn}
|
||||
* class. If the caller is not {@code userId}, {@link
|
||||
* android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
|
||||
*
|
||||
* @param packageName The package for which authorization state should change.
|
||||
* @param userId User for whom {@code packageName} is installed.
|
||||
* @param vpnType The {@link VpnManager.VpnType} constant representing what class of VPN
|
||||
* permissions should be granted. When unauthorizing an app, {@link
|
||||
* VpnManager.TYPE_VPN_NONE} should be used.
|
||||
* @hide
|
||||
*/
|
||||
public void setVpnPackageAuthorization(
|
||||
String packageName, int userId, @VpnManager.VpnType int vpnType) {
|
||||
try {
|
||||
mService.setVpnPackageAuthorization(packageName, userId, vpnType);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the legacy VPN information for the specified user ID.
|
||||
* @hide
|
||||
*/
|
||||
public LegacyVpnInfo getLegacyVpnInfo(@UserIdInt int userId) {
|
||||
try {
|
||||
return mService.getLegacyVpnInfo(userId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a legacy VPN.
|
||||
* @hide
|
||||
*/
|
||||
public void startLegacyVpn(VpnProfile profile) {
|
||||
try {
|
||||
mService.startLegacyVpn(profile);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs the service that legacy lockdown VPN state should be updated (e.g., if its keystore
|
||||
* entry has been updated). If the LockdownVpn mechanism is enabled, updates the vpn
|
||||
* with a reload of its profile.
|
||||
*
|
||||
* <p>This method can only be called by the system UID
|
||||
* @return a boolean indicating success
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean updateLockdownVpn() {
|
||||
try {
|
||||
return mService.updateLockdownVpn();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1263,6 +1263,13 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
}
|
||||
|
||||
private void processBroadcastForVpn(Intent intent) {
|
||||
// The BroadcastReceiver for this broadcast checks it is being run on the handler thread.
|
||||
final Handler handler = new Handler(mCsHandlerThread.getLooper());
|
||||
handler.post(() -> mServiceContext.sendBroadcast(intent));
|
||||
waitForIdle();
|
||||
}
|
||||
|
||||
private void mockUidNetworkingBlocked() {
|
||||
doAnswer(i -> mContext.getSystemService(NetworkPolicyManager.class)
|
||||
.checkUidNetworkingBlocked(i.getArgument(0) /* uid */, mUidRules,
|
||||
@@ -5405,20 +5412,20 @@ public class ConnectivityServiceTest {
|
||||
// MOBILE_IFNAME even though the default network is wifi.
|
||||
// TODO: fix this to pass in the actual default network interface. Whether or not the VPN
|
||||
// applies to the system server UID should not have any bearing on network stats.
|
||||
mService.setUnderlyingNetworksForVpn(onlyCell);
|
||||
mMockVpn.setUnderlyingNetworks(onlyCell);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
new String[]{MOBILE_IFNAME});
|
||||
reset(mStatsService);
|
||||
|
||||
mService.setUnderlyingNetworksForVpn(cellAndWifi);
|
||||
mMockVpn.setUnderlyingNetworks(cellAndWifi);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
new String[]{MOBILE_IFNAME, WIFI_IFNAME});
|
||||
reset(mStatsService);
|
||||
|
||||
// Null underlying networks are ignored.
|
||||
mService.setUnderlyingNetworksForVpn(cellNullAndWifi);
|
||||
mMockVpn.setUnderlyingNetworks(cellNullAndWifi);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
new String[]{MOBILE_IFNAME, WIFI_IFNAME});
|
||||
@@ -5467,25 +5474,25 @@ public class ConnectivityServiceTest {
|
||||
// is probably a performance improvement (though it's very unlikely that a VPN would declare
|
||||
// no underlying networks).
|
||||
// Also, for the same reason as above, the active interface passed in is null.
|
||||
mService.setUnderlyingNetworksForVpn(new Network[0]);
|
||||
mMockVpn.setUnderlyingNetworks(new Network[0]);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, null);
|
||||
reset(mStatsService);
|
||||
|
||||
// Specifying only a null underlying network is the same as no networks.
|
||||
mService.setUnderlyingNetworksForVpn(onlyNull);
|
||||
mMockVpn.setUnderlyingNetworks(onlyNull);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, null);
|
||||
reset(mStatsService);
|
||||
|
||||
// Specifying networks that are all disconnected is the same as specifying no networks.
|
||||
mService.setUnderlyingNetworksForVpn(onlyCell);
|
||||
mMockVpn.setUnderlyingNetworks(onlyCell);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, null);
|
||||
reset(mStatsService);
|
||||
|
||||
// Passing in null again means follow the default network again.
|
||||
mService.setUnderlyingNetworksForVpn(null);
|
||||
mMockVpn.setUnderlyingNetworks(null);
|
||||
waitForIdle();
|
||||
expectForceUpdateIfaces(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
|
||||
new String[]{WIFI_IFNAME});
|
||||
@@ -5960,7 +5967,7 @@ public class ConnectivityServiceTest {
|
||||
mMockVpn.establishForMyUid(false, true, false);
|
||||
assertUidRangesUpdatedForMyUid(true);
|
||||
final Network wifiNetwork = new Network(mNetIdManager.peekNextNetId());
|
||||
mService.setUnderlyingNetworksForVpn(new Network[]{wifiNetwork});
|
||||
mMockVpn.setUnderlyingNetworks(new Network[]{wifiNetwork});
|
||||
callback.expectAvailableCallbacksUnvalidated(mMockVpn);
|
||||
assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork())
|
||||
.hasTransport(TRANSPORT_VPN));
|
||||
@@ -6154,7 +6161,7 @@ public class ConnectivityServiceTest {
|
||||
|
||||
final Set<UidRange> ranges = uidRangesForUid(uid);
|
||||
mMockVpn.registerAgent(ranges);
|
||||
mService.setUnderlyingNetworksForVpn(new Network[0]);
|
||||
mMockVpn.setUnderlyingNetworks(new Network[0]);
|
||||
|
||||
// VPN networks do not satisfy the default request and are automatically validated
|
||||
// by NetworkMonitor
|
||||
@@ -6402,7 +6409,7 @@ public class ConnectivityServiceTest {
|
||||
mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
|
||||
mCellNetworkAgent.connect(true);
|
||||
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
mMockVpn.setUnderlyingNetworks(
|
||||
new Network[] { mCellNetworkAgent.getNetwork() });
|
||||
|
||||
vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
|
||||
@@ -6417,7 +6424,7 @@ public class ConnectivityServiceTest {
|
||||
mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
|
||||
mWiFiNetworkAgent.connect(true);
|
||||
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
mMockVpn.setUnderlyingNetworks(
|
||||
new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() });
|
||||
|
||||
vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
|
||||
@@ -6428,7 +6435,7 @@ public class ConnectivityServiceTest {
|
||||
assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent);
|
||||
|
||||
// Don't disconnect, but note the VPN is not using wifi any more.
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
mMockVpn.setUnderlyingNetworks(
|
||||
new Network[] { mCellNetworkAgent.getNetwork() });
|
||||
|
||||
vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
|
||||
@@ -6459,7 +6466,7 @@ public class ConnectivityServiceTest {
|
||||
vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, mMockVpn);
|
||||
|
||||
// Use Wifi but not cell. Note the VPN is now unmetered and not suspended.
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
mMockVpn.setUnderlyingNetworks(
|
||||
new Network[] { mWiFiNetworkAgent.getNetwork() });
|
||||
|
||||
vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
|
||||
@@ -6470,7 +6477,7 @@ public class ConnectivityServiceTest {
|
||||
assertDefaultNetworkCapabilities(userId, mWiFiNetworkAgent);
|
||||
|
||||
// Use both again.
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
mMockVpn.setUnderlyingNetworks(
|
||||
new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() });
|
||||
|
||||
vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
|
||||
@@ -6485,7 +6492,7 @@ public class ConnectivityServiceTest {
|
||||
vpnNetworkCallback.assertNoCallback();
|
||||
|
||||
// Stop using WiFi. The VPN is suspended again.
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
mMockVpn.setUnderlyingNetworks(
|
||||
new Network[] { mCellNetworkAgent.getNetwork() });
|
||||
vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
|
||||
(caps) -> caps.hasTransport(TRANSPORT_VPN)
|
||||
@@ -6496,7 +6503,7 @@ public class ConnectivityServiceTest {
|
||||
assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent);
|
||||
|
||||
// Use both again.
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
mMockVpn.setUnderlyingNetworks(
|
||||
new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() });
|
||||
|
||||
vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
|
||||
@@ -6631,9 +6638,7 @@ public class ConnectivityServiceTest {
|
||||
addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER);
|
||||
|
||||
// Send a USER_ADDED broadcast for it.
|
||||
// The BroadcastReceiver for this broadcast checks that is being run on the handler thread.
|
||||
final Handler handler = new Handler(mCsHandlerThread.getLooper());
|
||||
handler.post(() -> mServiceContext.sendBroadcast(addedIntent));
|
||||
processBroadcastForVpn(addedIntent);
|
||||
|
||||
// Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added
|
||||
// restricted user.
|
||||
@@ -6657,7 +6662,7 @@ public class ConnectivityServiceTest {
|
||||
// Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user.
|
||||
final Intent removedIntent = new Intent(ACTION_USER_REMOVED);
|
||||
removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER);
|
||||
handler.post(() -> mServiceContext.sendBroadcast(removedIntent));
|
||||
processBroadcastForVpn(removedIntent);
|
||||
|
||||
// Expect that the VPN gains the UID range for the restricted user, and that the capability
|
||||
// change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved.
|
||||
@@ -6714,9 +6719,7 @@ public class ConnectivityServiceTest {
|
||||
// TODO: check that VPN app within restricted profile still has access, etc.
|
||||
final Intent addedIntent = new Intent(ACTION_USER_ADDED);
|
||||
addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER);
|
||||
final Handler handler = new Handler(mCsHandlerThread.getLooper());
|
||||
handler.post(() -> mServiceContext.sendBroadcast(addedIntent));
|
||||
waitForIdle();
|
||||
processBroadcastForVpn(addedIntent);
|
||||
assertNull(mCm.getActiveNetworkForUid(uid));
|
||||
assertNull(mCm.getActiveNetworkForUid(restrictedUid));
|
||||
|
||||
@@ -6726,8 +6729,7 @@ public class ConnectivityServiceTest {
|
||||
// Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user.
|
||||
final Intent removedIntent = new Intent(ACTION_USER_REMOVED);
|
||||
removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER);
|
||||
handler.post(() -> mServiceContext.sendBroadcast(removedIntent));
|
||||
waitForIdle();
|
||||
processBroadcastForVpn(removedIntent);
|
||||
assertNull(mCm.getActiveNetworkForUid(uid));
|
||||
assertNotNull(mCm.getActiveNetworkForUid(restrictedUid));
|
||||
|
||||
@@ -6829,7 +6831,7 @@ public class ConnectivityServiceTest {
|
||||
// Ensure VPN is now the active network.
|
||||
assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork());
|
||||
// VPN is using Cell
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
mMockVpn.setUnderlyingNetworks(
|
||||
new Network[] { mCellNetworkAgent.getNetwork() });
|
||||
waitForIdle();
|
||||
|
||||
@@ -6837,7 +6839,7 @@ public class ConnectivityServiceTest {
|
||||
assertTrue(mCm.isActiveNetworkMetered());
|
||||
|
||||
// VPN is now using WiFi
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
mMockVpn.setUnderlyingNetworks(
|
||||
new Network[] { mWiFiNetworkAgent.getNetwork() });
|
||||
waitForIdle();
|
||||
|
||||
@@ -6845,7 +6847,7 @@ public class ConnectivityServiceTest {
|
||||
assertFalse(mCm.isActiveNetworkMetered());
|
||||
|
||||
// VPN is using Cell | WiFi.
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
mMockVpn.setUnderlyingNetworks(
|
||||
new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() });
|
||||
waitForIdle();
|
||||
|
||||
@@ -6853,7 +6855,7 @@ public class ConnectivityServiceTest {
|
||||
assertTrue(mCm.isActiveNetworkMetered());
|
||||
|
||||
// VPN is using WiFi | Cell.
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
mMockVpn.setUnderlyingNetworks(
|
||||
new Network[] { mWiFiNetworkAgent.getNetwork(), mCellNetworkAgent.getNetwork() });
|
||||
waitForIdle();
|
||||
|
||||
@@ -6861,7 +6863,7 @@ public class ConnectivityServiceTest {
|
||||
assertTrue(mCm.isActiveNetworkMetered());
|
||||
|
||||
// VPN is not using any underlying networks.
|
||||
mService.setUnderlyingNetworksForVpn(new Network[0]);
|
||||
mMockVpn.setUnderlyingNetworks(new Network[0]);
|
||||
waitForIdle();
|
||||
|
||||
// VPN without underlying networks is treated as metered.
|
||||
@@ -6888,7 +6890,7 @@ public class ConnectivityServiceTest {
|
||||
assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork());
|
||||
|
||||
// VPN is tracking current platform default (WiFi).
|
||||
mService.setUnderlyingNetworksForVpn(null);
|
||||
mMockVpn.setUnderlyingNetworks(null);
|
||||
waitForIdle();
|
||||
|
||||
// Despite VPN using WiFi (which is unmetered), VPN itself is marked as always metered.
|
||||
@@ -6896,7 +6898,7 @@ public class ConnectivityServiceTest {
|
||||
|
||||
|
||||
// VPN explicitly declares WiFi as its underlying network.
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
mMockVpn.setUnderlyingNetworks(
|
||||
new Network[] { mWiFiNetworkAgent.getNetwork() });
|
||||
waitForIdle();
|
||||
|
||||
@@ -7304,9 +7306,7 @@ public class ConnectivityServiceTest {
|
||||
final int userId = UserHandle.getUserId(Process.myUid());
|
||||
final Intent addedIntent = new Intent(ACTION_USER_UNLOCKED);
|
||||
addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
|
||||
final Handler handler = new Handler(mCsHandlerThread.getLooper());
|
||||
handler.post(() -> mServiceContext.sendBroadcast(addedIntent));
|
||||
waitForIdle();
|
||||
processBroadcastForVpn(addedIntent);
|
||||
|
||||
// Lockdown VPN disables teardown and enables lockdown.
|
||||
assertFalse(mMockVpn.getEnableTeardown());
|
||||
@@ -8748,7 +8748,7 @@ public class ConnectivityServiceTest {
|
||||
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION);
|
||||
|
||||
assertTrue(mService.setUnderlyingNetworksForVpn(new Network[] {naiWithoutUid.network}));
|
||||
assertTrue(mMockVpn.setUnderlyingNetworks(new Network[] {naiWithoutUid.network}));
|
||||
waitForIdle();
|
||||
assertTrue(
|
||||
"Active VPN permission not applied",
|
||||
@@ -8756,7 +8756,7 @@ public class ConnectivityServiceTest {
|
||||
Process.myPid(), Process.myUid(), naiWithoutUid,
|
||||
mContext.getOpPackageName()));
|
||||
|
||||
assertTrue(mService.setUnderlyingNetworksForVpn(null));
|
||||
assertTrue(mMockVpn.setUnderlyingNetworks(null));
|
||||
waitForIdle();
|
||||
assertFalse(
|
||||
"VPN shouldn't receive callback on non-underlying network",
|
||||
|
||||
@@ -953,14 +953,7 @@ public class VpnTest {
|
||||
}
|
||||
|
||||
private Vpn startLegacyVpn(final Vpn vpn, final VpnProfile vpnProfile) throws Exception {
|
||||
// TODO(b/175883995): once these tests have been updated for the changes to the UserManager
|
||||
// API, remove this ad-hoc setup code and use setMockedUsers(primaryUser) again.
|
||||
// setMockedUsers(primaryUser);
|
||||
final ArrayList<UserInfo> users = new ArrayList<>();
|
||||
users.add(primaryUser);
|
||||
when(mUserManager.getAliveUsers()).thenReturn(users);
|
||||
when(mUserManager.getUserInfo(primaryUser.id)).thenReturn(primaryUser);
|
||||
when(mUserManager.canHaveRestrictedProfile()).thenReturn(false);
|
||||
setMockedUsers(primaryUser);
|
||||
|
||||
// Dummy egress interface
|
||||
final LinkProperties lp = new LinkProperties();
|
||||
@@ -1159,10 +1152,6 @@ public class VpnTest {
|
||||
doReturn(UserHandle.of(userId)).when(asUserContext).getUser();
|
||||
when(mContext.createContextAsUser(eq(UserHandle.of(userId)), anyInt()))
|
||||
.thenReturn(asUserContext);
|
||||
when(asUserContext.getSystemServiceName(UserManager.class))
|
||||
.thenReturn(Context.USER_SERVICE);
|
||||
when(asUserContext.getSystemService(UserManager.class))
|
||||
.thenReturn(mUserManager);
|
||||
final TestLooper testLooper = new TestLooper();
|
||||
final Vpn vpn = new Vpn(testLooper.getLooper(), mContext, new TestDeps(), mNetService,
|
||||
mNetd, userId, mKeyStore, mSystemServices, mIkev2SessionCreator);
|
||||
|
||||
Reference in New Issue
Block a user