FileDocCategorySizeDatePackage
JobStore.javaAPI DocAndroid 5.1 API27994Thu Mar 12 22:22:42 GMT 2015com.android.server.job

JobStore

public class JobStore extends Object
Maintains the master list of jobs that the job scheduler is tracking. These jobs are compared by reference, so none of the functions in this class should make a copy. Also handles read/write of persisted jobs. Note on locking: All callers to this class must lock on the class object they are calling. This is important b/c {@link com.android.server.job.JobStore.WriteJobsMapToDiskRunnable} and {@link com.android.server.job.JobStore.ReadJobMapFromDiskRunnable} lock on that object.

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private static final int
MAX_OPS_BEFORE_WRITE
Threshold to adjust how often we want to write to the db.
final android.util.ArraySet
mJobSet
final android.content.Context
mContext
private int
mDirtyOperations
private static final Object
sSingletonLock
private final android.util.AtomicFile
mJobsFile
private final android.os.Handler
mIoHandler
Handler backed by IoThread for writing to disk.
private static JobStore
sSingleton
private static final int
JOBS_FILE_VERSION
Version of the db schema.
private static final String
XML_TAG_PARAMS_CONSTRAINTS
Tag corresponds to constraints this job needs.
private static final String
XML_TAG_PERIODIC
Tag corresponds to execution parameters.
private static final String
XML_TAG_ONEOFF
private static final String
XML_TAG_EXTRAS
Constructors Summary
private JobStore(android.content.Context context, File dataDir)
Construct the instance of the job store. This results in a blocking read from disk.

        mContext = context;
        mDirtyOperations = 0;

        File systemDir = new File(dataDir, "system");
        File jobDir = new File(systemDir, "job");
        jobDir.mkdirs();
        mJobsFile = new AtomicFile(new File(jobDir, "jobs.xml"));

        mJobSet = new ArraySet<JobStatus>();

        readJobMapFromDisk(mJobSet);
    
Methods Summary
public booleanadd(com.android.server.job.controllers.JobStatus jobStatus)
Add a job to the master list, persisting it if necessary. If the JobStatus already exists, it will be replaced.

param
jobStatus Job to add.
return
Whether or not an equivalent JobStatus was replaced by this operation.

        boolean replaced = mJobSet.remove(jobStatus);
        mJobSet.add(jobStatus);
        if (jobStatus.isPersisted()) {
            maybeWriteStatusToDiskAsync();
        }
        if (DEBUG) {
            Slog.d(TAG, "Added job status to store: " + jobStatus);
        }
        return replaced;
    
public voidclear()

        mJobSet.clear();
        maybeWriteStatusToDiskAsync();
    
booleancontainsJob(com.android.server.job.controllers.JobStatus jobStatus)

        return mJobSet.contains(jobStatus);
    
public booleancontainsJobIdForUid(int jobId, int uId)
Whether this jobStatus object already exists in the JobStore.

        for (int i=mJobSet.size()-1; i>=0; i--) {
            JobStatus ts = mJobSet.valueAt(i);
            if (ts.getUid() == uId && ts.getJobId() == jobId) {
                return true;
            }
        }
        return false;
    
public com.android.server.job.controllers.JobStatusgetJobByUidAndJobId(int uid, int jobId)

param
uid Uid of the requesting app.
param
jobId Job id, specified at schedule-time.
return
the JobStatus that matches the provided uId and jobId, or null if none found.

        Iterator<JobStatus> it = mJobSet.iterator();
        while (it.hasNext()) {
            JobStatus ts = it.next();
            if (ts.getUid() == uid && ts.getJobId() == jobId) {
                return ts;
            }
        }
        return null;
    
public android.util.ArraySetgetJobs()

return
The live array of JobStatus objects.

        return mJobSet;
    
public java.util.ListgetJobsByUid(int uid)

param
uid Uid of the requesting app.
return
All JobStatus objects for a given uid from the master list. Never null.

        List<JobStatus> matchingJobs = new ArrayList<JobStatus>();
        Iterator<JobStatus> it = mJobSet.iterator();
        while (it.hasNext()) {
            JobStatus ts = it.next();
            if (ts.getUid() == uid) {
                matchingJobs.add(ts);
            }
        }
        return matchingJobs;
    
public java.util.ListgetJobsByUser(int userHandle)

param
userHandle User for whom we are querying the list of jobs.
return
A list of all the jobs scheduled by the provided user. Never null.

        List<JobStatus> matchingJobs = new ArrayList<JobStatus>();
        Iterator<JobStatus> it = mJobSet.iterator();
        while (it.hasNext()) {
            JobStatus ts = it.next();
            if (UserHandle.getUserId(ts.getUid()) == userHandle) {
                matchingJobs.add(ts);
            }
        }
        return matchingJobs;
    
static com.android.server.job.JobStoreinitAndGet(JobSchedulerService jobManagerService)
Used by the {@link JobSchedulerService} to instantiate the JobStore.


              
        
        synchronized (sSingletonLock) {
            if (sSingleton == null) {
                sSingleton = new JobStore(jobManagerService.getContext(),
                        Environment.getDataDirectory());
            }
            return sSingleton;
        }
    
public static com.android.server.job.JobStoreinitAndGetForTesting(android.content.Context context, java.io.File dataDir)

return
A freshly initialized job store object, with no loaded jobs.

        JobStore jobStoreUnderTest = new JobStore(context, dataDir);
        jobStoreUnderTest.clear();
        return jobStoreUnderTest;
    
private voidmaybeWriteStatusToDiskAsync()
Every time the state changes we write all the jobs in one swath, instead of trying to track incremental changes.

return
Whether the operation was successful. This will only fail for e.g. if the system is low on storage. If this happens, we continue as normal


                                                       
       
        mDirtyOperations++;
        if (mDirtyOperations >= MAX_OPS_BEFORE_WRITE) {
            if (DEBUG) {
                Slog.v(TAG, "Writing jobs to disk.");
            }
            mIoHandler.post(new WriteJobsMapToDiskRunnable());
        }
    
public voidreadJobMapFromDisk(android.util.ArraySet jobSet)

        new ReadJobMapFromDiskRunnable(jobSet).run();
    
public booleanremove(com.android.server.job.controllers.JobStatus jobStatus)
Remove the provided job. Will also delete the job if it was persisted.

return
Whether or not the job existed to be removed.

        boolean removed = mJobSet.remove(jobStatus);
        if (!removed) {
            if (DEBUG) {
                Slog.d(TAG, "Couldn't remove job: didn't exist: " + jobStatus);
            }
            return false;
        }
        if (jobStatus.isPersisted()) {
            maybeWriteStatusToDiskAsync();
        }
        return removed;
    
public intsize()

        return mJobSet.size();