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