1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net; 18 19 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; 20 21 import static com.android.internal.util.Preconditions.checkNotNull; 22 23 import android.annotation.FlaggedApi; 24 import android.annotation.IntDef; 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.annotation.RequiresPermission; 28 import android.annotation.SdkConstant; 29 import android.annotation.SystemApi; 30 import android.annotation.UserIdInt; 31 import android.app.Activity; 32 import android.content.ComponentName; 33 import android.content.Context; 34 import android.content.Intent; 35 import android.content.res.Resources; 36 import android.net.platform.flags.Flags; 37 import android.os.RemoteException; 38 39 import com.android.internal.net.LegacyVpnInfo; 40 import com.android.internal.net.VpnConfig; 41 import com.android.internal.net.VpnProfile; 42 43 import java.io.IOException; 44 import java.lang.annotation.Retention; 45 import java.lang.annotation.RetentionPolicy; 46 import java.security.GeneralSecurityException; 47 import java.util.List; 48 49 /** 50 * This class provides an interface for apps to manage platform VPN profiles 51 * 52 * <p>Apps can use this API to provide profiles with which the platform can set up a VPN without 53 * further app intermediation. When a VPN profile is present and the app is selected as an always-on 54 * VPN, the platform will directly trigger the negotiation of the VPN without starting or waking the 55 * app (unlike VpnService). 56 * 57 * <p>VPN apps using supported protocols should preferentially use this API over the {@link 58 * VpnService} API for ease-of-development and reduced maintenance burden. This also give the user 59 * the guarantee that VPN network traffic is not subjected to on-device packet interception. 60 * 61 * @see Ikev2VpnProfile 62 */ 63 public class VpnManager { 64 /** Type representing a lack of VPN @hide */ 65 @SystemApi(client = MODULE_LIBRARIES) 66 public static final int TYPE_VPN_NONE = -1; 67 68 /** 69 * A VPN created by an app using the {@link VpnService} API. 70 * @hide 71 */ 72 @SystemApi(client = MODULE_LIBRARIES) 73 public static final int TYPE_VPN_SERVICE = 1; 74 75 /** 76 * A VPN created using a {@link VpnManager} API such as {@link #startProvisionedVpnProfile}. 77 * @hide 78 */ 79 @SystemApi(client = MODULE_LIBRARIES) 80 public static final int TYPE_VPN_PLATFORM = 2; 81 82 /** 83 * An IPsec VPN created by the built-in LegacyVpnRunner. 84 * @hide 85 */ 86 @SystemApi(client = MODULE_LIBRARIES) 87 public static final int TYPE_VPN_LEGACY = 3; 88 89 /** 90 * A VPN created by OEM code through other means than {@link VpnService} or {@link VpnManager}. 91 * @hide 92 */ 93 @SystemApi(client = MODULE_LIBRARIES) 94 public static final int TYPE_VPN_OEM = 4; 95 96 /** 97 * A VPN created by OEM code using {@link VpnService}, and which OEM code desires to 98 * differentiate from other VPN types. The core networking stack will treat this VPN type 99 * similarly to {@link #TYPE_VPN_SERVICE}. 100 * @hide 101 */ 102 @FlaggedApi(Flags.FLAG_VPN_TYPE_OEM_SERVICE_AND_LEGACY) 103 @SystemApi(client = MODULE_LIBRARIES) 104 public static final int TYPE_VPN_OEM_SERVICE = 5; 105 106 /** 107 * A VPN created by OEM code using the legacy VPN mechanisms, and which OEM code desires to 108 * differentiate from other VPN types. The core networking stack will treat this VPN type 109 * similarly to {@link #TYPE_VPN_LEGACY}. 110 * @hide 111 */ 112 @FlaggedApi(Flags.FLAG_VPN_TYPE_OEM_SERVICE_AND_LEGACY) 113 @SystemApi(client = MODULE_LIBRARIES) 114 public static final int TYPE_VPN_OEM_LEGACY = 6; 115 116 /** 117 * Channel for VPN notifications. 118 * @hide 119 */ 120 public static final String NOTIFICATION_CHANNEL_VPN = "VPN"; 121 122 /** 123 * Action sent in {@link android.content.Intent}s to VpnManager clients when an event occurred. 124 * 125 * <p>If the provisioning application declares a service handling this intent action, but is not 126 * already running, it will be started. Upon starting, the application is granted a short grace 127 * period to run in the background even while the device is idle to handle any potential 128 * failures. Applications requiring long-running actions triggered by one of these events should 129 * declare a foreground service to prevent being killed once the grace period expires. 130 * 131 * This action will have a category of either {@link #CATEGORY_EVENT_IKE_ERROR}, 132 * {@link #CATEGORY_EVENT_NETWORK_ERROR}, or {@link #CATEGORY_EVENT_DEACTIVATED_BY_USER}, 133 * that the app can use to filter events it's interested in reacting to. 134 * 135 * It will also contain the following extras : 136 * <ul> 137 * <li>{@link #EXTRA_SESSION_KEY}, a {@code String} for the session key, as returned by 138 * {@link #startProvisionedVpnProfileSession}. 139 * <li>{@link #EXTRA_TIMESTAMP_MILLIS}, a long for the timestamp at which the error occurred, 140 * in milliseconds since the epoch, as returned by 141 * {@link java.lang.System#currentTimeMillis}. 142 * <li>{@link #EXTRA_UNDERLYING_NETWORK}, a {@link Network} containing the underlying 143 * network at the time the error occurred, or null if none. Note that this network 144 * may have disconnected already. 145 * <li>{@link #EXTRA_UNDERLYING_NETWORK_CAPABILITIES}, a {@link NetworkCapabilities} for 146 * the underlying network at the time the error occurred. 147 * <li>{@link #EXTRA_UNDERLYING_LINK_PROPERTIES}, a {@link LinkProperties} for the underlying 148 * network at the time the error occurred. 149 * </ul> 150 * When this event is an error, either {@link #CATEGORY_EVENT_IKE_ERROR} or 151 * {@link #CATEGORY_EVENT_NETWORK_ERROR}, the following extras will be populated : 152 * <ul> 153 * <li>{@link #EXTRA_ERROR_CLASS}, an {@code int} for the class of error, either 154 * {@link #ERROR_CLASS_RECOVERABLE} or {@link #ERROR_CLASS_NOT_RECOVERABLE}. 155 * <li>{@link #EXTRA_ERROR_CODE}, an {@code int} error code specific to the error. See 156 * {@link #EXTRA_ERROR_CODE} for details. 157 * </ul> 158 */ 159 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) 160 public static final String ACTION_VPN_MANAGER_EVENT = "android.net.action.VPN_MANAGER_EVENT"; 161 162 /** 163 * An IKE protocol error occurred. 164 * 165 * Codes (in {@link #EXTRA_ERROR_CODE}) are the codes from 166 * {@link android.net.ipsec.ike.exceptions.IkeProtocolException}, as defined by IANA in 167 * "IKEv2 Notify Message Types - Error Types". 168 */ 169 @SdkConstant(SdkConstant.SdkConstantType.INTENT_CATEGORY) 170 public static final String CATEGORY_EVENT_IKE_ERROR = "android.net.category.EVENT_IKE_ERROR"; 171 172 /** 173 * A network error occurred. 174 * 175 * Error codes (in {@link #EXTRA_ERROR_CODE}) are ERROR_CODE_NETWORK_*. 176 */ 177 @SdkConstant(SdkConstant.SdkConstantType.INTENT_CATEGORY) 178 public static final String CATEGORY_EVENT_NETWORK_ERROR = 179 "android.net.category.EVENT_NETWORK_ERROR"; 180 181 /** 182 * The user deactivated the VPN. 183 * 184 * This can happen either when the user turns the VPN off explicitly, or when they select 185 * a different VPN provider. 186 */ 187 @SdkConstant(SdkConstant.SdkConstantType.INTENT_CATEGORY) 188 public static final String CATEGORY_EVENT_DEACTIVATED_BY_USER = 189 "android.net.category.EVENT_DEACTIVATED_BY_USER"; 190 191 /** 192 * The always-on state of this VPN was changed 193 * 194 * <p>This may be the result of a user changing VPN settings, or a Device Policy Manager app 195 * having changed the VPN policy. 196 */ 197 @SdkConstant(SdkConstant.SdkConstantType.INTENT_CATEGORY) 198 public static final String CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED = 199 "android.net.category.EVENT_ALWAYS_ON_STATE_CHANGED"; 200 201 /** 202 * The VpnProfileState at the time that this event occurred. 203 * 204 * <p>This extra may be null if the VPN was revoked by the user, or the profile was deleted. 205 */ 206 public static final String EXTRA_VPN_PROFILE_STATE = "android.net.extra.VPN_PROFILE_STATE"; 207 208 /** 209 * The key of the session that experienced this event, as a {@code String}. 210 * 211 * This is the same key that was returned by {@link #startProvisionedVpnProfileSession}. 212 */ 213 public static final String EXTRA_SESSION_KEY = "android.net.extra.SESSION_KEY"; 214 215 /** 216 * The network that was underlying the VPN when the event occurred, as a {@link Network}. 217 * 218 * <p>This extra will be null if there was no underlying network at the time of the event, or 219 * the underlying network has no bearing on the event, as in the case of: 220 * <ul> 221 * <li>CATEGORY_EVENT_DEACTIVATED_BY_USER 222 * <li>CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED 223 * </ul> 224 */ 225 public static final String EXTRA_UNDERLYING_NETWORK = "android.net.extra.UNDERLYING_NETWORK"; 226 227 /** 228 * The {@link NetworkCapabilities} of the underlying network when the event occurred. 229 * 230 * <p>This extra will be null if there was no underlying network at the time of the event, or 231 * the underlying network has no bearing on the event, as in the case of: 232 * <ul> 233 * <li>CATEGORY_EVENT_DEACTIVATED_BY_USER 234 * <li>CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED 235 * </ul> 236 */ 237 public static final String EXTRA_UNDERLYING_NETWORK_CAPABILITIES = 238 "android.net.extra.UNDERLYING_NETWORK_CAPABILITIES"; 239 240 /** 241 * The {@link LinkProperties} of the underlying network when the event occurred. 242 * 243 * <p>This extra will be null if there was no underlying network at the time of the event, or 244 * the underlying network has no bearing on the event, as in the case of: 245 * <ul> 246 * <li>CATEGORY_EVENT_DEACTIVATED_BY_USER 247 * <li>CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED 248 * </ul> 249 */ 250 public static final String EXTRA_UNDERLYING_LINK_PROPERTIES = 251 "android.net.extra.UNDERLYING_LINK_PROPERTIES"; 252 253 /** 254 * A {@code long} timestamp containing the time at which the event occurred. 255 * 256 * This is a number of milliseconds since the epoch, suitable to be compared with 257 * {@link java.lang.System#currentTimeMillis}. 258 */ 259 public static final String EXTRA_TIMESTAMP_MILLIS = "android.net.extra.TIMESTAMP_MILLIS"; 260 261 /** 262 * Extra for the error class, as an {@code int}. 263 * 264 * This is always either {@link #ERROR_CLASS_NOT_RECOVERABLE} or 265 * {@link #ERROR_CLASS_RECOVERABLE}. This extra is only populated for error categories. 266 */ 267 public static final String EXTRA_ERROR_CLASS = "android.net.extra.ERROR_CLASS"; 268 269 /** 270 * Extra for an error code, as an {@code int}. 271 * 272 * <ul> 273 * <li>For {@link #CATEGORY_EVENT_NETWORK_ERROR}, this is one of the 274 * {@code ERROR_CODE_NETWORK_*} constants. 275 * <li>For {@link #CATEGORY_EVENT_IKE_ERROR}, this is one of values defined in 276 * {@link android.net.ipsec.ike.exceptions.IkeProtocolException}.ERROR_TYPE_*. 277 * </ul> 278 * For non-error categories, this extra is not populated. 279 */ 280 public static final String EXTRA_ERROR_CODE = "android.net.extra.ERROR_CODE"; 281 282 /** 283 * {@link #EXTRA_ERROR_CLASS} coding for a non-recoverable error. 284 * 285 * This error is fatal, e.g. configuration error. The stack will not retry connection. 286 */ 287 public static final int ERROR_CLASS_NOT_RECOVERABLE = 1; 288 289 /** 290 * {@link #EXTRA_ERROR_CLASS} coding for a recoverable error. 291 * 292 * The stack experienced an error but will retry with exponential backoff, e.g. network timeout. 293 */ 294 public static final int ERROR_CLASS_RECOVERABLE = 2; 295 296 /** 297 * An {@link #EXTRA_ERROR_CODE} for {@link #CATEGORY_EVENT_NETWORK_ERROR} to indicate that the 298 * network host isn't known. 299 * 300 * This happens when domain name resolution could not resolve an IP address for the 301 * specified host. {@see java.net.UnknownHostException} 302 */ 303 public static final int ERROR_CODE_NETWORK_UNKNOWN_HOST = 0; 304 305 /** 306 * An {@link #EXTRA_ERROR_CODE} for {@link #CATEGORY_EVENT_NETWORK_ERROR} indicating a timeout. 307 * 308 * For Ikev2 VPNs, this happens typically after a retransmission failure. 309 * {@see android.net.ipsec.ike.exceptions.IkeTimeoutException} 310 */ 311 public static final int ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT = 1; 312 313 /** 314 * An {@link #EXTRA_ERROR_CODE} for {@link #CATEGORY_EVENT_NETWORK_ERROR} indicating that 315 * network connectivity was lost. 316 * 317 * The most common reason for this error is that the underlying network was disconnected, 318 * {@see android.net.ipsec.ike.exceptions.IkeNetworkLostException}. 319 */ 320 public static final int ERROR_CODE_NETWORK_LOST = 2; 321 322 /** 323 * An {@link #EXTRA_ERROR_CODE} for {@link #CATEGORY_EVENT_NETWORK_ERROR} indicating an 324 * input/output error. 325 * 326 * This code happens when reading or writing to sockets on the underlying networks was 327 * terminated by an I/O error. {@see IOException}. 328 */ 329 public static final int ERROR_CODE_NETWORK_IO = 3; 330 331 /** @hide */ 332 @IntDef(value = {TYPE_VPN_NONE, TYPE_VPN_SERVICE, TYPE_VPN_PLATFORM, TYPE_VPN_LEGACY, 333 TYPE_VPN_OEM, TYPE_VPN_OEM_SERVICE, TYPE_VPN_OEM_LEGACY}) 334 @Retention(RetentionPolicy.SOURCE) 335 public @interface VpnType {} 336 337 @NonNull private final Context mContext; 338 @NonNull private final IVpnManager mService; 339 getIntentForConfirmation()340 private static Intent getIntentForConfirmation() { 341 final Intent intent = new Intent(); 342 final ComponentName componentName = ComponentName.unflattenFromString( 343 Resources.getSystem().getString( 344 com.android.internal.R.string.config_platformVpnConfirmDialogComponent)); 345 intent.setComponent(componentName); 346 return intent; 347 } 348 349 /** 350 * Create an instance of the VpnManager with the given context. 351 * 352 * <p>Internal only. Applications are expected to obtain an instance of the VpnManager via the 353 * {@link Context.getSystemService()} method call. 354 * 355 * @hide 356 */ VpnManager(@onNull Context ctx, @NonNull IVpnManager service)357 public VpnManager(@NonNull Context ctx, @NonNull IVpnManager service) { 358 mContext = checkNotNull(ctx, "missing Context"); 359 mService = checkNotNull(service, "missing IVpnManager"); 360 } 361 362 /** 363 * Install a VpnProfile configuration keyed on the calling app's package name. 364 * 365 * <p>This method returns {@code null} if user consent has already been granted, or an {@link 366 * Intent} to a system activity. If an intent is returned, the application should launch the 367 * activity using {@link Activity#startActivityForResult} to request user consent. The activity 368 * may pop up a dialog to require user action, and the result will come back via its {@link 369 * Activity#onActivityResult}. If the result is {@link Activity#RESULT_OK}, the user has 370 * consented, and the VPN profile can be started. 371 * 372 * @param profile the VpnProfile provided by this package. Will override any previous VpnProfile 373 * stored for this package. 374 * @return an Intent requesting user consent to start the VPN, or null if consent is not 375 * required based on privileges or previous user consent. 376 */ 377 @Nullable provisionVpnProfile(@onNull PlatformVpnProfile profile)378 public Intent provisionVpnProfile(@NonNull PlatformVpnProfile profile) { 379 final VpnProfile internalProfile; 380 381 try { 382 internalProfile = profile.toVpnProfile(); 383 } catch (GeneralSecurityException | IOException e) { 384 // Conversion to VpnProfile failed; this is an invalid profile. Both of these exceptions 385 // indicate a failure to convert a PrivateKey or X509Certificate to a Base64 encoded 386 // string as required by the VpnProfile. 387 throw new IllegalArgumentException("Failed to serialize PlatformVpnProfile", e); 388 } 389 390 try { 391 // Profile can never be null; it either gets set, or an exception is thrown. 392 if (mService.provisionVpnProfile(internalProfile, mContext.getOpPackageName())) { 393 return null; 394 } 395 } catch (RemoteException e) { 396 throw e.rethrowFromSystemServer(); 397 } 398 return getIntentForConfirmation(); 399 } 400 401 /** 402 * Delete the VPN profile configuration that was provisioned by the calling app 403 * 404 * @throws SecurityException if this would violate user settings 405 */ deleteProvisionedVpnProfile()406 public void deleteProvisionedVpnProfile() { 407 try { 408 mService.deleteVpnProfile(mContext.getOpPackageName()); 409 } catch (RemoteException e) { 410 throw e.rethrowFromSystemServer(); 411 } 412 } 413 414 /** 415 * Request the startup of a previously provisioned VPN. 416 * 417 * @return A unique key corresponding to this session. 418 * @throws SecurityException exception if user or device settings prevent this VPN from being 419 * setup, or if user consent has not been granted 420 */ 421 @NonNull startProvisionedVpnProfileSession()422 public String startProvisionedVpnProfileSession() { 423 try { 424 return mService.startVpnProfile(mContext.getOpPackageName()); 425 } catch (RemoteException e) { 426 throw e.rethrowFromSystemServer(); 427 } 428 } 429 430 /** 431 * Request the startup of a previously provisioned VPN. 432 * 433 * @throws SecurityException exception if user or device settings prevent this VPN from being 434 * setup, or if user consent has not been granted 435 * @deprecated This method is replaced by startProvisionedVpnProfileSession which returns a 436 * session key for the caller to diagnose the errors. 437 */ 438 @Deprecated startProvisionedVpnProfile()439 public void startProvisionedVpnProfile() { 440 startProvisionedVpnProfileSession(); 441 } 442 443 /** Tear down the VPN provided by the calling app (if any) */ stopProvisionedVpnProfile()444 public void stopProvisionedVpnProfile() { 445 try { 446 mService.stopVpnProfile(mContext.getOpPackageName()); 447 } catch (RemoteException e) { 448 throw e.rethrowFromSystemServer(); 449 } 450 } 451 452 /** 453 * Return the VPN configuration for the given user ID. 454 * @hide 455 */ 456 @Nullable getVpnConfig(@serIdInt int userId)457 public VpnConfig getVpnConfig(@UserIdInt int userId) { 458 try { 459 return mService.getVpnConfig(userId); 460 } catch (RemoteException e) { 461 throw e.rethrowFromSystemServer(); 462 } 463 } 464 465 /** 466 * Retrieve the VpnProfileState for the profile provisioned by the calling package. 467 * 468 * @return the VpnProfileState with current information, or null if there was no profile 469 * provisioned and started by the calling package. 470 */ 471 @Nullable getProvisionedVpnProfileState()472 public VpnProfileState getProvisionedVpnProfileState() { 473 try { 474 return mService.getProvisionedVpnProfileState(mContext.getOpPackageName()); 475 } catch (RemoteException e) { 476 throw e.rethrowFromSystemServer(); 477 } 478 } 479 480 /** 481 * Resets all VPN settings back to factory defaults. 482 * @hide 483 */ 484 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) factoryReset()485 public void factoryReset() { 486 try { 487 mService.factoryReset(); 488 } catch (RemoteException e) { 489 throw e.rethrowFromSystemServer(); 490 } 491 } 492 493 /** 494 * Prepare for a VPN application. 495 * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId}, 496 * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required. 497 * 498 * @param oldPackage Package name of the application which currently controls VPN, which will 499 * be replaced. If there is no such application, this should should either be 500 * {@code null} or {@link VpnConfig.LEGACY_VPN}. 501 * @param newPackage Package name of the application which should gain control of VPN, or 502 * {@code null} to disable. 503 * @param userId User for whom to prepare the new VPN. 504 * 505 * @hide 506 */ prepareVpn(@ullable String oldPackage, @Nullable String newPackage, int userId)507 public boolean prepareVpn(@Nullable String oldPackage, @Nullable String newPackage, 508 int userId) { 509 try { 510 return mService.prepareVpn(oldPackage, newPackage, userId); 511 } catch (RemoteException e) { 512 throw e.rethrowFromSystemServer(); 513 } 514 } 515 516 /** 517 * Set whether the VPN package has the ability to launch VPNs without user intervention. This 518 * method is used by system-privileged apps. VPN permissions are checked in the {@link Vpn} 519 * class. If the caller is not {@code userId}, {@link 520 * android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required. 521 * 522 * @param packageName The package for which authorization state should change. 523 * @param userId User for whom {@code packageName} is installed. 524 * @param vpnType The {@link VpnManager.VpnType} constant representing what class of VPN 525 * permissions should be granted. When unauthorizing an app, {@link 526 * VpnManager.TYPE_VPN_NONE} should be used. 527 * @hide 528 */ setVpnPackageAuthorization( String packageName, int userId, @VpnManager.VpnType int vpnType)529 public void setVpnPackageAuthorization( 530 String packageName, int userId, @VpnManager.VpnType int vpnType) { 531 try { 532 mService.setVpnPackageAuthorization(packageName, userId, vpnType); 533 } catch (RemoteException e) { 534 throw e.rethrowFromSystemServer(); 535 } 536 } 537 538 /** 539 * Checks if a VPN app supports always-on mode. 540 * 541 * In order to support the always-on feature, an app has to 542 * <ul> 543 * <li>target {@link VERSION_CODES#N API 24} or above, and 544 * <li>not opt out through the {@link VpnService#SERVICE_META_DATA_SUPPORTS_ALWAYS_ON} 545 * meta-data field. 546 * </ul> 547 * 548 * @param userId The identifier of the user for whom the VPN app is installed. 549 * @param vpnPackage The canonical package name of the VPN app. 550 * @return {@code true} if and only if the VPN app exists and supports always-on mode. 551 * @hide 552 */ isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage)553 public boolean isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage) { 554 try { 555 return mService.isAlwaysOnVpnPackageSupported(userId, vpnPackage); 556 } catch (RemoteException e) { 557 throw e.rethrowFromSystemServer(); 558 } 559 } 560 561 /** 562 * Configures an always-on VPN connection through a specific application. 563 * This connection is automatically granted and persisted after a reboot. 564 * 565 * <p>The designated package should declare a {@link VpnService} in its 566 * manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE}, 567 * otherwise the call will fail. 568 * 569 * @param userId The identifier of the user to set an always-on VPN for. 570 * @param vpnPackage The package name for an installed VPN app on the device, or {@code null} 571 * to remove an existing always-on VPN configuration. 572 * @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or 573 * {@code false} otherwise. 574 * @param lockdownAllowlist The list of packages that are allowed to access network directly 575 * when VPN is in lockdown mode but is not running. Non-existent packages are ignored so 576 * this method must be called when a package that should be allowed is installed or 577 * uninstalled. 578 * @return {@code true} if the package is set as always-on VPN controller; 579 * {@code false} otherwise. 580 * @hide 581 */ 582 @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN) setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage, boolean lockdownEnabled, @Nullable List<String> lockdownAllowlist)583 public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage, 584 boolean lockdownEnabled, @Nullable List<String> lockdownAllowlist) { 585 try { 586 return mService.setAlwaysOnVpnPackage( 587 userId, vpnPackage, lockdownEnabled, lockdownAllowlist); 588 } catch (RemoteException e) { 589 throw e.rethrowFromSystemServer(); 590 } 591 } 592 593 /** 594 * Returns the package name of the currently set always-on VPN application. 595 * If there is no always-on VPN set, or the VPN is provided by the system instead 596 * of by an app, {@code null} will be returned. 597 * 598 * @return Package name of VPN controller responsible for always-on VPN, 599 * or {@code null} if none is set. 600 * @hide 601 */ 602 @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN) getAlwaysOnVpnPackageForUser(int userId)603 public String getAlwaysOnVpnPackageForUser(int userId) { 604 try { 605 return mService.getAlwaysOnVpnPackage(userId); 606 } catch (RemoteException e) { 607 throw e.rethrowFromSystemServer(); 608 } 609 } 610 611 /** 612 * @return whether always-on VPN is in lockdown mode. 613 * 614 * @hide 615 **/ 616 @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN) isVpnLockdownEnabled(int userId)617 public boolean isVpnLockdownEnabled(int userId) { 618 try { 619 return mService.isVpnLockdownEnabled(userId); 620 } catch (RemoteException e) { 621 throw e.rethrowFromSystemServer(); 622 } 623 } 624 625 /** 626 * Sets the application exclusion list for the specified VPN profile. 627 * 628 * <p>If an app in the set of excluded apps is not installed for the given user, it will be 629 * skipped in the list of app exclusions. If apps are installed or removed, any active VPN will 630 * have its UID set updated automatically. If the caller is not {@code userId}, 631 * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required. 632 * 633 * <p>This will ONLY affect VpnManager profiles. As such, the NETWORK_SETTINGS provider MUST NOT 634 * allow configuration of these options if the application has not provided a VPN profile. 635 * 636 * @param userId the identifier of the user to set app exclusion list 637 * @param vpnPackage The package name for an installed VPN app on the device 638 * @param excludedApps the app exclusion list 639 * @throws IllegalStateException exception if vpn for the @code userId} is not ready yet. 640 * 641 * @return whether setting the list is successful or not 642 * @hide 643 */ 644 @RequiresPermission(anyOf = { 645 android.Manifest.permission.NETWORK_SETTINGS, 646 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 647 android.Manifest.permission.NETWORK_STACK}) setAppExclusionList(int userId, @NonNull String vpnPackage, @NonNull List<String> excludedApps)648 public boolean setAppExclusionList(int userId, @NonNull String vpnPackage, 649 @NonNull List<String> excludedApps) { 650 try { 651 return mService.setAppExclusionList(userId, vpnPackage, excludedApps); 652 } catch (RemoteException e) { 653 throw e.rethrowFromSystemServer(); 654 } 655 } 656 657 /** 658 * Gets the application exclusion list for the specified VPN profile. If the caller is not 659 * {@code userId}, {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission 660 * is required. 661 * 662 * @param userId the identifier of the user to set app exclusion list 663 * @param vpnPackage The package name for an installed VPN app on the device 664 * @return the list of packages for the specified VPN profile or null if no corresponding VPN 665 * profile configured. 666 * 667 * @hide 668 */ 669 @RequiresPermission(anyOf = { 670 android.Manifest.permission.NETWORK_SETTINGS, 671 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 672 android.Manifest.permission.NETWORK_STACK}) 673 @Nullable getAppExclusionList(int userId, @NonNull String vpnPackage)674 public List<String> getAppExclusionList(int userId, @NonNull String vpnPackage) { 675 try { 676 return mService.getAppExclusionList(userId, vpnPackage); 677 } catch (RemoteException e) { 678 throw e.rethrowFromSystemServer(); 679 } 680 } 681 682 /** 683 * @return the list of packages that are allowed to access network when always-on VPN is in 684 * lockdown mode but not connected. Returns {@code null} when VPN lockdown is not active. 685 * 686 * @hide 687 **/ 688 @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN) getVpnLockdownAllowlist(int userId)689 public List<String> getVpnLockdownAllowlist(int userId) { 690 try { 691 return mService.getVpnLockdownAllowlist(userId); 692 } catch (RemoteException e) { 693 throw e.rethrowFromSystemServer(); 694 } 695 } 696 697 /** 698 * Return the legacy VPN information for the specified user ID. 699 * @hide 700 */ getLegacyVpnInfo(@serIdInt int userId)701 public LegacyVpnInfo getLegacyVpnInfo(@UserIdInt int userId) { 702 try { 703 return mService.getLegacyVpnInfo(userId); 704 } catch (RemoteException e) { 705 throw e.rethrowFromSystemServer(); 706 } 707 } 708 709 /** 710 * Starts a legacy VPN. 711 * 712 * Legacy VPN is deprecated starting from Android S. So this API shouldn't be called if the 713 * initial SDK version of device is Android S+. Otherwise, UnsupportedOperationException will be 714 * thrown. 715 * @hide 716 */ startLegacyVpn(VpnProfile profile)717 public void startLegacyVpn(VpnProfile profile) { 718 try { 719 mService.startLegacyVpn(profile); 720 } catch (RemoteException e) { 721 throw e.rethrowFromSystemServer(); 722 } 723 } 724 725 /** 726 * Informs the service that legacy lockdown VPN state should be updated (e.g., if its keystore 727 * entry has been updated). If the LockdownVpn mechanism is enabled, updates the vpn 728 * with a reload of its profile. 729 * 730 * <p>This method can only be called by the system UID 731 * @return a boolean indicating success 732 * 733 * @hide 734 */ updateLockdownVpn()735 public boolean updateLockdownVpn() { 736 try { 737 return mService.updateLockdownVpn(); 738 } catch (RemoteException e) { 739 throw e.rethrowFromSystemServer(); 740 } 741 } 742 743 /** 744 * Get the vpn profile owned by the calling uid with the given name from the vpn database. 745 * 746 * <p>Note this method should not be used for platform VPN profiles. </p> 747 * 748 * @param name The name of the profile to retrieve. 749 * @return the unstructured blob for the matching vpn profile. 750 * Returns null if no profile with a matching name was found. 751 * @hide 752 */ 753 @Nullable getFromVpnProfileStore(@onNull String name)754 public byte[] getFromVpnProfileStore(@NonNull String name) { 755 try { 756 return mService.getFromVpnProfileStore(name); 757 } catch (RemoteException e) { 758 throw e.rethrowFromSystemServer(); 759 } 760 } 761 762 /** 763 * Put the given vpn profile owned by the calling uid with the given name into the vpn database. 764 * Existing profiles with the same name will be replaced. 765 * 766 * <p>Note this method should not be used for platform VPN profiles. 767 * To update a platform VPN, use provisionVpnProfile() instead. </p> 768 * 769 * @param name The name of the profile to put. 770 * @param blob The profile. 771 * @return true if the profile was successfully added. False otherwise. 772 * @hide 773 */ putIntoVpnProfileStore(@onNull String name, @NonNull byte[] blob)774 public boolean putIntoVpnProfileStore(@NonNull String name, @NonNull byte[] blob) { 775 try { 776 return mService.putIntoVpnProfileStore(name, blob); 777 } catch (RemoteException e) { 778 throw e.rethrowFromSystemServer(); 779 } 780 } 781 782 /** 783 * Removes the vpn profile owned by the calling uid with the given name from the vpn database. 784 * 785 * <p>Note this method should not be used for platform VPN profiles. 786 * To remove a platform VPN, use deleteVpnProfile() instead.</p> 787 * 788 * @param name The name of the profile to be removed. 789 * @return true if a profile was removed. False if no profile with a matching name was found. 790 * @hide 791 */ removeFromVpnProfileStore(@onNull String name)792 public boolean removeFromVpnProfileStore(@NonNull String name) { 793 try { 794 return mService.removeFromVpnProfileStore(name); 795 } catch (RemoteException e) { 796 throw e.rethrowFromSystemServer(); 797 } 798 } 799 800 /** 801 * Returns a list of the name suffixes of the vpn profiles owned by the calling uid in the vpn 802 * database matching the given prefix, sorted in ascending order. 803 * 804 * <p>Note this method should not be used for platform VPN profiles. </p> 805 * 806 * @param prefix The prefix to match. 807 * @return an array of strings representing the name suffixes stored in the profile database 808 * matching the given prefix. The return value may be empty but never null. 809 * @hide 810 */ 811 @NonNull listFromVpnProfileStore(@onNull String prefix)812 public String[] listFromVpnProfileStore(@NonNull String prefix) { 813 try { 814 return mService.listFromVpnProfileStore(prefix); 815 } catch (RemoteException e) { 816 throw e.rethrowFromSystemServer(); 817 } 818 } 819 } 820