Loading api/system-current.txt +13 −0 Original line number Diff line number Diff line Loading @@ -4695,6 +4695,7 @@ package android.net { method @Deprecated @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String getCaptivePortalServerUrl(); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener); method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported(); method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public int registerNetworkProvider(@NonNull android.net.NetworkProvider); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_AIRPLANE_MODE, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public boolean shouldAvoidBadWifi(); Loading @@ -4702,6 +4703,7 @@ package android.net { method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int); method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void unregisterNetworkProvider(@NonNull android.net.NetworkProvider); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void unregisterTetheringEventCallback(@NonNull android.net.ConnectivityManager.OnTetheringEventCallback); field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC"; field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT"; Loading Loading @@ -4872,6 +4874,17 @@ package android.net { field public final android.net.WifiKey wifiKey; } public class NetworkProvider { ctor public NetworkProvider(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String); method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull android.net.NetworkRequest); method @Nullable public android.os.Messenger getMessenger(); method @NonNull public String getName(); method public int getProviderId(); method public void onNetworkRequested(@NonNull android.net.NetworkRequest, int, int); method public void onRequestWithdrawn(@NonNull android.net.NetworkRequest); field public static final int ID_NONE = -1; // 0xffffffff } public abstract class NetworkRecommendationProvider { ctor public NetworkRecommendationProvider(android.content.Context, java.util.concurrent.Executor); method public final android.os.IBinder getBinder(); Loading core/java/android/net/ConnectivityManager.java +57 −0 Original line number Diff line number Diff line Loading @@ -3107,6 +3107,63 @@ public class ConnectivityManager { } } /** * Registers the specified {@link NetworkProvider}. * Each listener must only be registered once. The listener can be unregistered with * {@link #unregisterNetworkProvider}. * * @param provider the provider to register * @return the ID of the provider. This ID must be used by the provider when registering * {@link android.net.NetworkAgent}s. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public int registerNetworkProvider(@NonNull NetworkProvider provider) { if (provider.getProviderId() != NetworkProvider.ID_NONE) { // TODO: Provide a better method for checking this by moving NetworkFactory.SerialNumber // out of NetworkFactory. throw new IllegalStateException("NetworkProviders can only be registered once"); } try { int providerId = mService.registerNetworkProvider(provider.getMessenger(), provider.getName()); provider.setProviderId(providerId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } return provider.getProviderId(); } /** * Unregisters the specified NetworkProvider. * * @param provider the provider to unregister * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void unregisterNetworkProvider(@NonNull NetworkProvider provider) { try { mService.unregisterNetworkProvider(provider.getMessenger()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } provider.setProviderId(NetworkProvider.ID_NONE); } /** @hide exposed via the NetworkProvider class. */ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) { try { mService.declareNetworkRequestUnfulfillable(request); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } // TODO : remove this method. It is a stopgap measure to help sheperding a number // of dependent changes that would conflict throughout the automerger graph. Having this // temporarily helps with the process of going through with all these dependent changes across Loading core/java/android/net/IConnectivityManager.aidl +6 −2 Original line number Diff line number Diff line Loading @@ -142,12 +142,16 @@ interface IConnectivityManager void setAirplaneMode(boolean enable); int registerNetworkFactory(in Messenger messenger, in String name); boolean requestBandwidthUpdate(in Network network); int registerNetworkFactory(in Messenger messenger, in String name); void unregisterNetworkFactory(in Messenger messenger); int registerNetworkProvider(in Messenger messenger, in String name); void unregisterNetworkProvider(in Messenger messenger); void declareNetworkRequestUnfulfillable(in NetworkRequest request); int registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp, in NetworkCapabilities nc, int score, in NetworkMisc misc, in int factorySerialNumber); Loading core/java/android/net/NetworkProvider.java 0 → 100644 +166 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.util.Log; /** * Base class for network providers such as telephony or Wi-Fi. NetworkProviders connect the device * to networks and makes them available to to the core network stack by creating * {@link NetworkAgent}s. The networks can then provide connectivity to apps and can be interacted * with via networking APIs such as {@link ConnectivityManager}. * * Subclasses should implement {@link #onNetworkRequested} and {@link #onRequestWithdrawn} to * receive {@link NetworkRequest}s sent by the system and by apps. A network that is not the * best (highest-scoring) network for any request is generally not used by the system, and torn * down. * * @hide */ @SystemApi public class NetworkProvider { /** * {@code providerId} value that indicates the absence of a provider. It is the providerId of * any NetworkProvider that is not currently registered, and of any NetworkRequest that is not * currently being satisfied by a network. */ public static final int ID_NONE = -1; /** * A hardcoded ID for NetworkAgents representing VPNs. These agents are not created by any * provider, so they use this constant for clarity instead of NONE. * @hide only used by ConnectivityService. */ public static final int ID_VPN = -2; /** * The first providerId value that will be allocated. * @hide only used by ConnectivityService. */ public static final int FIRST_PROVIDER_ID = 1; /** @hide only used by ConnectivityService */ public static final int CMD_REQUEST_NETWORK = 1; /** @hide only used by ConnectivityService */ public static final int CMD_CANCEL_REQUEST = 2; private final Messenger mMessenger; private final String mName; private final ConnectivityManager mCm; private int mProviderId = ID_NONE; /** * Constructs a new NetworkProvider. * * @param looper the Looper on which to run {@link #onNetworkRequested} and * {@link #onRequestWithdrawn}. * @param name the name of the listener, used only for debugging. * * @hide */ @SystemApi public NetworkProvider(@NonNull Context context, @NonNull Looper looper, @NonNull String name) { mCm = ConnectivityManager.from(context); Handler handler = new Handler(looper) { @Override public void handleMessage(Message m) { switch (m.what) { case CMD_REQUEST_NETWORK: onNetworkRequested((NetworkRequest) m.obj, m.arg1, m.arg2); break; case CMD_CANCEL_REQUEST: onRequestWithdrawn((NetworkRequest) m.obj); break; default: Log.e(mName, "Unhandled message: " + m.what); } } }; mMessenger = new Messenger(handler); mName = name; } // TODO: consider adding a register() method so ConnectivityManager does not need to call this. public @Nullable Messenger getMessenger() { return mMessenger; } public @NonNull String getName() { return mName; } /** * Returns the ID of this provider. This is known only once the provider is registered via * {@link ConnectivityManager#registerNetworkProvider()}, otherwise the ID is {@link #ID_NONE}. * This ID must be used when registering any {@link NetworkAgent}s. */ public int getProviderId() { return mProviderId; } /** @hide */ public void setProviderId(int providerId) { mProviderId = providerId; } /** * Called when a NetworkRequest is received. The request may be a new request or an existing * request with a different score. * * @param request the NetworkRequest being received * @param score the score of the network currently satisfying the request, or 0 if none. * @param providerId the ID of the provider that created the network currently satisfying this * request, or {@link #ID_NONE} if none. * * @hide */ @SystemApi public void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId) {} /** * Called when a NetworkRequest is withdrawn. * @hide */ @SystemApi public void onRequestWithdrawn(@NonNull NetworkRequest request) {} /** * Asserts that no provider will ever be able to satisfy the specified request. The provider * must only call this method if it knows that it is the only provider on the system capable of * satisfying this request, and that the request cannot be satisfied. The application filing the * request will receive an {@link NetworkCallback#onUnavailable()} callback. * * @param request the request that cannot be fulfilled * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) { mCm.declareNetworkRequestUnfulfillable(request); } } services/core/java/com/android/server/ConnectivityService.java +92 −9 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkMisc; import android.net.NetworkMonitorManager; import android.net.NetworkPolicyManager; import android.net.NetworkProvider; import android.net.NetworkQuotaInfo; import android.net.NetworkRequest; import android.net.NetworkScore; Loading Loading @@ -219,6 +220,7 @@ import java.util.Objects; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.atomic.AtomicInteger; /** * @hide Loading Loading @@ -595,6 +597,10 @@ public class ConnectivityService extends IConnectivityManager.Stub // sequence number of NetworkRequests private int mNextNetworkRequestId = 1; // Sequence number for NetworkProvider IDs. private final AtomicInteger mNextNetworkProviderId = new AtomicInteger( NetworkProvider.FIRST_PROVIDER_ID); // NetworkRequest activity String log entries. private static final int MAX_NETWORK_REQUEST_LOGS = 20; private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS); Loading Loading @@ -4911,33 +4917,71 @@ public class ConnectivityService extends IConnectivityManager.Stub public final String name; public final Messenger messenger; private final AsyncChannel mAsyncChannel; private final IBinder.DeathRecipient mDeathRecipient; public final int factorySerialNumber; NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel, int factorySerialNumber) { int factorySerialNumber, IBinder.DeathRecipient deathRecipient) { this.name = name; this.messenger = messenger; this.mAsyncChannel = asyncChannel; this.factorySerialNumber = factorySerialNumber; mAsyncChannel = asyncChannel; mDeathRecipient = deathRecipient; if ((mAsyncChannel == null) == (mDeathRecipient == null)) { throw new AssertionError("Must pass exactly one of asyncChannel or deathRecipient"); } } boolean isLegacyNetworkFactory() { return mAsyncChannel != null; } void sendMessageToNetworkProvider(int what, int arg1, int arg2, Object obj) { try { messenger.send(Message.obtain(null /* handler */, what, arg1, arg2, obj)); } catch (RemoteException e) { // Remote process died. Ignore; the death recipient will remove this // NetworkFactoryInfo from mNetworkFactoryInfos. } } void requestNetwork(NetworkRequest request, int score, int servingSerialNumber) { if (isLegacyNetworkFactory()) { mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, servingSerialNumber, request); } else { sendMessageToNetworkProvider(NetworkProvider.CMD_REQUEST_NETWORK, score, servingSerialNumber, request); } } void cancelRequest(NetworkRequest request) { if (isLegacyNetworkFactory()) { mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, request); } else { sendMessageToNetworkProvider(NetworkProvider.CMD_CANCEL_REQUEST, 0, 0, request); } } void connect(Context context, Handler handler) { if (isLegacyNetworkFactory()) { mAsyncChannel.connect(context, handler, messenger); } else { try { messenger.getBinder().linkToDeath(mDeathRecipient, 0); } catch (RemoteException e) { mDeathRecipient.binderDied(); } } } void completeConnection() { if (isLegacyNetworkFactory()) { mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); } } } private void ensureNetworkRequestHasType(NetworkRequest request) { if (request.type == NetworkRequest.Type.NONE) { Loading Loading @@ -5306,6 +5350,11 @@ public class ConnectivityService extends IConnectivityManager.Stub mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); } /** Returns the next Network provider ID. */ public final int nextNetworkProviderId() { return mNextNetworkProviderId.getAndIncrement(); } @Override public void releaseNetworkRequest(NetworkRequest networkRequest) { ensureNetworkRequestHasType(networkRequest); Loading @@ -5317,23 +5366,51 @@ public class ConnectivityService extends IConnectivityManager.Stub public int registerNetworkFactory(Messenger messenger, String name) { enforceNetworkFactoryPermission(); NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel(), NetworkFactory.SerialNumber.nextSerialNumber()); nextNetworkProviderId(), null /* deathRecipient */); mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi)); return nfi.factorySerialNumber; } private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) { if (mNetworkFactoryInfos.containsKey(nfi.messenger)) { // Avoid creating duplicates. even if an app makes a direct AIDL call. // This will never happen if an app calls ConnectivityManager#registerNetworkProvider, // as that will throw if a duplicate provider is registered. Slog.e(TAG, "Attempt to register existing NetworkFactoryInfo " + mNetworkFactoryInfos.get(nfi.messenger).name); return; } if (DBG) log("Got NetworkFactory Messenger for " + nfi.name); mNetworkFactoryInfos.put(nfi.messenger, nfi); nfi.connect(mContext, mTrackerHandler); if (!nfi.isLegacyNetworkFactory()) { // Legacy NetworkFactories get their requests when their AsyncChannel connects. sendAllRequestsToFactory(nfi); } } @Override public void unregisterNetworkFactory(Messenger messenger) { public int registerNetworkProvider(Messenger messenger, String name) { enforceNetworkFactoryPermission(); NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, null /* asyncChannel */, nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger)); mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi)); return nfi.factorySerialNumber; } @Override public void unregisterNetworkProvider(Messenger messenger) { enforceNetworkFactoryPermission(); mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger)); } @Override public void unregisterNetworkFactory(Messenger messenger) { unregisterNetworkProvider(messenger); } private void handleUnregisterNetworkFactory(Messenger messenger) { NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger); if (nfi == null) { Loading @@ -5343,6 +5420,12 @@ public class ConnectivityService extends IConnectivityManager.Stub if (DBG) log("unregisterNetworkFactory for " + nfi.name); } @Override public void declareNetworkRequestUnfulfillable(NetworkRequest request) { enforceNetworkFactoryPermission(); mHandler.post(() -> handleReleaseNetworkRequest(request, Binder.getCallingUid(), true)); } // NOTE: Accessed on multiple threads, must be synchronized on itself. @GuardedBy("mNetworkForNetId") private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>(); Loading Loading
api/system-current.txt +13 −0 Original line number Diff line number Diff line Loading @@ -4695,6 +4695,7 @@ package android.net { method @Deprecated @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String getCaptivePortalServerUrl(); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener); method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported(); method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public int registerNetworkProvider(@NonNull android.net.NetworkProvider); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_AIRPLANE_MODE, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public boolean shouldAvoidBadWifi(); Loading @@ -4702,6 +4703,7 @@ package android.net { method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int); method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void unregisterNetworkProvider(@NonNull android.net.NetworkProvider); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void unregisterTetheringEventCallback(@NonNull android.net.ConnectivityManager.OnTetheringEventCallback); field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC"; field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT"; Loading Loading @@ -4872,6 +4874,17 @@ package android.net { field public final android.net.WifiKey wifiKey; } public class NetworkProvider { ctor public NetworkProvider(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String); method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull android.net.NetworkRequest); method @Nullable public android.os.Messenger getMessenger(); method @NonNull public String getName(); method public int getProviderId(); method public void onNetworkRequested(@NonNull android.net.NetworkRequest, int, int); method public void onRequestWithdrawn(@NonNull android.net.NetworkRequest); field public static final int ID_NONE = -1; // 0xffffffff } public abstract class NetworkRecommendationProvider { ctor public NetworkRecommendationProvider(android.content.Context, java.util.concurrent.Executor); method public final android.os.IBinder getBinder(); Loading
core/java/android/net/ConnectivityManager.java +57 −0 Original line number Diff line number Diff line Loading @@ -3107,6 +3107,63 @@ public class ConnectivityManager { } } /** * Registers the specified {@link NetworkProvider}. * Each listener must only be registered once. The listener can be unregistered with * {@link #unregisterNetworkProvider}. * * @param provider the provider to register * @return the ID of the provider. This ID must be used by the provider when registering * {@link android.net.NetworkAgent}s. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public int registerNetworkProvider(@NonNull NetworkProvider provider) { if (provider.getProviderId() != NetworkProvider.ID_NONE) { // TODO: Provide a better method for checking this by moving NetworkFactory.SerialNumber // out of NetworkFactory. throw new IllegalStateException("NetworkProviders can only be registered once"); } try { int providerId = mService.registerNetworkProvider(provider.getMessenger(), provider.getName()); provider.setProviderId(providerId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } return provider.getProviderId(); } /** * Unregisters the specified NetworkProvider. * * @param provider the provider to unregister * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void unregisterNetworkProvider(@NonNull NetworkProvider provider) { try { mService.unregisterNetworkProvider(provider.getMessenger()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } provider.setProviderId(NetworkProvider.ID_NONE); } /** @hide exposed via the NetworkProvider class. */ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) { try { mService.declareNetworkRequestUnfulfillable(request); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } // TODO : remove this method. It is a stopgap measure to help sheperding a number // of dependent changes that would conflict throughout the automerger graph. Having this // temporarily helps with the process of going through with all these dependent changes across Loading
core/java/android/net/IConnectivityManager.aidl +6 −2 Original line number Diff line number Diff line Loading @@ -142,12 +142,16 @@ interface IConnectivityManager void setAirplaneMode(boolean enable); int registerNetworkFactory(in Messenger messenger, in String name); boolean requestBandwidthUpdate(in Network network); int registerNetworkFactory(in Messenger messenger, in String name); void unregisterNetworkFactory(in Messenger messenger); int registerNetworkProvider(in Messenger messenger, in String name); void unregisterNetworkProvider(in Messenger messenger); void declareNetworkRequestUnfulfillable(in NetworkRequest request); int registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp, in NetworkCapabilities nc, int score, in NetworkMisc misc, in int factorySerialNumber); Loading
core/java/android/net/NetworkProvider.java 0 → 100644 +166 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.util.Log; /** * Base class for network providers such as telephony or Wi-Fi. NetworkProviders connect the device * to networks and makes them available to to the core network stack by creating * {@link NetworkAgent}s. The networks can then provide connectivity to apps and can be interacted * with via networking APIs such as {@link ConnectivityManager}. * * Subclasses should implement {@link #onNetworkRequested} and {@link #onRequestWithdrawn} to * receive {@link NetworkRequest}s sent by the system and by apps. A network that is not the * best (highest-scoring) network for any request is generally not used by the system, and torn * down. * * @hide */ @SystemApi public class NetworkProvider { /** * {@code providerId} value that indicates the absence of a provider. It is the providerId of * any NetworkProvider that is not currently registered, and of any NetworkRequest that is not * currently being satisfied by a network. */ public static final int ID_NONE = -1; /** * A hardcoded ID for NetworkAgents representing VPNs. These agents are not created by any * provider, so they use this constant for clarity instead of NONE. * @hide only used by ConnectivityService. */ public static final int ID_VPN = -2; /** * The first providerId value that will be allocated. * @hide only used by ConnectivityService. */ public static final int FIRST_PROVIDER_ID = 1; /** @hide only used by ConnectivityService */ public static final int CMD_REQUEST_NETWORK = 1; /** @hide only used by ConnectivityService */ public static final int CMD_CANCEL_REQUEST = 2; private final Messenger mMessenger; private final String mName; private final ConnectivityManager mCm; private int mProviderId = ID_NONE; /** * Constructs a new NetworkProvider. * * @param looper the Looper on which to run {@link #onNetworkRequested} and * {@link #onRequestWithdrawn}. * @param name the name of the listener, used only for debugging. * * @hide */ @SystemApi public NetworkProvider(@NonNull Context context, @NonNull Looper looper, @NonNull String name) { mCm = ConnectivityManager.from(context); Handler handler = new Handler(looper) { @Override public void handleMessage(Message m) { switch (m.what) { case CMD_REQUEST_NETWORK: onNetworkRequested((NetworkRequest) m.obj, m.arg1, m.arg2); break; case CMD_CANCEL_REQUEST: onRequestWithdrawn((NetworkRequest) m.obj); break; default: Log.e(mName, "Unhandled message: " + m.what); } } }; mMessenger = new Messenger(handler); mName = name; } // TODO: consider adding a register() method so ConnectivityManager does not need to call this. public @Nullable Messenger getMessenger() { return mMessenger; } public @NonNull String getName() { return mName; } /** * Returns the ID of this provider. This is known only once the provider is registered via * {@link ConnectivityManager#registerNetworkProvider()}, otherwise the ID is {@link #ID_NONE}. * This ID must be used when registering any {@link NetworkAgent}s. */ public int getProviderId() { return mProviderId; } /** @hide */ public void setProviderId(int providerId) { mProviderId = providerId; } /** * Called when a NetworkRequest is received. The request may be a new request or an existing * request with a different score. * * @param request the NetworkRequest being received * @param score the score of the network currently satisfying the request, or 0 if none. * @param providerId the ID of the provider that created the network currently satisfying this * request, or {@link #ID_NONE} if none. * * @hide */ @SystemApi public void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId) {} /** * Called when a NetworkRequest is withdrawn. * @hide */ @SystemApi public void onRequestWithdrawn(@NonNull NetworkRequest request) {} /** * Asserts that no provider will ever be able to satisfy the specified request. The provider * must only call this method if it knows that it is the only provider on the system capable of * satisfying this request, and that the request cannot be satisfied. The application filing the * request will receive an {@link NetworkCallback#onUnavailable()} callback. * * @param request the request that cannot be fulfilled * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) { mCm.declareNetworkRequestUnfulfillable(request); } }
services/core/java/com/android/server/ConnectivityService.java +92 −9 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkMisc; import android.net.NetworkMonitorManager; import android.net.NetworkPolicyManager; import android.net.NetworkProvider; import android.net.NetworkQuotaInfo; import android.net.NetworkRequest; import android.net.NetworkScore; Loading Loading @@ -219,6 +220,7 @@ import java.util.Objects; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.atomic.AtomicInteger; /** * @hide Loading Loading @@ -595,6 +597,10 @@ public class ConnectivityService extends IConnectivityManager.Stub // sequence number of NetworkRequests private int mNextNetworkRequestId = 1; // Sequence number for NetworkProvider IDs. private final AtomicInteger mNextNetworkProviderId = new AtomicInteger( NetworkProvider.FIRST_PROVIDER_ID); // NetworkRequest activity String log entries. private static final int MAX_NETWORK_REQUEST_LOGS = 20; private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS); Loading Loading @@ -4911,33 +4917,71 @@ public class ConnectivityService extends IConnectivityManager.Stub public final String name; public final Messenger messenger; private final AsyncChannel mAsyncChannel; private final IBinder.DeathRecipient mDeathRecipient; public final int factorySerialNumber; NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel, int factorySerialNumber) { int factorySerialNumber, IBinder.DeathRecipient deathRecipient) { this.name = name; this.messenger = messenger; this.mAsyncChannel = asyncChannel; this.factorySerialNumber = factorySerialNumber; mAsyncChannel = asyncChannel; mDeathRecipient = deathRecipient; if ((mAsyncChannel == null) == (mDeathRecipient == null)) { throw new AssertionError("Must pass exactly one of asyncChannel or deathRecipient"); } } boolean isLegacyNetworkFactory() { return mAsyncChannel != null; } void sendMessageToNetworkProvider(int what, int arg1, int arg2, Object obj) { try { messenger.send(Message.obtain(null /* handler */, what, arg1, arg2, obj)); } catch (RemoteException e) { // Remote process died. Ignore; the death recipient will remove this // NetworkFactoryInfo from mNetworkFactoryInfos. } } void requestNetwork(NetworkRequest request, int score, int servingSerialNumber) { if (isLegacyNetworkFactory()) { mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, servingSerialNumber, request); } else { sendMessageToNetworkProvider(NetworkProvider.CMD_REQUEST_NETWORK, score, servingSerialNumber, request); } } void cancelRequest(NetworkRequest request) { if (isLegacyNetworkFactory()) { mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, request); } else { sendMessageToNetworkProvider(NetworkProvider.CMD_CANCEL_REQUEST, 0, 0, request); } } void connect(Context context, Handler handler) { if (isLegacyNetworkFactory()) { mAsyncChannel.connect(context, handler, messenger); } else { try { messenger.getBinder().linkToDeath(mDeathRecipient, 0); } catch (RemoteException e) { mDeathRecipient.binderDied(); } } } void completeConnection() { if (isLegacyNetworkFactory()) { mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); } } } private void ensureNetworkRequestHasType(NetworkRequest request) { if (request.type == NetworkRequest.Type.NONE) { Loading Loading @@ -5306,6 +5350,11 @@ public class ConnectivityService extends IConnectivityManager.Stub mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); } /** Returns the next Network provider ID. */ public final int nextNetworkProviderId() { return mNextNetworkProviderId.getAndIncrement(); } @Override public void releaseNetworkRequest(NetworkRequest networkRequest) { ensureNetworkRequestHasType(networkRequest); Loading @@ -5317,23 +5366,51 @@ public class ConnectivityService extends IConnectivityManager.Stub public int registerNetworkFactory(Messenger messenger, String name) { enforceNetworkFactoryPermission(); NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel(), NetworkFactory.SerialNumber.nextSerialNumber()); nextNetworkProviderId(), null /* deathRecipient */); mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi)); return nfi.factorySerialNumber; } private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) { if (mNetworkFactoryInfos.containsKey(nfi.messenger)) { // Avoid creating duplicates. even if an app makes a direct AIDL call. // This will never happen if an app calls ConnectivityManager#registerNetworkProvider, // as that will throw if a duplicate provider is registered. Slog.e(TAG, "Attempt to register existing NetworkFactoryInfo " + mNetworkFactoryInfos.get(nfi.messenger).name); return; } if (DBG) log("Got NetworkFactory Messenger for " + nfi.name); mNetworkFactoryInfos.put(nfi.messenger, nfi); nfi.connect(mContext, mTrackerHandler); if (!nfi.isLegacyNetworkFactory()) { // Legacy NetworkFactories get their requests when their AsyncChannel connects. sendAllRequestsToFactory(nfi); } } @Override public void unregisterNetworkFactory(Messenger messenger) { public int registerNetworkProvider(Messenger messenger, String name) { enforceNetworkFactoryPermission(); NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, null /* asyncChannel */, nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger)); mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi)); return nfi.factorySerialNumber; } @Override public void unregisterNetworkProvider(Messenger messenger) { enforceNetworkFactoryPermission(); mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger)); } @Override public void unregisterNetworkFactory(Messenger messenger) { unregisterNetworkProvider(messenger); } private void handleUnregisterNetworkFactory(Messenger messenger) { NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger); if (nfi == null) { Loading @@ -5343,6 +5420,12 @@ public class ConnectivityService extends IConnectivityManager.Stub if (DBG) log("unregisterNetworkFactory for " + nfi.name); } @Override public void declareNetworkRequestUnfulfillable(NetworkRequest request) { enforceNetworkFactoryPermission(); mHandler.post(() -> handleReleaseNetworkRequest(request, Binder.getCallingUid(), true)); } // NOTE: Accessed on multiple threads, must be synchronized on itself. @GuardedBy("mNetworkForNetId") private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>(); Loading