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

Commit 490c3ee6 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Synchronize access to notif settings

And fix an instance where we were calling into PM with a
lock held.

Flag: EXEMPT bugfix
Bug: 343447769
Test: PreferenceHelperTest
Change-Id: I1fec0503bf347f176305744b77ad27d78fe8161c
parent 92716088
Loading
Loading
Loading
Loading
+110 −105

File changed.

Preview size limit exceeded, changes collapsed.

+59 −0
Original line number Diff line number Diff line
@@ -188,6 +188,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;

@SmallTest
@@ -489,6 +490,34 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        when(mPm.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid);
    }

    private static void testThreadSafety(Runnable operationToTest, int nThreads,
            int nRunsPerThread) throws Exception {
        final CountDownLatch startLatch = new CountDownLatch(1);
        final CountDownLatch doneLatch = new CountDownLatch(nThreads);

        for (int i = 0; i < nThreads; i++) {
            Runnable threadRunnable = () -> {
                try {
                    startLatch.await();
                    for (int j = 0; j < nRunsPerThread; j++) {
                        operationToTest.run();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    doneLatch.countDown();
                }
            };
            new Thread(threadRunnable, "Test Thread #" + i).start();
        }

        // Ready set go
        startLatch.countDown();

        // Wait for all test threads to be done.
        doneLatch.await();
    }

    @Test
    public void testWriteXml_onlyBackupsTargetUser() throws Exception {
        // Setup package notifications.
@@ -6193,6 +6222,36 @@ public class PreferencesHelperTest extends UiServiceTestCase {
                .isEqualTo(IMPORTANCE_LOW);
    }


    @Test
    public void testRestoredWithoutUid_threadSafety() throws Exception {
        when(mPm.getPackageUidAsUser(anyString(), anyInt())).thenReturn(UNKNOWN_UID);
        when(mPm.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())).thenThrow(
                new PackageManager.NameNotFoundException());
        when(mClock.millis()).thenReturn(System.currentTimeMillis());
        testThreadSafety(() -> {
            String id = "id";
            String xml = "<ranking version=\"1\">\n"
                    + "<package name=\"" + Thread.currentThread()+ "\" show_badge=\"true\">\n"
                    + "<channel id=\"" + id + "\" name=\"name\" importance=\"2\" "
                    + "show_badge=\"true\" />\n"
                    + "</package>\n"
                    + "<package name=\"" + PKG_P + "\" show_badge=\"true\">\n"
                    + "</package>\n"
                    + "</ranking>\n";

            try {
                loadByteArrayXml(xml.getBytes(), true, USER_SYSTEM);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            // trigger a removal from the list
            mXmlHelper.onPackagesChanged(true, USER_SYSTEM, new String[]{PKG_P},
                    new int[]{UNKNOWN_UID});
        }, 20, 50);
    }

    private static NotificationChannel cloneChannel(NotificationChannel original) {
        Parcel parcel = Parcel.obtain();
        try {