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

Commit 5c4bb911 authored by Chalard Jean's avatar Chalard Jean
Browse files

[NS01] Add NetworkScore

As attested by numerous TODOs in the code, a new way of
representing network quality and policy is needed instead
of an int.

An int representing the quality of the network requires
all parties using it to know how all other parties are
using it, and implementation details about the decision
algorithm. For all intents and purposes, the selection
is left to individual network factories who try to
achieve a desired result while piecing together all
possible states of the system.

As the number of such cases and desires increases, this
becomes both intractable and unmaintainable. Indeed, at
this time in the codebase nobody can really predict exactly
how a given change in score will affect selection across
the board, and it is essentially impossible to figure out
the behavior of network selection by inspecting the code
because the moving parts are scattered throughout the
entire codebase.

Having an object encapsulating policy and quality values
will let us centralize the selection and make it again
possible to maintain without knowledge of all behaviors
of all network factories. It will also provide better
guarantees of respecting policy, and allow bugfixes that
were not possible before because they'd touch too many
parts of the code.

Test: FrameworksNetTests FrameworksWifiTests NetworkStackTests
Change-Id: I3185a6412b9b659798faf0c6882699e9c63cc115
parent fb8aad8c
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
/**
 * 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;

parcelable NetworkScore;
+108 −0
Original line number Diff line number Diff line
/*
 * 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.os.Parcel;
import android.os.Parcelable;

/**
 * Object representing the quality of a network as perceived by the user.
 *
 * A NetworkScore object represents the characteristics of a network that affects how good the
 * network is considered for a particular use.
 * @hide
 */
// TODO : @SystemApi when the implementation is complete
public final class NetworkScore implements Parcelable {
    // This will be removed soon. Do *NOT* depend on it for any new code that is not part of
    // a migration.
    private final int mLegacyInt;

    /** @hide */
    NetworkScore(final int legacyInt) {
        this.mLegacyInt = legacyInt;
    }

    private NetworkScore(@NonNull final Parcel in) {
        mLegacyInt = in.readInt();
    }

    public int getLegacyInt() {
        return mLegacyInt;
    }

    @Override
    public String toString() {
        return "Score(" + mLegacyInt + ")";
    }

    @Override
    public void writeToParcel(@NonNull final Parcel dest, final int flags) {
        dest.writeInt(mLegacyInt);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @NonNull public static final Creator<NetworkScore> CREATOR = new Creator<>() {
        @Override
        @NonNull
        public NetworkScore createFromParcel(@NonNull final Parcel in) {
            return new NetworkScore(in);
        }

        @Override
        @NonNull
        public NetworkScore[] newArray(int size) {
            return new NetworkScore[size];
        }
    };

    /**
     * A builder for NetworkScore.
     */
    public static final class Builder {
        private static final int INVALID_LEGACY_INT = Integer.MIN_VALUE;
        private int mLegacyInt = INVALID_LEGACY_INT;

        /**
         * Sets the legacy int for this score.
         *
         * Do not rely on this. It will be gone by the time S is released.
         *
         * @param score the legacy int
         * @return this
         */
        @NonNull
        public Builder setLegacyInt(final int score) {
            mLegacyInt = score;
            return this;
        }

        /**
         * Builds this NetworkScore.
         * @return The built NetworkScore object.
         */
        @NonNull
        public NetworkScore build() {
            return new NetworkScore(mLegacyInt);
        }
    }
}
+2 −18
Original line number Diff line number Diff line
@@ -3205,10 +3205,6 @@ public class ConnectivityManager {
        }
    }

    // TODO : remove this method. It is a stopgap measure to help sheperding a number
    // of dependent changes that would conflict throughout the automerger graph. Having this
    // temporarily helps with the process of going through with all these dependent changes across
    // the entire tree.
    /**
     * @hide
     * Register a NetworkAgent with ConnectivityService.
@@ -3218,20 +3214,8 @@ public class ConnectivityManager {
            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
            android.Manifest.permission.NETWORK_FACTORY})
    public Network registerNetworkAgent(INetworkAgent na, NetworkInfo ni, LinkProperties lp,
            NetworkCapabilities nc, int score, NetworkAgentConfig config) {
        return registerNetworkAgent(na, ni, lp, nc, score, config, NetworkProvider.ID_NONE);
    }

    /**
     * @hide
     * Register a NetworkAgent with ConnectivityService.
     * @return Network corresponding to NetworkAgent.
     */
    @RequiresPermission(anyOf = {
            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
            android.Manifest.permission.NETWORK_FACTORY})
    public Network registerNetworkAgent(INetworkAgent na, NetworkInfo ni, LinkProperties lp,
            NetworkCapabilities nc, int score, NetworkAgentConfig config, int providerId) {
            NetworkCapabilities nc, @NonNull NetworkScore score, NetworkAgentConfig config,
            int providerId) {
        try {
            return mService.registerNetworkAgent(na, ni, lp, nc, score, config, providerId);
        } catch (RemoteException e) {
+2 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.NetworkScore;
import android.net.NetworkState;
import android.net.NetworkStateSnapshot;
import android.net.OemNetworkPreferences;
@@ -138,7 +139,7 @@ interface IConnectivityManager
    void declareNetworkRequestUnfulfillable(in NetworkRequest request);

    Network registerNetworkAgent(in INetworkAgent na, in NetworkInfo ni, in LinkProperties lp,
            in NetworkCapabilities nc, int score, in NetworkAgentConfig config,
            in NetworkCapabilities nc, in NetworkScore score, in NetworkAgentConfig config,
            in int factorySerialNumber);

    NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, int reqType,
+31 −11
Original line number Diff line number Diff line
@@ -371,6 +371,14 @@ public abstract class NetworkAgent {
        return ni;
    }

    // Temporary backward compatibility constructor
    public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag,
            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
            @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) {
        this(context, looper, logTag, nc, lp,
                new NetworkScore.Builder().setLegacyInt(score).build(), config, provider);
    }

    /**
     * Create a new network agent.
     * @param context a {@link Context} to get system services from.
@@ -382,10 +390,12 @@ public abstract class NetworkAgent {
     * @param score the initial score of this network. Update with sendNetworkScore.
     * @param config an immutable {@link NetworkAgentConfig} for this agent.
     * @param provider the {@link NetworkProvider} managing this agent.
     * @hide TODO : unhide when impl is complete
     */
    public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag,
            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
            @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) {
            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp,
            @NonNull NetworkScore score, @NonNull NetworkAgentConfig config,
            @Nullable NetworkProvider provider) {
        this(looper, context, logTag, nc, lp, score, config,
                provider == null ? NetworkProvider.ID_NONE : provider.getProviderId(),
                getLegacyNetworkInfo(config));
@@ -395,12 +405,12 @@ public abstract class NetworkAgent {
        public final Context context;
        public final NetworkCapabilities capabilities;
        public final LinkProperties properties;
        public final int score;
        public final NetworkScore score;
        public final NetworkAgentConfig config;
        public final NetworkInfo info;
        InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities,
                @NonNull LinkProperties properties, int score, @NonNull NetworkAgentConfig config,
                @NonNull NetworkInfo info) {
                @NonNull LinkProperties properties, @NonNull NetworkScore score,
                @NonNull NetworkAgentConfig config, @NonNull NetworkInfo info) {
            this.context = context;
            this.capabilities = capabilities;
            this.properties = properties;
@@ -412,8 +422,9 @@ public abstract class NetworkAgent {
    private volatile InitialConfiguration mInitialConfiguration;

    private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag,
            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
            @NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni) {
            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp,
            @NonNull NetworkScore score, @NonNull NetworkAgentConfig config, int providerId,
            @NonNull NetworkInfo ni) {
        mHandler = new NetworkAgentHandler(looper);
        LOG_TAG = logTag;
        mNetworkInfo = new NetworkInfo(ni);
@@ -872,16 +883,25 @@ public abstract class NetworkAgent {
        queueOrSendMessage(reg -> reg.sendNetworkCapabilities(nc));
    }

    /**
     * Must be called by the agent to update the score of this network.
     *
     * @param score the new score.
     * @hide TODO : unhide when impl is complete
     */
    public final void sendNetworkScore(@NonNull NetworkScore score) {
        Objects.requireNonNull(score);
        queueOrSendMessage(reg -> reg.sendScore(score));
    }

    /**
     * Must be called by the agent to update the score of this network.
     *
     * @param score the new score, between 0 and 99.
     * deprecated use sendNetworkScore(NetworkScore) TODO : remove in S.
     */
    public final void sendNetworkScore(@IntRange(from = 0, to = 99) int score) {
        if (score < 0) {
            throw new IllegalArgumentException("Score must be >= 0");
        }
        queueOrSendMessage(reg -> reg.sendScore(score));
        sendNetworkScore(new NetworkScore.Builder().setLegacyInt(score).build());
    }

    /**
Loading