blob: b8070f0bbafce2dd92f374dcc31f72bbfaf1d911 [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;
Remi NGUYEN VAN11f39242020-03-09 13:56:18 +090025import android.annotation.RequiresPermission;
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +090026import android.annotation.SystemApi;
Jeff Sharkeyad1cebe2017-06-02 17:36:26 -060027import android.annotation.SystemService;
Artur Satayev164c7562019-12-10 17:47:52 +000028import android.compat.annotation.UnsupportedAppUsage;
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070029import android.content.Context;
Mathew Inwoodfe2fed72020-11-04 09:29:36 +000030import android.os.Build;
Patrick Rohrd6156a92022-03-17 19:19:21 +000031import android.os.OutcomeReceiver;
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070032import android.os.RemoteException;
Xiao Mabb9a49c2022-04-27 10:56:05 +090033import android.util.ArrayMap;
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070034
Remi NGUYEN VAN55838a82020-12-03 17:58:49 +090035import com.android.internal.annotations.GuardedBy;
Xiao Madbc8e0f2021-12-28 09:16:09 +000036import com.android.modules.utils.BackgroundThread;
Remi NGUYEN VAN55838a82020-12-03 17:58:49 +090037
Xiao Ma7f9ac502022-01-30 11:27:16 +000038import java.lang.annotation.Retention;
39import java.lang.annotation.RetentionPolicy;
Xiao Ma1edd4552022-03-17 05:56:09 +000040import java.util.List;
Lorenzo Colitti19b8b882020-01-24 19:29:17 +090041import java.util.Objects;
markchienc8e7d752020-02-26 20:54:55 +080042import java.util.concurrent.Executor;
markchien5912ab62022-03-17 18:19:39 +080043import java.util.function.IntConsumer;
Jaewan Kim32b3f2c2014-10-20 12:04:13 +090044
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070045/**
Xiao Ma7f9ac502022-01-30 11:27:16 +000046 * A class that manages and configures Ethernet interfaces.
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070047 *
48 * @hide
49 */
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +090050@SystemApi
Jeff Sharkeyad1cebe2017-06-02 17:36:26 -060051@SystemService(Context.ETHERNET_SERVICE)
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070052public class EthernetManager {
53 private static final String TAG = "EthernetManager";
54
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -070055 private final IEthernetManager mService;
markchien5912ab62022-03-17 18:19:39 +080056 @GuardedBy("mListenerLock")
Xiao Mabb9a49c2022-04-27 10:56:05 +090057 private final ArrayMap<InterfaceStateListener, IEthernetServiceListener>
58 mIfaceServiceListeners = new ArrayMap<>();
markchien5912ab62022-03-17 18:19:39 +080059 @GuardedBy("mListenerLock")
Xiao Mabb9a49c2022-04-27 10:56:05 +090060 private final ArrayMap<IntConsumer, IEthernetServiceListener> mStateServiceListeners =
61 new ArrayMap<>();
markchien5912ab62022-03-17 18:19:39 +080062 final Object mListenerLock = new Object();
Jaewan Kim32b3f2c2014-10-20 12:04:13 +090063
markchien5912ab62022-03-17 18:19:39 +080064 /**
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
Jaewan Kim32b3f2c2014-10-20 12:04:13 +090080 /**
Xiao Ma7f9ac502022-01-30 11:27:16 +000081 * The interface is absent.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +090082 * @hide
Jaewan Kim32b3f2c2014-10-20 12:04:13 +090083 */
Xiao Ma7f9ac502022-01-30 11:27:16 +000084 @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.
Lorenzo Colitti6c032e52022-02-11 12:18:59 +0900144 * @param role whether the interface is in client mode or server mode.
Xiao Ma7f9ac502022-01-30 11:27:16 +0000145 * @param configuration the current IP configuration of the interface.
146 * @hide
147 */
148 @SystemApi(client = MODULE_LIBRARIES)
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 {
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900159 /**
160 * Called when Ethernet port's availability is changed.
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700161 * @param iface Ethernet interface name
162 * @param isAvailable {@code true} if Ethernet port exists.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900163 * @hide
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900164 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000165 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700166 void onAvailabilityChanged(String iface, boolean isAvailable);
Xiao Ma7f9ac502022-01-30 11:27:16 +0000167
168 /** Default implementation for backwards compatibility. Only calls the legacy listener. */
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
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900174 }
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700175
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}.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900181 * @hide
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700182 */
183 public EthernetManager(Context context, IEthernetManager service) {
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700184 mService = service;
185 }
186
187 /**
Lorenzo Colitti56e4e582014-05-22 11:51:27 -0700188 * Get Ethernet configuration.
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700189 * @return the Ethernet Configuration, contained in {@link IpConfiguration}.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900190 * @hide
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700191 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000192 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700193 public IpConfiguration getConfiguration(String iface) {
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700194 try {
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700195 return mService.getConfiguration(iface);
Jeff Sharkeyf7138282016-03-01 19:27:23 -0700196 } catch (RemoteException e) {
197 throw e.rethrowFromSystemServer();
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700198 }
199 }
200
201 /**
Lorenzo Colitti56e4e582014-05-22 11:51:27 -0700202 * Set Ethernet configuration.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900203 * @hide
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700204 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000205 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Xiao Ma7f9ac502022-01-30 11:27:16 +0000206 public void setConfiguration(@NonNull String iface, @NonNull IpConfiguration config) {
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700207 try {
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700208 mService.setConfiguration(iface, config);
Jeff Sharkeyf7138282016-03-01 19:27:23 -0700209 } catch (RemoteException e) {
210 throw e.rethrowFromSystemServer();
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900211 }
212 }
213
214 /**
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700215 * Indicates whether the system currently has one or more Ethernet interfaces.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900216 * @hide
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900217 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000218 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900219 public boolean isAvailable() {
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700220 return getAvailableInterfaces().length > 0;
221 }
222
223 /**
224 * Indicates whether the system has given interface.
225 *
226 * @param iface Ethernet interface name
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900227 * @hide
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700228 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000229 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700230 public boolean isAvailable(String iface) {
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900231 try {
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700232 return mService.isAvailable(iface);
Jeff Sharkeyf7138282016-03-01 19:27:23 -0700233 } catch (RemoteException e) {
234 throw e.rethrowFromSystemServer();
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900235 }
236 }
237
238 /**
239 * Adds a listener.
Xiao Ma7f9ac502022-01-30 11:27:16 +0000240 * This has never been a supported API. Use {@link #addInterfaceStateListener} instead.
Remi NGUYEN VAN55838a82020-12-03 17:58:49 +0900241 *
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900242 * @param listener A {@link Listener} to add.
243 * @throws IllegalArgumentException If the listener is null.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900244 * @hide
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900245 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000246 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Remi NGUYEN VAN55838a82020-12-03 17:58:49 +0900247 public void addListener(@NonNull Listener listener) {
248 addListener(listener, BackgroundThread.getExecutor());
249 }
250
251 /**
252 * Adds a listener.
Xiao Ma7f9ac502022-01-30 11:27:16 +0000253 * This has never been a supported API. Use {@link #addInterfaceStateListener} instead.
254 *
Remi NGUYEN VAN55838a82020-12-03 17:58:49 +0900255 * @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)
261 public void addListener(@NonNull Listener listener, @NonNull Executor executor) {
Xiao Ma7f9ac502022-01-30 11:27:16 +0000262 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)
282 public void addInterfaceStateListener(@NonNull Executor executor,
283 @NonNull InterfaceStateListener listener) {
Remi NGUYEN VAN55838a82020-12-03 17:58:49 +0900284 if (listener == null || executor == null) {
285 throw new NullPointerException("listener and executor must not be null");
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900286 }
Xiao Mabb9a49c2022-04-27 10:56:05 +0900287
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 };
markchien5912ab62022-03-17 18:19:39 +0800299 synchronized (mListenerLock) {
Xiao Mabb9a49c2022-04-27 10:56:05 +0900300 addServiceListener(serviceListener);
301 mIfaceServiceListeners.put(listener, serviceListener);
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900302 }
303 }
304
markchien5912ab62022-03-17 18:19:39 +0800305 @GuardedBy("mListenerLock")
Xiao Mabb9a49c2022-04-27 10:56:05 +0900306 private void addServiceListener(@NonNull final IEthernetServiceListener listener) {
markchien5912ab62022-03-17 18:19:39 +0800307 try {
Xiao Mabb9a49c2022-04-27 10:56:05 +0900308 mService.addListener(listener);
markchien5912ab62022-03-17 18:19:39 +0800309 } catch (RemoteException e) {
310 throw e.rethrowFromSystemServer();
311 }
312
313 }
314
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900315 /**
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700316 * Returns an array of available Ethernet interface names.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900317 * @hide
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700318 */
Mathew Inwoodfe2fed72020-11-04 09:29:36 +0000319 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Pavel Maltsev50ec1f32017-10-31 15:34:16 -0700320 public String[] getAvailableInterfaces() {
321 try {
322 return mService.getAvailableInterfaces();
323 } catch (RemoteException e) {
324 throw e.rethrowAsRuntimeException();
325 }
326 }
327
328 /**
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900329 * Removes a listener.
Xiao Ma7f9ac502022-01-30 11:27:16 +0000330 *
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900331 * @param listener A {@link Listener} to remove.
Remi NGUYEN VAN199d6852020-01-24 22:57:09 +0900332 * @hide
Jaewan Kim32b3f2c2014-10-20 12:04:13 +0900333 */
Xiao Ma7f9ac502022-01-30 11:27:16 +0000334 @SystemApi(client = MODULE_LIBRARIES)
335 public void removeInterfaceStateListener(@NonNull InterfaceStateListener listener) {
336 Objects.requireNonNull(listener);
markchien5912ab62022-03-17 18:19:39 +0800337 synchronized (mListenerLock) {
Xiao Mabb9a49c2022-04-27 10:56:05 +0900338 maybeRemoveServiceListener(mIfaceServiceListeners.remove(listener));
markchien5912ab62022-03-17 18:19:39 +0800339 }
340 }
341
342 @GuardedBy("mListenerLock")
Xiao Mabb9a49c2022-04-27 10:56:05 +0900343 private void maybeRemoveServiceListener(@Nullable final IEthernetServiceListener listener) {
344 if (listener == null) return;
markchien5912ab62022-03-17 18:19:39 +0800345
346 try {
Xiao Mabb9a49c2022-04-27 10:56:05 +0900347 mService.removeListener(listener);
markchien5912ab62022-03-17 18:19:39 +0800348 } catch (RemoteException e) {
349 throw e.rethrowFromSystemServer();
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700350 }
351 }
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900352
353 /**
Xiao Ma7f9ac502022-01-30 11:27:16 +0000354 * 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)
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 /**
Lorenzo Colitti013187d2020-03-17 00:16:13 +0900368 * 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 */
Xiao Ma7f9ac502022-01-30 11:27:16 +0000373 @SystemApi(client = MODULE_LIBRARIES)
Lorenzo Colitti013187d2020-03-17 00:16:13 +0900374 public void setIncludeTestInterfaces(boolean include) {
375 try {
376 mService.setIncludeTestInterfaces(include);
377 } catch (RemoteException e) {
378 throw e.rethrowFromSystemServer();
379 }
380 }
381
382 /**
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900383 * A request for a tethered interface.
384 */
385 public static class TetheredInterfaceRequest {
386 private final IEthernetManager mService;
387 private final ITetheredInterfaceCallback mCb;
388
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 */
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 */
416 void onAvailable(@NonNull String iface);
417
418 /**
419 * Called when the tethered interface is now unavailable.
420 */
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 */
Remi NGUYEN VAN11f39242020-03-09 13:56:18 +0900432 @RequiresPermission(anyOf = {
433 android.Manifest.permission.NETWORK_STACK,
434 android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
435 })
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900436 @NonNull
markchienc8e7d752020-02-26 20:54:55 +0800437 public TetheredInterfaceRequest requestTetheredInterface(@NonNull final Executor executor,
438 @NonNull final TetheredInterfaceCallback callback) {
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900439 Objects.requireNonNull(callback, "Callback must be non-null");
markchienc8e7d752020-02-26 20:54:55 +0800440 Objects.requireNonNull(executor, "Executor must be non-null");
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900441 final ITetheredInterfaceCallback cbInternal = new ITetheredInterfaceCallback.Stub() {
442 @Override
443 public void onAvailable(String iface) {
markchienc8e7d752020-02-26 20:54:55 +0800444 executor.execute(() -> callback.onAvailable(iface));
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900445 }
446
447 @Override
448 public void onUnavailable() {
markchienc8e7d752020-02-26 20:54:55 +0800449 executor.execute(() -> callback.onUnavailable());
Lorenzo Colitti19b8b882020-01-24 19:29:17 +0900450 }
451 };
452
453 try {
454 mService.requestTetheredInterface(cbInternal);
455 } catch (RemoteException e) {
456 throw e.rethrowFromSystemServer();
457 }
458 return new TetheredInterfaceRequest(mService, cbInternal);
459 }
James Mattis407ea1d2021-12-14 18:23:30 -0800460
Patrick Rohrd6156a92022-03-17 19:19:21 +0000461 private static final class NetworkInterfaceOutcomeReceiver
462 extends INetworkInterfaceOutcomeReceiver.Stub {
James Mattis407ea1d2021-12-14 18:23:30 -0800463 @NonNull
464 private final Executor mExecutor;
465 @NonNull
Patrick Rohrd6156a92022-03-17 19:19:21 +0000466 private final OutcomeReceiver<String, EthernetNetworkManagementException> mCallback;
James Mattis407ea1d2021-12-14 18:23:30 -0800467
Patrick Rohrd6156a92022-03-17 19:19:21 +0000468 NetworkInterfaceOutcomeReceiver(
James Mattis407ea1d2021-12-14 18:23:30 -0800469 @NonNull final Executor executor,
Patrick Rohrd6156a92022-03-17 19:19:21 +0000470 @NonNull final OutcomeReceiver<String, EthernetNetworkManagementException>
471 callback) {
James Mattis407ea1d2021-12-14 18:23:30 -0800472 Objects.requireNonNull(executor, "Pass a non-null executor");
Patrick Rohrd6156a92022-03-17 19:19:21 +0000473 Objects.requireNonNull(callback, "Pass a non-null callback");
James Mattis407ea1d2021-12-14 18:23:30 -0800474 mExecutor = executor;
Patrick Rohrd6156a92022-03-17 19:19:21 +0000475 mCallback = callback;
James Mattis407ea1d2021-12-14 18:23:30 -0800476 }
477
478 @Override
Patrick Rohrd6156a92022-03-17 19:19:21 +0000479 public void onResult(@NonNull String iface) {
480 mExecutor.execute(() -> mCallback.onResult(iface));
481 }
482
483 @Override
484 public void onError(@NonNull EthernetNetworkManagementException e) {
485 mExecutor.execute(() -> mCallback.onError(e));
James Mattis407ea1d2021-12-14 18:23:30 -0800486 }
487 }
488
Patrick Rohrd6156a92022-03-17 19:19:21 +0000489 private NetworkInterfaceOutcomeReceiver makeNetworkInterfaceOutcomeReceiver(
James Mattis407ea1d2021-12-14 18:23:30 -0800490 @Nullable final Executor executor,
Patrick Rohrd6156a92022-03-17 19:19:21 +0000491 @Nullable final OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
492 if (null != callback) {
493 Objects.requireNonNull(executor, "Pass a non-null executor, or a null callback");
James Mattis407ea1d2021-12-14 18:23:30 -0800494 }
Patrick Rohrd6156a92022-03-17 19:19:21 +0000495 final NetworkInterfaceOutcomeReceiver proxy;
496 if (null == callback) {
James Mattis407ea1d2021-12-14 18:23:30 -0800497 proxy = null;
498 } else {
Patrick Rohrd6156a92022-03-17 19:19:21 +0000499 proxy = new NetworkInterfaceOutcomeReceiver(executor, callback);
James Mattis407ea1d2021-12-14 18:23:30 -0800500 }
501 return proxy;
502 }
503
James Mattis28547372022-02-02 14:32:40 -0800504 /**
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 *
Patrick Rohr50c470e2022-03-28 13:03:08 +0200514 * The provided {@link OutcomeReceiver} is called once the operation has finished execution.
James Mattis28547372022-02-02 14:32:40 -0800515 *
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.
Patrick Rohrd6156a92022-03-17 19:19:21 +0000519 * @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.
James Mattis28547372022-02-02 14:32:40 -0800524 * @throws SecurityException if the process doesn't hold
525 * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
Patrick Rohr0f2cbe92022-03-28 11:47:20 +0200526 * @throws UnsupportedOperationException if the {@link NetworkCapabilities} are updated on a
527 * non-automotive device or this function is called on an
James Mattis28547372022-02-02 14:32:40 -0800528 * 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})
James Mattis28547372022-02-02 14:32:40 -0800536 public void updateConfiguration(
James Mattis407ea1d2021-12-14 18:23:30 -0800537 @NonNull String iface,
James Mattis1ecadfa2022-01-28 13:42:38 -0800538 @NonNull EthernetNetworkUpdateRequest request,
James Mattis407ea1d2021-12-14 18:23:30 -0800539 @Nullable @CallbackExecutor Executor executor,
Patrick Rohrd6156a92022-03-17 19:19:21 +0000540 @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
James Mattis28547372022-02-02 14:32:40 -0800541 Objects.requireNonNull(iface, "iface must be non-null");
542 Objects.requireNonNull(request, "request must be non-null");
Patrick Rohrd6156a92022-03-17 19:19:21 +0000543 final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
544 executor, callback);
James Mattis407ea1d2021-12-14 18:23:30 -0800545 try {
546 mService.updateConfiguration(iface, request, proxy);
547 } catch (RemoteException e) {
548 throw e.rethrowFromSystemServer();
549 }
550 }
551
James Mattis28547372022-02-02 14:32:40 -0800552 /**
Patrick Rohr3879cf12022-03-16 12:34:41 +0100553 * Enable a network interface.
James Mattis28547372022-02-02 14:32:40 -0800554 *
Patrick Rohr50c470e2022-03-28 13:03:08 +0200555 * 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.
James Mattis28547372022-02-02 14:32:40 -0800558 *
Patrick Rohr3879cf12022-03-16 12:34:41 +0100559 * @param iface the name of the interface to enable.
Patrick Rohrd6156a92022-03-17 19:19:21 +0000560 * @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.
James Mattis28547372022-02-02 14:32:40 -0800565 * @throws SecurityException if the process doesn't hold
566 * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
James Mattis28547372022-02-02 14:32:40 -0800567 * @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})
Patrick Rohr3879cf12022-03-16 12:34:41 +0100574 public void enableInterface(
James Mattis407ea1d2021-12-14 18:23:30 -0800575 @NonNull String iface,
576 @Nullable @CallbackExecutor Executor executor,
Patrick Rohrd6156a92022-03-17 19:19:21 +0000577 @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
James Mattis28547372022-02-02 14:32:40 -0800578 Objects.requireNonNull(iface, "iface must be non-null");
Patrick Rohrd6156a92022-03-17 19:19:21 +0000579 final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
580 executor, callback);
James Mattis407ea1d2021-12-14 18:23:30 -0800581 try {
Patrick Rohrfd829a52022-05-23 16:38:55 -0700582 mService.enableInterface(iface, proxy);
James Mattis407ea1d2021-12-14 18:23:30 -0800583 } catch (RemoteException e) {
584 throw e.rethrowFromSystemServer();
585 }
586 }
587
James Mattis28547372022-02-02 14:32:40 -0800588 /**
Patrick Rohr3879cf12022-03-16 12:34:41 +0100589 * Disable a network interface.
James Mattis28547372022-02-02 14:32:40 -0800590 *
Patrick Rohr50c470e2022-03-28 13:03:08 +0200591 * 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.
James Mattis28547372022-02-02 14:32:40 -0800594 *
Patrick Rohr3879cf12022-03-16 12:34:41 +0100595 * @param iface the name of the interface to disable.
Patrick Rohrd6156a92022-03-17 19:19:21 +0000596 * @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.
James Mattis28547372022-02-02 14:32:40 -0800601 * @throws SecurityException if the process doesn't hold
602 * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
James Mattis28547372022-02-02 14:32:40 -0800603 * @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})
Patrick Rohr3879cf12022-03-16 12:34:41 +0100610 public void disableInterface(
James Mattis407ea1d2021-12-14 18:23:30 -0800611 @NonNull String iface,
612 @Nullable @CallbackExecutor Executor executor,
Patrick Rohrd6156a92022-03-17 19:19:21 +0000613 @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
James Mattis28547372022-02-02 14:32:40 -0800614 Objects.requireNonNull(iface, "iface must be non-null");
Patrick Rohrd6156a92022-03-17 19:19:21 +0000615 final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
616 executor, callback);
James Mattis407ea1d2021-12-14 18:23:30 -0800617 try {
Patrick Rohrfd829a52022-05-23 16:38:55 -0700618 mService.disableInterface(iface, proxy);
James Mattis407ea1d2021-12-14 18:23:30 -0800619 } catch (RemoteException e) {
620 throw e.rethrowFromSystemServer();
621 }
622 }
markchien5912ab62022-03-17 18:19:39 +0800623
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)
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)
654 public void addEthernetStateListener(@NonNull Executor executor,
655 @NonNull IntConsumer listener) {
656 Objects.requireNonNull(executor);
657 Objects.requireNonNull(listener);
Xiao Mabb9a49c2022-04-27 10:56:05 +0900658 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 };
markchien5912ab62022-03-17 18:19:39 +0800668 synchronized (mListenerLock) {
Xiao Mabb9a49c2022-04-27 10:56:05 +0900669 addServiceListener(serviceListener);
670 mStateServiceListeners.put(listener, serviceListener);
markchien5912ab62022-03-17 18:19:39 +0800671 }
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)
683 public void removeEthernetStateListener(@NonNull IntConsumer listener) {
684 Objects.requireNonNull(listener);
685 synchronized (mListenerLock) {
Xiao Mabb9a49c2022-04-27 10:56:05 +0900686 maybeRemoveServiceListener(mStateServiceListeners.remove(listener));
markchien5912ab62022-03-17 18:19:39 +0800687 }
688 }
Xiao Ma1edd4552022-03-17 05:56:09 +0000689
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
698 public List<String> getInterfaceList() {
699 try {
700 return mService.getInterfaceList();
701 } catch (RemoteException e) {
702 throw e.rethrowAsRuntimeException();
703 }
704 }
Lorenzo Colitti2edad7a2014-05-21 16:23:43 -0700705}