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

Commit 2356bf8b authored by Timothy Yiu's avatar Timothy Yiu
Browse files

Enable Process Observer onProcessStarted broadcast

This change was previously reverted due to b/323925686 and has not been revisited since.

Looking at the bug, it seems like it is a concurrency issue where there are concurrent access to RemoteCallbackList's beginBroadcastInternal.

Adding synchronized block should resolve the issue.

Bug: 323959187
Bug: 323925686
Bug: 389579807
Test: atest FrameworksMockingServicesTests
Flag: android.app.enable_process_observer_broadcast_on_process_started
Change-Id: I706d8a3cda7418e30a95614a1c9303f0bec55537
parent c09deed1
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -190,3 +190,10 @@ flag {
         purpose: PURPOSE_BUGFIX
     }
}

flag {
     name: "enable_process_observer_broadcast_on_process_started"
     namespace: "system_performance"
     description: "Enable ProcessObserver's onProcessStarted callbacks."
     bug: "323959187"
}
+65 −37
Original line number Diff line number Diff line
@@ -793,6 +793,7 @@ public final class ProcessList {
    final ProcessMap<ProcessRecord> mDyingProcesses = new ProcessMap<>();

    // Self locked with the inner lock within the RemoteCallbackList
    @GuardedBy("mProcessObservers")
    private final RemoteCallbackList<IProcessObserver> mProcessObservers =
            new RemoteCallbackList<>();

@@ -4980,12 +4981,16 @@ public final class ProcessList {
    }

    void registerProcessObserver(IProcessObserver observer) {
        synchronized  (mProcessObservers) {
            mProcessObservers.register(observer);
        }
    }

    void unregisterProcessObserver(IProcessObserver observer) {
        synchronized (mProcessObservers) {
            mProcessObservers.unregister(observer);
        }
    }

    void dispatchProcessesChanged() {
        int numOfChanges;
@@ -5002,6 +5007,7 @@ public final class ProcessList {
            }
        }

        synchronized (mProcessObservers) {
            int i = mProcessObservers.beginBroadcast();
            while (i > 0) {
                i--;
@@ -5019,7 +5025,8 @@ public final class ProcessList {
                                observer.onForegroundActivitiesChanged(item.pid, item.uid,
                                        item.foregroundActivities);
                            }
                        if ((item.changes & ProcessChangeItem.CHANGE_FOREGROUND_SERVICES) != 0) {
                            if ((item.changes & ProcessChangeItem.CHANGE_FOREGROUND_SERVICES)
                                    != 0) {
                                if (DEBUG_PROCESS_OBSERVERS) {
                                    Slog.i(TAG_PROCESS_OBSERVERS,
                                            "FOREGROUND SERVICES CHANGED pid=" + item.pid + " uid="
@@ -5034,6 +5041,7 @@ public final class ProcessList {
                }
            }
            mProcessObservers.finishBroadcast();
        }

        synchronized (mProcessChangeLock) {
            for (int j = 0; j < numOfChanges; j++) {
@@ -5122,10 +5130,29 @@ public final class ProcessList {
    }

    void dispatchProcessStarted(ProcessRecord app, int pid) {
        // TODO(b/323959187) Add the implementation.
        if (!android.app.Flags.enableProcessObserverBroadcastOnProcessStarted()) {
            Slog.i(TAG, "ProcessObserver broadcast disabled");
            return;
        }
        synchronized (mProcessObservers) {
            int i = mProcessObservers.beginBroadcast();
            while (i > 0) {
                i--;
                final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
                if (observer != null) {
                    try {
                        observer.onProcessStarted(pid, app.uid, app.info.uid,
                                app.info.packageName, app.processName);
                    } catch (RemoteException e) {
                    }
                }
            }
            mProcessObservers.finishBroadcast();
        }
    }

    void dispatchProcessDied(int pid, int uid) {
        synchronized (mProcessObservers) {
            int i = mProcessObservers.beginBroadcast();
            while (i > 0) {
                i--;
@@ -5139,6 +5166,7 @@ public final class ProcessList {
            }
            mProcessObservers.finishBroadcast();
        }
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
    ArrayList<ProcessRecord> collectProcessesLOSP(int start, boolean allPkgs, String[] args) {
+5 −1
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.Log;

import androidx.test.filters.MediumTest;
@@ -79,6 +81,8 @@ public class ProcessObserverTest {
    @Rule
    public final ApplicationExitInfoTest.ServiceThreadRule
            mServiceThreadRule = new ApplicationExitInfoTest.ServiceThreadRule();
    @Rule
    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    private Context mContext;
    private HandlerThread mHandlerThread;
@@ -239,8 +243,8 @@ public class ProcessObserverTest {
    /**
     * Verify that a process start event is dispatched to process observers.
     */
    @Ignore("b/323959187")
    @Test
    @EnableFlags(android.app.Flags.FLAG_ENABLE_PROCESS_OBSERVER_BROADCAST_ON_PROCESS_STARTED)
    public void testNormal() throws Exception {
        ProcessRecord app = startProcess();
        verify(mProcessObserver).onProcessStarted(