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

Commit e82b43f7 authored by Hugo Benichi's avatar Hugo Benichi Committed by android-build-merger
Browse files

Merge \"Fix unsafe concurrent access in LegacyTypeTracker\"

am: ee4c8fb9

Change-Id: I928b2c6ef8e20e197425c214242287185a9daa06
parents 2747eb7e ee4c8fb9
Loading
Loading
Loading
Loading
+30 −17
Original line number Original line Diff line number Diff line
@@ -487,8 +487,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
         *
         *
         * The actual lists are populated when we scan the network types that
         * The actual lists are populated when we scan the network types that
         * are supported on this device.
         * are supported on this device.
         *
         * Threading model:
         *  - addSupportedType() is only called in the constructor
         *  - add(), update(), remove() are only called from the ConnectivityService handler thread.
         *    They are therefore not thread-safe with respect to each other.
         *  - getNetworkForType() can be called at any time on binder threads. It is synchronized
         *    on mTypeLists to be thread-safe with respect to a concurrent remove call.
         *  - dump is thread-safe with respect to concurrent add and remove calls.
         */
         */
        private ArrayList<NetworkAgentInfo> mTypeLists[];
        private final ArrayList<NetworkAgentInfo> mTypeLists[];


        public LegacyTypeTracker() {
        public LegacyTypeTracker() {
            mTypeLists = (ArrayList<NetworkAgentInfo>[])
            mTypeLists = (ArrayList<NetworkAgentInfo>[])
@@ -508,12 +516,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
        }
        }


        public NetworkAgentInfo getNetworkForType(int type) {
        public NetworkAgentInfo getNetworkForType(int type) {
            synchronized (mTypeLists) {
                if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) {
                if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) {
                    return mTypeLists[type].get(0);
                    return mTypeLists[type].get(0);
            } else {
                return null;
                }
                }
            }
            }
            return null;
        }


        private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type,
        private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type,
                boolean isDefaultNetwork) {
                boolean isDefaultNetwork) {
@@ -535,12 +544,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
            if (list.contains(nai)) {
            if (list.contains(nai)) {
                return;
                return;
            }
            }

            synchronized (mTypeLists) {
                list.add(nai);
                list.add(nai);
            }


            // Send a broadcast if this is the first network of its type or if it's the default.
            // Send a broadcast if this is the first network of its type or if it's the default.
            final boolean isDefaultNetwork = isDefaultNetwork(nai);
            final boolean isDefaultNetwork = isDefaultNetwork(nai);
            if (list.size() == 1 || isDefaultNetwork) {
            if ((list.size() == 1) || isDefaultNetwork) {
                maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isDefaultNetwork);
                maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isDefaultNetwork);
                sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type);
                sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type);
            }
            }
@@ -552,12 +562,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
            if (list == null || list.isEmpty()) {
            if (list == null || list.isEmpty()) {
                return;
                return;
            }
            }

            final boolean wasFirstNetwork = list.get(0).equals(nai);
            final boolean wasFirstNetwork = list.get(0).equals(nai);


            synchronized (mTypeLists) {
                if (!list.remove(nai)) {
                if (!list.remove(nai)) {
                    return;
                    return;
                }
                }
            }


            final DetailedState state = DetailedState.DISCONNECTED;
            final DetailedState state = DetailedState.DISCONNECTED;


@@ -591,8 +602,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
            for (int type = 0; type < mTypeLists.length; type++) {
            for (int type = 0; type < mTypeLists.length; type++) {
                final ArrayList<NetworkAgentInfo> list = mTypeLists[type];
                final ArrayList<NetworkAgentInfo> list = mTypeLists[type];
                final boolean contains = (list != null && list.contains(nai));
                final boolean contains = (list != null && list.contains(nai));
                final boolean isFirst = (list != null && list.size() > 0 && nai == list.get(0));
                final boolean isFirst = contains && (nai == list.get(0));
                if (isFirst || (contains && isDefault)) {
                if (isFirst || contains && isDefault) {
                    maybeLogBroadcast(nai, state, type, isDefault);
                    maybeLogBroadcast(nai, state, type, isDefault);
                    sendLegacyNetworkBroadcast(nai, state, type);
                    sendLegacyNetworkBroadcast(nai, state, type);
                }
                }
@@ -617,12 +628,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
            pw.println();
            pw.println();
            pw.println("Current state:");
            pw.println("Current state:");
            pw.increaseIndent();
            pw.increaseIndent();
            synchronized (mTypeLists) {
                for (int type = 0; type < mTypeLists.length; type++) {
                for (int type = 0; type < mTypeLists.length; type++) {
                if (mTypeLists[type] == null|| mTypeLists[type].size() == 0) continue;
                    if (mTypeLists[type] == null || mTypeLists[type].isEmpty()) continue;
                    for (NetworkAgentInfo nai : mTypeLists[type]) {
                    for (NetworkAgentInfo nai : mTypeLists[type]) {
                        pw.println(type + " " + naiToString(nai));
                        pw.println(type + " " + naiToString(nai));
                    }
                    }
                }
                }
            }
            pw.decreaseIndent();
            pw.decreaseIndent();
            pw.decreaseIndent();
            pw.decreaseIndent();
            pw.println();
            pw.println();