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

Commit 6973634c authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Direct notification of network interface changes.

Connectivity broadcasts recently changed and are no longer sent for
certain types of network changes.  For example, when stacked network
interfaces change for a mobile network.  To ensure that we pick up
all these details, directly wire the two services together.

Also remove some unused code for split network types.

Bug: 18666753
Change-Id: I0467bd5b330c0e0cb51af2306d821b41ad16337a
parent 3256601f
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -40,8 +40,12 @@ interface INetworkStatsService {


    /** Mark given UID as being in foreground for stats purposes. */
    /** Mark given UID as being in foreground for stats purposes. */
    void setUidForeground(int uid, boolean uidForeground);
    void setUidForeground(int uid, boolean uidForeground);

    /** Force update of ifaces. */
    void forceUpdateIfaces();
    /** Force update of statistics. */
    /** Force update of statistics. */
    void forceUpdate();
    void forceUpdate();

    /** Advise persistance threshold; may be overridden internally. */
    /** Advise persistance threshold; may be overridden internally. */
    void advisePersistThreshold(long thresholdBytes);
    void advisePersistThreshold(long thresholdBytes);


+4 −0
Original line number Original line Diff line number Diff line
@@ -41,7 +41,11 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
    /**
    /**
     * When enabled, combine all {@link #mSubType} together under
     * When enabled, combine all {@link #mSubType} together under
     * {@link #SUBTYPE_COMBINED}.
     * {@link #SUBTYPE_COMBINED}.
     *
     * @deprecated we no longer offer to collect statistics on a per-subtype
     *             basis; this is always disabled.
     */
     */
    @Deprecated
    public static final boolean COMBINE_SUBTYPE_ENABLED = true;
    public static final boolean COMBINE_SUBTYPE_ENABLED = true;


    public static final int SUBTYPE_COMBINED = -1;
    public static final int SUBTYPE_COMBINED = -1;
+4 −0
Original line number Original line Diff line number Diff line
@@ -49,7 +49,9 @@ import java.util.Objects;
public class NetworkTemplate implements Parcelable {
public class NetworkTemplate implements Parcelable {


    public static final int MATCH_MOBILE_ALL = 1;
    public static final int MATCH_MOBILE_ALL = 1;
    @Deprecated
    public static final int MATCH_MOBILE_3G_LOWER = 2;
    public static final int MATCH_MOBILE_3G_LOWER = 2;
    @Deprecated
    public static final int MATCH_MOBILE_4G = 3;
    public static final int MATCH_MOBILE_4G = 3;
    public static final int MATCH_WIFI = 4;
    public static final int MATCH_WIFI = 4;
    public static final int MATCH_ETHERNET = 5;
    public static final int MATCH_ETHERNET = 5;
@@ -293,6 +295,7 @@ public class NetworkTemplate implements Parcelable {
    /**
    /**
     * Check if mobile network classified 3G or lower with matching IMSI.
     * Check if mobile network classified 3G or lower with matching IMSI.
     */
     */
    @Deprecated
    private boolean matchesMobile3gLower(NetworkIdentity ident) {
    private boolean matchesMobile3gLower(NetworkIdentity ident) {
        ensureSubtypeAvailable();
        ensureSubtypeAvailable();
        if (ident.mType == TYPE_WIMAX) {
        if (ident.mType == TYPE_WIMAX) {
@@ -311,6 +314,7 @@ public class NetworkTemplate implements Parcelable {
    /**
    /**
     * Check if mobile network classified 4G with matching IMSI.
     * Check if mobile network classified 4G with matching IMSI.
     */
     */
    @Deprecated
    private boolean matchesMobile4g(NetworkIdentity ident) {
    private boolean matchesMobile4g(NetworkIdentity ident) {
        ensureSubtypeAvailable();
        ensureSubtypeAvailable();
        if (ident.mType == TYPE_WIMAX) {
        if (ident.mType == TYPE_WIMAX) {
+15 −0
Original line number Original line Diff line number Diff line
@@ -231,6 +231,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
    private static ConnectivityService sServiceInstance;
    private static ConnectivityService sServiceInstance;


    private INetworkManagementService mNetd;
    private INetworkManagementService mNetd;
    private INetworkStatsService mStatsService;
    private INetworkPolicyManager mPolicyManager;
    private INetworkPolicyManager mPolicyManager;


    private String mCurrentTcpBufferSizes;
    private String mCurrentTcpBufferSizes;
@@ -630,6 +631,7 @@ public class ConnectivityService extends IConnectivityManager.Stub


        mContext = checkNotNull(context, "missing Context");
        mContext = checkNotNull(context, "missing Context");
        mNetd = checkNotNull(netManager, "missing INetworkManagementService");
        mNetd = checkNotNull(netManager, "missing INetworkManagementService");
        mStatsService = checkNotNull(statsService, "missing INetworkStatsService");
        mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
        mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
        mKeyStore = KeyStore.getInstance();
        mKeyStore = KeyStore.getInstance();
        mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
@@ -2166,6 +2168,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
            if (isDefaultNetwork(nai)) {
            if (isDefaultNetwork(nai)) {
                mDefaultInetConditionPublished = 0;
                mDefaultInetConditionPublished = 0;
            }
            }
            notifyIfacesChanged();
            notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
            notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
            nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
            nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
            mNetworkAgentInfos.remove(msg.replyTo);
            mNetworkAgentInfos.remove(msg.replyTo);
@@ -3660,6 +3663,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        if (isDefaultNetwork(networkAgent)) handleApplyDefaultProxy(newLp.getHttpProxy());
        if (isDefaultNetwork(networkAgent)) handleApplyDefaultProxy(newLp.getHttpProxy());
        // TODO - move this check to cover the whole function
        // TODO - move this check to cover the whole function
        if (!Objects.equals(newLp, oldLp)) {
        if (!Objects.equals(newLp, oldLp)) {
            notifyIfacesChanged();
            notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
            notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
        }
        }
    }
    }
@@ -4250,6 +4254,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
            }
            }
            networkAgent.created = true;
            networkAgent.created = true;
            updateLinkProperties(networkAgent, null);
            updateLinkProperties(networkAgent, null);
            notifyIfacesChanged();
            notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
            notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
            networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
            networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
            if (networkAgent.isVPN()) {
            if (networkAgent.isVPN()) {
@@ -4393,6 +4398,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
        return "UNKNOWN";
        return "UNKNOWN";
    }
    }


    /**
     * Notify other system services that set of active ifaces has changed.
     */
    private void notifyIfacesChanged() {
        try {
            mStatsService.forceUpdateIfaces();
        } catch (Exception ignored) {
        }
    }

    @Override
    @Override
    public boolean addVpnAddress(String address, int prefixLength) {
    public boolean addVpnAddress(String address, int prefixLength) {
        throwIfLockdownEnabled();
        throwIfLockdownEnabled();
+13 −63
Original line number Original line Diff line number Diff line
@@ -26,9 +26,7 @@ import static android.content.Intent.ACTION_UID_REMOVED;
import static android.content.Intent.ACTION_USER_REMOVED;
import static android.content.Intent.ACTION_USER_REMOVED;
import static android.content.Intent.EXTRA_UID;
import static android.content.Intent.EXTRA_UID;
import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
import static android.net.ConnectivityManager.isNetworkTypeMobile;
import static android.net.ConnectivityManager.isNetworkTypeMobile;
import static android.net.NetworkIdentity.COMBINE_SUBTYPE_ENABLED;
import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.SET_DEFAULT;
@@ -55,8 +53,6 @@ import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
import static android.telephony.PhoneStateListener.LISTEN_DATA_CONNECTION_STATE;
import static android.telephony.PhoneStateListener.LISTEN_NONE;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -102,7 +98,6 @@ import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Settings.Global;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;
import android.text.format.DateUtils;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArrayMap;
@@ -308,10 +303,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
            bootstrapStatsLocked();
            bootstrapStatsLocked();
        }
        }


        // watch for network interfaces to be claimed
        final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION_IMMEDIATE);
        mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);

        // watch for tethering changes
        // watch for tethering changes
        final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
        final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
        mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
        mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
@@ -338,12 +329,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
            // ignored; service lives in system_server
            // ignored; service lives in system_server
        }
        }


        // watch for networkType changes that aren't broadcast through
        // CONNECTIVITY_ACTION_IMMEDIATE above.
        if (!COMBINE_SUBTYPE_ENABLED) {
            mTeleManager.listen(mPhoneListener, LISTEN_DATA_CONNECTION_STATE);
        }

        registerPollAlarmLocked();
        registerPollAlarmLocked();
        registerGlobalAlert();
        registerGlobalAlert();
    }
    }
@@ -358,16 +343,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
    }
    }


    private void shutdownLocked() {
    private void shutdownLocked() {
        mContext.unregisterReceiver(mConnReceiver);
        mContext.unregisterReceiver(mTetherReceiver);
        mContext.unregisterReceiver(mTetherReceiver);
        mContext.unregisterReceiver(mPollReceiver);
        mContext.unregisterReceiver(mPollReceiver);
        mContext.unregisterReceiver(mRemovedReceiver);
        mContext.unregisterReceiver(mRemovedReceiver);
        mContext.unregisterReceiver(mShutdownReceiver);
        mContext.unregisterReceiver(mShutdownReceiver);


        if (!COMBINE_SUBTYPE_ENABLED) {
            mTeleManager.listen(mPhoneListener, LISTEN_NONE);
        }

        final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
        final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
                : System.currentTimeMillis();
                : System.currentTimeMillis();


@@ -619,6 +599,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        }
        }
    }
    }


    @Override
    public void forceUpdateIfaces() {
        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
        assertBandwidthControlEnabled();

        final long token = Binder.clearCallingIdentity();
        try {
            updateIfaces();
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    @Override
    @Override
    public void forceUpdate() {
    public void forceUpdate() {
        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
@@ -675,20 +668,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
        mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
    }
    }


    /**
     * Receiver that watches for {@link IConnectivityManager} to claim network
     * interfaces. Used to associate {@link TelephonyManager#getSubscriberId()}
     * with mobile interfaces.
     */
    private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // on background handler thread, and verified CONNECTIVITY_INTERNAL
            // permission above.
            updateIfaces();
        }
    };

    /**
    /**
     * Receiver that watches for {@link Tethering} to claim interface pairs.
     * Receiver that watches for {@link Tethering} to claim interface pairs.
     */
     */
@@ -784,35 +763,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        }
        }
    };
    };


    private int mLastPhoneState = TelephonyManager.DATA_UNKNOWN;
    private int mLastPhoneNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;

    /**
     * Receiver that watches for {@link TelephonyManager} changes, such as
     * transitioning between network types.
     */
    private PhoneStateListener mPhoneListener = new PhoneStateListener() {
        @Override
        public void onDataConnectionStateChanged(int state, int networkType) {
            final boolean stateChanged = state != mLastPhoneState;
            final boolean networkTypeChanged = networkType != mLastPhoneNetworkType;

            if (networkTypeChanged && !stateChanged) {
                // networkType changed without a state change, which means we
                // need to roll our own update. delay long enough for
                // ConnectivityManager to process.
                // TODO: add direct event to ConnectivityService instead of
                // relying on this delay.
                if (LOGV) Slog.v(TAG, "triggering delayed updateIfaces()");
                mHandler.sendMessageDelayed(
                        mHandler.obtainMessage(MSG_UPDATE_IFACES), SECOND_IN_MILLIS);
            }

            mLastPhoneState = state;
            mLastPhoneNetworkType = networkType;
        }
    };

    private void updateIfaces() {
    private void updateIfaces() {
        synchronized (mStatsLock) {
        synchronized (mStatsLock) {
            mWakeLock.acquire();
            mWakeLock.acquire();