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

Commit 80aba05a authored by Junyu Lai's avatar Junyu Lai Committed by Automerger Merge Worker
Browse files

Merge "Allow network providers to set the linger duration." into sc-dev am: 7f7a3271

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14100410

Change-Id: I425bdc7c5b26f7d22a3ced1018c10e33ec2a5c8a
parents 3f071606 7f7a3271
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -239,6 +239,7 @@ package android.net {
    method public final void sendQosSessionLost(int, int, int);
    method public final void sendSocketKeepaliveEvent(int, int);
    method @Deprecated public void setLegacySubtype(int, @NonNull String);
    method public void setLingerDuration(@NonNull java.time.Duration);
    method public void setTeardownDelayMs(@IntRange(from=0, to=0x1388) int);
    method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
    method public void unregister();
+1 −0
Original line number Diff line number Diff line
@@ -42,4 +42,5 @@ oneway interface INetworkAgentRegistry {
    void sendQosSessionLost(int qosCallbackId, in QosSession session);
    void sendQosCallbackError(int qosCallbackId, int exceptionType);
    void sendTeardownDelayMs(int teardownDelayMs);
    void sendLingerDuration(int durationMs);
}
+29 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Build;
@@ -106,6 +107,9 @@ public abstract class NetworkAgent {
    private final String LOG_TAG;
    private static final boolean DBG = true;
    private static final boolean VDBG = false;
    /** @hide */
    @TestApi
    public static final int MIN_LINGER_TIMER_MS = 2000;
    private final ArrayList<RegistryAction> mPreConnectedQueue = new ArrayList<>();
    private volatile long mLastBwRefreshTime = 0;
    private static final long BW_REFRESH_MIN_WIN_MS = 500;
@@ -391,6 +395,15 @@ public abstract class NetworkAgent {
     */
    public static final int CMD_NETWORK_DESTROYED = BASE + 23;

    /**
     * Sent by the NetworkAgent to ConnectivityService to set the linger duration for this network
     * agent.
     * arg1 = the linger duration, represents by {@link Duration}.
     *
     * @hide
     */
    public static final int EVENT_LINGER_DURATION_CHANGED = BASE + 24;

    private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) {
        final NetworkInfo ni = new NetworkInfo(config.legacyType, config.legacySubType,
                config.legacyTypeName, config.legacySubTypeName);
@@ -1287,6 +1300,22 @@ public abstract class NetworkAgent {
        queueOrSendMessage(ra -> ra.sendQosCallbackError(qosCallbackId, exceptionType));
    }

    /**
     * Set the linger duration for this network agent.
     * @param duration the delay between the moment the network becomes unneeded and the
     *                 moment the network is disconnected or moved into the background.
     *                 Note that If this duration has greater than millisecond precision, then
     *                 the internal implementation will drop any excess precision.
     */
    public void setLingerDuration(@NonNull final Duration duration) {
        Objects.requireNonNull(duration);
        final long durationMs = duration.toMillis();
        if (durationMs < MIN_LINGER_TIMER_MS || durationMs > Integer.MAX_VALUE) {
            throw new IllegalArgumentException("Duration must be within ["
                    + MIN_LINGER_TIMER_MS + "," + Integer.MAX_VALUE + "]ms");
        }
        queueOrSendMessage(ra -> ra.sendLingerDuration((int) durationMs));
    }

    /** @hide */
    protected void log(final String s) {
+10 −4
Original line number Diff line number Diff line
@@ -1353,8 +1353,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
                new NetworkInfo(TYPE_NONE, 0, "", ""),
                new LinkProperties(), new NetworkCapabilities(),
                new NetworkScore.Builder().setLegacyInt(0).build(), mContext, null,
                new NetworkAgentConfig(), this, null, null, 0, INVALID_UID, mQosCallbackTracker,
                mDeps);
                new NetworkAgentConfig(), this, null, null, 0, INVALID_UID,
                mLingerDelayMs, mQosCallbackTracker, mDeps);
    }

    private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
@@ -3167,6 +3167,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
                    } else {
                        logwtf(nai.toShortString() + " set invalid teardown delay " + msg.arg1);
                    }
                    break;
                }
                case NetworkAgent.EVENT_LINGER_DURATION_CHANGED: {
                    nai.setLingerDuration((int) arg.second);
                    break;
                }
            }
        }
@@ -6516,7 +6521,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
        final NetworkAgentInfo nai = new NetworkAgentInfo(na,
                new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
                currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
                this, mNetd, mDnsResolver, providerId, uid, mQosCallbackTracker, mDeps);
                this, mNetd, mDnsResolver, providerId, uid, mLingerDelayMs,
                mQosCallbackTracker, mDeps);

        // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
        processCapabilitiesFromAgent(nai, nc);
@@ -7759,7 +7765,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
                    log("   accepting network in place of " + previousSatisfier.toShortString());
                }
                previousSatisfier.removeRequest(previousRequest.requestId);
                previousSatisfier.lingerRequest(previousRequest.requestId, now, mLingerDelayMs);
                previousSatisfier.lingerRequest(previousRequest.requestId, now);
            } else {
                if (VDBG || DDBG) log("   accepting network in place of null");
            }
+57 −5
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import com.android.internal.util.WakeupMessage;
import com.android.server.ConnectivityService;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
@@ -281,6 +282,9 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
     */
    public static final int ARG_AGENT_SUCCESS = 1;

    // How long this network should linger for.
    private int mLingerDurationMs;

    // All inactivity timers for this network, sorted by expiry time. A timer is added whenever
    // a request is moved to a network with a better score, regardless of whether the network is or
    // was lingering or not. An inactivity timer is also added when a network connects
@@ -349,7 +353,8 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
            @NonNull NetworkScore score, Context context,
            Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd,
            IDnsResolver dnsResolver, int factorySerialNumber, int creatorUid,
            QosCallbackTracker qosCallbackTracker, ConnectivityService.Dependencies deps) {
            int lingerDurationMs, QosCallbackTracker qosCallbackTracker,
            ConnectivityService.Dependencies deps) {
        Objects.requireNonNull(net);
        Objects.requireNonNull(info);
        Objects.requireNonNull(lp);
@@ -370,6 +375,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
        mHandler = handler;
        this.factorySerialNumber = factorySerialNumber;
        this.creatorUid = creatorUid;
        mLingerDurationMs = lingerDurationMs;
        mQosCallbackTracker = qosCallbackTracker;
    }

@@ -685,6 +691,12 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
            mHandler.obtainMessage(NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED,
                    teardownDelayMs, 0, new Pair<>(NetworkAgentInfo.this, null)).sendToTarget();
        }

        @Override
        public void sendLingerDuration(final int durationMs) {
            mHandler.obtainMessage(NetworkAgent.EVENT_LINGER_DURATION_CHANGED,
                    new Pair<>(NetworkAgentInfo.this, durationMs)).sendToTarget();
        }
    }

    /**
@@ -954,13 +966,14 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa

    /**
     * Sets the specified requestId to linger on this network for the specified time. Called by
     * ConnectivityService when the request is moved to another network with a higher score, or
     * ConnectivityService when any request is moved to another network with a higher score, or
     * when a network is newly created.
     *
     * @param requestId The requestId of the request that no longer need to be served by this
     *                  network. Or {@link NetworkRequest.REQUEST_ID_NONE} if this is the
     *                  {@code LingerTimer} for a newly created network.
     *                  {@code InactivityTimer} for a newly created network.
     */
    // TODO: Consider creating a dedicated function for nascent network, e.g. start/stopNascent.
    public void lingerRequest(int requestId, long now, long duration) {
        if (mInactivityTimerForRequest.get(requestId) != null) {
            // Cannot happen. Once a request is lingering on a particular network, we cannot
@@ -975,6 +988,19 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
        mInactivityTimerForRequest.put(requestId, timer);
    }

    /**
     * Sets the specified requestId to linger on this network for the timeout set when
     * initializing or modified by {@link #setLingerDuration(int)}. Called by
     * ConnectivityService when any request is moved to another network with a higher score.
     *
     * @param requestId The requestId of the request that no longer need to be served by this
     *                  network.
     * @param now current system timestamp obtained by {@code SystemClock.elapsedRealtime}.
     */
    public void lingerRequest(int requestId, long now) {
        lingerRequest(requestId, now, mLingerDurationMs);
    }

    /**
     * Cancel lingering. Called by ConnectivityService when a request is added to this network.
     * Returns true if the given requestId was lingering on this network, false otherwise.
@@ -1012,6 +1038,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
        }

        if (newExpiry > 0) {
            // If the newExpiry timestamp is in the past, the wakeup message will fire immediately.
            mInactivityMessage = new WakeupMessage(
                    mContext, mHandler,
                    "NETWORK_LINGER_COMPLETE." + network.getNetId() /* cmdName */,
@@ -1041,8 +1068,33 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
    }

    /**
     * Return whether the network is just connected and about to be torn down because of not
     * satisfying any request.
     * Set the linger duration for this NAI.
     * @param durationMs The new linger duration, in milliseconds.
     */
    public void setLingerDuration(final int durationMs) {
        final long diff = durationMs - mLingerDurationMs;
        final ArrayList<InactivityTimer> newTimers = new ArrayList<>();
        for (final InactivityTimer timer : mInactivityTimers) {
            if (timer.requestId == NetworkRequest.REQUEST_ID_NONE) {
                // Don't touch nascent timer, re-add as is.
                newTimers.add(timer);
            } else {
                newTimers.add(new InactivityTimer(timer.requestId, timer.expiryMs + diff));
            }
        }
        mInactivityTimers.clear();
        mInactivityTimers.addAll(newTimers);
        updateInactivityTimer();
        mLingerDurationMs = durationMs;
    }

    /**
     * Return whether the network satisfies no request, but is still being kept up
     * because it has just connected less than
     * {@code ConnectivityService#DEFAULT_NASCENT_DELAY_MS}ms ago and is thus still considered
     * nascent. Note that nascent mechanism uses inactivity timer which isn't
     * associated with a request. Thus, use {@link NetworkRequest#REQUEST_ID_NONE} to identify it.
     *
     */
    public boolean isNascent() {
        return mInactive && mInactivityTimers.size() == 1
Loading