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

Commit e16594f6 authored by Matt Pietal's avatar Matt Pietal
Browse files

Protect callbacks from NullPointerException

The list could be modified during the copy. Synchronize the list
modification.

Fixes: 378823219
Test: atest SystemUITests
Flag: EXEMPT bugfix
Change-Id: Ib7828d61222bf03d0fe3762bc5e0bf473452d972
parent 2d3cb6b8
Loading
Loading
Loading
Loading
+24 −18
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

import javax.inject.Inject;

@@ -63,19 +64,23 @@ public class ManagedProfileControllerImpl implements ManagedProfileController {

    @Override
    public void addCallback(@NonNull Callback callback) {
        synchronized (mCallbacks) {
            mCallbacks.add(callback);
            if (mCallbacks.size() == 1) {
                setListening(true);
            }
            callback.onManagedProfileChanged();
        }
    }

    @Override
    public void removeCallback(@NonNull Callback callback) {
        synchronized (mCallbacks) {
            if (mCallbacks.remove(callback) && mCallbacks.size() == 0) {
                setListening(false);
            }
        }
    }

    public void setWorkModeEnabled(boolean enableWorkMode) {
        synchronized (mProfiles) {
@@ -109,10 +114,7 @@ public class ManagedProfileControllerImpl implements ManagedProfileController {
    }

    private void notifyManagedProfileRemoved() {
        ArrayList<Callback> copy = new ArrayList<>(mCallbacks);
        for (Callback callback : copy) {
            callback.onManagedProfileRemoved();
        }
        notifyCallbacks(Callback::onManagedProfileRemoved);
    }

    public boolean hasActiveProfile() {
@@ -136,6 +138,16 @@ public class ManagedProfileControllerImpl implements ManagedProfileController {
        }
    }

    private void notifyCallbacks(Consumer<Callback> method) {
        ArrayList<Callback> copy;
        synchronized (mCallbacks) {
            copy = new ArrayList<>(mCallbacks);
        }
        for (Callback callback : copy) {
            method.accept(callback);
        }
    }

    private void setListening(boolean listening) {
        if (mListening == listening) {
            return;
@@ -154,19 +166,13 @@ public class ManagedProfileControllerImpl implements ManagedProfileController {
        @Override
        public void onUserChanged(int newUser, @NonNull Context userContext) {
            reloadManagedProfiles();
            ArrayList<Callback> copy = new ArrayList<>(mCallbacks);
            for (Callback callback : copy) {
                callback.onManagedProfileChanged();
            }
            notifyCallbacks(Callback::onManagedProfileChanged);
        }

        @Override
        public void onProfilesChanged(@NonNull List<UserInfo> profiles) {
            reloadManagedProfiles();
            ArrayList<Callback> copy = new ArrayList<>(mCallbacks);
            for (Callback callback : copy) {
                callback.onManagedProfileChanged();
            }
            notifyCallbacks(Callback::onManagedProfileChanged);
        }
    }
}