Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da355c80 authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by Android Git Automerger
Browse files

am c3f21f3b: Support NetworkCallbacks based on signal strength.

* commit 'c3f21f3b':
  Support NetworkCallbacks based on signal strength.
parents e647d93d c3f21f3b
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -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);
    }
+77 −3
Original line number Diff line number Diff line
@@ -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;
    }

    /**
@@ -301,6 +303,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;
    }

@@ -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
     * @hide
@@ -578,6 +643,7 @@ public final class NetworkCapabilities implements Parcelable {
        combineTransportTypes(nc);
        combineLinkBandwidths(nc);
        combineSpecifiers(nc);
        combineSignalStrength(nc);
    }

    /**
@@ -594,7 +660,8 @@ public final class NetworkCapabilities implements Parcelable {
                satisfiedByNetCapabilities(nc, onlyImmutable) &&
                satisfiedByTransportTypes(nc) &&
                (onlyImmutable || satisfiedByLinkBandwidths(nc)) &&
                satisfiedBySpecifier(nc));
                satisfiedBySpecifier(nc) &&
                (onlyImmutable || satisfiedBySignalStrength(nc)));
    }

    /**
@@ -639,6 +706,7 @@ public final class NetworkCapabilities implements Parcelable {
        return (equalsNetCapabilities(that) &&
                equalsTransportTypes(that) &&
                equalsLinkBandwidths(that) &&
                equalsSignalStrength(that) &&
                equalsSpecifier(that));
    }

@@ -650,7 +718,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
@@ -664,7 +733,9 @@ public final class NetworkCapabilities implements Parcelable {
        dest.writeInt(mLinkUpBandwidthKbps);
        dest.writeInt(mLinkDownBandwidthKbps);
        dest.writeString(mNetworkSpecifier);
        dest.writeInt(mSignalStrength);
    }

    public static final Creator<NetworkCapabilities> CREATOR =
        new Creator<NetworkCapabilities>() {
            @Override
@@ -676,6 +747,7 @@ public final class NetworkCapabilities implements Parcelable {
                netCap.mLinkUpBandwidthKbps = in.readInt();
                netCap.mLinkDownBandwidthKbps = in.readInt();
                netCap.mNetworkSpecifier = in.readString();
                netCap.mSignalStrength = in.readInt();
                return netCap;
            }
            @Override
@@ -732,6 +804,8 @@ public final class NetworkCapabilities implements Parcelable {
        String specifier = (mNetworkSpecifier == null ?
                "" : " Specifier: <" + mNetworkSpecifier + ">");

        return "[" + transports + capabilities + upBand + dnBand + specifier + "]";
        String signalStrength = (hasSignalStrength() ? " SignalStrength: " + mSignalStrength : "");

        return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength + "]";
    }
}
+18 −0
Original line number Diff line number Diff line
@@ -185,6 +185,24 @@ public class NetworkRequest implements Parcelable {
            mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
            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
+50 −1
Original line number Diff line number Diff line
@@ -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;
@@ -1934,7 +1936,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)) {
@@ -2250,6 +2252,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
    private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
        mNetworkRequests.put(nri.request, nri);
        mNetworkRequestInfoLogs.log("REGISTER " + nri);
        if (!nri.isRequest) {
            for (NetworkAgentInfo network : mNetworkAgentInfos.values()) {
                if (network.satisfiesImmutableCapabilitiesOf(nri.request)) {
                    updateSignalStrengthThresholds(network);
                }
            }
        }
        rematchAllNetworksAndRequests(null, 0);
        if (nri.isRequest && mNetworkForRequestId.get(nri.request.requestId) == null) {
            sendUpdatedScoreToFactories(nri.request, 0);
@@ -2363,6 +2372,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);
@@ -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
    public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
            Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
@@ -4523,6 +4563,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
                // 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.
            rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP);

+6 −0
Original line number Diff line number Diff line
@@ -194,6 +194,12 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
                request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities);
    }

    public boolean satisfiesImmutableCapabilitiesOf(NetworkRequest request) {
        return created &&
                request.networkCapabilities.satisfiedByImmutableNetworkCapabilities(
                        networkCapabilities);
    }

    public boolean isVPN() {
        return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
    }