1 /* 2 * Copyright (C) 2014 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 android.annotation.CallbackExecutor; 22 import android.annotation.IntDef; 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.annotation.RequiresFeature; 26 import android.annotation.RequiresPermission; 27 import android.annotation.SystemApi; 28 import android.annotation.SystemService; 29 import android.compat.annotation.UnsupportedAppUsage; 30 import android.content.Context; 31 import android.content.pm.PackageManager; 32 import android.os.Build; 33 import android.os.OutcomeReceiver; 34 import android.os.RemoteException; 35 import android.util.ArrayMap; 36 37 import com.android.internal.annotations.GuardedBy; 38 import com.android.modules.utils.BackgroundThread; 39 40 import java.lang.annotation.Retention; 41 import java.lang.annotation.RetentionPolicy; 42 import java.util.List; 43 import java.util.Objects; 44 import java.util.concurrent.Executor; 45 import java.util.function.IntConsumer; 46 47 /** 48 * A class that manages and configures Ethernet interfaces. 49 * 50 * @hide 51 */ 52 @SystemApi 53 @SystemService(Context.ETHERNET_SERVICE) 54 public class EthernetManager { 55 private static final String TAG = "EthernetManager"; 56 57 private final IEthernetManager mService; 58 @GuardedBy("mListenerLock") 59 private final ArrayMap<InterfaceStateListener, IEthernetServiceListener> 60 mIfaceServiceListeners = new ArrayMap<>(); 61 @GuardedBy("mListenerLock") 62 private final ArrayMap<IntConsumer, IEthernetServiceListener> mStateServiceListeners = 63 new ArrayMap<>(); 64 final Object mListenerLock = new Object(); 65 66 /** 67 * Indicates that Ethernet is disabled. 68 * 69 * @hide 70 */ 71 @SystemApi(client = MODULE_LIBRARIES) 72 public static final int ETHERNET_STATE_DISABLED = 0; 73 74 /** 75 * Indicates that Ethernet is enabled. 76 * 77 * @hide 78 */ 79 @SystemApi(client = MODULE_LIBRARIES) 80 public static final int ETHERNET_STATE_ENABLED = 1; 81 82 /** 83 * The interface is absent. 84 * @hide 85 */ 86 @SystemApi(client = MODULE_LIBRARIES) 87 public static final int STATE_ABSENT = 0; 88 89 /** 90 * The interface is present but link is down. 91 * @hide 92 */ 93 @SystemApi(client = MODULE_LIBRARIES) 94 public static final int STATE_LINK_DOWN = 1; 95 96 /** 97 * The interface is present and link is up. 98 * @hide 99 */ 100 @SystemApi(client = MODULE_LIBRARIES) 101 public static final int STATE_LINK_UP = 2; 102 103 /** @hide */ 104 @IntDef(prefix = "STATE_", value = {STATE_ABSENT, STATE_LINK_DOWN, STATE_LINK_UP}) 105 @Retention(RetentionPolicy.SOURCE) 106 public @interface InterfaceState {} 107 108 /** 109 * The interface currently does not have any specific role. 110 * @hide 111 */ 112 @SystemApi(client = MODULE_LIBRARIES) 113 public static final int ROLE_NONE = 0; 114 115 /** 116 * The interface is in client mode (e.g., connected to the Internet). 117 * @hide 118 */ 119 @SystemApi(client = MODULE_LIBRARIES) 120 public static final int ROLE_CLIENT = 1; 121 122 /** 123 * Ethernet interface is in server mode (e.g., providing Internet access to tethered devices). 124 * @hide 125 */ 126 @SystemApi(client = MODULE_LIBRARIES) 127 public static final int ROLE_SERVER = 2; 128 129 /** @hide */ 130 @IntDef(prefix = "ROLE_", value = {ROLE_NONE, ROLE_CLIENT, ROLE_SERVER}) 131 @Retention(RetentionPolicy.SOURCE) 132 public @interface Role {} 133 134 /** 135 * A listener that receives notifications about the state of Ethernet interfaces on the system. 136 * @hide 137 */ 138 @SystemApi(client = MODULE_LIBRARIES) 139 public interface InterfaceStateListener { 140 /** 141 * Called when an Ethernet interface changes state. 142 * 143 * @param iface the name of the interface. 144 * @param state the current state of the interface, or {@link #STATE_ABSENT} if the 145 * interface was removed. 146 * @param role whether the interface is in client mode or server mode. 147 * @param configuration the current IP configuration of the interface. 148 * @hide 149 */ 150 @SystemApi(client = MODULE_LIBRARIES) onInterfaceStateChanged(@onNull String iface, @InterfaceState int state, @Role int role, @Nullable IpConfiguration configuration)151 void onInterfaceStateChanged(@NonNull String iface, @InterfaceState int state, 152 @Role int role, @Nullable IpConfiguration configuration); 153 } 154 155 /** 156 * A listener interface to receive notification on changes in Ethernet. 157 * This has never been a supported API. Use {@link InterfaceStateListener} instead. 158 * @hide 159 */ 160 public interface Listener extends InterfaceStateListener { 161 /** 162 * Called when Ethernet port's availability is changed. 163 * @param iface Ethernet interface name 164 * @param isAvailable {@code true} if Ethernet port exists. 165 * @hide 166 */ 167 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) onAvailabilityChanged(String iface, boolean isAvailable)168 void onAvailabilityChanged(String iface, boolean isAvailable); 169 170 /** Default implementation for backwards compatibility. Only calls the legacy listener. */ onInterfaceStateChanged(@onNull String iface, @InterfaceState int state, @Role int role, @Nullable IpConfiguration configuration)171 default void onInterfaceStateChanged(@NonNull String iface, @InterfaceState int state, 172 @Role int role, @Nullable IpConfiguration configuration) { 173 onAvailabilityChanged(iface, (state >= STATE_LINK_UP)); 174 } 175 176 } 177 178 /** 179 * Create a new EthernetManager instance. 180 * Applications will almost always want to use 181 * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve 182 * the standard {@link android.content.Context#ETHERNET_SERVICE Context.ETHERNET_SERVICE}. 183 * @hide 184 */ EthernetManager(Context context, IEthernetManager service)185 public EthernetManager(Context context, IEthernetManager service) { 186 mService = service; 187 } 188 189 /** 190 * Get Ethernet configuration. 191 * @return the Ethernet Configuration, contained in {@link IpConfiguration}. 192 * @hide 193 */ 194 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getConfiguration(String iface)195 public IpConfiguration getConfiguration(String iface) { 196 try { 197 return mService.getConfiguration(iface); 198 } catch (RemoteException e) { 199 throw e.rethrowFromSystemServer(); 200 } 201 } 202 203 /** 204 * Set Ethernet configuration. 205 * @hide 206 */ 207 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) setConfiguration(@onNull String iface, @NonNull IpConfiguration config)208 public void setConfiguration(@NonNull String iface, @NonNull IpConfiguration config) { 209 try { 210 mService.setConfiguration(iface, config); 211 } catch (RemoteException e) { 212 throw e.rethrowFromSystemServer(); 213 } 214 } 215 216 /** 217 * Indicates whether the system currently has one or more Ethernet interfaces. 218 * @hide 219 */ 220 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) isAvailable()221 public boolean isAvailable() { 222 return getAvailableInterfaces().length > 0; 223 } 224 225 /** 226 * Indicates whether the system has given interface. 227 * 228 * @param iface Ethernet interface name 229 * @hide 230 */ 231 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) isAvailable(String iface)232 public boolean isAvailable(String iface) { 233 try { 234 return mService.isAvailable(iface); 235 } catch (RemoteException e) { 236 throw e.rethrowFromSystemServer(); 237 } 238 } 239 240 /** 241 * Adds a listener. 242 * This has never been a supported API. Use {@link #addInterfaceStateListener} instead. 243 * 244 * @param listener A {@link Listener} to add. 245 * @throws IllegalArgumentException If the listener is null. 246 * @hide 247 */ 248 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) addListener(@onNull Listener listener)249 public void addListener(@NonNull Listener listener) { 250 addListener(listener, BackgroundThread.getExecutor()); 251 } 252 253 /** 254 * Adds a listener. 255 * This has never been a supported API. Use {@link #addInterfaceStateListener} instead. 256 * 257 * @param listener A {@link Listener} to add. 258 * @param executor Executor to run callbacks on. 259 * @throws IllegalArgumentException If the listener or executor is null. 260 * @hide 261 */ 262 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) addListener(@onNull Listener listener, @NonNull Executor executor)263 public void addListener(@NonNull Listener listener, @NonNull Executor executor) { 264 addInterfaceStateListener(executor, listener); 265 } 266 267 /** 268 * Listen to changes in the state of Ethernet interfaces. 269 * 270 * Adds a listener to receive notification for any state change of all existing Ethernet 271 * interfaces. 272 * <p>{@link Listener#onInterfaceStateChanged} will be triggered immediately for all 273 * existing interfaces upon adding a listener. The same method will be called on the 274 * listener every time any of the interface changes state. In particular, if an 275 * interface is removed, it will be called with state {@link #STATE_ABSENT}. 276 * <p>Use {@link #removeInterfaceStateListener} with the same object to stop listening. 277 * 278 * @param executor Executor to run callbacks on. 279 * @param listener A {@link Listener} to add. 280 * @hide 281 */ 282 @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) 283 @SystemApi(client = MODULE_LIBRARIES) addInterfaceStateListener(@onNull Executor executor, @NonNull InterfaceStateListener listener)284 public void addInterfaceStateListener(@NonNull Executor executor, 285 @NonNull InterfaceStateListener listener) { 286 if (listener == null || executor == null) { 287 throw new NullPointerException("listener and executor must not be null"); 288 } 289 290 final IEthernetServiceListener.Stub serviceListener = new IEthernetServiceListener.Stub() { 291 @Override 292 public void onEthernetStateChanged(int state) {} 293 294 @Override 295 public void onInterfaceStateChanged(String iface, int state, int role, 296 IpConfiguration configuration) { 297 executor.execute(() -> 298 listener.onInterfaceStateChanged(iface, state, role, configuration)); 299 } 300 }; 301 synchronized (mListenerLock) { 302 addServiceListener(serviceListener); 303 mIfaceServiceListeners.put(listener, serviceListener); 304 } 305 } 306 307 @GuardedBy("mListenerLock") addServiceListener(@onNull final IEthernetServiceListener listener)308 private void addServiceListener(@NonNull final IEthernetServiceListener listener) { 309 try { 310 mService.addListener(listener); 311 } catch (RemoteException e) { 312 throw e.rethrowFromSystemServer(); 313 } 314 315 } 316 317 /** 318 * Returns an array of available Ethernet interface names. 319 * @hide 320 */ 321 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getAvailableInterfaces()322 public String[] getAvailableInterfaces() { 323 try { 324 return mService.getAvailableInterfaces(); 325 } catch (RemoteException e) { 326 throw e.rethrowAsRuntimeException(); 327 } 328 } 329 330 /** 331 * Removes a listener. 332 * 333 * @param listener A {@link Listener} to remove. 334 * @hide 335 */ 336 @SystemApi(client = MODULE_LIBRARIES) removeInterfaceStateListener(@onNull InterfaceStateListener listener)337 public void removeInterfaceStateListener(@NonNull InterfaceStateListener listener) { 338 Objects.requireNonNull(listener); 339 synchronized (mListenerLock) { 340 maybeRemoveServiceListener(mIfaceServiceListeners.remove(listener)); 341 } 342 } 343 344 @GuardedBy("mListenerLock") maybeRemoveServiceListener(@ullable final IEthernetServiceListener listener)345 private void maybeRemoveServiceListener(@Nullable final IEthernetServiceListener listener) { 346 if (listener == null) return; 347 348 try { 349 mService.removeListener(listener); 350 } catch (RemoteException e) { 351 throw e.rethrowFromSystemServer(); 352 } 353 } 354 355 /** 356 * Removes a listener. 357 * This has never been a supported API. Use {@link #removeInterfaceStateListener} instead. 358 * @param listener A {@link Listener} to remove. 359 * @hide 360 */ 361 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) removeListener(@onNull Listener listener)362 public void removeListener(@NonNull Listener listener) { 363 if (listener == null) { 364 throw new IllegalArgumentException("listener must not be null"); 365 } 366 removeInterfaceStateListener(listener); 367 } 368 369 /** 370 * Whether to treat interfaces created by {@link TestNetworkManager#createTapInterface} 371 * as Ethernet interfaces. The effects of this method apply to any test interfaces that are 372 * already present on the system. 373 * @hide 374 */ 375 @SystemApi(client = MODULE_LIBRARIES) setIncludeTestInterfaces(boolean include)376 public void setIncludeTestInterfaces(boolean include) { 377 try { 378 mService.setIncludeTestInterfaces(include); 379 } catch (RemoteException e) { 380 throw e.rethrowFromSystemServer(); 381 } 382 } 383 384 /** 385 * A request for a tethered interface. 386 */ 387 public static class TetheredInterfaceRequest { 388 private final IEthernetManager mService; 389 private final ITetheredInterfaceCallback mCb; 390 TetheredInterfaceRequest(@onNull IEthernetManager service, @NonNull ITetheredInterfaceCallback cb)391 private TetheredInterfaceRequest(@NonNull IEthernetManager service, 392 @NonNull ITetheredInterfaceCallback cb) { 393 this.mService = service; 394 this.mCb = cb; 395 } 396 397 /** 398 * Release the request, causing the interface to revert back from tethering mode if there 399 * is no other requestor. 400 */ release()401 public void release() { 402 try { 403 mService.releaseTetheredInterface(mCb); 404 } catch (RemoteException e) { 405 e.rethrowFromSystemServer(); 406 } 407 } 408 } 409 410 /** 411 * Callback for {@link #requestTetheredInterface(TetheredInterfaceCallback)}. 412 */ 413 public interface TetheredInterfaceCallback { 414 /** 415 * Called when the tethered interface is available. 416 * @param iface The name of the interface. 417 */ onAvailable(@onNull String iface)418 void onAvailable(@NonNull String iface); 419 420 /** 421 * Called when the tethered interface is now unavailable. 422 */ onUnavailable()423 void onUnavailable(); 424 } 425 426 /** 427 * Request a tethered interface in tethering mode. 428 * 429 * <p>When this method is called and there is at least one ethernet interface available, the 430 * system will designate one to act as a tethered interface. If there is already a tethered 431 * interface, the existing interface will be used. 432 * @param callback A callback to be called once the request has been fulfilled. 433 */ 434 @RequiresPermission(anyOf = { 435 android.Manifest.permission.NETWORK_STACK, 436 android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK 437 }) 438 @NonNull requestTetheredInterface(@onNull final Executor executor, @NonNull final TetheredInterfaceCallback callback)439 public TetheredInterfaceRequest requestTetheredInterface(@NonNull final Executor executor, 440 @NonNull final TetheredInterfaceCallback callback) { 441 Objects.requireNonNull(callback, "Callback must be non-null"); 442 Objects.requireNonNull(executor, "Executor must be non-null"); 443 final ITetheredInterfaceCallback cbInternal = new ITetheredInterfaceCallback.Stub() { 444 @Override 445 public void onAvailable(String iface) { 446 executor.execute(() -> callback.onAvailable(iface)); 447 } 448 449 @Override 450 public void onUnavailable() { 451 executor.execute(() -> callback.onUnavailable()); 452 } 453 }; 454 455 try { 456 mService.requestTetheredInterface(cbInternal); 457 } catch (RemoteException e) { 458 throw e.rethrowFromSystemServer(); 459 } 460 return new TetheredInterfaceRequest(mService, cbInternal); 461 } 462 463 private static final class NetworkInterfaceOutcomeReceiver 464 extends INetworkInterfaceOutcomeReceiver.Stub { 465 @NonNull 466 private final Executor mExecutor; 467 @NonNull 468 private final OutcomeReceiver<String, EthernetNetworkManagementException> mCallback; 469 NetworkInterfaceOutcomeReceiver( @onNull final Executor executor, @NonNull final OutcomeReceiver<String, EthernetNetworkManagementException> callback)470 NetworkInterfaceOutcomeReceiver( 471 @NonNull final Executor executor, 472 @NonNull final OutcomeReceiver<String, EthernetNetworkManagementException> 473 callback) { 474 Objects.requireNonNull(executor, "Pass a non-null executor"); 475 Objects.requireNonNull(callback, "Pass a non-null callback"); 476 mExecutor = executor; 477 mCallback = callback; 478 } 479 480 @Override onResult(@onNull String iface)481 public void onResult(@NonNull String iface) { 482 mExecutor.execute(() -> mCallback.onResult(iface)); 483 } 484 485 @Override onError(@onNull EthernetNetworkManagementException e)486 public void onError(@NonNull EthernetNetworkManagementException e) { 487 mExecutor.execute(() -> mCallback.onError(e)); 488 } 489 } 490 makeNetworkInterfaceOutcomeReceiver( @ullable final Executor executor, @Nullable final OutcomeReceiver<String, EthernetNetworkManagementException> callback)491 private NetworkInterfaceOutcomeReceiver makeNetworkInterfaceOutcomeReceiver( 492 @Nullable final Executor executor, 493 @Nullable final OutcomeReceiver<String, EthernetNetworkManagementException> callback) { 494 if (null != callback) { 495 Objects.requireNonNull(executor, "Pass a non-null executor, or a null callback"); 496 } 497 final NetworkInterfaceOutcomeReceiver proxy; 498 if (null == callback) { 499 proxy = null; 500 } else { 501 proxy = new NetworkInterfaceOutcomeReceiver(executor, callback); 502 } 503 return proxy; 504 } 505 506 /** 507 * Updates the configuration of an automotive device's ethernet network. 508 * 509 * The {@link EthernetNetworkUpdateRequest} {@code request} argument describes how to update the 510 * configuration for this network. 511 * Use {@link StaticIpConfiguration.Builder} to build a {@code StaticIpConfiguration} object for 512 * this network to put inside the {@code request}. 513 * Similarly, use {@link NetworkCapabilities.Builder} to build a {@code NetworkCapabilities} 514 * object for this network to put inside the {@code request}. 515 * 516 * The provided {@link OutcomeReceiver} is called once the operation has finished execution. 517 * 518 * @param iface the name of the interface to act upon. 519 * @param request the {@link EthernetNetworkUpdateRequest} used to set an ethernet network's 520 * {@link StaticIpConfiguration} and {@link NetworkCapabilities} values. 521 * @param executor an {@link Executor} to execute the callback on. Optional if callback is null. 522 * @param callback an optional {@link OutcomeReceiver} to listen for completion of the 523 * operation. On success, {@link OutcomeReceiver#onResult} is called with the 524 * interface name. On error, {@link OutcomeReceiver#onError} is called with more 525 * information about the error. 526 * @throws SecurityException if the process doesn't hold 527 * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}. 528 * @throws UnsupportedOperationException if the {@link NetworkCapabilities} are updated on a 529 * non-automotive device or this function is called on an 530 * unsupported interface. 531 * @hide 532 */ 533 @SystemApi 534 @RequiresPermission(anyOf = { 535 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 536 android.Manifest.permission.NETWORK_STACK, 537 android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}) updateConfiguration( @onNull String iface, @NonNull EthernetNetworkUpdateRequest request, @Nullable @CallbackExecutor Executor executor, @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback)538 public void updateConfiguration( 539 @NonNull String iface, 540 @NonNull EthernetNetworkUpdateRequest request, 541 @Nullable @CallbackExecutor Executor executor, 542 @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) { 543 Objects.requireNonNull(iface, "iface must be non-null"); 544 Objects.requireNonNull(request, "request must be non-null"); 545 final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver( 546 executor, callback); 547 try { 548 mService.updateConfiguration(iface, request, proxy); 549 } catch (RemoteException e) { 550 throw e.rethrowFromSystemServer(); 551 } 552 } 553 554 /** 555 * Enable a network interface. 556 * 557 * Enables a previously disabled network interface. An attempt to enable an already-enabled 558 * interface is ignored. 559 * The provided {@link OutcomeReceiver} is called once the operation has finished execution. 560 * 561 * @param iface the name of the interface to enable. 562 * @param executor an {@link Executor} to execute the callback on. Optional if callback is null. 563 * @param callback an optional {@link OutcomeReceiver} to listen for completion of the 564 * operation. On success, {@link OutcomeReceiver#onResult} is called with the 565 * interface name. On error, {@link OutcomeReceiver#onError} is called with more 566 * information about the error. 567 * @throws SecurityException if the process doesn't hold 568 * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}. 569 * @hide 570 */ 571 @SystemApi 572 @RequiresPermission(anyOf = { 573 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 574 android.Manifest.permission.NETWORK_STACK, 575 android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}) 576 @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) enableInterface( @onNull String iface, @Nullable @CallbackExecutor Executor executor, @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback)577 public void enableInterface( 578 @NonNull String iface, 579 @Nullable @CallbackExecutor Executor executor, 580 @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) { 581 Objects.requireNonNull(iface, "iface must be non-null"); 582 final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver( 583 executor, callback); 584 try { 585 mService.connectNetwork(iface, proxy); 586 } catch (RemoteException e) { 587 throw e.rethrowFromSystemServer(); 588 } 589 } 590 591 /** 592 * Disable a network interface. 593 * 594 * Disables the specified interface. If this interface is in use in a connected 595 * {@link android.net.Network}, then that {@code Network} will be torn down. 596 * The provided {@link OutcomeReceiver} is called once the operation has finished execution. 597 * 598 * @param iface the name of the interface to disable. 599 * @param executor an {@link Executor} to execute the callback on. Optional if callback is null. 600 * @param callback an optional {@link OutcomeReceiver} to listen for completion of the 601 * operation. On success, {@link OutcomeReceiver#onResult} is called with the 602 * interface name. On error, {@link OutcomeReceiver#onError} is called with more 603 * information about the error. 604 * @throws SecurityException if the process doesn't hold 605 * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}. 606 * @hide 607 */ 608 @SystemApi 609 @RequiresPermission(anyOf = { 610 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 611 android.Manifest.permission.NETWORK_STACK, 612 android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}) 613 @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) disableInterface( @onNull String iface, @Nullable @CallbackExecutor Executor executor, @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback)614 public void disableInterface( 615 @NonNull String iface, 616 @Nullable @CallbackExecutor Executor executor, 617 @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) { 618 Objects.requireNonNull(iface, "iface must be non-null"); 619 final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver( 620 executor, callback); 621 try { 622 mService.disconnectNetwork(iface, proxy); 623 } catch (RemoteException e) { 624 throw e.rethrowFromSystemServer(); 625 } 626 } 627 628 /** 629 * Change ethernet setting. 630 * 631 * @param enabled enable or disable ethernet settings. 632 * 633 * @hide 634 */ 635 @RequiresPermission(anyOf = { 636 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 637 android.Manifest.permission.NETWORK_STACK, 638 android.Manifest.permission.NETWORK_SETTINGS}) 639 @SystemApi(client = MODULE_LIBRARIES) setEthernetEnabled(boolean enabled)640 public void setEthernetEnabled(boolean enabled) { 641 try { 642 mService.setEthernetEnabled(enabled); 643 } catch (RemoteException e) { 644 throw e.rethrowFromSystemServer(); 645 } 646 } 647 648 /** 649 * Listen to changes in the state of ethernet. 650 * 651 * @param executor to run callbacks on. 652 * @param listener to listen ethernet state changed. 653 * 654 * @hide 655 */ 656 @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) 657 @SystemApi(client = MODULE_LIBRARIES) addEthernetStateListener(@onNull Executor executor, @NonNull IntConsumer listener)658 public void addEthernetStateListener(@NonNull Executor executor, 659 @NonNull IntConsumer listener) { 660 Objects.requireNonNull(executor); 661 Objects.requireNonNull(listener); 662 final IEthernetServiceListener.Stub serviceListener = new IEthernetServiceListener.Stub() { 663 @Override 664 public void onEthernetStateChanged(int state) { 665 executor.execute(() -> listener.accept(state)); 666 } 667 668 @Override 669 public void onInterfaceStateChanged(String iface, int state, int role, 670 IpConfiguration configuration) {} 671 }; 672 synchronized (mListenerLock) { 673 addServiceListener(serviceListener); 674 mStateServiceListeners.put(listener, serviceListener); 675 } 676 } 677 678 /** 679 * Removes a listener. 680 * 681 * @param listener to listen ethernet state changed. 682 * 683 * @hide 684 */ 685 @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) 686 @SystemApi(client = MODULE_LIBRARIES) removeEthernetStateListener(@onNull IntConsumer listener)687 public void removeEthernetStateListener(@NonNull IntConsumer listener) { 688 Objects.requireNonNull(listener); 689 synchronized (mListenerLock) { 690 maybeRemoveServiceListener(mStateServiceListeners.remove(listener)); 691 } 692 } 693 694 /** 695 * Returns an array of existing Ethernet interface names regardless whether the interface 696 * is available or not currently. 697 * @hide 698 */ 699 @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) 700 @SystemApi(client = MODULE_LIBRARIES) 701 @NonNull getInterfaceList()702 public List<String> getInterfaceList() { 703 try { 704 return mService.getInterfaceList(); 705 } catch (RemoteException e) { 706 throw e.rethrowAsRuntimeException(); 707 } 708 } 709 } 710