diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index 85a584a8ca..0af6e7c698 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -184,6 +184,14 @@ public abstract class NetworkAgent extends Handler { */ 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, NetworkCapabilities nc, LinkProperties lp, int score) { this(looper, context, logTag, ni, nc, lp, score, null); @@ -286,6 +294,11 @@ public abstract class NetworkAgent extends Handler { stopPacketKeepalive(msg); 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); } + /** + * 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) { Log.d(LOG_TAG, "NetworkAgent: " + s); } diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index d69d00fdbe..847b77726e 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -48,6 +48,7 @@ public final class NetworkCapabilities implements Parcelable { mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps; mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps; mNetworkSpecifier = nc.mNetworkSpecifier; + mSignalStrength = nc.mSignalStrength; } } @@ -60,6 +61,7 @@ public final class NetworkCapabilities implements Parcelable { mNetworkCapabilities = mTransportTypes = 0; mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = 0; mNetworkSpecifier = null; + mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED; } /** @@ -300,6 +302,7 @@ public final class NetworkCapabilities implements Parcelable { return "unknown non-requestable capabilities " + Long.toHexString(mNetworkCapabilities); } if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth"; + if (hasSignalStrength()) return "signalStrength"; return null; } @@ -568,6 +571,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. + *
+ * 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
* @hide
@@ -577,6 +642,7 @@ public final class NetworkCapabilities implements Parcelable {
combineTransportTypes(nc);
combineLinkBandwidths(nc);
combineSpecifiers(nc);
+ combineSignalStrength(nc);
}
/**
@@ -593,7 +659,8 @@ public final class NetworkCapabilities implements Parcelable {
satisfiedByNetCapabilities(nc, onlyImmutable) &&
satisfiedByTransportTypes(nc) &&
(onlyImmutable || satisfiedByLinkBandwidths(nc)) &&
- satisfiedBySpecifier(nc));
+ satisfiedBySpecifier(nc) &&
+ (onlyImmutable || satisfiedBySignalStrength(nc)));
}
/**
@@ -638,6 +705,7 @@ public final class NetworkCapabilities implements Parcelable {
return (equalsNetCapabilities(that) &&
equalsTransportTypes(that) &&
equalsLinkBandwidths(that) &&
+ equalsSignalStrength(that) &&
equalsSpecifier(that));
}
@@ -649,7 +717,8 @@ public final class NetworkCapabilities implements Parcelable {
((int)(mTransportTypes >> 32) * 7) +
(mLinkUpBandwidthKbps * 11) +
(mLinkDownBandwidthKbps * 13) +
- (TextUtils.isEmpty(mNetworkSpecifier) ? 0 : mNetworkSpecifier.hashCode() * 17));
+ (TextUtils.isEmpty(mNetworkSpecifier) ? 0 : mNetworkSpecifier.hashCode() * 17) +
+ (mSignalStrength * 19));
}
@Override
@@ -663,7 +732,9 @@ public final class NetworkCapabilities implements Parcelable {
dest.writeInt(mLinkUpBandwidthKbps);
dest.writeInt(mLinkDownBandwidthKbps);
dest.writeString(mNetworkSpecifier);
+ dest.writeInt(mSignalStrength);
}
+
public static final Creator
+ * 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
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index e71bd19f3f..c35e4cb46a 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -150,6 +150,8 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.SortedSet;
+import java.util.TreeSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -1914,7 +1916,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
(NetworkCapabilities)msg.obj;
if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL) ||
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(
networkCapabilities)) {
@@ -2274,6 +2276,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
bestNetwork = network;
}
}
+ if (!nri.isRequest && network.satisfiesImmutableCapabilitiesOf(nri.request)) {
+ updateSignalStrengthThresholds(network);
+ }
}
if (bestNetwork != null) {
if (DBG) log("using " + bestNetwork.name());
@@ -2419,6 +2424,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
// if this listen request applies and remove it.
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
nai.networkRequests.remove(nri.request.requestId);
+ if (nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
+ updateSignalStrengthThresholds(nai);
+ }
}
}
callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED);
@@ -3664,6 +3672,34 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
+ private int[] getSignalStrengthThresholds(NetworkAgentInfo nai) {
+ final SortedSet