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

Commit cdd02c5d authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Collect and persist tethering stats.

Use new "gettetherstats" netd command to retrieve statistics for
active tethering connections.  Keep tethering poll events separate
from UID poll, even though they end up same historical structures.

Bug: 5244846
Change-Id: Ia0c5165f6712c12b51586f86c331a2aad4ad6afb
parent f79ec360
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -83,6 +83,12 @@ interface IConnectivityManager

    String[] getTetheredIfaces();

    /**
     * Return list of interface pairs that are actively tethered.  Even indexes are
     * remote interface, and odd indexes are corresponding local interfaces.
     */
    String[] getTetheredIfacePairs();

    String[] getTetheringErroredIfaces();

    String[] getTetherableUsbRegexs();
+15 −3
Original line number Diff line number Diff line
@@ -52,26 +52,34 @@ public class TrafficStats {
     */
    public static final int UID_REMOVED = -4;

    /**
     * Special UID value used when collecting {@link NetworkStatsHistory} for
     * tethering traffic.
     *
     * @hide
     */
    public static final int UID_TETHERING = -5;

    /**
     * Default tag value for {@link DownloadManager} traffic.
     *
     * @hide
     */
    public static final int TAG_SYSTEM_DOWNLOAD = 0xFFFF0001;
    public static final int TAG_SYSTEM_DOWNLOAD = 0xFFFFFF01;

    /**
     * Default tag value for {@link MediaPlayer} traffic.
     *
     * @hide
     */
    public static final int TAG_SYSTEM_MEDIA = 0xFFFF0002;
    public static final int TAG_SYSTEM_MEDIA = 0xFFFFFF02;

    /**
     * Default tag value for {@link BackupManager} traffic.
     *
     * @hide
     */
    public static final int TAG_SYSTEM_BACKUP = 0xFFFF0003;
    public static final int TAG_SYSTEM_BACKUP = 0xFFFFFF03;

    /**
     * Snapshot of {@link NetworkStats} when the currently active profiling
@@ -90,6 +98,10 @@ public class TrafficStats {
     * <p>
     * Changes only take effect during subsequent calls to
     * {@link #tagSocket(Socket)}.
     * <p>
     * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and
     * used internally by system services like {@link DownloadManager} when
     * performing traffic on behalf of an application.
     */
    public static void setThreadStatsTag(int tag) {
        NetworkManagementSocketTagger.setThreadSocketStatsTag(tag);
+7 −0
Original line number Diff line number Diff line
@@ -230,6 +230,13 @@ interface INetworkManagementService
     */
    NetworkStats getNetworkStatsUidDetail(int uid);

    /**
     * Return summary of network statistics for the requested pairs of
     * tethering interfaces.  Even indexes are remote interface, and odd
     * indexes are corresponding local interfaces.
     */
    NetworkStats getNetworkStatsTethering(in String[] ifacePairs);

    /**
     * Set quota for an interface.
     */
+6 −0
Original line number Diff line number Diff line
@@ -2394,6 +2394,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
        return mTethering.getTetheredIfaces();
    }

    @Override
    public String[] getTetheredIfacePairs() {
        enforceTetherAccessPermission();
        return mTethering.getTetheredIfacePairs();
    }

    public String[] getTetheringErroredIfaces() {
        enforceTetherAccessPermission();
        return mTethering.getErroredIfaces();
+69 −0
Original line number Diff line number Diff line
@@ -123,6 +123,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub
        public static final int InterfaceTxCounterResult  = 217;
        public static final int InterfaceRxThrottleResult = 218;
        public static final int InterfaceTxThrottleResult = 219;
        public static final int QuotaCounterResult        = 220;
        public static final int TetheringStatsResult      = 221;

        public static final int InterfaceChange           = 600;
        public static final int BandwidthControl          = 601;
@@ -1443,6 +1445,73 @@ public class NetworkManagementService extends INetworkManagementService.Stub
        return stats;
    }

    @Override
    public NetworkStats getNetworkStatsTethering(String[] ifacePairs) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");

        if (ifacePairs.length % 2 != 0) {
            throw new IllegalArgumentException(
                    "unexpected ifacePairs; length=" + ifacePairs.length);
        }

        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
        for (int i = 0; i < ifacePairs.length; i += 2) {
            final String ifaceIn = ifacePairs[i];
            final String ifaceOut = ifacePairs[i + 1];
            if (ifaceIn != null && ifaceOut != null) {
                stats.combineValues(getNetworkStatsTethering(ifaceIn, ifaceOut));
            }
        }
        return stats;
    }

    private NetworkStats.Entry getNetworkStatsTethering(String ifaceIn, String ifaceOut) {
        final StringBuilder command = new StringBuilder();
        command.append("bandwidth gettetherstats ").append(ifaceIn).append(" ").append(ifaceOut);

        final String rsp;
        try {
            rsp = mConnector.doCommand(command.toString()).get(0);
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException("Error communicating to native daemon", e);
        }

        final String[] tok = rsp.split(" ");
        /* Expecting: "code ifaceIn ifaceOut rx_bytes rx_packets tx_bytes tx_packets" */
        if (tok.length != 7) {
            throw new IllegalStateException("Native daemon returned unexpected result: " + rsp);
        }

        final int code;
        try {
            code = Integer.parseInt(tok[0]);
        } catch (NumberFormatException e) {
            throw new IllegalStateException(
                    "Failed to parse native daemon return code for " + ifaceIn + " " + ifaceOut);
        }
        if (code != NetdResponseCode.TetheringStatsResult) {
            throw new IllegalStateException(
                    "Unexpected return code from native daemon for " + ifaceIn + " " + ifaceOut);
        }

        try {
            final NetworkStats.Entry entry = new NetworkStats.Entry();
            entry.iface = ifaceIn;
            entry.uid = UID_ALL;
            entry.set = SET_DEFAULT;
            entry.tag = TAG_NONE;
            entry.rxBytes = Long.parseLong(tok[3]);
            entry.rxPackets = Long.parseLong(tok[4]);
            entry.txBytes = Long.parseLong(tok[5]);
            entry.txPackets = Long.parseLong(tok[6]);
            return entry;
        } catch (NumberFormatException e) {
            throw new IllegalStateException(
                    "problem parsing tethering stats for " + ifaceIn + " " + ifaceOut + ": " + e);
        }
    }

    public void setInterfaceThrottle(String iface, int rxKbps, int txKbps) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
Loading