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

Commit 2bb0a70d authored by Kweku Adams's avatar Kweku Adams
Browse files

Skip irrelevant files when loading jobs from disk.

When loading from disk, skip files such as backup & temp files created
during the AtomicFile writing process to avoid incorrectly reading
duplicate jobs from them.

Bug: 289062813
Bug: 305169670
Test: atest FrameworksServicesTests:JobStoreTest
Change-Id: I28a180e2b24357219d34be6a22c785311be6e72e
parent 2a0f9e11
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ import java.util.StringJoiner;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.regex.Pattern;

/**
 * Maintains the master list of jobs that the job scheduler is tracking. These jobs are compared by
@@ -99,6 +100,8 @@ public final class JobStore {
    private static final long SCHEDULED_JOB_HIGH_WATER_MARK_PERIOD_MS = 30 * 60_000L;
    @VisibleForTesting
    static final String JOB_FILE_SPLIT_PREFIX = "jobs_";
    private static final Pattern SPLIT_FILE_PATTERN =
            Pattern.compile("^" + JOB_FILE_SPLIT_PREFIX + "\\d+.xml$");
    private static final int ALL_UIDS = -1;
    @VisibleForTesting
    static final int INVALID_UID = -2;
@@ -1121,6 +1124,11 @@ public final class JobStore {
            int numDuplicates = 0;
            synchronized (mLock) {
                for (File file : files) {
                    if (!file.getName().equals("jobs.xml")
                            && !SPLIT_FILE_PATTERN.matcher(file.getName()).matches()) {
                        // Skip temporary or other files.
                        continue;
                    }
                    final AtomicFile aFile = createJobFile(file);
                    try (FileInputStream fis = aFile.openRead()) {
                        jobs = readJobMapImpl(fis, rtcGood, nowElapsed);
+46 −6
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;

import static com.android.server.job.JobStore.JOB_FILE_SPLIT_PREFIX;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -46,6 +48,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.File;
import java.nio.file.Files;
import java.time.Clock;
import java.time.ZoneOffset;
import java.util.ArrayList;
@@ -209,6 +212,43 @@ public class JobStoreTest {
        assertEquals("Incorrect # of persisted tasks.", 0, jobStatusSet.size());
    }

    @Test
    public void testSkipExtraFiles() throws Exception {
        setUseSplitFiles(true);
        final JobInfo task1 = new Builder(8, mComponent)
                .setRequiresDeviceIdle(true)
                .setPeriodic(10000L)
                .setRequiresCharging(true)
                .setPersisted(true)
                .build();
        final JobInfo task2 = new Builder(12, mComponent)
                .setMinimumLatency(5000L)
                .setBackoffCriteria(15000L, JobInfo.BACKOFF_POLICY_LINEAR)
                .setOverrideDeadline(30000L)
                .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
                .setPersisted(true)
                .build();
        final int uid1 = SOME_UID;
        final int uid2 = uid1 + 1;
        final JobStatus JobStatus1 = JobStatus.createFromJobInfo(task1, uid1, null, -1, null, null);
        final JobStatus JobStatus2 = JobStatus.createFromJobInfo(task2, uid2, null, -1, null, null);
        runWritingJobsToDisk(JobStatus1, JobStatus2);

        final File rootDir = new File(mTestContext.getFilesDir(), "system/job");
        final File file1 = new File(rootDir, JOB_FILE_SPLIT_PREFIX + uid1 + ".xml");
        final File file2 = new File(rootDir, JOB_FILE_SPLIT_PREFIX + uid2 + ".xml");

        Files.copy(file1.toPath(),
                new File(rootDir, JOB_FILE_SPLIT_PREFIX + uid1 + ".xml.bak").toPath());
        Files.copy(file1.toPath(), new File(rootDir, "random.xml").toPath());
        Files.copy(file2.toPath(),
                new File(rootDir, "blah" + JOB_FILE_SPLIT_PREFIX + uid1 + ".xml").toPath());

        JobSet jobStatusSet = new JobSet();
        mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
        assertEquals("Incorrect # of persisted tasks.", 2, jobStatusSet.size());
    }

    /**
     * Test that dynamic constraints aren't written to disk.
     */
@@ -254,22 +294,22 @@ public class JobStoreTest {
        file = new File(mTestContext.getFilesDir(), "10000");
        assertEquals(JobStore.INVALID_UID, JobStore.extractUidFromJobFileName(file));

        file = new File(mTestContext.getFilesDir(), JobStore.JOB_FILE_SPLIT_PREFIX);
        file = new File(mTestContext.getFilesDir(), JOB_FILE_SPLIT_PREFIX);
        assertEquals(JobStore.INVALID_UID, JobStore.extractUidFromJobFileName(file));

        file = new File(mTestContext.getFilesDir(), JobStore.JOB_FILE_SPLIT_PREFIX + "text.xml");
        file = new File(mTestContext.getFilesDir(), JOB_FILE_SPLIT_PREFIX + "text.xml");
        assertEquals(JobStore.INVALID_UID, JobStore.extractUidFromJobFileName(file));

        file = new File(mTestContext.getFilesDir(), JobStore.JOB_FILE_SPLIT_PREFIX + ".xml");
        file = new File(mTestContext.getFilesDir(), JOB_FILE_SPLIT_PREFIX + ".xml");
        assertEquals(JobStore.INVALID_UID, JobStore.extractUidFromJobFileName(file));

        file = new File(mTestContext.getFilesDir(), JobStore.JOB_FILE_SPLIT_PREFIX + "-10123.xml");
        file = new File(mTestContext.getFilesDir(), JOB_FILE_SPLIT_PREFIX + "-10123.xml");
        assertEquals(JobStore.INVALID_UID, JobStore.extractUidFromJobFileName(file));

        file = new File(mTestContext.getFilesDir(), JobStore.JOB_FILE_SPLIT_PREFIX + "1.xml");
        file = new File(mTestContext.getFilesDir(), JOB_FILE_SPLIT_PREFIX + "1.xml");
        assertEquals(1, JobStore.extractUidFromJobFileName(file));

        file = new File(mTestContext.getFilesDir(), JobStore.JOB_FILE_SPLIT_PREFIX + "101023.xml");
        file = new File(mTestContext.getFilesDir(), JOB_FILE_SPLIT_PREFIX + "101023.xml");
        assertEquals(101023, JobStore.extractUidFromJobFileName(file));
    }