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

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

Merge changes from topic "ms65-identity" am: 3e389629 am: af3d521d am:...

Merge changes from topic "ms65-identity" am: 3e389629 am: af3d521d am: 2e39612b am: 7b7fcd3e

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

Change-Id: Ib449635e1b121fde7c97f0d668b6f9ce92d8c3eb
parents b1a51112 7b7fcd3e
Loading
Loading
Loading
Loading
+230 −29
Original line number Diff line number Diff line
@@ -19,8 +19,10 @@ package android.net;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.service.NetworkIdentityProto;
@@ -31,6 +33,8 @@ import android.util.proto.ProtoOutputStream;
import com.android.net.module.util.NetworkCapabilitiesUtils;
import com.android.net.module.util.NetworkIdentityUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Objects;

@@ -49,6 +53,15 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
    //  {@link NetworkTemplate#NETWORK_TYPE_ALL} instead.
    public static final int SUBTYPE_COMBINED = -1;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "OEM_MANAGED_" }, value = {
            NetworkTemplate.OEM_MANAGED_NO,
            NetworkTemplate.OEM_MANAGED_PAID,
            NetworkTemplate.OEM_MANAGED_PRIVATE
    })
    public @interface OemManaged{}

    /**
     * Network has no {@code NetworkCapabilities#NET_CAPABILITY_OEM_*}.
     * @hide
@@ -177,42 +190,62 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
        proto.end(start);
    }

    /** @hide */
    /** Get the network type of this instance. */
    public int getType() {
        return mType;
    }

    /** @hide */
    /** Get the Radio Access Technology(RAT) type of this instance. */
    public int getRatType() {
        return mRatType;
    }

    /** @hide */
    /** Get the Subscriber Id of this instance. */
    @Nullable
    public String getSubscriberId() {
        return mSubscriberId;
    }

    /** @hide */
    /** Get the Wifi Network Key of this instance. See {@link WifiInfo#getCurrentNetworkKey()}. */
    @Nullable
    public String getWifiNetworkKey() {
        return mWifiNetworkKey;
    }

    /** @hide */
    // TODO: Remove this function after all callers are removed.
    public boolean getRoaming() {
        return mRoaming;
    }

    /** Return the roaming status of this instance. */
    public boolean isRoaming() {
        return mRoaming;
    }

    /** @hide */
    // TODO: Remove this function after all callers are removed.
    public boolean getMetered() {
        return mMetered;
    }

    /** Return the meteredness of this instance. */
    public boolean isMetered() {
        return mMetered;
    }

    /** @hide */
    // TODO: Remove this function after all callers are removed.
    public boolean getDefaultNetwork() {
        return mDefaultNetwork;
    }

    /** @hide */
    /** Return the default network status of this instance. */
    public boolean isDefaultNetwork() {
        return mDefaultNetwork;
    }

    /** Get the OEM managed type of this instance. */
    public int getOemManaged() {
        return mOemManaged;
    }
@@ -229,36 +262,16 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
     *                {@link TelephonyManager#NETWORK_TYPE_UNKNOWN} if not applicable.
     *                See {@code TelephonyManager.NETWORK_TYPE_*}.
     * @hide
     * @deprecated See {@link NetworkIdentity#Builder}.
     */
    // TODO: Remove this after all callers are migrated to use new Api.
    @Deprecated
    @NonNull
    public static NetworkIdentity buildNetworkIdentity(Context context,
            @NonNull NetworkStateSnapshot snapshot,
            boolean defaultNetwork, @Annotation.NetworkType int ratType) {
        final int legacyType = snapshot.getLegacyType();

        final String subscriberId = snapshot.getSubscriberId();
        String wifiNetworkKey = null;
        boolean roaming = !snapshot.getNetworkCapabilities().hasCapability(
                NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
        boolean metered = !(snapshot.getNetworkCapabilities().hasCapability(
                NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
                || snapshot.getNetworkCapabilities().hasCapability(
                NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED));

        final int oemManaged = getOemBitfield(snapshot.getNetworkCapabilities());

        if (legacyType == TYPE_WIFI) {
            final TransportInfo transportInfo = snapshot.getNetworkCapabilities()
                    .getTransportInfo();
            if (transportInfo instanceof WifiInfo) {
                final WifiInfo info = (WifiInfo) transportInfo;
                wifiNetworkKey = info != null ? info.getCurrentNetworkKey() : null;
            }
        }

        return new NetworkIdentity(legacyType, ratType, subscriberId, wifiNetworkKey, roaming,
                metered, defaultNetwork, oemManaged);
        return new NetworkIdentity.Builder().setNetworkStateSnapshot(snapshot)
                .setDefaultNetwork(defaultNetwork).setRatType(ratType).build();
    }

    /**
@@ -305,4 +318,192 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
        }
        return res;
    }

    /**
     * Builder class for {@link NetworkIdentity}.
     */
    public static final class Builder {
        private int mType;
        private int mRatType;
        private String mSubscriberId;
        private String mWifiNetworkKey;
        private boolean mRoaming;
        private boolean mMetered;
        private boolean mDefaultNetwork;
        private int mOemManaged;

        /**
         * Creates a new Builder.
         */
        public Builder() {
            // Initialize with default values. Will be overwritten by setters.
            mType = ConnectivityManager.TYPE_NONE;
            mRatType = NetworkTemplate.NETWORK_TYPE_ALL;
            mSubscriberId = null;
            mWifiNetworkKey = null;
            mRoaming = false;
            mMetered = false;
            mDefaultNetwork = false;
            mOemManaged = NetworkTemplate.OEM_MANAGED_NO;
        }

        /**
         * Add an {@link NetworkStateSnapshot} into the {@link NetworkIdentity} instance.
         * This is to read roaming, metered, wifikey... from the snapshot for convenience.
         *
         * @param snapshot The target {@link NetworkStateSnapshot} object.
         * @return The builder object.
         */
        @SuppressLint("MissingGetterMatchingBuilder")
        @NonNull
        public Builder setNetworkStateSnapshot(@NonNull NetworkStateSnapshot snapshot) {
            setType(snapshot.getLegacyType());

            setSubscriberId(snapshot.getSubscriberId());
            setRoaming(!snapshot.getNetworkCapabilities().hasCapability(
                    NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING));
            setMetered(!(snapshot.getNetworkCapabilities().hasCapability(
                    NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
                    || snapshot.getNetworkCapabilities().hasCapability(
                    NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)));

            setOemManaged(getOemBitfield(snapshot.getNetworkCapabilities()));

            if (mType == TYPE_WIFI) {
                final TransportInfo transportInfo = snapshot.getNetworkCapabilities()
                        .getTransportInfo();
                if (transportInfo instanceof WifiInfo) {
                    final WifiInfo info = (WifiInfo) transportInfo;
                    if (info != null) {
                        setWifiNetworkKey(info.getCurrentNetworkKey());
                    }
                }
            }
            return this;
        }

        /**
         * Set the network type of the network.
         *
         * @param type the network type. See {@link ConnectivityManager#TYPE_*}.
         *
         * @return this builder.
         */
        @NonNull
        public Builder setType(int type) {
            mType = type;
            return this;
        }

        /**
         * Set the Radio Access Technology(RAT) type of the network.
         *
         * @param ratType the Radio Access Technology(RAT) type if applicable. See
         *                {@code TelephonyManager.NETWORK_TYPE_*}.
         *
         * @return this builder.
         */
        @NonNull
        public Builder setRatType(@Annotation.NetworkType int ratType) {
            mRatType = ratType;
            return this;
        }

        /**
         * Clear the Radio Access Technology(RAT) type of the network.
         *
         * @return this builder.
         */
        @NonNull
        public Builder clearRatType() {
            mRatType = NetworkTemplate.NETWORK_TYPE_ALL;
            return this;
        }

        /**
         * Set the Subscriber Id.
         *
         * @param subscriberId the Subscriber Id of the network. Or null if not applicable.
         * @return this builder.
         */
        @NonNull
        public Builder setSubscriberId(@Nullable String subscriberId) {
            mSubscriberId = subscriberId;
            return this;
        }

        /**
         * Set the Wifi Network Key.
         *
         * @param wifiNetworkKey Wifi Network Key of the network,
         *                        see {@link WifiInfo#getCurrentNetworkKey()}.
         *                        Or null if not applicable.
         * @return this builder.
         */
        @NonNull
        public Builder setWifiNetworkKey(@Nullable String wifiNetworkKey) {
            mWifiNetworkKey = wifiNetworkKey;
            return this;
        }

        /**
         * Set the roaming.
         *
         * @param roaming the roaming status of the network.
         * @return this builder.
         */
        @NonNull
        public Builder setRoaming(boolean roaming) {
            mRoaming = roaming;
            return this;
        }

        /**
         * Set the meteredness.
         *
         * @param metered the meteredness of the network.
         * @return this builder.
         */
        @NonNull
        public Builder setMetered(boolean metered) {
            mMetered = metered;
            return this;
        }

        /**
         * Set the default network status.
         *
         * @param defaultNetwork the default network status of the network.
         * @return this builder.
         */
        @NonNull
        public Builder setDefaultNetwork(boolean defaultNetwork) {
            mDefaultNetwork = defaultNetwork;
            return this;
        }

        /**
         * Set the OEM managed type.
         *
         * @param oemManaged Type of OEM managed network or unmanaged networks.
         *                   See {@code NetworkTemplate#OEM_MANAGED_*}.
         * @return this builder.
         */
        @NonNull
        public Builder setOemManaged(@OemManaged int oemManaged) {
            mOemManaged = oemManaged;
            return this;
        }

        /**
         * Builds the instance of the {@link NetworkIdentity}.
         *
         * @return the built instance of {@link NetworkIdentity}.
         */
        @NonNull
        public NetworkIdentity build() {
            return new NetworkIdentity(mType, mRatType, mSubscriberId, mWifiNetworkKey,
                    mRoaming, mMetered, mDefaultNetwork, mOemManaged);
        }
    }
}
+6 −6
Original line number Diff line number Diff line
@@ -116,9 +116,9 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
            out.writeInt(ident.getRatType());
            writeOptionalString(out, ident.getSubscriberId());
            writeOptionalString(out, ident.getWifiNetworkKey());
            out.writeBoolean(ident.getRoaming());
            out.writeBoolean(ident.getMetered());
            out.writeBoolean(ident.getDefaultNetwork());
            out.writeBoolean(ident.isRoaming());
            out.writeBoolean(ident.isMetered());
            out.writeBoolean(ident.isDefaultNetwork());
            out.writeInt(ident.getOemManaged());
        }
    }
@@ -132,7 +132,7 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
            return false;
        }
        for (NetworkIdentity ident : this) {
            if (ident.getMetered()) {
            if (ident.isMetered()) {
                return true;
            }
        }
@@ -148,7 +148,7 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
            return false;
        }
        for (NetworkIdentity ident : this) {
            if (ident.getRoaming()) {
            if (ident.isRoaming()) {
                return true;
            }
        }
@@ -165,7 +165,7 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
            return true;
        }
        for (NetworkIdentity ident : this) {
            if (!ident.getDefaultNetwork()) {
            if (!ident.isDefaultNetwork()) {
                return false;
            }
        }
+2 −2
Original line number Diff line number Diff line
@@ -1402,12 +1402,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
                // VT is considered always metered in framework's layer. If VT is not metered
                // per carrier's policy, modem will report 0 usage for VT calls.
                if (snapshot.getNetworkCapabilities().hasCapability(
                        NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
                        NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.isMetered()) {

                    // Copy the identify from IMS one but mark it as metered.
                    NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
                            ident.getRatType(), ident.getSubscriberId(), ident.getWifiNetworkKey(),
                            ident.getRoaming(), true /* metered */,
                            ident.isRoaming(), true /* metered */,
                            true /* onDefaultNetwork */, ident.getOemManaged());
                    final String ifaceVt = IFACE_VT + getSubIdForMobile(snapshot);
                    findOrCreateNetworkIdentitySet(mActiveIfaces, ifaceVt).add(vtIdent);
+37 −25
Original line number Diff line number Diff line
@@ -16,23 +16,16 @@

package com.android.settingslib.net;

import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;

import android.annotation.NonNull;
import android.app.usage.NetworkStats;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
import android.net.INetworkStatsService;
import android.net.INetworkStatsSession;
import android.net.NetworkPolicy;
import android.net.NetworkPolicyManager;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.net.TrafficStats;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.format.DateUtils;
import android.util.Pair;
import android.util.Range;

import androidx.annotation.VisibleForTesting;
import androidx.loader.content.AsyncTaskLoader;
@@ -52,8 +45,6 @@ public abstract class NetworkCycleDataLoader<D> extends AsyncTaskLoader<D> {
    protected final NetworkTemplate mNetworkTemplate;
    private final NetworkPolicy mPolicy;
    private final ArrayList<Long> mCycles;
    @VisibleForTesting
    final INetworkStatsService mNetworkStatsService;

    protected NetworkCycleDataLoader(Builder<?> builder) {
        super(builder.mContext);
@@ -61,8 +52,6 @@ public abstract class NetworkCycleDataLoader<D> extends AsyncTaskLoader<D> {
        mCycles = builder.mCycles;
        mNetworkStatsManager = (NetworkStatsManager)
            builder.mContext.getSystemService(Context.NETWORK_STATS_SERVICE);
        mNetworkStatsService = INetworkStatsService.Stub.asInterface(
            ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
        final NetworkPolicyEditor policyEditor =
            new NetworkPolicyEditor(NetworkPolicyManager.from(builder.mContext));
        policyEditor.read();
@@ -112,23 +101,20 @@ public abstract class NetworkCycleDataLoader<D> extends AsyncTaskLoader<D> {

    @VisibleForTesting
    void loadFourWeeksData() {
        if (mNetworkTemplate == null) return;
        final NetworkStats stats = mNetworkStatsManager.queryDetailsForDevice(
                mNetworkTemplate, Long.MIN_VALUE, Long.MAX_VALUE);
        try {
            final INetworkStatsSession networkSession = mNetworkStatsService.openSession();
            final NetworkStatsHistory networkHistory = networkSession.getHistoryForNetwork(
                mNetworkTemplate, FIELD_RX_BYTES | FIELD_TX_BYTES);
            final long historyStart = networkHistory.getStart();
            final long historyEnd = networkHistory.getEnd();

            long cycleEnd = historyEnd;
            while (cycleEnd > historyStart) {
            final Range<Long> historyTimeRange = getTimeRangeOf(stats);

            long cycleEnd = historyTimeRange.getUpper();
            while (cycleEnd > historyTimeRange.getLower()) {
                final long cycleStart = cycleEnd - (DateUtils.WEEK_IN_MILLIS * 4);
                recordUsage(cycleStart, cycleEnd);
                cycleEnd = cycleStart;
            }

            TrafficStats.closeQuietly(networkSession);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        } catch (IllegalArgumentException e) {
            // Empty history, ignore.
        }
    }

@@ -169,6 +155,32 @@ public abstract class NetworkCycleDataLoader<D> extends AsyncTaskLoader<D> {
        return bytes;
    }

    @NonNull
    @VisibleForTesting
    Range getTimeRangeOf(@NonNull NetworkStats stats) {
        long start = Long.MAX_VALUE;
        long end = Long.MIN_VALUE;
        while (hasNextBucket(stats)) {
            final NetworkStats.Bucket bucket = getNextBucket(stats);
            start = Math.min(start, bucket.getStartTimeStamp());
            end = Math.max(end, bucket.getEndTimeStamp());
        }
        return new Range(start, end);
    }

    @VisibleForTesting
    boolean hasNextBucket(@NonNull NetworkStats stats) {
        return stats.hasNextBucket();
    }

    @NonNull
    @VisibleForTesting
    NetworkStats.Bucket getNextBucket(@NonNull NetworkStats stats) {
        NetworkStats.Bucket bucket = new NetworkStats.Bucket();
        stats.getNextBucket(bucket);
        return bucket;
    }

    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
    public ArrayList<Long> getCycles() {
        return mCycles;
+57 −18
Original line number Diff line number Diff line
@@ -16,24 +16,24 @@

package com.android.settingslib.net;

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.nullable;
import static android.app.usage.NetworkStats.Bucket.UID_ALL;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.annotation.NonNull;
import android.app.usage.NetworkStats;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.INetworkStatsService;
import android.net.INetworkStatsSession;
import android.net.NetworkPolicy;
import android.net.NetworkPolicyManager;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.os.RemoteException;
import android.text.format.DateUtils;
import android.util.Range;

@@ -49,6 +49,8 @@ import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

@RunWith(RobolectricTestRunner.class)
public class NetworkCycleDataLoaderTest {
@@ -63,8 +65,6 @@ public class NetworkCycleDataLoaderTest {
    private NetworkPolicy mPolicy;
    @Mock
    private Iterator<Range<ZonedDateTime>> mIterator;
    @Mock
    private INetworkStatsService mNetworkStatsService;

    private NetworkCycleDataTestLoader mLoader;

@@ -132,20 +132,24 @@ public class NetworkCycleDataLoaderTest {
        verify(mLoader).recordUsage(nowInMs, nowInMs);
    }

    private NetworkStats.Bucket makeMockBucket(int uid, long rxBytes, long txBytes,
            long start, long end) {
        NetworkStats.Bucket ret = mock(NetworkStats.Bucket.class);
        when(ret.getUid()).thenReturn(uid);
        when(ret.getRxBytes()).thenReturn(rxBytes);
        when(ret.getTxBytes()).thenReturn(txBytes);
        when(ret.getStartTimeStamp()).thenReturn(start);
        when(ret.getEndTimeStamp()).thenReturn(end);
        return ret;
    }

    @Test
    public void loadFourWeeksData_shouldRecordUsageForLast4Weeks() throws RemoteException {
    public void loadFourWeeksData_shouldRecordUsageForLast4Weeks() {
        mLoader = spy(new NetworkCycleDataTestLoader(mContext));
        ReflectionHelpers.setField(mLoader, "mNetworkStatsService", mNetworkStatsService);
        final INetworkStatsSession networkSession = mock(INetworkStatsSession.class);
        when(mNetworkStatsService.openSession()).thenReturn(networkSession);
        final NetworkStatsHistory networkHistory = mock(NetworkStatsHistory.class);
        when(networkSession.getHistoryForNetwork(nullable(NetworkTemplate.class), anyInt()))
            .thenReturn(networkHistory);
        final long now = System.currentTimeMillis();
        final long fourWeeksAgo = now - (DateUtils.WEEK_IN_MILLIS * 4);
        final long twoDaysAgo = now - (DateUtils.DAY_IN_MILLIS * 2);
        when(networkHistory.getStart()).thenReturn(twoDaysAgo);
        when(networkHistory.getEnd()).thenReturn(now);
        mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, twoDaysAgo, now));

        mLoader.loadFourWeeksData();

@@ -173,10 +177,31 @@ public class NetworkCycleDataLoaderTest {
        verify(mLoader).recordUsage(thirtyDaysAgo, twentyDaysAgo);
    }

    @Test
    public void getTimeRangeOf() {
        mLoader = spy(new NetworkCycleDataTestLoader(mContext));
        // If empty, new Range(MAX_VALUE, MIN_VALUE) will be constructed. Hence, the function
        // should throw.
        assertThrows(IllegalArgumentException.class,
                () -> mLoader.getTimeRangeOf(mock(NetworkStats.class)));

        mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 0, 10));
        // Feed the function with unused NetworkStats. The actual data injection is
        // done by addBucket.
        assertEquals(new Range(0L, 10L), mLoader.getTimeRangeOf(mock(NetworkStats.class)));

        mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 0, 10));
        mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 30, 40));
        mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 10, 25));
        assertEquals(new Range(0L, 40L), mLoader.getTimeRangeOf(mock(NetworkStats.class)));
    }

    public class NetworkCycleDataTestLoader extends NetworkCycleDataLoader<List<NetworkCycleData>> {
        private final Queue<NetworkStats.Bucket> mMockedBuckets = new LinkedBlockingQueue<>();

        private NetworkCycleDataTestLoader(Context context) {
            super(NetworkCycleDataLoader.builder(mContext));
            super(NetworkCycleDataLoader.builder(mContext)
                    .setNetworkTemplate(mock(NetworkTemplate.class)));
            mContext = context;
        }

@@ -188,5 +213,19 @@ public class NetworkCycleDataLoaderTest {
        List<NetworkCycleData> getCycleUsage() {
            return null;
        }

        public void addBucket(NetworkStats.Bucket bucket) {
            mMockedBuckets.add(bucket);
        }

        @Override
        public boolean hasNextBucket(@NonNull NetworkStats unused) {
            return !mMockedBuckets.isEmpty();
        }

        @Override
        public NetworkStats.Bucket getNextBucket(@NonNull NetworkStats unused) {
            return mMockedBuckets.remove();
        }
    }
}