Merge changes Ia68f482a,I4911e214,Ied379654,I66d18512,Ie8e1bd63
* changes: Check registering system default callback needs NETWORK_SETTINGS. Move VPN code from ConnectivityService to VpnManagerService. Add a skeleton VpnManagerService, and start it on boot. Convert LockdownVpnTracker to NetworkCallbacks. Minor fixes to VpnTransportInfo.
This commit is contained in:
@@ -49,17 +49,6 @@ public final class ConnectivityFrameworkInitializer {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: move outside of the connectivity JAR
|
|
||||||
SystemServiceRegistry.registerContextAwareService(
|
|
||||||
Context.VPN_MANAGEMENT_SERVICE,
|
|
||||||
VpnManager.class,
|
|
||||||
(context) -> {
|
|
||||||
final ConnectivityManager cm = context.getSystemService(
|
|
||||||
ConnectivityManager.class);
|
|
||||||
return cm.createVpnManager();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
SystemServiceRegistry.registerContextAwareService(
|
SystemServiceRegistry.registerContextAwareService(
|
||||||
Context.CONNECTIVITY_DIAGNOSTICS_SERVICE,
|
Context.CONNECTIVITY_DIAGNOSTICS_SERVICE,
|
||||||
ConnectivityDiagnosticsManager.class,
|
ConnectivityDiagnosticsManager.class,
|
||||||
|
|||||||
@@ -824,6 +824,7 @@ public class ConnectivityManager {
|
|||||||
|
|
||||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
|
||||||
private final IConnectivityManager mService;
|
private final IConnectivityManager mService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A kludge to facilitate static access where a Context pointer isn't available, like in the
|
* A kludge to facilitate static access where a Context pointer isn't available, like in the
|
||||||
* case of the static set/getProcessDefaultNetwork methods and from the Network class.
|
* case of the static set/getProcessDefaultNetwork methods and from the Network class.
|
||||||
@@ -1069,106 +1070,55 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a VPN app supports always-on mode.
|
* Calls VpnManager#isAlwaysOnVpnPackageSupportedForUser.
|
||||||
*
|
* @deprecated TODO: remove when callers have migrated to VpnManager.
|
||||||
* In order to support the always-on feature, an app has to
|
|
||||||
* <ul>
|
|
||||||
* <li>target {@link VERSION_CODES#N API 24} or above, and
|
|
||||||
* <li>not opt out through the {@link VpnService#SERVICE_META_DATA_SUPPORTS_ALWAYS_ON}
|
|
||||||
* meta-data field.
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @param userId The identifier of the user for whom the VPN app is installed.
|
|
||||||
* @param vpnPackage The canonical package name of the VPN app.
|
|
||||||
* @return {@code true} if and only if the VPN app exists and supports always-on mode.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public boolean isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage) {
|
public boolean isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage) {
|
||||||
try {
|
return getVpnManager().isAlwaysOnVpnPackageSupportedForUser(userId, vpnPackage);
|
||||||
return mService.isAlwaysOnVpnPackageSupported(userId, vpnPackage);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
throw e.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures an always-on VPN connection through a specific application.
|
* Calls VpnManager#setAlwaysOnVpnPackageForUser.
|
||||||
* This connection is automatically granted and persisted after a reboot.
|
* @deprecated TODO: remove when callers have migrated to VpnManager.
|
||||||
*
|
|
||||||
* <p>The designated package should declare a {@link VpnService} in its
|
|
||||||
* manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE},
|
|
||||||
* otherwise the call will fail.
|
|
||||||
*
|
|
||||||
* @param userId The identifier of the user to set an always-on VPN for.
|
|
||||||
* @param vpnPackage The package name for an installed VPN app on the device, or {@code null}
|
|
||||||
* to remove an existing always-on VPN configuration.
|
|
||||||
* @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or
|
|
||||||
* {@code false} otherwise.
|
|
||||||
* @param lockdownAllowlist The list of packages that are allowed to access network directly
|
|
||||||
* when VPN is in lockdown mode but is not running. Non-existent packages are ignored so
|
|
||||||
* this method must be called when a package that should be allowed is installed or
|
|
||||||
* uninstalled.
|
|
||||||
* @return {@code true} if the package is set as always-on VPN controller;
|
|
||||||
* {@code false} otherwise.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
|
@Deprecated
|
||||||
public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
|
public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
|
||||||
boolean lockdownEnabled, @Nullable List<String> lockdownAllowlist) {
|
boolean lockdownEnabled, @Nullable List<String> lockdownAllowlist) {
|
||||||
try {
|
return getVpnManager().setAlwaysOnVpnPackageForUser(userId, vpnPackage, lockdownEnabled,
|
||||||
return mService.setAlwaysOnVpnPackage(
|
lockdownAllowlist);
|
||||||
userId, vpnPackage, lockdownEnabled, lockdownAllowlist);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
throw e.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the package name of the currently set always-on VPN application.
|
* Calls VpnManager#getAlwaysOnVpnPackageForUser.
|
||||||
* If there is no always-on VPN set, or the VPN is provided by the system instead
|
* @deprecated TODO: remove when callers have migrated to VpnManager.
|
||||||
* of by an app, {@code null} will be returned.
|
|
||||||
*
|
|
||||||
* @return Package name of VPN controller responsible for always-on VPN,
|
|
||||||
* or {@code null} if none is set.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
|
@Deprecated
|
||||||
public String getAlwaysOnVpnPackageForUser(int userId) {
|
public String getAlwaysOnVpnPackageForUser(int userId) {
|
||||||
try {
|
return getVpnManager().getAlwaysOnVpnPackageForUser(userId);
|
||||||
return mService.getAlwaysOnVpnPackage(userId);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
throw e.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return whether always-on VPN is in lockdown mode.
|
* Calls VpnManager#isVpnLockdownEnabled.
|
||||||
*
|
* @deprecated TODO: remove when callers have migrated to VpnManager.
|
||||||
* @hide
|
* @hide
|
||||||
**/
|
*/
|
||||||
@RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
|
@Deprecated
|
||||||
public boolean isVpnLockdownEnabled(int userId) {
|
public boolean isVpnLockdownEnabled(int userId) {
|
||||||
try {
|
return getVpnManager().isVpnLockdownEnabled(userId);
|
||||||
return mService.isVpnLockdownEnabled(userId);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
throw e.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the list of packages that are allowed to access network when always-on VPN is in
|
* Calls VpnManager#getVpnLockdownAllowlist.
|
||||||
* lockdown mode but not connected. Returns {@code null} when VPN lockdown is not active.
|
* @deprecated TODO: remove when callers have migrated to VpnManager.
|
||||||
*
|
|
||||||
* @hide
|
* @hide
|
||||||
**/
|
*/
|
||||||
@RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
|
@Deprecated
|
||||||
public List<String> getVpnLockdownWhitelist(int userId) {
|
public List<String> getVpnLockdownWhitelist(int userId) {
|
||||||
try {
|
return getVpnManager().getVpnLockdownAllowlist(userId);
|
||||||
return mService.getVpnLockdownWhitelist(userId);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
throw e.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1220,6 +1170,45 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Informs ConnectivityService of whether the legacy lockdown VPN, as implemented by
|
||||||
|
* LockdownVpnTracker, is in use. This is deprecated for new devices starting from Android 12
|
||||||
|
* but is still supported for backwards compatibility.
|
||||||
|
* <p>
|
||||||
|
* This type of VPN is assumed always to use the system default network, and must always declare
|
||||||
|
* exactly one underlying network, which is the network that was the default when the VPN
|
||||||
|
* connected.
|
||||||
|
* <p>
|
||||||
|
* Calling this method with {@code true} enables legacy behaviour, specifically:
|
||||||
|
* <ul>
|
||||||
|
* <li>Any VPN that applies to userId 0 behaves specially with respect to deprecated
|
||||||
|
* {@link #CONNECTIVITY_ACTION} broadcasts. Any such broadcasts will have the state in the
|
||||||
|
* {@link #EXTRA_NETWORK_INFO} replaced by state of the VPN network. Also, any time the VPN
|
||||||
|
* connects, a {@link #CONNECTIVITY_ACTION} broadcast will be sent for the network
|
||||||
|
* underlying the VPN.</li>
|
||||||
|
* <li>Deprecated APIs that return {@link NetworkInfo} objects will have their state
|
||||||
|
* similarly replaced by the VPN network state.</li>
|
||||||
|
* <li>Information on current network interfaces passed to NetworkStatsService will not
|
||||||
|
* include any VPN interfaces.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param enabled whether legacy lockdown VPN is enabled or disabled
|
||||||
|
*
|
||||||
|
* TODO: @SystemApi(client = MODULE_LIBRARIES)
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@RequiresPermission(anyOf = {
|
||||||
|
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
|
||||||
|
android.Manifest.permission.NETWORK_SETTINGS})
|
||||||
|
public void setLegacyLockdownVpnEnabled(boolean enabled) {
|
||||||
|
try {
|
||||||
|
mService.setLegacyLockdownVpnEnabled(enabled);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns details about the currently active default data network
|
* Returns details about the currently active default data network
|
||||||
* for a given uid. This is for internal use only to avoid spying
|
* for a given uid. This is for internal use only to avoid spying
|
||||||
@@ -3180,20 +3169,13 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the LockdownVpn mechanism is enabled, updates the vpn
|
* Calls VpnManager#updateLockdownVpn.
|
||||||
* with a reload of its profile.
|
* @deprecated TODO: remove when callers have migrated to VpnManager.
|
||||||
*
|
* @hide
|
||||||
* @return a boolean with {@code} indicating success
|
|
||||||
*
|
|
||||||
* <p>This method can only be called by the system UID
|
|
||||||
* {@hide}
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public boolean updateLockdownVpn() {
|
public boolean updateLockdownVpn() {
|
||||||
try {
|
return getVpnManager().updateLockdownVpn();
|
||||||
return mService.updateLockdownVpn();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
throw e.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -4557,6 +4539,8 @@ public class ConnectivityManager {
|
|||||||
try {
|
try {
|
||||||
mService.factoryReset();
|
mService.factoryReset();
|
||||||
mTetheringManager.stopAllTethering();
|
mTetheringManager.stopAllTethering();
|
||||||
|
// TODO: Migrate callers to VpnManager#factoryReset.
|
||||||
|
getVpnManager().factoryReset();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
@@ -4850,9 +4834,13 @@ public class ConnectivityManager {
|
|||||||
return new TestNetworkManager(ITestNetworkManager.Stub.asInterface(tnBinder));
|
return new TestNetworkManager(ITestNetworkManager.Stub.asInterface(tnBinder));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
public VpnManager createVpnManager() {
|
* Temporary hack to shim calls from ConnectivityManager to VpnManager. We cannot store a
|
||||||
return new VpnManager(mContext, mService);
|
* private final mVpnManager because ConnectivityManager is initialized before VpnManager.
|
||||||
|
* @hide TODO: remove.
|
||||||
|
*/
|
||||||
|
public VpnManager getVpnManager() {
|
||||||
|
return mContext.getSystemService(VpnManager.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
|
|||||||
@@ -43,9 +43,6 @@ import android.os.PersistableBundle;
|
|||||||
import android.os.ResultReceiver;
|
import android.os.ResultReceiver;
|
||||||
|
|
||||||
import com.android.connectivity.aidl.INetworkAgent;
|
import com.android.connectivity.aidl.INetworkAgent;
|
||||||
import com.android.internal.net.LegacyVpnInfo;
|
|
||||||
import com.android.internal.net.VpnConfig;
|
|
||||||
import com.android.internal.net.VpnProfile;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface that answers queries about, and allows changing, the
|
* Interface that answers queries about, and allows changing, the
|
||||||
@@ -123,35 +120,8 @@ interface IConnectivityManager
|
|||||||
|
|
||||||
ProxyInfo getProxyForNetwork(in Network nework);
|
ProxyInfo getProxyForNetwork(in Network nework);
|
||||||
|
|
||||||
boolean prepareVpn(String oldPackage, String newPackage, int userId);
|
|
||||||
|
|
||||||
void setVpnPackageAuthorization(String packageName, int userId, int vpnType);
|
|
||||||
|
|
||||||
ParcelFileDescriptor establishVpn(in VpnConfig config);
|
|
||||||
|
|
||||||
boolean provisionVpnProfile(in VpnProfile profile, String packageName);
|
|
||||||
|
|
||||||
void deleteVpnProfile(String packageName);
|
|
||||||
|
|
||||||
void startVpnProfile(String packageName);
|
|
||||||
|
|
||||||
void stopVpnProfile(String packageName);
|
|
||||||
|
|
||||||
VpnConfig getVpnConfig(int userId);
|
|
||||||
|
|
||||||
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
|
|
||||||
void startLegacyVpn(in VpnProfile profile);
|
|
||||||
|
|
||||||
LegacyVpnInfo getLegacyVpnInfo(int userId);
|
|
||||||
|
|
||||||
boolean updateLockdownVpn();
|
|
||||||
boolean isAlwaysOnVpnPackageSupported(int userId, String packageName);
|
|
||||||
boolean setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdown,
|
|
||||||
in List<String> lockdownWhitelist);
|
|
||||||
String getAlwaysOnVpnPackage(int userId);
|
|
||||||
boolean isVpnLockdownEnabled(int userId);
|
|
||||||
List<String> getVpnLockdownWhitelist(int userId);
|
|
||||||
void setRequireVpnForUids(boolean requireVpn, in UidRange[] ranges);
|
void setRequireVpnForUids(boolean requireVpn, in UidRange[] ranges);
|
||||||
|
void setLegacyLockdownVpnEnabled(boolean enabled);
|
||||||
|
|
||||||
void setProvisioningNotificationVisible(boolean visible, int networkType, in String action);
|
void setProvisioningNotificationVisible(boolean visible, int networkType, in String action);
|
||||||
|
|
||||||
@@ -200,10 +170,6 @@ interface IConnectivityManager
|
|||||||
|
|
||||||
int getRestoreDefaultNetworkDelay(int networkType);
|
int getRestoreDefaultNetworkDelay(int networkType);
|
||||||
|
|
||||||
boolean addVpnAddress(String address, int prefixLength);
|
|
||||||
boolean removeVpnAddress(String address, int prefixLength);
|
|
||||||
boolean setUnderlyingNetworksForVpn(in Network[] networks);
|
|
||||||
|
|
||||||
void factoryReset();
|
void factoryReset();
|
||||||
|
|
||||||
void startNattKeepalive(in Network network, int intervalSeconds,
|
void startNattKeepalive(in Network network, int intervalSeconds,
|
||||||
@@ -223,8 +189,6 @@ interface IConnectivityManager
|
|||||||
byte[] getNetworkWatchlistConfigHash();
|
byte[] getNetworkWatchlistConfigHash();
|
||||||
|
|
||||||
int getConnectionOwnerUid(in ConnectionInfo connectionInfo);
|
int getConnectionOwnerUid(in ConnectionInfo connectionInfo);
|
||||||
boolean isCallerCurrentAlwaysOnVpnApp();
|
|
||||||
boolean isCallerCurrentAlwaysOnVpnLockdownApp();
|
|
||||||
|
|
||||||
void registerConnectivityDiagnosticsCallback(in IConnectivityDiagnosticsCallback callback,
|
void registerConnectivityDiagnosticsCallback(in IConnectivityDiagnosticsCallback callback,
|
||||||
in NetworkRequest request, String callingPackageName);
|
in NetworkRequest request, String callingPackageName);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import static com.android.internal.util.Preconditions.checkNotNull;
|
|||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.annotation.RequiresPermission;
|
||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
@@ -37,6 +38,7 @@ import java.io.IOException;
|
|||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides an interface for apps to manage platform VPN profiles
|
* This class provides an interface for apps to manage platform VPN profiles
|
||||||
@@ -76,13 +78,19 @@ public class VpnManager {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public static final int TYPE_VPN_LEGACY = 3;
|
public static final int TYPE_VPN_LEGACY = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Channel for VPN notifications.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final String NOTIFICATION_CHANNEL_VPN = "VPN";
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@IntDef(value = {TYPE_VPN_NONE, TYPE_VPN_SERVICE, TYPE_VPN_PLATFORM, TYPE_VPN_LEGACY})
|
@IntDef(value = {TYPE_VPN_NONE, TYPE_VPN_SERVICE, TYPE_VPN_PLATFORM, TYPE_VPN_LEGACY})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface VpnType {}
|
public @interface VpnType {}
|
||||||
|
|
||||||
@NonNull private final Context mContext;
|
@NonNull private final Context mContext;
|
||||||
@NonNull private final IConnectivityManager mService;
|
@NonNull private final IVpnManager mService;
|
||||||
|
|
||||||
private static Intent getIntentForConfirmation() {
|
private static Intent getIntentForConfirmation() {
|
||||||
final Intent intent = new Intent();
|
final Intent intent = new Intent();
|
||||||
@@ -101,9 +109,9 @@ public class VpnManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public VpnManager(@NonNull Context ctx, @NonNull IConnectivityManager service) {
|
public VpnManager(@NonNull Context ctx, @NonNull IVpnManager service) {
|
||||||
mContext = checkNotNull(ctx, "missing Context");
|
mContext = checkNotNull(ctx, "missing Context");
|
||||||
mService = checkNotNull(service, "missing IConnectivityManager");
|
mService = checkNotNull(service, "missing IVpnManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -194,6 +202,19 @@ public class VpnManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets all VPN settings back to factory defaults.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
|
||||||
|
public void factoryReset() {
|
||||||
|
try {
|
||||||
|
mService.factoryReset();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare for a VPN application.
|
* Prepare for a VPN application.
|
||||||
* VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId},
|
* VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId},
|
||||||
@@ -239,6 +260,108 @@ public class VpnManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a VPN app supports always-on mode.
|
||||||
|
*
|
||||||
|
* In order to support the always-on feature, an app has to
|
||||||
|
* <ul>
|
||||||
|
* <li>target {@link VERSION_CODES#N API 24} or above, and
|
||||||
|
* <li>not opt out through the {@link VpnService#SERVICE_META_DATA_SUPPORTS_ALWAYS_ON}
|
||||||
|
* meta-data field.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param userId The identifier of the user for whom the VPN app is installed.
|
||||||
|
* @param vpnPackage The canonical package name of the VPN app.
|
||||||
|
* @return {@code true} if and only if the VPN app exists and supports always-on mode.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage) {
|
||||||
|
try {
|
||||||
|
return mService.isAlwaysOnVpnPackageSupported(userId, vpnPackage);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures an always-on VPN connection through a specific application.
|
||||||
|
* This connection is automatically granted and persisted after a reboot.
|
||||||
|
*
|
||||||
|
* <p>The designated package should declare a {@link VpnService} in its
|
||||||
|
* manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE},
|
||||||
|
* otherwise the call will fail.
|
||||||
|
*
|
||||||
|
* @param userId The identifier of the user to set an always-on VPN for.
|
||||||
|
* @param vpnPackage The package name for an installed VPN app on the device, or {@code null}
|
||||||
|
* to remove an existing always-on VPN configuration.
|
||||||
|
* @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or
|
||||||
|
* {@code false} otherwise.
|
||||||
|
* @param lockdownAllowlist The list of packages that are allowed to access network directly
|
||||||
|
* when VPN is in lockdown mode but is not running. Non-existent packages are ignored so
|
||||||
|
* this method must be called when a package that should be allowed is installed or
|
||||||
|
* uninstalled.
|
||||||
|
* @return {@code true} if the package is set as always-on VPN controller;
|
||||||
|
* {@code false} otherwise.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
|
||||||
|
public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
|
||||||
|
boolean lockdownEnabled, @Nullable List<String> lockdownAllowlist) {
|
||||||
|
try {
|
||||||
|
return mService.setAlwaysOnVpnPackage(
|
||||||
|
userId, vpnPackage, lockdownEnabled, lockdownAllowlist);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the package name of the currently set always-on VPN application.
|
||||||
|
* If there is no always-on VPN set, or the VPN is provided by the system instead
|
||||||
|
* of by an app, {@code null} will be returned.
|
||||||
|
*
|
||||||
|
* @return Package name of VPN controller responsible for always-on VPN,
|
||||||
|
* or {@code null} if none is set.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
|
||||||
|
public String getAlwaysOnVpnPackageForUser(int userId) {
|
||||||
|
try {
|
||||||
|
return mService.getAlwaysOnVpnPackage(userId);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return whether always-on VPN is in lockdown mode.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
**/
|
||||||
|
@RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
|
||||||
|
public boolean isVpnLockdownEnabled(int userId) {
|
||||||
|
try {
|
||||||
|
return mService.isVpnLockdownEnabled(userId);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the list of packages that are allowed to access network when always-on VPN is in
|
||||||
|
* lockdown mode but not connected. Returns {@code null} when VPN lockdown is not active.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
**/
|
||||||
|
@RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
|
||||||
|
public List<String> getVpnLockdownAllowlist(int userId) {
|
||||||
|
try {
|
||||||
|
return mService.getVpnLockdownAllowlist(userId);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the legacy VPN information for the specified user ID.
|
* Return the legacy VPN information for the specified user ID.
|
||||||
* @hide
|
* @hide
|
||||||
|
|||||||
@@ -170,12 +170,11 @@ public class VpnService extends Service {
|
|||||||
"android.net.VpnService.SUPPORTS_ALWAYS_ON";
|
"android.net.VpnService.SUPPORTS_ALWAYS_ON";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use IConnectivityManager since those methods are hidden and not
|
* Use IVpnManager since those methods are hidden and not available in VpnManager.
|
||||||
* available in ConnectivityManager.
|
|
||||||
*/
|
*/
|
||||||
private static IConnectivityManager getService() {
|
private static IVpnManager getService() {
|
||||||
return IConnectivityManager.Stub.asInterface(
|
return IVpnManager.Stub.asInterface(
|
||||||
ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
|
ServiceManager.getService(Context.VPN_MANAGEMENT_SERVICE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -226,15 +225,15 @@ public class VpnService extends Service {
|
|||||||
@SystemApi
|
@SystemApi
|
||||||
@RequiresPermission(android.Manifest.permission.CONTROL_VPN)
|
@RequiresPermission(android.Manifest.permission.CONTROL_VPN)
|
||||||
public static void prepareAndAuthorize(Context context) {
|
public static void prepareAndAuthorize(Context context) {
|
||||||
IConnectivityManager cm = getService();
|
IVpnManager vm = getService();
|
||||||
String packageName = context.getPackageName();
|
String packageName = context.getPackageName();
|
||||||
try {
|
try {
|
||||||
// Only prepare if we're not already prepared.
|
// Only prepare if we're not already prepared.
|
||||||
int userId = context.getUserId();
|
int userId = context.getUserId();
|
||||||
if (!cm.prepareVpn(packageName, null, userId)) {
|
if (!vm.prepareVpn(packageName, null, userId)) {
|
||||||
cm.prepareVpn(null, packageName, userId);
|
vm.prepareVpn(null, packageName, userId);
|
||||||
}
|
}
|
||||||
cm.setVpnPackageAuthorization(packageName, userId, VpnManager.TYPE_VPN_SERVICE);
|
vm.setVpnPackageAuthorization(packageName, userId, VpnManager.TYPE_VPN_SERVICE);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user