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