blob: 886d19499cbc78cd7309f94f8484fee9352b6b61 [file] [log] [blame]
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -07001/*
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
17package android.net;
18
Xiao Ma7f9ac502022-01-30 11:27:16 +000019import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
20
James Mattis407ea1d2021-12-14 18:23:30 -080021import android.annotation.CallbackExecutor;
Xiao Ma7f9ac502022-01-30 11:27:16 +000022import android.annotation.IntDef;
Lorenzo Colitti19b8b882020-01-24 19:29:17 +090023import android.annotation.NonNull;
James Mattis407ea1d2021-12-14 18:23:30 -080024import android.annotation.Nullable;
James Mattis28547372022-02-02 14:32:40 -080025import android.annotation.RequiresFeature;
Remi NGUYEN VAN11f39242020-03-09 13:56:18 +090026import android.annotation.RequiresPermission;
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +090027import android.annotation.SystemApi;
Jeff Sharkeyad1cebe2017-06-02 17:36:26 -060028import android.annotation.SystemService;
Artur Satayev164c7562019-12-10 17:47:52 +000029import android.compat.annotation.UnsupportedAppUsage;
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070030import android.content.Context;
James Mattis28547372022-02-02 14:32:40 -080031import android.content.pm.PackageManager;
Mathew Inwoodfe2fed72020-11-04 09:29:36 +000032import android.os.Build;
Patrick Rohrd6156a92022-03-17 19:19:21 +000033import android.os.OutcomeReceiver;
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070034import android.os.RemoteException;
Xiao Mab60e77f2022-04-27 10:56:05 +090035import android.util.ArrayMap;
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070036
Remi NGUYEN VAN55838a82020-12-03 17:58:49 +090037import com.android.internal.annotations.GuardedBy;
Xiao Madbc8e0f2021-12-28 09:16:09 +000038import com.android.modules.utils.BackgroundThread;
Remi NGUYEN VAN55838a82020-12-03 17:58:49 +090039
Xiao Ma7f9ac502022-01-30 11:27:16 +000040import java.lang.annotation.Retention;
41import java.lang.annotation.RetentionPolicy;
Xiao Ma1edd4552022-03-17 05:56:09 +000042import java.util.List;
Lorenzo Colitti19b8b882020-01-24 19:29:17 +090043import java.util.Objects;
markchienc8e7d752020-02-26 20:54:55 +080044import java.util.concurrent.Executor;
markchien5912ab62022-03-17 18:19:39 +080045import java.util.function.IntConsumer;
Jaewan Kim32b3f2c2014-10-20 12:04:13 +090046
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070047/**
Xiao Ma7f9ac502022-01-30 11:27:16 +000048 * A class that manages and configures Ethernet interfaces.
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070049 *
50 * @hide
51 */
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +090052@SystemApi
Jeff Sharkeyad1cebe2017-06-02 17:36:26 -060053@SystemService(Context.ETHERNET_SERVICE)
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070054public class EthernetManager {
55 private static final String TAG = "EthernetManager";
56
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070057 private final IEthernetManager mService;
markchien5912ab62022-03-17 18:19:39 +080058 @GuardedBy("mListenerLock")
Xiao Mab60e77f2022-04-27 10:56:05 +090059 private final ArrayMap<InterfaceStateListener, IEthernetServiceListener>
60 mIfaceServiceListeners = new ArrayMap<>();
markchien5912ab62022-03-17 18:19:39 +080061 @GuardedBy("mListenerLock")
Xiao Mab60e77f2022-04-27 10:56:05 +090062 private final ArrayMap<IntConsumer, IEthernetServiceListener> mStateServiceListeners =
63 new ArrayMap<>();
markchien5912ab62022-03-17 18:19:39 +080064 final Object mListenerLock = new Object();
Jaewan Kim32b3f2c2014-10-20 12:04:13 +090065
markchien5912ab62022-03-17 18:19:39 +080066 /**
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
Jaewan Kim32b3f2c2014-10-20 12:04:13 +090082 /**
Xiao Ma7f9ac502022-01-30 11:27:16 +000083 * The interface is absent.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +090084 * @hide
Jaewan Kim32b3f2c2014-10-20 12:04:13 +090085 */
Xiao Ma7f9ac502022-01-30 11:27:16 +000086 @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.
Lorenzo Colitti6c032e52022-02-11 12:18:59 +0900146 * @param role whether the interface is in client mode or server mode.
Xiao Ma7f9ac502022-01-30 11:27:16 +0000147 * @param configuration the current IP configuration of the interface.
148 * @hide
149 */
150 @SystemApi(client = MODULE_LIBRARIES)
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 {
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900161 /**
162 * Called when Ethernet port's availability is changed.
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700163 * @param iface Ethernet interface name
164 * @param isAvailable {@code true} if Ethernet port exists.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900165 * @hide
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900166 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000167 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700168 void onAvailabilityChanged(String iface, boolean isAvailable);
Xiao Ma7f9ac502022-01-30 11:27:16 +0000169
170 /** Default implementation for backwards compatibility. Only calls the legacy listener. */
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
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900176 }
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700177
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}.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900183 * @hide
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700184 */
185 public EthernetManager(Context context, IEthernetManager service) {
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700186 mService = service;
187 }
188
189 /**
Lorenzo Colitti56e4e582014-05-22 11:51:27 -0700190 * Get Ethernet configuration.
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700191 * @return the Ethernet Configuration, contained in {@link IpConfiguration}.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900192 * @hide
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700193 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000194 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700195 public IpConfiguration getConfiguration(String iface) {
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700196 try {
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700197 return mService.getConfiguration(iface);
Jeff Sharkeyf7138282016-03-01 19:27:23 -0700198 } catch (RemoteException e) {
199 throw e.rethrowFromSystemServer();
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700200 }
201 }
202
203 /**
Lorenzo Colitti56e4e582014-05-22 11:51:27 -0700204 * Set Ethernet configuration.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900205 * @hide
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700206 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000207 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Xiao Ma7f9ac502022-01-30 11:27:16 +0000208 public void setConfiguration(@NonNull String iface, @NonNull IpConfiguration config) {
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700209 try {
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700210 mService.setConfiguration(iface, config);
Jeff Sharkeyf7138282016-03-01 19:27:23 -0700211 } catch (RemoteException e) {
212 throw e.rethrowFromSystemServer();
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900213 }
214 }
215
216 /**
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700217 * Indicates whether the system currently has one or more Ethernet interfaces.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900218 * @hide
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900219 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000220 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900221 public boolean isAvailable() {
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700222 return getAvailableInterfaces().length > 0;
223 }
224
225 /**
226 * Indicates whether the system has given interface.
227 *
228 * @param iface Ethernet interface name
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900229 * @hide
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700230 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000231 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700232 public boolean isAvailable(String iface) {
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900233 try {
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700234 return mService.isAvailable(iface);
Jeff Sharkeyf7138282016-03-01 19:27:23 -0700235 } catch (RemoteException e) {
236 throw e.rethrowFromSystemServer();
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900237 }
238 }
239
240 /**
241 * Adds a listener.
Xiao Ma7f9ac502022-01-30 11:27:16 +0000242 * This has never been a supported API. Use {@link #addInterfaceStateListener} instead.
Remi NGUYEN VAN55838a82020-12-03 17:58:49 +0900243 *
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900244 * @param listener A {@link Listener} to add.
245 * @throws IllegalArgumentException If the listener is null.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900246 * @hide
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900247 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000248 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Remi NGUYEN VAN55838a82020-12-03 17:58:49 +0900249 public void addListener(@NonNull Listener listener) {
250 addListener(listener, BackgroundThread.getExecutor());
251 }
252
253 /**
254 * Adds a listener.
Xiao Ma7f9ac502022-01-30 11:27:16 +0000255 * This has never been a supported API. Use {@link #addInterfaceStateListener} instead.
256 *
Remi NGUYEN VAN55838a82020-12-03 17:58:49 +0900257 * @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)
263 public void addListener(@NonNull Listener listener, @NonNull Executor executor) {
Xiao Ma7f9ac502022-01-30 11:27:16 +0000264 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)
284 public void addInterfaceStateListener(@NonNull Executor executor,
285 @NonNull InterfaceStateListener listener) {
Remi NGUYEN VAN55838a82020-12-03 17:58:49 +0900286 if (listener == null || executor == null) {
287 throw new NullPointerException("listener and executor must not be null");
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900288 }
Xiao Mab60e77f2022-04-27 10:56:05 +0900289
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 };
markchien5912ab62022-03-17 18:19:39 +0800301 synchronized (mListenerLock) {
Xiao Mab60e77f2022-04-27 10:56:05 +0900302 addServiceListener(serviceListener);
303 mIfaceServiceListeners.put(listener, serviceListener);
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900304 }
305 }
306
markchien5912ab62022-03-17 18:19:39 +0800307 @GuardedBy("mListenerLock")
Xiao Mab60e77f2022-04-27 10:56:05 +0900308 private void addServiceListener(@NonNull final IEthernetServiceListener listener) {
markchien5912ab62022-03-17 18:19:39 +0800309 try {
Xiao Mab60e77f2022-04-27 10:56:05 +0900310 mService.addListener(listener);
markchien5912ab62022-03-17 18:19:39 +0800311 } catch (RemoteException e) {
312 throw e.rethrowFromSystemServer();
313 }
314
315 }
316
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900317 /**
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700318 * Returns an array of available Ethernet interface names.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900319 * @hide
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700320 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000321 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700322 public String[] getAvailableInterfaces() {
323 try {
324 return mService.getAvailableInterfaces();
325 } catch (RemoteException e) {
326 throw e.rethrowAsRuntimeException();
327 }
328 }
329
330 /**
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900331 * Removes a listener.
Xiao Ma7f9ac502022-01-30 11:27:16 +0000332 *
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900333 * @param listener A {@link Listener} to remove.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900334 * @hide
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900335 */
Xiao Ma7f9ac502022-01-30 11:27:16 +0000336 @SystemApi(client = MODULE_LIBRARIES)
337 public void removeInterfaceStateListener(@NonNull InterfaceStateListener listener) {
338 Objects.requireNonNull(listener);
markchien5912ab62022-03-17 18:19:39 +0800339 synchronized (mListenerLock) {
Xiao Mab60e77f2022-04-27 10:56:05 +0900340 maybeRemoveServiceListener(mIfaceServiceListeners.remove(listener));
markchien5912ab62022-03-17 18:19:39 +0800341 }
342 }
343
344 @GuardedBy("mListenerLock")
Xiao Mab60e77f2022-04-27 10:56:05 +0900345 private void maybeRemoveServiceListener(@Nullable final IEthernetServiceListener listener) {
346 if (listener == null) return;
markchien5912ab62022-03-17 18:19:39 +0800347
348 try {
Xiao Mab60e77f2022-04-27 10:56:05 +0900349 mService.removeListener(listener);
markchien5912ab62022-03-17 18:19:39 +0800350 } catch (RemoteException e) {
351 throw e.rethrowFromSystemServer();
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700352 }
353 }
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900354
355 /**
Xiao Ma7f9ac502022-01-30 11:27:16 +0000356 * 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)
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 /**
Lorenzo Colitti013187d2020-03-17 00:16:13 +0900370 * 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 */
Xiao Ma7f9ac502022-01-30 11:27:16 +0000375 @SystemApi(client = MODULE_LIBRARIES)
Lorenzo Colitti013187d2020-03-17 00:16:13 +0900376 public void setIncludeTestInterfaces(boolean include) {
377 try {
378 mService.setIncludeTestInterfaces(include);
379 } catch (RemoteException e) {
380 throw e.rethrowFromSystemServer();
381 }
382 }
383
384 /**
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900385 * A request for a tethered interface.
386 */
387 public static class TetheredInterfaceRequest {
388 private final IEthernetManager mService;
389 private final ITetheredInterfaceCallback mCb;
390
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 */
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 */
418 void onAvailable(@NonNull String iface);
419
420 /**
421 * Called when the tethered interface is now unavailable.
422 */
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 */
Remi NGUYEN VAN11f39242020-03-09 13:56:18 +0900434 @RequiresPermission(anyOf = {
435 android.Manifest.permission.NETWORK_STACK,
436 android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
437 })
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900438 @NonNull
markchienc8e7d752020-02-26 20:54:55 +0800439 public TetheredInterfaceRequest requestTetheredInterface(@NonNull final Executor executor,
440 @NonNull final TetheredInterfaceCallback callback) {
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900441 Objects.requireNonNull(callback, "Callback must be non-null");
markchienc8e7d752020-02-26 20:54:55 +0800442 Objects.requireNonNull(executor, "Executor must be non-null");
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900443 final ITetheredInterfaceCallback cbInternal = new ITetheredInterfaceCallback.Stub() {
444 @Override
445 public void onAvailable(String iface) {
markchienc8e7d752020-02-26 20:54:55 +0800446 executor.execute(() -> callback.onAvailable(iface));
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900447 }
448
449 @Override
450 public void onUnavailable() {
markchienc8e7d752020-02-26 20:54:55 +0800451 executor.execute(() -> callback.onUnavailable());
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900452 }
453 };
454
455 try {
456 mService.requestTetheredInterface(cbInternal);
457 } catch (RemoteException e) {
458 throw e.rethrowFromSystemServer();
459 }
460 return new TetheredInterfaceRequest(mService, cbInternal);
461 }
James Mattis407ea1d2021-12-14 18:23:30 -0800462
Patrick Rohrd6156a92022-03-17 19:19:21 +0000463 private static final class NetworkInterfaceOutcomeReceiver
464 extends INetworkInterfaceOutcomeReceiver.Stub {
James Mattis407ea1d2021-12-14 18:23:30 -0800465 @NonNull
466 private final Executor mExecutor;
467 @NonNull
Patrick Rohrd6156a92022-03-17 19:19:21 +0000468 private final OutcomeReceiver<String, EthernetNetworkManagementException> mCallback;
James Mattis407ea1d2021-12-14 18:23:30 -0800469
Patrick Rohrd6156a92022-03-17 19:19:21 +0000470 NetworkInterfaceOutcomeReceiver(
James Mattis407ea1d2021-12-14 18:23:30 -0800471 @NonNull final Executor executor,
Patrick Rohrd6156a92022-03-17 19:19:21 +0000472 @NonNull final OutcomeReceiver<String, EthernetNetworkManagementException>
473 callback) {
James Mattis407ea1d2021-12-14 18:23:30 -0800474 Objects.requireNonNull(executor, "Pass a non-null executor");
Patrick Rohrd6156a92022-03-17 19:19:21 +0000475 Objects.requireNonNull(callback, "Pass a non-null callback");
James Mattis407ea1d2021-12-14 18:23:30 -0800476 mExecutor = executor;
Patrick Rohrd6156a92022-03-17 19:19:21 +0000477 mCallback = callback;
James Mattis407ea1d2021-12-14 18:23:30 -0800478 }
479
480 @Override
Patrick Rohrd6156a92022-03-17 19:19:21 +0000481 public void onResult(@NonNull String iface) {
482 mExecutor.execute(() -> mCallback.onResult(iface));
483 }
484
485 @Override
486 public void onError(@NonNull EthernetNetworkManagementException e) {
487 mExecutor.execute(() -> mCallback.onError(e));
James Mattis407ea1d2021-12-14 18:23:30 -0800488 }
489 }
490
Patrick Rohrd6156a92022-03-17 19:19:21 +0000491 private NetworkInterfaceOutcomeReceiver makeNetworkInterfaceOutcomeReceiver(
James Mattis407ea1d2021-12-14 18:23:30 -0800492 @Nullable final Executor executor,
Patrick Rohrd6156a92022-03-17 19:19:21 +0000493 @Nullable final OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
494 if (null != callback) {
495 Objects.requireNonNull(executor, "Pass a non-null executor, or a null callback");
James Mattis407ea1d2021-12-14 18:23:30 -0800496 }
Patrick Rohrd6156a92022-03-17 19:19:21 +0000497 final NetworkInterfaceOutcomeReceiver proxy;
498 if (null == callback) {
James Mattis407ea1d2021-12-14 18:23:30 -0800499 proxy = null;
500 } else {
Patrick Rohrd6156a92022-03-17 19:19:21 +0000501 proxy = new NetworkInterfaceOutcomeReceiver(executor, callback);
James Mattis407ea1d2021-12-14 18:23:30 -0800502 }
503 return proxy;
504 }
505
James Mattis28547372022-02-02 14:32:40 -0800506 /**
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 *
Patrick Rohr50c470e2022-03-28 13:03:08 +0200516 * The provided {@link OutcomeReceiver} is called once the operation has finished execution.
James Mattis28547372022-02-02 14:32:40 -0800517 *
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.
Patrick Rohrd6156a92022-03-17 19:19:21 +0000521 * @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.
James Mattis28547372022-02-02 14:32:40 -0800526 * @throws SecurityException if the process doesn't hold
527 * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
Patrick Rohr0f2cbe92022-03-28 11:47:20 +0200528 * @throws UnsupportedOperationException if the {@link NetworkCapabilities} are updated on a
529 * non-automotive device or this function is called on an
James Mattis28547372022-02-02 14:32:40 -0800530 * 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})
James Mattis28547372022-02-02 14:32:40 -0800538 public void updateConfiguration(
James Mattis407ea1d2021-12-14 18:23:30 -0800539 @NonNull String iface,
James Mattis1ecadfa2022-01-28 13:42:38 -0800540 @NonNull EthernetNetworkUpdateRequest request,
James Mattis407ea1d2021-12-14 18:23:30 -0800541 @Nullable @CallbackExecutor Executor executor,
Patrick Rohrd6156a92022-03-17 19:19:21 +0000542 @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
James Mattis28547372022-02-02 14:32:40 -0800543 Objects.requireNonNull(iface, "iface must be non-null");
544 Objects.requireNonNull(request, "request must be non-null");
Patrick Rohrd6156a92022-03-17 19:19:21 +0000545 final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
546 executor, callback);
James Mattis407ea1d2021-12-14 18:23:30 -0800547 try {
548 mService.updateConfiguration(iface, request, proxy);
549 } catch (RemoteException e) {
550 throw e.rethrowFromSystemServer();
551 }
552 }
553
James Mattis28547372022-02-02 14:32:40 -0800554 /**
Patrick Rohr3879cf12022-03-16 12:34:41 +0100555 * Enable a network interface.
James Mattis28547372022-02-02 14:32:40 -0800556 *
Patrick Rohr50c470e2022-03-28 13:03:08 +0200557 * 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.
James Mattis28547372022-02-02 14:32:40 -0800560 *
Patrick Rohr3879cf12022-03-16 12:34:41 +0100561 * @param iface the name of the interface to enable.
Patrick Rohrd6156a92022-03-17 19:19:21 +0000562 * @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.
James Mattis28547372022-02-02 14:32:40 -0800567 * @throws SecurityException if the process doesn't hold
568 * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
James Mattis28547372022-02-02 14:32:40 -0800569 * @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)
Patrick Rohr3879cf12022-03-16 12:34:41 +0100577 public void enableInterface(
James Mattis407ea1d2021-12-14 18:23:30 -0800578 @NonNull String iface,
579 @Nullable @CallbackExecutor Executor executor,
Patrick Rohrd6156a92022-03-17 19:19:21 +0000580 @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
James Mattis28547372022-02-02 14:32:40 -0800581 Objects.requireNonNull(iface, "iface must be non-null");
Patrick Rohrd6156a92022-03-17 19:19:21 +0000582 final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
583 executor, callback);
James Mattis407ea1d2021-12-14 18:23:30 -0800584 try {
585 mService.connectNetwork(iface, proxy);
586 } catch (RemoteException e) {
587 throw e.rethrowFromSystemServer();
588 }
589 }
590
James Mattis28547372022-02-02 14:32:40 -0800591 /**
Patrick Rohr3879cf12022-03-16 12:34:41 +0100592 * Disable a network interface.
James Mattis28547372022-02-02 14:32:40 -0800593 *
Patrick Rohr50c470e2022-03-28 13:03:08 +0200594 * 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.
James Mattis28547372022-02-02 14:32:40 -0800597 *
Patrick Rohr3879cf12022-03-16 12:34:41 +0100598 * @param iface the name of the interface to disable.
Patrick Rohrd6156a92022-03-17 19:19:21 +0000599 * @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.
James Mattis28547372022-02-02 14:32:40 -0800604 * @throws SecurityException if the process doesn't hold
605 * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
James Mattis28547372022-02-02 14:32:40 -0800606 * @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)
Patrick Rohr3879cf12022-03-16 12:34:41 +0100614 public void disableInterface(
James Mattis407ea1d2021-12-14 18:23:30 -0800615 @NonNull String iface,
616 @Nullable @CallbackExecutor Executor executor,
Patrick Rohrd6156a92022-03-17 19:19:21 +0000617 @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
James Mattis28547372022-02-02 14:32:40 -0800618 Objects.requireNonNull(iface, "iface must be non-null");
Patrick Rohrd6156a92022-03-17 19:19:21 +0000619 final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
620 executor, callback);
James Mattis407ea1d2021-12-14 18:23:30 -0800621 try {
622 mService.disconnectNetwork(iface, proxy);
623 } catch (RemoteException e) {
624 throw e.rethrowFromSystemServer();
625 }
626 }
markchien5912ab62022-03-17 18:19:39 +0800627
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)
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)
658 public void addEthernetStateListener(@NonNull Executor executor,
659 @NonNull IntConsumer listener) {
660 Objects.requireNonNull(executor);
661 Objects.requireNonNull(listener);
Xiao Mab60e77f2022-04-27 10:56:05 +0900662 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 };
markchien5912ab62022-03-17 18:19:39 +0800672 synchronized (mListenerLock) {
Xiao Mab60e77f2022-04-27 10:56:05 +0900673 addServiceListener(serviceListener);
674 mStateServiceListeners.put(listener, serviceListener);
markchien5912ab62022-03-17 18:19:39 +0800675 }
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)
687 public void removeEthernetStateListener(@NonNull IntConsumer listener) {
688 Objects.requireNonNull(listener);
689 synchronized (mListenerLock) {
Xiao Mab60e77f2022-04-27 10:56:05 +0900690 maybeRemoveServiceListener(mStateServiceListeners.remove(listener));
markchien5912ab62022-03-17 18:19:39 +0800691 }
692 }
Xiao Ma1edd4552022-03-17 05:56:09 +0000693
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
702 public List<String> getInterfaceList() {
703 try {
704 return mService.getInterfaceList();
705 } catch (RemoteException e) {
706 throw e.rethrowAsRuntimeException();
707 }
708 }
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700709}