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

Commit f71ca8a5 authored by Haoyu Bai's avatar Haoyu Bai
Browse files

Setup idletimer for network interface.

Change-Id: I1251b60f4c3c31c75c2acd531495ca75bbb35ff5
parent db9d339d
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -322,6 +322,27 @@ interface INetworkManagementService
     */
    int getInterfaceTxThrottle(String iface);

    /**
     * Sets idletimer for an interface.
     *
     * This either initializes a new idletimer or increases its
     * reference-counting if an idletimer already exists for given
     * {@code iface}.
     *
     * {@code label} usually represents the network type of {@code iface}.
     * Caller should ensure that {@code label} for an {@code iface} remains the
     * same for all calls to addIdleTimer.
     *
     * Every {@code addIdleTimer} should be paired with a
     * {@link removeIdleTimer} to cleanup when the network disconnects.
     */
    void addIdleTimer(String iface, int timeout, String label);

    /**
     * Removes idletimer for an interface.
     */
    void removeIdleTimer(String iface);

    /**
     * Sets the name of the default interface in the DNS resolver.
     */
+23 −0
Original line number Diff line number Diff line
@@ -2845,6 +2845,29 @@ public final class Settings {
         */
        public static final String TETHER_DUN_APN = "tether_dun_apn";

        /** Inactivity timeout to track mobile data activity.
         *
         * If set to a positive integer, it indicates the inactivity timeout value in seconds to
         * infer the data activity of mobile network. After a period of no activity on mobile
         * networks with length specified by the timeout, an {@code ACTION_DATA_ACTIVITY_CHANGE}
         * intent is fired to indicate a transition of network status from "active" to "idle". Any
         * subsequent activity on mobile networks triggers the firing of {@code
         * ACTION_DATA_ACTIVITY_CHANGE} intent indicating transition from "idle" to "active".
         *
         * Network activity refers to transmitting or receiving data on the network interfaces.
         *
         * Tracking is disabled if set to zero or negative value.
         *
         * @hide
         */
        public static final String DATA_ACTIVITY_TIMEOUT_MOBILE = "data_activity_timeout_mobile";

        /** Timeout to tracking Wifi data activity. Same as {@code DATA_ACTIVITY_TIMEOUT_MOBILE}
         * but for Wifi network.
         * @hide
         */
        public static final String DATA_ACTIVITY_TIMEOUT_WIFI = "data_activity_timeout_wifi";

        /**
         * No longer supported.
         */
+59 −1
Original line number Diff line number Diff line
@@ -1593,6 +1593,10 @@ public class ConnectivityService extends IConnectivityManager.Stub {
        int prevNetType = info.getType();

        mNetTrackers[prevNetType].setTeardownRequested(false);

        // Remove idletimer previously setup in {@code handleConnect}
        removeDataActivityTracking(prevNetType);

        /*
         * If the disconnected network is not the active one, then don't report
         * this as a loss of connectivity. What probably happened is that we're
@@ -1869,10 +1873,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {

    private void handleConnect(NetworkInfo info) {
        final int type = info.getType();
        final NetworkStateTracker thisNet = mNetTrackers[type];

        setupDataActivityTracking(type);

        // snapshot isFailover, because sendConnectedBroadcast() resets it
        boolean isFailover = info.isFailover();
        final NetworkStateTracker thisNet = mNetTrackers[type];

        // if this is a default net and other default is running
        // kill the one not preferred
@@ -1941,6 +1947,58 @@ public class ConnectivityService extends IConnectivityManager.Stub {
        }
    }

    /**
     * Setup data activity tracking for the given network interface.
     *
     * Every {@code setupDataActivityTracking} should be paired with a
     * {@link removeDataActivityTracking} for cleanup.
     */
    private void setupDataActivityTracking(int type) {
        final NetworkStateTracker thisNet = mNetTrackers[type];
        final String iface = thisNet.getLinkProperties().getInterfaceName();

        final int timeout;

        if (ConnectivityManager.isNetworkTypeMobile(type)) {
            timeout = Settings.Secure.getInt(mContext.getContentResolver(),
                                             Settings.Secure.DATA_ACTIVITY_TIMEOUT_MOBILE,
                                             0);
            // Canonicalize mobile network type
            type = ConnectivityManager.TYPE_MOBILE;
        } else if (ConnectivityManager.TYPE_WIFI == type) {
            timeout = Settings.Secure.getInt(mContext.getContentResolver(),
                                             Settings.Secure.DATA_ACTIVITY_TIMEOUT_WIFI,
                                             0);
        } else {
            // do not track any other networks
            timeout = 0;
        }

        if (timeout > 0 && iface != null) {
            try {
                mNetd.addIdleTimer(iface, timeout, Integer.toString(type));
            } catch (RemoteException e) {
            }
        }
    }

    /**
     * Remove data activity tracking when network disconnects.
     */
    private void removeDataActivityTracking(int type) {
        final NetworkStateTracker net = mNetTrackers[type];
        final String iface = net.getLinkProperties().getInterfaceName();

        if (iface != null && (ConnectivityManager.isNetworkTypeMobile(type) ||
                              ConnectivityManager.TYPE_WIFI == type)) {
            try {
                // the call fails silently if no idletimer setup for this interface
                mNetd.removeIdleTimer(iface);
            } catch (RemoteException e) {
            }
        }
    }

    /**
     * After a change in the connectivity state of a network. We're mainly
     * concerned with making sure that the list of DNS servers is set up
+60 −0
Original line number Diff line number Diff line
@@ -153,6 +153,21 @@ public class NetworkManagementService extends INetworkManagementService.Stub
    /** Set of UIDs with active reject rules. */
    private SparseBooleanArray mUidRejectOnQuota = new SparseBooleanArray();

    private Object mIdleTimerLock = new Object();
    /** Set of interfaces with active idle timers. */
    private static class IdleTimerParams {
        public final int timeout;
        public final String label;
        public int networkCount;

        IdleTimerParams(int timeout, String label) {
            this.timeout = timeout;
            this.label = label;
            this.networkCount = 1;
        }
    }
    private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();

    private volatile boolean mBandwidthControlEnabled;

    /**
@@ -1046,6 +1061,51 @@ public class NetworkManagementService extends INetworkManagementService.Stub
        }
    }

    @Override
    public void addIdleTimer(String iface, int timeout, String label) {
        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);

        if (DBG) Slog.d(TAG, "Adding idletimer");

        synchronized (mIdleTimerLock) {
            IdleTimerParams params = mActiveIdleTimers.get(iface);
            if (params != null) {
                // the interface already has idletimer, update network count
                params.networkCount++;
                return;
            }

            try {
                mConnector.execute("idletimer", "add", iface, Integer.toString(timeout), label);
            } catch (NativeDaemonConnectorException e) {
                throw e.rethrowAsParcelableException();
            }
            mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, label));
        }
    }

    @Override
    public void removeIdleTimer(String iface) {
        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);

        if (DBG) Slog.d(TAG, "Removing idletimer");

        synchronized (mIdleTimerLock) {
            IdleTimerParams params = mActiveIdleTimers.get(iface);
            if (params == null || --(params.networkCount) > 0) {
                return;
            }

            try {
                mConnector.execute("idletimer", "remove", iface,
                        Integer.toString(params.timeout), params.label);
            } catch (NativeDaemonConnectorException e) {
                throw e.rethrowAsParcelableException();
            }
            mActiveIdleTimers.remove(iface);
        }
    }

    @Override
    public NetworkStats getNetworkStatsSummaryDev() {
        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);