Support both R and S+ in NetworkFactory
NetworkFactory needs to be backwards compatible as
it is statically linked by the Wifi module, which
needs to run on both R and S.
To achieve this, maintain 2 separate implementations
called NetworkFactoryImpl (S+) and
NetworkFactoryLegacyImpl (R). NetworkFactory itself
becomes a shim that delegates to one of these
implementations depending on the device's SDK version.
CP of ag/14265947
Ignore-AOSP-First: Merge in internal first to fix
S-on-R test breakages.
Bug: 183902758
Test: ClientModeImplTest
OemWifiNetworkFactoryTest
TelephonyNetworkFactoryTest
UntrustedWifiNetworkFactoryTest
WifiNetworkFactoryTest
Change-Id: I6a08f39ad1633dd7c1582c362c97821e24ce6683
Merged-In: I6a08f39ad1633dd7c1582c362c97821e24ce6683
This commit is contained in:
@@ -34,9 +34,9 @@ package {
|
||||
java_library {
|
||||
name: "net-utils-device-common",
|
||||
srcs: [
|
||||
"device/**/*.java",
|
||||
"device/com/android/net/module/util/**/*.java",
|
||||
// This library is used by system modules, for which the system health impact of Kotlin
|
||||
// has not yet been evaluated.
|
||||
// has not yet been evaluated. Annotations may need jarjar'ing.
|
||||
// "src_devicecommon/**/*.kt",
|
||||
":framework-annotations",
|
||||
],
|
||||
@@ -117,13 +117,15 @@ java_library {
|
||||
"//frameworks/libs/net/common/tests:__subpackages__",
|
||||
"//frameworks/libs/net/common/device",
|
||||
"//packages/modules/Wifi/framework/tests:__subpackages__",
|
||||
]
|
||||
],
|
||||
}
|
||||
|
||||
filegroup {
|
||||
name: "net-utils-services-common-srcs",
|
||||
srcs: [
|
||||
"device/android/net/NetworkFactory.java",
|
||||
"device/android/net/NetworkFactoryImpl.java",
|
||||
"device/android/net/NetworkFactoryLegacyImpl.java",
|
||||
"device/android/net/NetworkFactoryShim.java",
|
||||
],
|
||||
visibility: [
|
||||
"//frameworks/base/services/net",
|
||||
@@ -138,6 +140,9 @@ java_library {
|
||||
],
|
||||
sdk_version: "system_current",
|
||||
min_sdk_version: "30",
|
||||
static_libs: [
|
||||
"modules-utils-build_system",
|
||||
],
|
||||
visibility: [
|
||||
"//frameworks/base/services/net",
|
||||
],
|
||||
@@ -150,6 +155,9 @@ filegroup {
|
||||
srcs: [
|
||||
// Any class here *must* have a corresponding jarjar rule in the telephony build rules.
|
||||
"device/android/net/NetworkFactory.java",
|
||||
"device/android/net/NetworkFactoryImpl.java",
|
||||
"device/android/net/NetworkFactoryLegacyImpl.java",
|
||||
"device/android/net/NetworkFactoryShim.java",
|
||||
],
|
||||
path: "device",
|
||||
visibility: [
|
||||
@@ -178,6 +186,9 @@ filegroup {
|
||||
name: "net-utils-wifi-service-common-srcs",
|
||||
srcs: [
|
||||
"device/android/net/NetworkFactory.java",
|
||||
"device/android/net/NetworkFactoryImpl.java",
|
||||
"device/android/net/NetworkFactoryLegacyImpl.java",
|
||||
"device/android/net/NetworkFactoryShim.java",
|
||||
"framework/com/android/net/module/util/NetUtils.java",
|
||||
],
|
||||
visibility: [
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
package android.net;
|
||||
|
||||
import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.net.NetworkProvider.NetworkOfferCallback;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
@@ -29,9 +29,6 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* A NetworkFactory is an entity that creates NetworkAgent objects.
|
||||
@@ -46,109 +43,54 @@ import java.util.concurrent.Executor;
|
||||
* functions can be overridden. If the bearer needs more interaction, it can
|
||||
* override addNetworkRequest and removeNetworkRequest which will give it each
|
||||
* request that passes their current filters.
|
||||
*
|
||||
* This class is mostly a shim which delegates to one of two implementations depending
|
||||
* on the SDK level of the device it's running on.
|
||||
*
|
||||
* @hide
|
||||
**/
|
||||
public class NetworkFactory extends Handler {
|
||||
private static final boolean DBG = true;
|
||||
private static final boolean VDBG = false;
|
||||
public class NetworkFactory {
|
||||
static final boolean DBG = true;
|
||||
static final boolean VDBG = false;
|
||||
|
||||
// A score that will win against everything, so that score filtering will let all requests
|
||||
// through
|
||||
// TODO : remove this and replace with an API to listen to all requests.
|
||||
@NonNull
|
||||
private static final NetworkScore INVINCIBLE_SCORE =
|
||||
new NetworkScore.Builder().setLegacyInt(1000).build();
|
||||
final NetworkFactoryShim mImpl;
|
||||
|
||||
/**
|
||||
* Pass a network request to the bearer. If the bearer believes it can
|
||||
* satisfy the request it should connect to the network and create a
|
||||
* NetworkAgent. Once the NetworkAgent is fully functional it will
|
||||
* register itself with ConnectivityService using registerNetworkAgent.
|
||||
* If the bearer cannot immediately satisfy the request (no network,
|
||||
* user disabled the radio, lower-scored network) it should remember
|
||||
* any NetworkRequests it may be able to satisfy in the future. It may
|
||||
* disregard any that it will never be able to service, for example
|
||||
* those requiring a different bearer.
|
||||
* msg.obj = NetworkRequest
|
||||
*/
|
||||
// TODO : this and CANCEL_REQUEST are only used by telephony tests. Replace it in the tests
|
||||
// and remove them and the associated code.
|
||||
public static final int CMD_REQUEST_NETWORK = 1;
|
||||
|
||||
/**
|
||||
* Cancel a network request
|
||||
* msg.obj = NetworkRequest
|
||||
*/
|
||||
public static final int CMD_CANCEL_REQUEST = 2;
|
||||
|
||||
/**
|
||||
* Internally used to set our best-guess score.
|
||||
* msg.obj = new score
|
||||
*/
|
||||
private static final int CMD_SET_SCORE = 3;
|
||||
|
||||
/**
|
||||
* Internally used to set our current filter for coarse bandwidth changes with
|
||||
* technology changes.
|
||||
* msg.obj = new filter
|
||||
*/
|
||||
private static final int CMD_SET_FILTER = 4;
|
||||
|
||||
/**
|
||||
* Internally used to send the network offer associated with this factory.
|
||||
* No arguments, will read from members
|
||||
*/
|
||||
private static final int CMD_OFFER_NETWORK = 5;
|
||||
|
||||
/**
|
||||
* Internally used to send the request to listen to all requests.
|
||||
* No arguments, will read from members
|
||||
*/
|
||||
private static final int CMD_LISTEN_TO_ALL_REQUESTS = 6;
|
||||
|
||||
private final Context mContext;
|
||||
private final String LOG_TAG;
|
||||
|
||||
private final Map<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
|
||||
new LinkedHashMap<>();
|
||||
|
||||
@NonNull private NetworkScore mScore = new NetworkScore.Builder().setLegacyInt(0).build();
|
||||
@NonNull private NetworkCapabilities mCapabilityFilter;
|
||||
|
||||
private int mRefCount = 0;
|
||||
private NetworkProvider mProvider = null;
|
||||
|
||||
private final NetworkOfferCallback mRequestCallback = new NetworkOfferCallback() {
|
||||
@Override
|
||||
public void onNetworkNeeded(@NonNull final NetworkRequest request) {
|
||||
handleAddRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkUnneeded(@NonNull final NetworkRequest request) {
|
||||
handleRemoveRequest(request);
|
||||
}
|
||||
};
|
||||
@NonNull private final Executor mExecutor = command -> post(command);
|
||||
|
||||
// Ideally the filter argument would be non-null, but null has historically meant to see
|
||||
// no requests and telephony passes null.
|
||||
public NetworkFactory(Looper looper, Context context, String logTag,
|
||||
@Nullable final NetworkCapabilities filter) {
|
||||
super(looper);
|
||||
LOG_TAG = logTag;
|
||||
mContext = context;
|
||||
if (null != filter) {
|
||||
mCapabilityFilter = filter;
|
||||
if (isAtLeastS()) {
|
||||
mImpl = new NetworkFactoryImpl(this, looper, context, filter);
|
||||
} else {
|
||||
mCapabilityFilter = new NetworkCapabilities.Builder()
|
||||
.withoutDefaultCapabilities().build();
|
||||
mImpl = new NetworkFactoryLegacyImpl(this, looper, context, filter);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : these two constants and the method are only used by telephony tests. Replace it in
|
||||
// the tests and remove them and the associated code.
|
||||
public static final int CMD_REQUEST_NETWORK = 1;
|
||||
public static final int CMD_CANCEL_REQUEST = 2;
|
||||
/** Like Handler#obtainMessage */
|
||||
@VisibleForTesting
|
||||
public Message obtainMessage(final int what, final int arg1, final int arg2,
|
||||
final @Nullable Object obj) {
|
||||
return mImpl.obtainMessage(what, arg1, arg2, obj);
|
||||
}
|
||||
|
||||
// Called by BluetoothNetworkFactory
|
||||
public final Looper getLooper() {
|
||||
return mImpl.getLooper();
|
||||
}
|
||||
|
||||
// Refcount for simple mode requests
|
||||
private int mRefCount = 0;
|
||||
|
||||
/* Registers this NetworkFactory with the system. May only be called once per factory. */
|
||||
public void register() {
|
||||
register(false);
|
||||
mImpl.register(LOG_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,152 +99,16 @@ public class NetworkFactory extends Handler {
|
||||
* May only be called once per factory.
|
||||
*/
|
||||
public void registerIgnoringScore() {
|
||||
register(true);
|
||||
}
|
||||
|
||||
private void register(final boolean listenToAllRequests) {
|
||||
if (mProvider != null) {
|
||||
throw new IllegalStateException("A NetworkFactory must only be registered once");
|
||||
}
|
||||
if (DBG) log("Registering NetworkFactory");
|
||||
|
||||
mProvider = new NetworkProvider(mContext, NetworkFactory.this.getLooper(), LOG_TAG) {
|
||||
@Override
|
||||
public void onNetworkRequested(@NonNull NetworkRequest request, int score,
|
||||
int servingProviderId) {
|
||||
handleAddRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {
|
||||
handleRemoveRequest(request);
|
||||
}
|
||||
};
|
||||
|
||||
((ConnectivityManager) mContext.getSystemService(
|
||||
Context.CONNECTIVITY_SERVICE)).registerNetworkProvider(mProvider);
|
||||
|
||||
// The mScore and mCapabilityFilter members can only be accessed on the handler thread.
|
||||
// TODO : offer a separate API to listen to all requests instead
|
||||
if (listenToAllRequests) {
|
||||
sendMessage(obtainMessage(CMD_LISTEN_TO_ALL_REQUESTS));
|
||||
} else {
|
||||
sendMessage(obtainMessage(CMD_OFFER_NETWORK));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleOfferNetwork(@NonNull final NetworkScore score) {
|
||||
mProvider.registerNetworkOffer(score, mCapabilityFilter, mExecutor, mRequestCallback);
|
||||
mImpl.registerIgnoringScore(LOG_TAG);
|
||||
}
|
||||
|
||||
/** Unregisters this NetworkFactory. After this call, the object can no longer be used. */
|
||||
public void terminate() {
|
||||
if (mProvider == null) {
|
||||
throw new IllegalStateException("This NetworkFactory was never registered");
|
||||
}
|
||||
if (DBG) log("Unregistering NetworkFactory");
|
||||
|
||||
((ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
|
||||
.unregisterNetworkProvider(mProvider);
|
||||
|
||||
// Remove all pending messages, since this object cannot be reused. Any message currently
|
||||
// being processed will continue to run.
|
||||
removeCallbacksAndMessages(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case CMD_REQUEST_NETWORK: {
|
||||
handleAddRequest((NetworkRequest) msg.obj);
|
||||
break;
|
||||
}
|
||||
case CMD_CANCEL_REQUEST: {
|
||||
handleRemoveRequest((NetworkRequest) msg.obj);
|
||||
break;
|
||||
}
|
||||
case CMD_SET_SCORE: {
|
||||
handleSetScore((NetworkScore) msg.obj);
|
||||
break;
|
||||
}
|
||||
case CMD_SET_FILTER: {
|
||||
handleSetFilter((NetworkCapabilities) msg.obj);
|
||||
break;
|
||||
}
|
||||
case CMD_OFFER_NETWORK: {
|
||||
handleOfferNetwork(mScore);
|
||||
break;
|
||||
}
|
||||
case CMD_LISTEN_TO_ALL_REQUESTS: {
|
||||
handleOfferNetwork(INVINCIBLE_SCORE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class NetworkRequestInfo {
|
||||
@NonNull public final NetworkRequest request;
|
||||
public boolean requested; // do we have a request outstanding, limited by score
|
||||
|
||||
NetworkRequestInfo(@NonNull final NetworkRequest request) {
|
||||
this.request = request;
|
||||
this.requested = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + request + ", requested=" + requested + "}";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a NetworkRequest that the bearer may want to attempt to satisfy.
|
||||
* @see #CMD_REQUEST_NETWORK
|
||||
*
|
||||
* @param request the request to handle.
|
||||
*/
|
||||
private void handleAddRequest(@NonNull final NetworkRequest request) {
|
||||
NetworkRequestInfo n = mNetworkRequests.get(request);
|
||||
if (n == null) {
|
||||
if (DBG) log("got request " + request);
|
||||
n = new NetworkRequestInfo(request);
|
||||
mNetworkRequests.put(n.request, n);
|
||||
} else {
|
||||
if (VDBG) {
|
||||
log("handle existing request " + request);
|
||||
}
|
||||
}
|
||||
if (VDBG) log(" my score=" + mScore + ", my filter=" + mCapabilityFilter);
|
||||
|
||||
if (acceptRequest(request)) {
|
||||
n.requested = true;
|
||||
needNetworkFor(request);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRemoveRequest(NetworkRequest request) {
|
||||
NetworkRequestInfo n = mNetworkRequests.get(request);
|
||||
if (n != null) {
|
||||
mNetworkRequests.remove(request);
|
||||
if (n.requested) releaseNetworkFor(n.request);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSetScore(@NonNull final NetworkScore score) {
|
||||
if (mScore.equals(score)) return;
|
||||
mScore = score;
|
||||
reevaluateAllRequests();
|
||||
}
|
||||
|
||||
private void handleSetFilter(@NonNull final NetworkCapabilities netCap) {
|
||||
if (netCap.equals(mCapabilityFilter)) return;
|
||||
mCapabilityFilter = netCap;
|
||||
reevaluateAllRequests();
|
||||
mImpl.terminate();
|
||||
}
|
||||
|
||||
protected final void reevaluateAllRequests() {
|
||||
if (mProvider == null) return;
|
||||
mProvider.registerNetworkOffer(mScore, mCapabilityFilter, mExecutor, mRequestCallback);
|
||||
mImpl.reevaluateAllRequests();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -327,6 +133,7 @@ public class NetworkFactory extends Handler {
|
||||
public boolean acceptRequest(@NonNull final NetworkRequest request) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be called by a factory to release a request as unfulfillable: the request will be
|
||||
* removed, and the caller will get a
|
||||
@@ -337,15 +144,7 @@ public class NetworkFactory extends Handler {
|
||||
* is able to fulfill this request!
|
||||
*/
|
||||
protected void releaseRequestAsUnfulfillableByAnyFactory(NetworkRequest r) {
|
||||
post(() -> {
|
||||
if (DBG) log("releaseRequestAsUnfulfillableByAnyFactory: " + r);
|
||||
final NetworkProvider provider = mProvider;
|
||||
if (provider == null) {
|
||||
Log.e(LOG_TAG, "Ignoring attempt to release unregistered request as unfulfillable");
|
||||
return;
|
||||
}
|
||||
provider.declareNetworkRequestUnfulfillable(r);
|
||||
});
|
||||
mImpl.releaseRequestAsUnfulfillableByAnyFactory(r);
|
||||
}
|
||||
|
||||
// override to do simple mode (request independent)
|
||||
@@ -363,11 +162,11 @@ public class NetworkFactory extends Handler {
|
||||
|
||||
/**
|
||||
* @deprecated this method was never part of the API (system or public) and is only added
|
||||
* for migration of existing clients. It will be removed before S ships.
|
||||
* for migration of existing clients.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setScoreFilter(final int score) {
|
||||
setScoreFilter(new NetworkScore.Builder().setLegacyInt(score).build());
|
||||
mImpl.setScoreFilter(score);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -381,25 +180,24 @@ public class NetworkFactory extends Handler {
|
||||
* @param score the filter
|
||||
*/
|
||||
public void setScoreFilter(@NonNull final NetworkScore score) {
|
||||
sendMessage(obtainMessage(CMD_SET_SCORE, score));
|
||||
mImpl.setScoreFilter(score);
|
||||
}
|
||||
|
||||
public void setCapabilityFilter(NetworkCapabilities netCap) {
|
||||
sendMessage(obtainMessage(CMD_SET_FILTER, new NetworkCapabilities(netCap)));
|
||||
mImpl.setCapabilityFilter(netCap);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected int getRequestCount() {
|
||||
return mNetworkRequests.size();
|
||||
return mImpl.getRequestCount();
|
||||
}
|
||||
|
||||
/* TODO: delete when all callers have migrated to NetworkProvider IDs. */
|
||||
public int getSerialNumber() {
|
||||
return mProvider.getProviderId();
|
||||
return mImpl.getSerialNumber();
|
||||
}
|
||||
|
||||
public NetworkProvider getProvider() {
|
||||
return mProvider;
|
||||
return mImpl.getProvider();
|
||||
}
|
||||
|
||||
protected void log(String s) {
|
||||
@@ -407,18 +205,11 @@ public class NetworkFactory extends Handler {
|
||||
}
|
||||
|
||||
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
|
||||
writer.println(toString());
|
||||
for (NetworkRequestInfo n : mNetworkRequests.values()) {
|
||||
writer.println(" " + n);
|
||||
}
|
||||
mImpl.dump(fd, writer, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + LOG_TAG + " - providerId="
|
||||
+ mProvider.getProviderId() + ", ScoreFilter="
|
||||
+ mScore + ", Filter=" + mCapabilityFilter + ", requests="
|
||||
+ mNetworkRequests.size() + ", refCount=" + mRefCount
|
||||
+ "}";
|
||||
return "{" + LOG_TAG + " " + mImpl.toString() + "}";
|
||||
}
|
||||
}
|
||||
|
||||
323
staticlibs/device/android/net/NetworkFactoryImpl.java
Normal file
323
staticlibs/device/android/net/NetworkFactoryImpl.java
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.content.Context;
|
||||
import android.net.NetworkProvider.NetworkOfferCallback;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* A NetworkFactory is an entity that creates NetworkAgent objects.
|
||||
* The bearers register with ConnectivityService using {@link #register} and
|
||||
* their factory will start receiving scored NetworkRequests. NetworkRequests
|
||||
* can be filtered 3 ways: by NetworkCapabilities, by score and more complexly by
|
||||
* overridden function. All of these can be dynamic - changing NetworkCapabilities
|
||||
* or score forces re-evaluation of all current requests.
|
||||
*
|
||||
* If any requests pass the filter some overrideable functions will be called.
|
||||
* If the bearer only cares about very simple start/stopNetwork callbacks, those
|
||||
* functions can be overridden. If the bearer needs more interaction, it can
|
||||
* override addNetworkRequest and removeNetworkRequest which will give it each
|
||||
* request that passes their current filters.
|
||||
* @hide
|
||||
**/
|
||||
// TODO(b/187083878): factor out common code between this and NetworkFactoryLegacyImpl
|
||||
class NetworkFactoryImpl extends NetworkFactoryLegacyImpl {
|
||||
private static final boolean DBG = NetworkFactory.DBG;
|
||||
private static final boolean VDBG = NetworkFactory.VDBG;
|
||||
|
||||
// A score that will win against everything, so that score filtering will let all requests
|
||||
// through
|
||||
// TODO : remove this and replace with an API to listen to all requests.
|
||||
@NonNull
|
||||
private static final NetworkScore INVINCIBLE_SCORE =
|
||||
new NetworkScore.Builder().setLegacyInt(1000).build();
|
||||
|
||||
// TODO(b/187082970): Replace CMD_* with Handler.post(() -> { ... }) since all the CMDs do is to
|
||||
// run the tasks asynchronously on the Handler thread.
|
||||
|
||||
/**
|
||||
* Pass a network request to the bearer. If the bearer believes it can
|
||||
* satisfy the request it should connect to the network and create a
|
||||
* NetworkAgent. Once the NetworkAgent is fully functional it will
|
||||
* register itself with ConnectivityService using registerNetworkAgent.
|
||||
* If the bearer cannot immediately satisfy the request (no network,
|
||||
* user disabled the radio, lower-scored network) it should remember
|
||||
* any NetworkRequests it may be able to satisfy in the future. It may
|
||||
* disregard any that it will never be able to service, for example
|
||||
* those requiring a different bearer.
|
||||
* msg.obj = NetworkRequest
|
||||
*/
|
||||
// TODO : this and CANCEL_REQUEST are only used by telephony tests. Replace it in the tests
|
||||
// and remove them and the associated code.
|
||||
private static final int CMD_REQUEST_NETWORK = NetworkFactory.CMD_REQUEST_NETWORK;
|
||||
|
||||
/**
|
||||
* Cancel a network request
|
||||
* msg.obj = NetworkRequest
|
||||
*/
|
||||
private static final int CMD_CANCEL_REQUEST = NetworkFactory.CMD_CANCEL_REQUEST;
|
||||
|
||||
/**
|
||||
* Internally used to set our best-guess score.
|
||||
* msg.obj = new score
|
||||
*/
|
||||
private static final int CMD_SET_SCORE = 3;
|
||||
|
||||
/**
|
||||
* Internally used to set our current filter for coarse bandwidth changes with
|
||||
* technology changes.
|
||||
* msg.obj = new filter
|
||||
*/
|
||||
private static final int CMD_SET_FILTER = 4;
|
||||
|
||||
/**
|
||||
* Internally used to send the network offer associated with this factory.
|
||||
* No arguments, will read from members
|
||||
*/
|
||||
private static final int CMD_OFFER_NETWORK = 5;
|
||||
|
||||
/**
|
||||
* Internally used to send the request to listen to all requests.
|
||||
* No arguments, will read from members
|
||||
*/
|
||||
private static final int CMD_LISTEN_TO_ALL_REQUESTS = 6;
|
||||
|
||||
private final Map<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
|
||||
new LinkedHashMap<>();
|
||||
|
||||
@NonNull private NetworkScore mScore = new NetworkScore.Builder().setLegacyInt(0).build();
|
||||
|
||||
private final NetworkOfferCallback mRequestCallback = new NetworkOfferCallback() {
|
||||
@Override
|
||||
public void onNetworkNeeded(@NonNull final NetworkRequest request) {
|
||||
handleAddRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkUnneeded(@NonNull final NetworkRequest request) {
|
||||
handleRemoveRequest(request);
|
||||
}
|
||||
};
|
||||
@NonNull private final Executor mExecutor = command -> post(command);
|
||||
|
||||
|
||||
// Ideally the filter argument would be non-null, but null has historically meant to see
|
||||
// no requests and telephony passes null.
|
||||
NetworkFactoryImpl(NetworkFactory parent, Looper looper, Context context,
|
||||
@Nullable final NetworkCapabilities filter) {
|
||||
super(parent, looper, context,
|
||||
null != filter ? filter :
|
||||
new NetworkCapabilities.Builder().withoutDefaultCapabilities().build());
|
||||
}
|
||||
|
||||
/* Registers this NetworkFactory with the system. May only be called once per factory. */
|
||||
@Override public void register(final String logTag) {
|
||||
register(logTag, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this NetworkFactory with the system ignoring the score filter. This will let
|
||||
* the factory always see all network requests matching its capabilities filter.
|
||||
* May only be called once per factory.
|
||||
*/
|
||||
@Override public void registerIgnoringScore(final String logTag) {
|
||||
register(logTag, true);
|
||||
}
|
||||
|
||||
private void register(final String logTag, final boolean listenToAllRequests) {
|
||||
if (mProvider != null) {
|
||||
throw new IllegalStateException("A NetworkFactory must only be registered once");
|
||||
}
|
||||
if (DBG) mParent.log("Registering NetworkFactory");
|
||||
|
||||
mProvider = new NetworkProvider(mContext, NetworkFactoryImpl.this.getLooper(), logTag) {
|
||||
@Override
|
||||
public void onNetworkRequested(@NonNull NetworkRequest request, int score,
|
||||
int servingProviderId) {
|
||||
handleAddRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {
|
||||
handleRemoveRequest(request);
|
||||
}
|
||||
};
|
||||
|
||||
((ConnectivityManager) mContext.getSystemService(
|
||||
Context.CONNECTIVITY_SERVICE)).registerNetworkProvider(mProvider);
|
||||
|
||||
// The mScore and mCapabilityFilter members can only be accessed on the handler thread.
|
||||
// TODO : offer a separate API to listen to all requests instead
|
||||
if (listenToAllRequests) {
|
||||
sendMessage(obtainMessage(CMD_LISTEN_TO_ALL_REQUESTS));
|
||||
} else {
|
||||
sendMessage(obtainMessage(CMD_OFFER_NETWORK));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleOfferNetwork(@NonNull final NetworkScore score) {
|
||||
mProvider.registerNetworkOffer(score, mCapabilityFilter, mExecutor, mRequestCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case CMD_REQUEST_NETWORK: {
|
||||
handleAddRequest((NetworkRequest) msg.obj);
|
||||
break;
|
||||
}
|
||||
case CMD_CANCEL_REQUEST: {
|
||||
handleRemoveRequest((NetworkRequest) msg.obj);
|
||||
break;
|
||||
}
|
||||
case CMD_SET_SCORE: {
|
||||
handleSetScore((NetworkScore) msg.obj);
|
||||
break;
|
||||
}
|
||||
case CMD_SET_FILTER: {
|
||||
handleSetFilter((NetworkCapabilities) msg.obj);
|
||||
break;
|
||||
}
|
||||
case CMD_OFFER_NETWORK: {
|
||||
handleOfferNetwork(mScore);
|
||||
break;
|
||||
}
|
||||
case CMD_LISTEN_TO_ALL_REQUESTS: {
|
||||
handleOfferNetwork(INVINCIBLE_SCORE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class NetworkRequestInfo {
|
||||
@NonNull public final NetworkRequest request;
|
||||
public boolean requested; // do we have a request outstanding, limited by score
|
||||
|
||||
NetworkRequestInfo(@NonNull final NetworkRequest request) {
|
||||
this.request = request;
|
||||
this.requested = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + request + ", requested=" + requested + "}";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a NetworkRequest that the bearer may want to attempt to satisfy.
|
||||
* @see #CMD_REQUEST_NETWORK
|
||||
*
|
||||
* @param request the request to handle.
|
||||
*/
|
||||
private void handleAddRequest(@NonNull final NetworkRequest request) {
|
||||
NetworkRequestInfo n = mNetworkRequests.get(request);
|
||||
if (n == null) {
|
||||
if (DBG) mParent.log("got request " + request);
|
||||
n = new NetworkRequestInfo(request);
|
||||
mNetworkRequests.put(n.request, n);
|
||||
} else {
|
||||
if (VDBG) mParent.log("handle existing request " + request);
|
||||
}
|
||||
if (VDBG) mParent.log(" my score=" + mScore + ", my filter=" + mCapabilityFilter);
|
||||
|
||||
if (mParent.acceptRequest(request)) {
|
||||
n.requested = true;
|
||||
mParent.needNetworkFor(request);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRemoveRequest(NetworkRequest request) {
|
||||
NetworkRequestInfo n = mNetworkRequests.get(request);
|
||||
if (n != null) {
|
||||
mNetworkRequests.remove(request);
|
||||
if (n.requested) mParent.releaseNetworkFor(n.request);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSetScore(@NonNull final NetworkScore score) {
|
||||
if (mScore.equals(score)) return;
|
||||
mScore = score;
|
||||
mParent.reevaluateAllRequests();
|
||||
}
|
||||
|
||||
private void handleSetFilter(@NonNull final NetworkCapabilities netCap) {
|
||||
if (netCap.equals(mCapabilityFilter)) return;
|
||||
mCapabilityFilter = netCap;
|
||||
mParent.reevaluateAllRequests();
|
||||
}
|
||||
|
||||
@Override public final void reevaluateAllRequests() {
|
||||
if (mProvider == null) return;
|
||||
mProvider.registerNetworkOffer(mScore, mCapabilityFilter, mExecutor, mRequestCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated this method was never part of the API (system or public) and is only added
|
||||
* for migration of existing clients.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setScoreFilter(final int score) {
|
||||
setScoreFilter(new NetworkScore.Builder().setLegacyInt(score).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a score filter for this factory.
|
||||
*
|
||||
* This should include the transports the factory knows its networks will have, and
|
||||
* an optimistic view of the attributes it may have. This does not commit the factory
|
||||
* to being able to bring up such a network ; it only lets it avoid hearing about
|
||||
* requests that it has no chance of fulfilling.
|
||||
*
|
||||
* @param score the filter
|
||||
*/
|
||||
@Override public void setScoreFilter(@NonNull final NetworkScore score) {
|
||||
sendMessage(obtainMessage(CMD_SET_SCORE, score));
|
||||
}
|
||||
|
||||
@Override public void setCapabilityFilter(NetworkCapabilities netCap) {
|
||||
sendMessage(obtainMessage(CMD_SET_FILTER, new NetworkCapabilities(netCap)));
|
||||
}
|
||||
|
||||
@Override public int getRequestCount() {
|
||||
return mNetworkRequests.size();
|
||||
}
|
||||
|
||||
@Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
|
||||
writer.println(toString());
|
||||
for (NetworkRequestInfo n : mNetworkRequests.values()) {
|
||||
writer.println(" " + n);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "providerId="
|
||||
+ mProvider.getProviderId() + ", ScoreFilter="
|
||||
+ mScore + ", Filter=" + mCapabilityFilter + ", requests="
|
||||
+ mNetworkRequests.size();
|
||||
}
|
||||
}
|
||||
398
staticlibs/device/android/net/NetworkFactoryLegacyImpl.java
Normal file
398
staticlibs/device/android/net/NetworkFactoryLegacyImpl.java
Normal file
@@ -0,0 +1,398 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A NetworkFactory is an entity that creates NetworkAgent objects.
|
||||
* The bearers register with ConnectivityService using {@link #register} and
|
||||
* their factory will start receiving scored NetworkRequests. NetworkRequests
|
||||
* can be filtered 3 ways: by NetworkCapabilities, by score and more complexly by
|
||||
* overridden function. All of these can be dynamic - changing NetworkCapabilities
|
||||
* or score forces re-evaluation of all current requests.
|
||||
*
|
||||
* If any requests pass the filter some overrideable functions will be called.
|
||||
* If the bearer only cares about very simple start/stopNetwork callbacks, those
|
||||
* functions can be overridden. If the bearer needs more interaction, it can
|
||||
* override addNetworkRequest and removeNetworkRequest which will give it each
|
||||
* request that passes their current filters.
|
||||
* @hide
|
||||
**/
|
||||
// TODO(b/187083878): factor out common code between this and NetworkFactoryImpl
|
||||
class NetworkFactoryLegacyImpl extends Handler
|
||||
implements NetworkFactoryShim {
|
||||
private static final boolean DBG = NetworkFactory.DBG;
|
||||
private static final boolean VDBG = NetworkFactory.VDBG;
|
||||
|
||||
// TODO(b/187082970): Replace CMD_* with Handler.post(() -> { ... }) since all the CMDs do is to
|
||||
// run the tasks asynchronously on the Handler thread.
|
||||
|
||||
/**
|
||||
* Pass a network request to the bearer. If the bearer believes it can
|
||||
* satisfy the request it should connect to the network and create a
|
||||
* NetworkAgent. Once the NetworkAgent is fully functional it will
|
||||
* register itself with ConnectivityService using registerNetworkAgent.
|
||||
* If the bearer cannot immediately satisfy the request (no network,
|
||||
* user disabled the radio, lower-scored network) it should remember
|
||||
* any NetworkRequests it may be able to satisfy in the future. It may
|
||||
* disregard any that it will never be able to service, for example
|
||||
* those requiring a different bearer.
|
||||
* msg.obj = NetworkRequest
|
||||
* msg.arg1 = score - the score of the network currently satisfying this
|
||||
* request. If this bearer knows in advance it cannot
|
||||
* exceed this score it should not try to connect, holding the request
|
||||
* for the future.
|
||||
* Note that subsequent events may give a different (lower
|
||||
* or higher) score for this request, transmitted to each
|
||||
* NetworkFactory through additional CMD_REQUEST_NETWORK msgs
|
||||
* with the same NetworkRequest but an updated score.
|
||||
* Also, network conditions may change for this bearer
|
||||
* allowing for a better score in the future.
|
||||
* msg.arg2 = the ID of the NetworkProvider currently responsible for the
|
||||
* NetworkAgent handling this request, or NetworkProvider.ID_NONE if none.
|
||||
*/
|
||||
public static final int CMD_REQUEST_NETWORK = 1;
|
||||
|
||||
/**
|
||||
* Cancel a network request
|
||||
* msg.obj = NetworkRequest
|
||||
*/
|
||||
public static final int CMD_CANCEL_REQUEST = 2;
|
||||
|
||||
/**
|
||||
* Internally used to set our best-guess score.
|
||||
* msg.arg1 = new score
|
||||
*/
|
||||
private static final int CMD_SET_SCORE = 3;
|
||||
|
||||
/**
|
||||
* Internally used to set our current filter for coarse bandwidth changes with
|
||||
* technology changes.
|
||||
* msg.obj = new filter
|
||||
*/
|
||||
private static final int CMD_SET_FILTER = 4;
|
||||
|
||||
final Context mContext;
|
||||
final NetworkFactory mParent;
|
||||
|
||||
private final Map<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
|
||||
new LinkedHashMap<>();
|
||||
|
||||
private int mScore;
|
||||
NetworkCapabilities mCapabilityFilter;
|
||||
|
||||
NetworkProvider mProvider = null;
|
||||
|
||||
NetworkFactoryLegacyImpl(NetworkFactory parent, Looper looper, Context context,
|
||||
NetworkCapabilities filter) {
|
||||
super(looper);
|
||||
mParent = parent;
|
||||
mContext = context;
|
||||
mCapabilityFilter = filter;
|
||||
}
|
||||
|
||||
/* Registers this NetworkFactory with the system. May only be called once per factory. */
|
||||
@Override public void register(final String logTag) {
|
||||
if (mProvider != null) {
|
||||
throw new IllegalStateException("A NetworkFactory must only be registered once");
|
||||
}
|
||||
if (DBG) mParent.log("Registering NetworkFactory");
|
||||
|
||||
mProvider = new NetworkProvider(mContext, NetworkFactoryLegacyImpl.this.getLooper(),
|
||||
logTag) {
|
||||
@Override
|
||||
public void onNetworkRequested(@NonNull NetworkRequest request, int score,
|
||||
int servingProviderId) {
|
||||
handleAddRequest(request, score, servingProviderId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {
|
||||
handleRemoveRequest(request);
|
||||
}
|
||||
};
|
||||
|
||||
((ConnectivityManager) mContext.getSystemService(
|
||||
Context.CONNECTIVITY_SERVICE)).registerNetworkProvider(mProvider);
|
||||
}
|
||||
|
||||
/** Unregisters this NetworkFactory. After this call, the object can no longer be used. */
|
||||
@Override public void terminate() {
|
||||
if (mProvider == null) {
|
||||
throw new IllegalStateException("This NetworkFactory was never registered");
|
||||
}
|
||||
if (DBG) mParent.log("Unregistering NetworkFactory");
|
||||
|
||||
((ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
|
||||
.unregisterNetworkProvider(mProvider);
|
||||
|
||||
// Remove all pending messages, since this object cannot be reused. Any message currently
|
||||
// being processed will continue to run.
|
||||
removeCallbacksAndMessages(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case CMD_REQUEST_NETWORK: {
|
||||
handleAddRequest((NetworkRequest) msg.obj, msg.arg1, msg.arg2);
|
||||
break;
|
||||
}
|
||||
case CMD_CANCEL_REQUEST: {
|
||||
handleRemoveRequest((NetworkRequest) msg.obj);
|
||||
break;
|
||||
}
|
||||
case CMD_SET_SCORE: {
|
||||
handleSetScore(msg.arg1);
|
||||
break;
|
||||
}
|
||||
case CMD_SET_FILTER: {
|
||||
handleSetFilter((NetworkCapabilities) msg.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class NetworkRequestInfo {
|
||||
public final NetworkRequest request;
|
||||
public int score;
|
||||
public boolean requested; // do we have a request outstanding, limited by score
|
||||
public int providerId;
|
||||
|
||||
NetworkRequestInfo(NetworkRequest request, int score, int providerId) {
|
||||
this.request = request;
|
||||
this.score = score;
|
||||
this.requested = false;
|
||||
this.providerId = providerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + request + ", score=" + score + ", requested=" + requested + "}";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a NetworkRequest that the bearer may want to attempt to satisfy.
|
||||
* @see #CMD_REQUEST_NETWORK
|
||||
*
|
||||
* @param request the request to handle.
|
||||
* @param score the score of the NetworkAgent currently satisfying this request.
|
||||
* @param servingProviderId the ID of the NetworkProvider that created the NetworkAgent
|
||||
* currently satisfying this request.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected void handleAddRequest(NetworkRequest request, int score, int servingProviderId) {
|
||||
NetworkRequestInfo n = mNetworkRequests.get(request);
|
||||
if (n == null) {
|
||||
if (DBG) {
|
||||
mParent.log("got request " + request + " with score " + score
|
||||
+ " and providerId " + servingProviderId);
|
||||
}
|
||||
n = new NetworkRequestInfo(request, score, servingProviderId);
|
||||
mNetworkRequests.put(n.request, n);
|
||||
} else {
|
||||
if (VDBG) {
|
||||
mParent.log("new score " + score + " for existing request " + request
|
||||
+ " and providerId " + servingProviderId);
|
||||
}
|
||||
n.score = score;
|
||||
n.providerId = servingProviderId;
|
||||
}
|
||||
if (VDBG) mParent.log(" my score=" + mScore + ", my filter=" + mCapabilityFilter);
|
||||
|
||||
evalRequest(n);
|
||||
}
|
||||
|
||||
private void handleRemoveRequest(NetworkRequest request) {
|
||||
NetworkRequestInfo n = mNetworkRequests.get(request);
|
||||
if (n != null) {
|
||||
mNetworkRequests.remove(request);
|
||||
if (n.requested) mParent.releaseNetworkFor(n.request);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSetScore(int score) {
|
||||
mScore = score;
|
||||
evalRequests();
|
||||
}
|
||||
|
||||
private void handleSetFilter(NetworkCapabilities netCap) {
|
||||
mCapabilityFilter = netCap;
|
||||
evalRequests();
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridable function to provide complex filtering.
|
||||
* Called for every request every time a new NetworkRequest is seen
|
||||
* and whenever the filterScore or filterNetworkCapabilities change.
|
||||
*
|
||||
* acceptRequest can be overridden to provide complex filter behavior
|
||||
* for the incoming requests
|
||||
*
|
||||
* For output, this class will call {@link NetworkFactory#needNetworkFor} and
|
||||
* {@link NetworkFactory#releaseNetworkFor} for every request that passes the filters.
|
||||
* If you don't need to see every request, you can leave the base
|
||||
* implementations of those two functions and instead override
|
||||
* {@link NetworkFactory#startNetwork} and {@link NetworkFactory#stopNetwork}.
|
||||
*
|
||||
* If you want to see every score fluctuation on every request, set
|
||||
* your score filter to a very high number and watch {@link NetworkFactory#needNetworkFor}.
|
||||
*
|
||||
* @return {@code true} to accept the request.
|
||||
*/
|
||||
public boolean acceptRequest(NetworkRequest request) {
|
||||
return mParent.acceptRequest(request);
|
||||
}
|
||||
|
||||
private void evalRequest(NetworkRequestInfo n) {
|
||||
if (VDBG) {
|
||||
mParent.log("evalRequest");
|
||||
mParent.log(" n.requests = " + n.requested);
|
||||
mParent.log(" n.score = " + n.score);
|
||||
mParent.log(" mScore = " + mScore);
|
||||
mParent.log(" request.providerId = " + n.providerId);
|
||||
mParent.log(" mProvider.id = " + mProvider.getProviderId());
|
||||
}
|
||||
if (shouldNeedNetworkFor(n)) {
|
||||
if (VDBG) mParent.log(" needNetworkFor");
|
||||
mParent.needNetworkFor(n.request);
|
||||
n.requested = true;
|
||||
} else if (shouldReleaseNetworkFor(n)) {
|
||||
if (VDBG) mParent.log(" releaseNetworkFor");
|
||||
mParent.releaseNetworkFor(n.request);
|
||||
n.requested = false;
|
||||
} else {
|
||||
if (VDBG) mParent.log(" done");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldNeedNetworkFor(NetworkRequestInfo n) {
|
||||
// If this request is already tracked, it doesn't qualify for need
|
||||
return !n.requested
|
||||
// If the score of this request is higher or equal to that of this factory and some
|
||||
// other factory is responsible for it, then this factory should not track the request
|
||||
// because it has no hope of satisfying it.
|
||||
&& (n.score < mScore || n.providerId == mProvider.getProviderId())
|
||||
// If this factory can't satisfy the capability needs of this request, then it
|
||||
// should not be tracked.
|
||||
&& n.request.canBeSatisfiedBy(mCapabilityFilter)
|
||||
// Finally if the concrete implementation of the factory rejects the request, then
|
||||
// don't track it.
|
||||
&& acceptRequest(n.request);
|
||||
}
|
||||
|
||||
private boolean shouldReleaseNetworkFor(NetworkRequestInfo n) {
|
||||
// Don't release a request that's not tracked.
|
||||
return n.requested
|
||||
// The request should be released if it can't be satisfied by this factory. That
|
||||
// means either of the following conditions are met :
|
||||
// - Its score is too high to be satisfied by this factory and it's not already
|
||||
// assigned to the factory
|
||||
// - This factory can't satisfy the capability needs of the request
|
||||
// - The concrete implementation of the factory rejects the request
|
||||
&& ((n.score > mScore && n.providerId != mProvider.getProviderId())
|
||||
|| !n.request.canBeSatisfiedBy(mCapabilityFilter)
|
||||
|| !acceptRequest(n.request));
|
||||
}
|
||||
|
||||
private void evalRequests() {
|
||||
for (NetworkRequestInfo n : mNetworkRequests.values()) {
|
||||
evalRequest(n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Post a command, on this NetworkFactory Handler, to re-evaluate all
|
||||
* outstanding requests. Can be called from a factory implementation.
|
||||
*/
|
||||
@Override public void reevaluateAllRequests() {
|
||||
post(this::evalRequests);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be called by a factory to release a request as unfulfillable: the request will be
|
||||
* removed, and the caller will get a
|
||||
* {@link ConnectivityManager.NetworkCallback#onUnavailable()} callback after this function
|
||||
* returns.
|
||||
*
|
||||
* Note: this should only be called by factory which KNOWS that it is the ONLY factory which
|
||||
* is able to fulfill this request!
|
||||
*/
|
||||
@Override public void releaseRequestAsUnfulfillableByAnyFactory(NetworkRequest r) {
|
||||
post(() -> {
|
||||
if (DBG) mParent.log("releaseRequestAsUnfulfillableByAnyFactory: " + r);
|
||||
final NetworkProvider provider = mProvider;
|
||||
if (provider == null) {
|
||||
mParent.log("Ignoring attempt to release unregistered request as unfulfillable");
|
||||
return;
|
||||
}
|
||||
provider.declareNetworkRequestUnfulfillable(r);
|
||||
});
|
||||
}
|
||||
|
||||
@Override public void setScoreFilter(int score) {
|
||||
sendMessage(obtainMessage(CMD_SET_SCORE, score, 0));
|
||||
}
|
||||
|
||||
@Override public void setScoreFilter(@NonNull final NetworkScore score) {
|
||||
setScoreFilter(score.getLegacyInt());
|
||||
}
|
||||
|
||||
@Override public void setCapabilityFilter(NetworkCapabilities netCap) {
|
||||
sendMessage(obtainMessage(CMD_SET_FILTER, new NetworkCapabilities(netCap)));
|
||||
}
|
||||
|
||||
@Override public int getRequestCount() {
|
||||
return mNetworkRequests.size();
|
||||
}
|
||||
|
||||
/* TODO: delete when all callers have migrated to NetworkProvider IDs. */
|
||||
@Override public int getSerialNumber() {
|
||||
return mProvider.getProviderId();
|
||||
}
|
||||
|
||||
@Override public NetworkProvider getProvider() {
|
||||
return mProvider;
|
||||
}
|
||||
|
||||
@Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
|
||||
writer.println(toString());
|
||||
for (NetworkRequestInfo n : mNetworkRequests.values()) {
|
||||
writer.println(" " + n);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "providerId="
|
||||
+ mProvider.getProviderId() + ", ScoreFilter="
|
||||
+ mScore + ", Filter=" + mCapabilityFilter + ", requests="
|
||||
+ mNetworkRequests.size();
|
||||
}
|
||||
}
|
||||
71
staticlibs/device/android/net/NetworkFactoryShim.java
Normal file
71
staticlibs/device/android/net/NetworkFactoryShim.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.os.Looper;
|
||||
import android.os.Message;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Extract an interface for multiple implementation of {@link NetworkFactory}, depending on the SDK
|
||||
* version.
|
||||
*
|
||||
* Known implementations:
|
||||
* - {@link NetworkFactoryImpl}: For Android S+
|
||||
* - {@link NetworkFactoryLegacyImpl}: For Android R-
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
interface NetworkFactoryShim {
|
||||
void register(String logTag);
|
||||
|
||||
default void registerIgnoringScore(String logTag) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
void terminate();
|
||||
|
||||
void releaseRequestAsUnfulfillableByAnyFactory(NetworkRequest r);
|
||||
|
||||
void reevaluateAllRequests();
|
||||
|
||||
void setScoreFilter(int score);
|
||||
|
||||
void setScoreFilter(@NonNull NetworkScore score);
|
||||
|
||||
void setCapabilityFilter(NetworkCapabilities netCap);
|
||||
|
||||
int getRequestCount();
|
||||
|
||||
int getSerialNumber();
|
||||
|
||||
NetworkProvider getProvider();
|
||||
|
||||
void dump(FileDescriptor fd, PrintWriter writer, String[] args);
|
||||
|
||||
// All impls inherit Handler
|
||||
@VisibleForTesting
|
||||
Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj);
|
||||
|
||||
Looper getLooper();
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
rule android.annotation.** com.android.net.module.annotation.@1
|
||||
rule com.android.internal.annotations.** com.android.net.module.annotation.@1
|
||||
rule com.android.modules.utils.build.** com.android.net.module.util.build.$1
|
||||
|
||||
Reference in New Issue
Block a user