Support NetworkCallbacks based on signal strength.
Bug: 21405941 Change-Id: I2ed8a5aeb8dac464a4305671ed22abcacb485bc9
This commit is contained in:
committed by
Prerepa Viswanadham
parent
8bf977d562
commit
c3f21f3b8b
@@ -184,6 +184,14 @@ public abstract class NetworkAgent extends Handler {
|
|||||||
*/
|
*/
|
||||||
public static final int EVENT_PACKET_KEEPALIVE = BASE + 13;
|
public static final int EVENT_PACKET_KEEPALIVE = BASE + 13;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sent by ConnectivityService to inform this network transport of signal strength thresholds
|
||||||
|
* that when crossed should trigger a system wakeup and a NetworkCapabilities update.
|
||||||
|
*
|
||||||
|
* obj = int[] describing signal strength thresholds.
|
||||||
|
*/
|
||||||
|
public static final int CMD_SET_SIGNAL_STRENGTH_THRESHOLDS = BASE + 14;
|
||||||
|
|
||||||
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
|
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
|
||||||
NetworkCapabilities nc, LinkProperties lp, int score) {
|
NetworkCapabilities nc, LinkProperties lp, int score) {
|
||||||
this(looper, context, logTag, ni, nc, lp, score, null);
|
this(looper, context, logTag, ni, nc, lp, score, null);
|
||||||
@@ -286,6 +294,11 @@ public abstract class NetworkAgent extends Handler {
|
|||||||
stopPacketKeepalive(msg);
|
stopPacketKeepalive(msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case CMD_SET_SIGNAL_STRENGTH_THRESHOLDS: {
|
||||||
|
setSignalStrengthThresholds((int[]) msg.obj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,6 +458,13 @@ public abstract class NetworkAgent extends Handler {
|
|||||||
queueOrSendMessage(EVENT_PACKET_KEEPALIVE, slot, reason);
|
queueOrSendMessage(EVENT_PACKET_KEEPALIVE, slot, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by ConnectivityService to inform this network transport of signal strength thresholds
|
||||||
|
* that when crossed should trigger a system wakeup and a NetworkCapabilities update.
|
||||||
|
*/
|
||||||
|
protected void setSignalStrengthThresholds(int[] thresholds) {
|
||||||
|
}
|
||||||
|
|
||||||
protected void log(String s) {
|
protected void log(String s) {
|
||||||
Log.d(LOG_TAG, "NetworkAgent: " + s);
|
Log.d(LOG_TAG, "NetworkAgent: " + s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
|
mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
|
||||||
mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
|
mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
|
||||||
mNetworkSpecifier = nc.mNetworkSpecifier;
|
mNetworkSpecifier = nc.mNetworkSpecifier;
|
||||||
|
mSignalStrength = nc.mSignalStrength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,6 +61,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
mNetworkCapabilities = mTransportTypes = 0;
|
mNetworkCapabilities = mTransportTypes = 0;
|
||||||
mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = 0;
|
mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = 0;
|
||||||
mNetworkSpecifier = null;
|
mNetworkSpecifier = null;
|
||||||
|
mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -301,6 +303,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
return "unknown non-requestable capabilities " + Long.toHexString(mNetworkCapabilities);
|
return "unknown non-requestable capabilities " + Long.toHexString(mNetworkCapabilities);
|
||||||
}
|
}
|
||||||
if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth";
|
if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth";
|
||||||
|
if (hasSignalStrength()) return "signalStrength";
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,6 +572,68 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic value that indicates no signal strength provided. A request specifying this value is
|
||||||
|
* always satisfied.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signal strength. This is a signed integer, and higher values indicate better signal.
|
||||||
|
* The exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
|
||||||
|
*/
|
||||||
|
private int mSignalStrength;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the signal strength. This is a signed integer, with higher values indicating a stronger
|
||||||
|
* signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units
|
||||||
|
* reported by WifiManager.
|
||||||
|
* <p>
|
||||||
|
* Note that when used to register a network callback, this specifies the minimum acceptable
|
||||||
|
* signal strength. When received as the state of an existing network it specifies the current
|
||||||
|
* value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no
|
||||||
|
* effect when requesting a callback.
|
||||||
|
*
|
||||||
|
* @param signalStrength the bearer-specific signal strength.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void setSignalStrength(int signalStrength) {
|
||||||
|
mSignalStrength = signalStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if this object specifies a signal strength.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean hasSignalStrength() {
|
||||||
|
return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the signal strength.
|
||||||
|
*
|
||||||
|
* @return The bearer-specific signal strength.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public int getSignalStrength() {
|
||||||
|
return mSignalStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void combineSignalStrength(NetworkCapabilities nc) {
|
||||||
|
this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean satisfiedBySignalStrength(NetworkCapabilities nc) {
|
||||||
|
return this.mSignalStrength <= nc.mSignalStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean equalsSignalStrength(NetworkCapabilities nc) {
|
||||||
|
return this.mSignalStrength == nc.mSignalStrength;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combine a set of Capabilities to this one. Useful for coming up with the complete set
|
* Combine a set of Capabilities to this one. Useful for coming up with the complete set
|
||||||
* @hide
|
* @hide
|
||||||
@@ -578,6 +643,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
combineTransportTypes(nc);
|
combineTransportTypes(nc);
|
||||||
combineLinkBandwidths(nc);
|
combineLinkBandwidths(nc);
|
||||||
combineSpecifiers(nc);
|
combineSpecifiers(nc);
|
||||||
|
combineSignalStrength(nc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -594,7 +660,8 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
satisfiedByNetCapabilities(nc, onlyImmutable) &&
|
satisfiedByNetCapabilities(nc, onlyImmutable) &&
|
||||||
satisfiedByTransportTypes(nc) &&
|
satisfiedByTransportTypes(nc) &&
|
||||||
(onlyImmutable || satisfiedByLinkBandwidths(nc)) &&
|
(onlyImmutable || satisfiedByLinkBandwidths(nc)) &&
|
||||||
satisfiedBySpecifier(nc));
|
satisfiedBySpecifier(nc) &&
|
||||||
|
(onlyImmutable || satisfiedBySignalStrength(nc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -639,6 +706,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
return (equalsNetCapabilities(that) &&
|
return (equalsNetCapabilities(that) &&
|
||||||
equalsTransportTypes(that) &&
|
equalsTransportTypes(that) &&
|
||||||
equalsLinkBandwidths(that) &&
|
equalsLinkBandwidths(that) &&
|
||||||
|
equalsSignalStrength(that) &&
|
||||||
equalsSpecifier(that));
|
equalsSpecifier(that));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -650,7 +718,8 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
((int)(mTransportTypes >> 32) * 7) +
|
((int)(mTransportTypes >> 32) * 7) +
|
||||||
(mLinkUpBandwidthKbps * 11) +
|
(mLinkUpBandwidthKbps * 11) +
|
||||||
(mLinkDownBandwidthKbps * 13) +
|
(mLinkDownBandwidthKbps * 13) +
|
||||||
(TextUtils.isEmpty(mNetworkSpecifier) ? 0 : mNetworkSpecifier.hashCode() * 17));
|
(TextUtils.isEmpty(mNetworkSpecifier) ? 0 : mNetworkSpecifier.hashCode() * 17) +
|
||||||
|
(mSignalStrength * 19));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -664,7 +733,9 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
dest.writeInt(mLinkUpBandwidthKbps);
|
dest.writeInt(mLinkUpBandwidthKbps);
|
||||||
dest.writeInt(mLinkDownBandwidthKbps);
|
dest.writeInt(mLinkDownBandwidthKbps);
|
||||||
dest.writeString(mNetworkSpecifier);
|
dest.writeString(mNetworkSpecifier);
|
||||||
|
dest.writeInt(mSignalStrength);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<NetworkCapabilities> CREATOR =
|
public static final Creator<NetworkCapabilities> CREATOR =
|
||||||
new Creator<NetworkCapabilities>() {
|
new Creator<NetworkCapabilities>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -676,6 +747,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
netCap.mLinkUpBandwidthKbps = in.readInt();
|
netCap.mLinkUpBandwidthKbps = in.readInt();
|
||||||
netCap.mLinkDownBandwidthKbps = in.readInt();
|
netCap.mLinkDownBandwidthKbps = in.readInt();
|
||||||
netCap.mNetworkSpecifier = in.readString();
|
netCap.mNetworkSpecifier = in.readString();
|
||||||
|
netCap.mSignalStrength = in.readInt();
|
||||||
return netCap;
|
return netCap;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@@ -732,6 +804,8 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
String specifier = (mNetworkSpecifier == null ?
|
String specifier = (mNetworkSpecifier == null ?
|
||||||
"" : " Specifier: <" + mNetworkSpecifier + ">");
|
"" : " Specifier: <" + mNetworkSpecifier + ">");
|
||||||
|
|
||||||
return "[" + transports + capabilities + upBand + dnBand + specifier + "]";
|
String signalStrength = (hasSignalStrength() ? " SignalStrength: " + mSignalStrength : "");
|
||||||
|
|
||||||
|
return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,6 +185,24 @@ public class NetworkRequest implements Parcelable {
|
|||||||
mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
|
mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the signal strength. This is a signed integer, with higher values indicating a
|
||||||
|
* stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same
|
||||||
|
* RSSI units reported by WifiManager.
|
||||||
|
* <p>
|
||||||
|
* Note that when used to register a network callback, this specifies the minimum acceptable
|
||||||
|
* signal strength. When received as the state of an existing network it specifies the
|
||||||
|
* current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when
|
||||||
|
* received and has no effect when requesting a callback.
|
||||||
|
*
|
||||||
|
* @param signalStrength the bearer-specific signal strength.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public Builder setSignalStrength(int signalStrength) {
|
||||||
|
mNetworkCapabilities.setSignalStrength(signalStrength);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// implement the Parcelable interface
|
// implement the Parcelable interface
|
||||||
|
|||||||
@@ -150,6 +150,8 @@ import java.util.Arrays;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.TreeSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -1934,7 +1936,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
(NetworkCapabilities)msg.obj;
|
(NetworkCapabilities)msg.obj;
|
||||||
if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL) ||
|
if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL) ||
|
||||||
networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
|
networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
|
||||||
Slog.wtf(TAG, "BUG: " + nai + " has stateful capability.");
|
Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
|
||||||
}
|
}
|
||||||
if (nai.created && !nai.networkCapabilities.equalImmutableCapabilities(
|
if (nai.created && !nai.networkCapabilities.equalImmutableCapabilities(
|
||||||
networkCapabilities)) {
|
networkCapabilities)) {
|
||||||
@@ -2250,6 +2252,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
|
private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
|
||||||
mNetworkRequests.put(nri.request, nri);
|
mNetworkRequests.put(nri.request, nri);
|
||||||
mNetworkRequestInfoLogs.log("REGISTER " + nri);
|
mNetworkRequestInfoLogs.log("REGISTER " + nri);
|
||||||
|
if (!nri.isRequest) {
|
||||||
|
for (NetworkAgentInfo network : mNetworkAgentInfos.values()) {
|
||||||
|
if (network.satisfiesImmutableCapabilitiesOf(nri.request)) {
|
||||||
|
updateSignalStrengthThresholds(network);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
rematchAllNetworksAndRequests(null, 0);
|
rematchAllNetworksAndRequests(null, 0);
|
||||||
if (nri.isRequest && mNetworkForRequestId.get(nri.request.requestId) == null) {
|
if (nri.isRequest && mNetworkForRequestId.get(nri.request.requestId) == null) {
|
||||||
sendUpdatedScoreToFactories(nri.request, 0);
|
sendUpdatedScoreToFactories(nri.request, 0);
|
||||||
@@ -2363,6 +2372,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// if this listen request applies and remove it.
|
// if this listen request applies and remove it.
|
||||||
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
|
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
|
||||||
nai.networkRequests.remove(nri.request.requestId);
|
nai.networkRequests.remove(nri.request.requestId);
|
||||||
|
if (nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
|
||||||
|
updateSignalStrengthThresholds(nai);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED);
|
callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED);
|
||||||
@@ -3599,6 +3611,34 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int[] getSignalStrengthThresholds(NetworkAgentInfo nai) {
|
||||||
|
final SortedSet<Integer> thresholds = new TreeSet();
|
||||||
|
synchronized (nai) {
|
||||||
|
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
|
||||||
|
if (nri.request.networkCapabilities.hasSignalStrength() &&
|
||||||
|
nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
|
||||||
|
thresholds.add(nri.request.networkCapabilities.getSignalStrength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We can't just do something like:
|
||||||
|
// return thresholds.toArray(new int[thresholds.size()]);
|
||||||
|
// because autoboxing does not work for primitive arrays.
|
||||||
|
final int[] out = new int[thresholds.size()];
|
||||||
|
int pos = 0;
|
||||||
|
for (Integer threshold : thresholds) {
|
||||||
|
out[pos] = threshold;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateSignalStrengthThresholds(NetworkAgentInfo nai) {
|
||||||
|
nai.asyncChannel.sendMessage(
|
||||||
|
android.net.NetworkAgent.CMD_SET_SIGNAL_STRENGTH_THRESHOLDS,
|
||||||
|
0, 0, getSignalStrengthThresholds(nai));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
|
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
|
||||||
Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
|
Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
|
||||||
@@ -4523,6 +4563,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// TODO: support proxy per network.
|
// TODO: support proxy per network.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Whether a particular NetworkRequest listen should cause signal strength thresholds to
|
||||||
|
// be communicated to a particular NetworkAgent depends only on the network's immutable,
|
||||||
|
// capabilities, so it only needs to be done once on initial connect, not every time the
|
||||||
|
// network's capabilities change. Note that we do this before rematching the network,
|
||||||
|
// so we could decide to tear it down immediately afterwards. That's fine though - on
|
||||||
|
// disconnection NetworkAgents should stop any signal strength monitoring they have been
|
||||||
|
// doing.
|
||||||
|
updateSignalStrengthThresholds(networkAgent);
|
||||||
|
|
||||||
// Consider network even though it is not yet validated.
|
// Consider network even though it is not yet validated.
|
||||||
rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP);
|
rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP);
|
||||||
|
|
||||||
|
|||||||
@@ -194,6 +194,12 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities);
|
request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean satisfiesImmutableCapabilitiesOf(NetworkRequest request) {
|
||||||
|
return created &&
|
||||||
|
request.networkCapabilities.satisfiedByImmutableNetworkCapabilities(
|
||||||
|
networkCapabilities);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isVPN() {
|
public boolean isVPN() {
|
||||||
return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
|
return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user