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

Commit 73ed9d8d authored by Robert Greenwalt's avatar Robert Greenwalt
Browse files

Fix CS/NetworkMonitor race.

If we have a message in flight about a NetworkAgentInfo when it gets disconnected
we are left with a zombie network.  Fixes this by verifing the network is still
live before we process the msg.

bug:17142206
Change-Id: I2c94a39b3ea97c1562066571b277280c1f69f71c
parent 92973b8f
Loading
Loading
Loading
Loading
+27 −7
Original line number Diff line number Diff line
@@ -1733,6 +1733,19 @@ public class ConnectivityService extends IConnectivityManager.Stub {
        }
    }

    private boolean isLiveNetworkAgent(NetworkAgentInfo nai, String msg) {
        final NetworkAgentInfo officialNai;
        synchronized (mNetworkForNetId) {
            officialNai = mNetworkForNetId.get(nai.network.netId);
        }
        if (officialNai != null && officialNai.equals(nai)) return true;
        if (officialNai != null || VDBG) {
            loge(msg + " - validateNetworkAgent found mismatched netId: " + officialNai +
                " - " + nai);
        }
        return false;
    }

    // must be stateless - things change under us.
    private class NetworkStateTrackerHandler extends Handler {
        public NetworkStateTrackerHandler(Looper looper) {
@@ -1862,23 +1875,30 @@ public class ConnectivityService extends IConnectivityManager.Stub {
                }
                case NetworkMonitor.EVENT_NETWORK_VALIDATED: {
                    NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;
                    if (isLiveNetworkAgent(nai, "EVENT_NETWORK_VALIDATED")) {
                        handleConnectionValidated(nai);
                    }
                    break;
                }
                case NetworkMonitor.EVENT_NETWORK_LINGER_COMPLETE: {
                    NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;
                    if (isLiveNetworkAgent(nai, "EVENT_NETWORK_LINGER_COMPLETE")) {
                        handleLingerComplete(nai);
                    }
                    break;
                }
                case NetworkMonitor.EVENT_PROVISIONING_NOTIFICATION: {
                    if (msg.arg1 == 0) {
                        setProvNotificationVisibleIntent(false, msg.arg2, 0, null, null);
                    } else {
                        NetworkAgentInfo nai = mNetworkForNetId.get(msg.arg2);
                    NetworkAgentInfo nai = null;
                    synchronized (mNetworkForNetId) {
                        nai = mNetworkForNetId.get(msg.arg2);
                    }
                    if (nai == null) {
                        loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
                        break;
                    }
                    if (msg.arg1 == 0) {
                        setProvNotificationVisibleIntent(false, msg.arg2, 0, null, null);
                    } else {
                        setProvNotificationVisibleIntent(true, msg.arg2, nai.networkInfo.getType(),
                                nai.networkInfo.getExtraInfo(), (PendingIntent)msg.obj);
                    }