diff --git a/services/core/java/com/android/server/MountServiceIdler.java b/services/core/java/com/android/server/MountServiceIdler.java
index 61790826..bcb6e9e 100644
--- a/services/core/java/com/android/server/MountServiceIdler.java
+++ b/services/core/java/com/android/server/MountServiceIdler.java
@@ -18,32 +18,32 @@
 
 import java.util.Calendar;
 
-import android.app.task.Task;
-import android.app.task.TaskManager;
-import android.app.task.TaskParams;
-import android.app.task.TaskService;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
 import android.content.ComponentName;
 import android.content.Context;
 import android.util.Slog;
 
-public class MountServiceIdler extends TaskService {
+public class MountServiceIdler extends JobService {
     private static final String TAG = "MountServiceIdler";
 
     private static ComponentName sIdleService =
             new ComponentName(MountServiceIdler.class.getPackage().getName(),
                     MountServiceIdler.class.getName());
 
-    private static int MOUNT_TASK_ID = 808;
+    private static int MOUNT_JOB_ID = 808;
 
     private boolean mStarted;
-    private TaskParams mTaskParams;
+    private JobParameters mJobParams;
     private Runnable mFinishCallback = new Runnable() {
         @Override
         public void run() {
             Slog.i(TAG, "Got mount service completion callback");
             synchronized (mFinishCallback) {
                 if (mStarted) {
-                    taskFinished(mTaskParams, false);
+                    jobFinished(mJobParams, false);
                     mStarted = false;
                 }
             }
@@ -53,12 +53,12 @@
     };
 
     @Override
-    public boolean onStartTask(TaskParams params) {
+    public boolean onStartJob(JobParameters params) {
         // The mount service will run an fstrim operation asynchronously
         // on a designated separate thread, so we provide it with a callback
         // that lets us cleanly end our idle timeslice.  It's safe to call
         // finishIdle() from any thread.
-        mTaskParams = params;
+        mJobParams = params;
         MountService ms = MountService.sSelf;
         if (ms != null) {
             synchronized (mFinishCallback) {
@@ -70,9 +70,9 @@
     }
 
     @Override
-    public boolean onStopTask(TaskParams params) {
+    public boolean onStopJob(JobParameters params) {
         // Once we kick off the fstrim we aren't actually interruptible; just note
-        // that we don't need to call taskFinished(), and let everything happen in
+        // that we don't need to call jobFinished(), and let everything happen in
         // the callback from the mount service.
         synchronized (mFinishCallback) {
             mStarted = false;
@@ -84,12 +84,12 @@
      * Schedule the idle job that will ping the mount service
      */
     public static void scheduleIdlePass(Context context) {
-        TaskManager tm = (TaskManager) context.getSystemService(Context.TASK_SERVICE);
+        JobScheduler tm = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
 
         Calendar calendar = tomorrowMidnight();
         final long timeToMidnight = calendar.getTimeInMillis() - System.currentTimeMillis();
 
-        Task.Builder builder = new Task.Builder(MOUNT_TASK_ID, sIdleService);
+        JobInfo.Builder builder = new JobInfo.Builder(MOUNT_JOB_ID, sIdleService);
         builder.setRequiresDeviceIdle(true);
         builder.setRequiresCharging(true);
         builder.setMinimumLatency(timeToMidnight);
diff --git a/services/core/java/com/android/server/task/TaskCompletedListener.java b/services/core/java/com/android/server/job/JobCompletedListener.java
similarity index 62%
rename from services/core/java/com/android/server/task/TaskCompletedListener.java
rename to services/core/java/com/android/server/job/JobCompletedListener.java
index c53f5ca..a7af9cd 100644
--- a/services/core/java/com/android/server/task/TaskCompletedListener.java
+++ b/services/core/java/com/android/server/job/JobCompletedListener.java
@@ -14,19 +14,19 @@
  * limitations under the License
  */
 
-package com.android.server.task;
+package com.android.server.job;
 
-import com.android.server.task.controllers.TaskStatus;
+import com.android.server.job.controllers.JobStatus;
 
 /**
- * Used for communication between {@link com.android.server.task.TaskServiceContext} and the
- * {@link com.android.server.task.TaskManagerService}.
+ * Used for communication between {@link com.android.server.job.JobServiceContext} and the
+ * {@link com.android.server.job.JobSchedulerService}.
  */
-public interface TaskCompletedListener {
+public interface JobCompletedListener {
 
     /**
-     * Callback for when a task is completed.
-     * @param needsReschedule Whether the implementing class should reschedule this task.
+     * Callback for when a job is completed.
+     * @param needsReschedule Whether the implementing class should reschedule this job.
      */
-    public void onTaskCompleted(TaskStatus taskStatus, boolean needsReschedule);
+    public void onJobCompleted(JobStatus jobStatus, boolean needsReschedule);
 }
diff --git a/services/core/java/com/android/server/task/TaskMapReadFinishedListener.java b/services/core/java/com/android/server/job/JobMapReadFinishedListener.java
similarity index 68%
rename from services/core/java/com/android/server/task/TaskMapReadFinishedListener.java
rename to services/core/java/com/android/server/job/JobMapReadFinishedListener.java
index c68d8db..f3e77e6 100644
--- a/services/core/java/com/android/server/task/TaskMapReadFinishedListener.java
+++ b/services/core/java/com/android/server/job/JobMapReadFinishedListener.java
@@ -14,21 +14,21 @@
  * limitations under the License
  */
 
-package com.android.server.task;
+package com.android.server.job;
 
 import java.util.List;
 
-import com.android.server.task.controllers.TaskStatus;
+import com.android.server.job.controllers.JobStatus;
 
 /**
- * Callback definition for I/O thread to let the TaskManagerService know when
+ * Callback definition for I/O thread to let the JobManagerService know when
  * I/O read has completed. Done this way so we don't stall the main thread on
  * boot.
  */
-public interface TaskMapReadFinishedListener {
+public interface JobMapReadFinishedListener {
 
     /**
-     * Called by the {@link TaskStore} at boot, when the disk read is finished.
+     * Called by the {@link JobStore} at boot, when the disk read is finished.
      */
-    public void onTaskMapReadFinished(List<TaskStatus> tasks);
+    public void onJobMapReadFinished(List<JobStatus> jobs);
 }
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
new file mode 100644
index 0000000..0e9a9cc
--- /dev/null
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -0,0 +1,764 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.app.job.IJobScheduler;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ServiceInfo;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.server.job.controllers.BatteryController;
+import com.android.server.job.controllers.ConnectivityController;
+import com.android.server.job.controllers.IdleController;
+import com.android.server.job.controllers.JobStatus;
+import com.android.server.job.controllers.StateController;
+import com.android.server.job.controllers.TimeController;
+
+import java.util.LinkedList;
+
+/**
+ * Responsible for taking jobs representing work to be performed by a client app, and determining
+ * based on the criteria specified when that job should be run against the client application's
+ * endpoint.
+ * Implements logic for scheduling, and rescheduling jobs. The JobSchedulerService knows nothing
+ * about constraints, or the state of active jobs. It receives callbacks from the various
+ * controllers and completed jobs and operates accordingly.
+ *
+ * Note on locking: Any operations that manipulate {@link #mJobs} need to lock on that object.
+ * Any function with the suffix 'Locked' also needs to lock on {@link #mJobs}.
+ * @hide
+ */
+public class JobSchedulerService extends com.android.server.SystemService
+        implements StateChangedListener, JobCompletedListener, JobMapReadFinishedListener {
+    // TODO: Switch this off for final version.
+    static final boolean DEBUG = true;
+    /** The number of concurrent jobs we run at one time. */
+    private static final int MAX_JOB_CONTEXTS_COUNT = 3;
+    static final String TAG = "JobManagerService";
+    /** Master list of jobs. */
+    private final JobStore mJobs;
+
+    static final int MSG_JOB_EXPIRED = 0;
+    static final int MSG_CHECK_JOB = 1;
+
+    // Policy constants
+    /**
+     * Minimum # of idle jobs that must be ready in order to force the JMS to schedule things
+     * early.
+     */
+    private static final int MIN_IDLE_COUNT = 1;
+    /**
+     * Minimum # of connectivity jobs that must be ready in order to force the JMS to schedule
+     * things early.
+     */
+    private static final int MIN_CONNECTIVITY_COUNT = 2;
+    /**
+     * Minimum # of jobs (with no particular constraints) for which the JMS will be happy running
+     * some work early.
+     */
+    private static final int MIN_READY_JOBS_COUNT = 4;
+
+    /**
+     * Track Services that have currently active or pending jobs. The index is provided by
+     * {@link JobStatus#getServiceToken()}
+     */
+    private final List<JobServiceContext> mActiveServices = new LinkedList<JobServiceContext>();
+    /** List of controllers that will notify this service of updates to jobs. */
+    private List<StateController> mControllers;
+    /**
+     * Queue of pending jobs. The JobServiceContext class will receive jobs from this list
+     * when ready to execute them.
+     */
+    private final LinkedList<JobStatus> mPendingJobs = new LinkedList<JobStatus>();
+
+    private final JobHandler mHandler;
+    private final JobSchedulerStub mJobSchedulerStub;
+    /**
+     * Cleans up outstanding jobs when a package is removed. Even if it's being replaced later we
+     * still clean up. On reinstall the package will have a new uid.
+     */
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Slog.d(TAG, "Receieved: " + intent.getAction());
+            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
+                int uidRemoved = intent.getIntExtra(Intent.EXTRA_UID, -1);
+                if (DEBUG) {
+                    Slog.d(TAG, "Removing jobs for uid: " + uidRemoved);
+                }
+                cancelJobsForUid(uidRemoved);
+            } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
+                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                if (DEBUG) {
+                    Slog.d(TAG, "Removing jobs for user: " + userId);
+                }
+                cancelJobsForUser(userId);
+            }
+        }
+    };
+
+    /**
+     * Entry point from client to schedule the provided job.
+     * This cancels the job if it's already been scheduled, and replaces it with the one provided.
+     * @param job JobInfo object containing execution parameters
+     * @param uId The package identifier of the application this job is for.
+     * @param canPersistJob Whether or not the client has the appropriate permissions for
+     *                       persisting this job.
+     * @return Result of this operation. See <code>JobScheduler#RESULT_*</code> return codes.
+     */
+    public int schedule(JobInfo job, int uId, boolean canPersistJob) {
+        JobStatus jobStatus = new JobStatus(job, uId, canPersistJob);
+        cancelJob(uId, job.getId());
+        startTrackingJob(jobStatus);
+        return JobScheduler.RESULT_SUCCESS;
+    }
+
+    public List<JobInfo> getPendingJobs(int uid) {
+        ArrayList<JobInfo> outList = new ArrayList<JobInfo>();
+        synchronized (mJobs) {
+            for (JobStatus job : mJobs.getJobs()) {
+                if (job.getUid() == uid) {
+                    outList.add(job.getJob());
+                }
+            }
+        }
+        return outList;
+    }
+
+    private void cancelJobsForUser(int userHandle) {
+        synchronized (mJobs) {
+            List<JobStatus> jobsForUser = mJobs.getJobsByUser(userHandle);
+            for (JobStatus toRemove : jobsForUser) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Cancelling: " + toRemove);
+                }
+                cancelJobLocked(toRemove);
+            }
+        }
+    }
+
+    /**
+     * Entry point from client to cancel all jobs originating from their uid.
+     * This will remove the job from the master list, and cancel the job if it was staged for
+     * execution or being executed.
+     * @param uid To check against for removal of a job.
+     */
+    public void cancelJobsForUid(int uid) {
+        // Remove from master list.
+        synchronized (mJobs) {
+            List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid);
+            for (JobStatus toRemove : jobsForUid) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Cancelling: " + toRemove);
+                }
+                cancelJobLocked(toRemove);
+            }
+        }
+    }
+
+    /**
+     * Entry point from client to cancel the job corresponding to the jobId provided.
+     * This will remove the job from the master list, and cancel the job if it was staged for
+     * execution or being executed.
+     * @param uid Uid of the calling client.
+     * @param jobId Id of the job, provided at schedule-time.
+     */
+    public void cancelJob(int uid, int jobId) {
+        JobStatus toCancel;
+        synchronized (mJobs) {
+            toCancel = mJobs.getJobByUidAndJobId(uid, jobId);
+            if (toCancel != null) {
+                cancelJobLocked(toCancel);
+            }
+        }
+    }
+
+    private void cancelJobLocked(JobStatus cancelled) {
+        // Remove from store.
+        stopTrackingJob(cancelled);
+        // Remove from pending queue.
+        mPendingJobs.remove(cancelled);
+        // Cancel if running.
+        stopJobOnServiceContextLocked(cancelled);
+    }
+
+    /**
+     * Initializes the system service.
+     * <p>
+     * Subclasses must define a single argument constructor that accepts the context
+     * and passes it to super.
+     * </p>
+     *
+     * @param context The system server context.
+     */
+    public JobSchedulerService(Context context) {
+        super(context);
+        // Create the controllers.
+        mControllers = new LinkedList<StateController>();
+        mControllers.add(ConnectivityController.get(this));
+        mControllers.add(TimeController.get(this));
+        mControllers.add(IdleController.get(this));
+        mControllers.add(BatteryController.get(this));
+
+        mHandler = new JobHandler(context.getMainLooper());
+        mJobSchedulerStub = new JobSchedulerStub();
+        // Create the "runners".
+        for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
+            mActiveServices.add(
+                    new JobServiceContext(this, context.getMainLooper()));
+        }
+        mJobs = JobStore.initAndGet(this);
+    }
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.JOB_SCHEDULER_SERVICE, mJobSchedulerStub);
+    }
+
+    @Override
+    public void onBootPhase(int phase) {
+        if (PHASE_SYSTEM_SERVICES_READY == phase) {
+            // Register br for package removals and user removals.
+            final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
+            filter.addDataScheme("package");
+            getContext().registerReceiverAsUser(
+                    mBroadcastReceiver, UserHandle.ALL, filter, null, null);
+            final IntentFilter userFilter = new IntentFilter(Intent.ACTION_USER_REMOVED);
+            getContext().registerReceiverAsUser(
+                    mBroadcastReceiver, UserHandle.ALL, userFilter, null, null);
+        }
+    }
+
+    /**
+     * Called when we have a job status object that we need to insert in our
+     * {@link com.android.server.job.JobStore}, and make sure all the relevant controllers know
+     * about.
+     */
+    private void startTrackingJob(JobStatus jobStatus) {
+        boolean update;
+        synchronized (mJobs) {
+            update = mJobs.add(jobStatus);
+        }
+        for (StateController controller : mControllers) {
+            if (update) {
+                controller.maybeStopTrackingJob(jobStatus);
+            }
+            controller.maybeStartTrackingJob(jobStatus);
+        }
+    }
+
+    /**
+     * Called when we want to remove a JobStatus object that we've finished executing. Returns the
+     * object removed.
+     */
+    private boolean stopTrackingJob(JobStatus jobStatus) {
+        boolean removed;
+        synchronized (mJobs) {
+            // Remove from store as well as controllers.
+            removed = mJobs.remove(jobStatus);
+        }
+        if (removed) {
+            for (StateController controller : mControllers) {
+                controller.maybeStopTrackingJob(jobStatus);
+            }
+        }
+        return removed;
+    }
+
+    private boolean stopJobOnServiceContextLocked(JobStatus job) {
+        for (JobServiceContext jsc : mActiveServices) {
+            final JobStatus executing = jsc.getRunningJob();
+            if (executing != null && executing.matches(job.getUid(), job.getJobId())) {
+                jsc.cancelExecutingJob();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @param job JobStatus we are querying against.
+     * @return Whether or not the job represented by the status object is currently being run or
+     * is pending.
+     */
+    private boolean isCurrentlyActiveLocked(JobStatus job) {
+        for (JobServiceContext serviceContext : mActiveServices) {
+            final JobStatus running = serviceContext.getRunningJob();
+            if (running != null && running.matches(job.getUid(), job.getJobId())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * A job is rescheduled with exponential back-off if the client requests this from their
+     * execution logic.
+     * A caveat is for idle-mode jobs, for which the idle-mode constraint will usurp the
+     * timeliness of the reschedule. For an idle-mode job, no deadline is given.
+     * @param failureToReschedule Provided job status that we will reschedule.
+     * @return A newly instantiated JobStatus with the same constraints as the last job except
+     * with adjusted timing constraints.
+     */
+    private JobStatus getRescheduleJobForFailure(JobStatus failureToReschedule) {
+        final long elapsedNowMillis = SystemClock.elapsedRealtime();
+        final JobInfo job = failureToReschedule.getJob();
+
+        final long initialBackoffMillis = job.getInitialBackoffMillis();
+        final int backoffAttempt = failureToReschedule.getNumFailures() + 1;
+        long newEarliestRuntimeElapsed = elapsedNowMillis;
+
+        switch (job.getBackoffPolicy()) {
+            case JobInfo.BackoffPolicy.LINEAR:
+                newEarliestRuntimeElapsed += initialBackoffMillis * backoffAttempt;
+                break;
+            default:
+                if (DEBUG) {
+                    Slog.v(TAG, "Unrecognised back-off policy, defaulting to exponential.");
+                }
+            case JobInfo.BackoffPolicy.EXPONENTIAL:
+                newEarliestRuntimeElapsed +=
+                        Math.pow(initialBackoffMillis * 0.001, backoffAttempt) * 1000;
+                break;
+        }
+        newEarliestRuntimeElapsed =
+                Math.min(newEarliestRuntimeElapsed, JobInfo.MAX_BACKOFF_DELAY_MILLIS);
+        return new JobStatus(failureToReschedule, newEarliestRuntimeElapsed,
+                JobStatus.NO_LATEST_RUNTIME, backoffAttempt);
+    }
+
+    /**
+     * Called after a periodic has executed so we can to re-add it. We take the last execution time
+     * of the job to be the time of completion (i.e. the time at which this function is called).
+     * This could be inaccurate b/c the job can run for as long as
+     * {@link com.android.server.job.JobServiceContext#EXECUTING_TIMESLICE_MILLIS}, but will lead
+     * to underscheduling at least, rather than if we had taken the last execution time to be the
+     * start of the execution.
+     * @return A new job representing the execution criteria for this instantiation of the
+     * recurring job.
+     */
+    private JobStatus getRescheduleJobForPeriodic(JobStatus periodicToReschedule) {
+        final long elapsedNow = SystemClock.elapsedRealtime();
+        // Compute how much of the period is remaining.
+        long runEarly = Math.max(periodicToReschedule.getLatestRunTimeElapsed() - elapsedNow, 0);
+        long newEarliestRunTimeElapsed = elapsedNow + runEarly;
+        long period = periodicToReschedule.getJob().getIntervalMillis();
+        long newLatestRuntimeElapsed = newEarliestRunTimeElapsed + period;
+
+        if (DEBUG) {
+            Slog.v(TAG, "Rescheduling executed periodic. New execution window [" +
+                    newEarliestRunTimeElapsed/1000 + ", " + newLatestRuntimeElapsed/1000 + "]s");
+        }
+        return new JobStatus(periodicToReschedule, newEarliestRunTimeElapsed,
+                newLatestRuntimeElapsed, 0 /* backoffAttempt */);
+    }
+
+    // JobCompletedListener implementations.
+
+    /**
+     * A job just finished executing. We fetch the
+     * {@link com.android.server.job.controllers.JobStatus} from the store and depending on
+     * whether we want to reschedule we readd it to the controllers.
+     * @param jobStatus Completed job.
+     * @param needsReschedule Whether the implementing class should reschedule this job.
+     */
+    @Override
+    public void onJobCompleted(JobStatus jobStatus, boolean needsReschedule) {
+        if (DEBUG) {
+            Slog.d(TAG, "Completed " + jobStatus + ", reschedule=" + needsReschedule);
+        }
+        if (!stopTrackingJob(jobStatus)) {
+            if (DEBUG) {
+                Slog.e(TAG, "Error removing job: could not find job to remove. Was job " +
+                        "removed while executing?");
+            }
+            return;
+        }
+        if (needsReschedule) {
+            JobStatus rescheduled = getRescheduleJobForFailure(jobStatus);
+            startTrackingJob(rescheduled);
+        } else if (jobStatus.getJob().isPeriodic()) {
+            JobStatus rescheduledPeriodic = getRescheduleJobForPeriodic(jobStatus);
+            startTrackingJob(rescheduledPeriodic);
+        }
+        mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
+    }
+
+    // StateChangedListener implementations.
+
+    /**
+     * Off-board work to our handler thread as quickly as possible, b/c this call is probably being
+     * made on the main thread.
+     * For now this takes the job and if it's ready to run it will run it. In future we might not
+     * provide the job, so that the StateChangedListener has to run through its list of jobs to
+     * see which are ready. This will further decouple the controllers from the execution logic.
+     */
+    @Override
+    public void onControllerStateChanged() {
+        // Post a message to to run through the list of jobs and start/stop any that are eligible.
+        mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
+    }
+
+    @Override
+    public void onRunJobNow(JobStatus jobStatus) {
+        mHandler.obtainMessage(MSG_JOB_EXPIRED, jobStatus).sendToTarget();
+    }
+
+    /**
+     * Disk I/O is finished, take the list of jobs we read from disk and add them to our
+     * {@link JobStore}.
+     * This is run on the {@link com.android.server.IoThread} instance, which is a separate thread,
+     * and is called once at boot.
+     */
+    @Override
+    public void onJobMapReadFinished(List<JobStatus> jobs) {
+        synchronized (mJobs) {
+            for (JobStatus js : jobs) {
+                if (mJobs.containsJobIdForUid(js.getJobId(), js.getUid())) {
+                    // An app with BOOT_COMPLETED *might* have decided to reschedule their job, in
+                    // the same amount of time it took us to read it from disk. If this is the case
+                    // we leave it be.
+                    continue;
+                }
+                startTrackingJob(js);
+            }
+        }
+    }
+
+    private class JobHandler extends Handler {
+
+        public JobHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message message) {
+            switch (message.what) {
+                case MSG_JOB_EXPIRED:
+                    synchronized (mJobs) {
+                        JobStatus runNow = (JobStatus) message.obj;
+                        if (!mPendingJobs.contains(runNow)) {
+                            mPendingJobs.add(runNow);
+                        }
+                    }
+                    queueReadyJobsForExecutionH();
+                    break;
+                case MSG_CHECK_JOB:
+                    // Check the list of jobs and run some of them if we feel inclined.
+                    maybeQueueReadyJobsForExecutionH();
+                    break;
+            }
+            maybeRunPendingJobsH();
+            // Don't remove JOB_EXPIRED in case one came along while processing the queue.
+            removeMessages(MSG_CHECK_JOB);
+        }
+
+        /**
+         * Run through list of jobs and execute all possible - at least one is expired so we do
+         * as many as we can.
+         */
+        private void queueReadyJobsForExecutionH() {
+            synchronized (mJobs) {
+                for (JobStatus job : mJobs.getJobs()) {
+                    if (isReadyToBeExecutedLocked(job)) {
+                        mPendingJobs.add(job);
+                    } else if (isReadyToBeCancelledLocked(job)) {
+                        stopJobOnServiceContextLocked(job);
+                    }
+                }
+            }
+        }
+
+        /**
+         * The state of at least one job has changed. Here is where we could enforce various
+         * policies on when we want to execute jobs.
+         * Right now the policy is such:
+         * If >1 of the ready jobs is idle mode we send all of them off
+         * if more than 2 network connectivity jobs are ready we send them all off.
+         * If more than 4 jobs total are ready we send them all off.
+         * TODO: It would be nice to consolidate these sort of high-level policies somewhere.
+         */
+        private void maybeQueueReadyJobsForExecutionH() {
+            synchronized (mJobs) {
+                int idleCount = 0;
+                int backoffCount = 0;
+                int connectivityCount = 0;
+                List<JobStatus> runnableJobs = new ArrayList<JobStatus>();
+                for (JobStatus job : mJobs.getJobs()) {
+                    if (isReadyToBeExecutedLocked(job)) {
+                        if (job.getNumFailures() > 0) {
+                            backoffCount++;
+                        }
+                        if (job.hasIdleConstraint()) {
+                            idleCount++;
+                        }
+                        if (job.hasConnectivityConstraint() || job.hasUnmeteredConstraint()) {
+                            connectivityCount++;
+                        }
+                        runnableJobs.add(job);
+                    } else if (isReadyToBeCancelledLocked(job)) {
+                        stopJobOnServiceContextLocked(job);
+                    }
+                }
+                if (backoffCount > 0 || idleCount >= MIN_IDLE_COUNT ||
+                        connectivityCount >= MIN_CONNECTIVITY_COUNT ||
+                        runnableJobs.size() >= MIN_READY_JOBS_COUNT) {
+                    for (JobStatus job : runnableJobs) {
+                        mPendingJobs.add(job);
+                    }
+                }
+            }
+        }
+
+        /**
+         * Criteria for moving a job into the pending queue:
+         *      - It's ready.
+         *      - It's not pending.
+         *      - It's not already running on a JSC.
+         */
+        private boolean isReadyToBeExecutedLocked(JobStatus job) {
+              return job.isReady() && !mPendingJobs.contains(job) && !isCurrentlyActiveLocked(job);
+        }
+
+        /**
+         * Criteria for cancelling an active job:
+         *      - It's not ready
+         *      - It's running on a JSC.
+         */
+        private boolean isReadyToBeCancelledLocked(JobStatus job) {
+            return !job.isReady() && isCurrentlyActiveLocked(job);
+        }
+
+        /**
+         * Reconcile jobs in the pending queue against available execution contexts.
+         * A controller can force a job into the pending queue even if it's already running, but
+         * here is where we decide whether to actually execute it.
+         */
+        private void maybeRunPendingJobsH() {
+            synchronized (mJobs) {
+                Iterator<JobStatus> it = mPendingJobs.iterator();
+                while (it.hasNext()) {
+                    JobStatus nextPending = it.next();
+                    JobServiceContext availableContext = null;
+                    for (JobServiceContext jsc : mActiveServices) {
+                        final JobStatus running = jsc.getRunningJob();
+                        if (running != null && running.matches(nextPending.getUid(),
+                                nextPending.getJobId())) {
+                            // Already running this tId for this uId, skip.
+                            availableContext = null;
+                            break;
+                        }
+                        if (jsc.isAvailable()) {
+                            availableContext = jsc;
+                        }
+                    }
+                    if (availableContext != null) {
+                        if (!availableContext.executeRunnableJob(nextPending)) {
+                            if (DEBUG) {
+                                Slog.d(TAG, "Error executing " + nextPending);
+                            }
+                            mJobs.remove(nextPending);
+                        }
+                        it.remove();
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Binder stub trampoline implementation
+     */
+    final class JobSchedulerStub extends IJobScheduler.Stub {
+        /** Cache determination of whether a given app can persist jobs
+         * key is uid of the calling app; value is undetermined/true/false
+         */
+        private final SparseArray<Boolean> mPersistCache = new SparseArray<Boolean>();
+
+        // Enforce that only the app itself (or shared uid participant) can schedule a
+        // job that runs one of the app's services, as well as verifying that the
+        // named service properly requires the BIND_JOB_SERVICE permission
+        private void enforceValidJobRequest(int uid, JobInfo job) {
+            final PackageManager pm = getContext().getPackageManager();
+            final ComponentName service = job.getService();
+            try {
+                ServiceInfo si = pm.getServiceInfo(service, 0);
+                if (si.applicationInfo.uid != uid) {
+                    throw new IllegalArgumentException("uid " + uid +
+                            " cannot schedule job in " + service.getPackageName());
+                }
+                if (!JobService.PERMISSION_BIND.equals(si.permission)) {
+                    throw new IllegalArgumentException("Scheduled service " + service
+                            + " does not require android.permission.BIND_JOB_SERVICE permission");
+                }
+            } catch (NameNotFoundException e) {
+                throw new IllegalArgumentException("No such service: " + service);
+            }
+        }
+
+        private boolean canPersistJobs(int pid, int uid) {
+            // If we get this far we're good to go; all we need to do now is check
+            // whether the app is allowed to persist its scheduled work.
+            final boolean canPersist;
+            synchronized (mPersistCache) {
+                Boolean cached = mPersistCache.get(uid);
+                if (cached != null) {
+                    canPersist = cached.booleanValue();
+                } else {
+                    // Persisting jobs is tantamount to running at boot, so we permit
+                    // it when the app has declared that it uses the RECEIVE_BOOT_COMPLETED
+                    // permission
+                    int result = getContext().checkPermission(
+                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED, pid, uid);
+                    canPersist = (result == PackageManager.PERMISSION_GRANTED);
+                    mPersistCache.put(uid, canPersist);
+                }
+            }
+            return canPersist;
+        }
+
+        // IJobScheduler implementation
+        @Override
+        public int schedule(JobInfo job) throws RemoteException {
+            if (DEBUG) {
+                Slog.d(TAG, "Scheduling job: " + job);
+            }
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+
+            enforceValidJobRequest(uid, job);
+            final boolean canPersist = canPersistJobs(pid, uid);
+
+            long ident = Binder.clearCallingIdentity();
+            try {
+                return JobSchedulerService.this.schedule(job, uid, canPersist);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override
+        public List<JobInfo> getAllPendingJobs() throws RemoteException {
+            final int uid = Binder.getCallingUid();
+
+            long ident = Binder.clearCallingIdentity();
+            try {
+                return JobSchedulerService.this.getPendingJobs(uid);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override
+        public void cancelAll() throws RemoteException {
+            final int uid = Binder.getCallingUid();
+
+            long ident = Binder.clearCallingIdentity();
+            try {
+                JobSchedulerService.this.cancelJobsForUid(uid);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override
+        public void cancel(int jobId) throws RemoteException {
+            final int uid = Binder.getCallingUid();
+
+            long ident = Binder.clearCallingIdentity();
+            try {
+                JobSchedulerService.this.cancelJob(uid, jobId);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        /**
+         * "dumpsys" infrastructure
+         */
+        @Override
+        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
+            long identityToken = Binder.clearCallingIdentity();
+            try {
+                JobSchedulerService.this.dumpInternal(pw);
+            } finally {
+                Binder.restoreCallingIdentity(identityToken);
+            }
+        }
+    };
+
+    void dumpInternal(PrintWriter pw) {
+        synchronized (mJobs) {
+            pw.println("Registered jobs:");
+            if (mJobs.size() > 0) {
+                for (JobStatus job : mJobs.getJobs()) {
+                    job.dump(pw, "  ");
+                }
+            } else {
+                pw.println();
+                pw.println("No jobs scheduled.");
+            }
+            for (StateController controller : mControllers) {
+                pw.println();
+                controller.dumpControllerState(pw);
+            }
+            pw.println();
+            pw.println("Pending");
+            for (JobStatus jobStatus : mPendingJobs) {
+                pw.println(jobStatus.hashCode());
+            }
+            pw.println();
+            pw.println("Active jobs:");
+            for (JobServiceContext jsc : mActiveServices) {
+                if (jsc.isAvailable()) {
+                    continue;
+                } else {
+                    pw.println(jsc.getRunningJob().hashCode() + " for: " +
+                            (SystemClock.elapsedRealtime()
+                                    - jsc.getExecutionStartTimeElapsed())/1000 + "s " +
+                            "timeout: " + jsc.getTimeoutElapsed());
+                }
+            }
+        }
+        pw.println();
+    }
+}
diff --git a/services/core/java/com/android/server/task/TaskServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
similarity index 66%
rename from services/core/java/com/android/server/task/TaskServiceContext.java
rename to services/core/java/com/android/server/job/JobServiceContext.java
index a21de88..92b643c 100644
--- a/services/core/java/com/android/server/task/TaskServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -14,12 +14,12 @@
  * limitations under the License
  */
 
-package com.android.server.task;
+package com.android.server.job;
 
 import android.app.ActivityManager;
-import android.app.task.ITaskCallback;
-import android.app.task.ITaskService;
-import android.app.task.TaskParams;
+import android.app.job.JobParameters;
+import android.app.job.IJobCallback;
+import android.app.job.IJobService;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -39,32 +39,32 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.task.controllers.TaskStatus;
+import com.android.server.job.controllers.JobStatus;
 
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
- * Handles client binding and lifecycle of a task. A task will only execute one at a time on an
+ * Handles client binding and lifecycle of a job. A job will only execute one at a time on an
  * instance of this class.
  */
-public class TaskServiceContext extends ITaskCallback.Stub implements ServiceConnection {
+public class JobServiceContext extends IJobCallback.Stub implements ServiceConnection {
     private static final boolean DEBUG = true;
-    private static final String TAG = "TaskServiceContext";
-    /** Define the maximum # of tasks allowed to run on a service at once. */
-    private static final int defaultMaxActiveTasksPerService =
+    private static final String TAG = "JobServiceContext";
+    /** Define the maximum # of jobs allowed to run on a service at once. */
+    private static final int defaultMaxActiveJobsPerService =
             ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
-    /** Amount of time a task is allowed to execute for before being considered timed-out. */
+    /** Amount of time a job is allowed to execute for before being considered timed-out. */
     private static final long EXECUTING_TIMESLICE_MILLIS = 60 * 1000;
-    /** Amount of time the TaskManager will wait for a response from an app for a message. */
+    /** Amount of time the JobScheduler will wait for a response from an app for a message. */
     private static final long OP_TIMEOUT_MILLIS = 8 * 1000;
     /** String prefix for all wakelock names. */
-    private static final String TM_WAKELOCK_PREFIX = "*task*/";
+    private static final String JS_WAKELOCK_PREFIX = "*job*/";
 
     private static final String[] VERB_STRINGS = {
             "VERB_STARTING", "VERB_EXECUTING", "VERB_STOPPING", "VERB_PENDING"
     };
 
-    // States that a task occupies while interacting with the client.
+    // States that a job occupies while interacting with the client.
     static final int VERB_BINDING = 0;
     static final int VERB_STARTING = 1;
     static final int VERB_EXECUTING = 2;
@@ -75,30 +75,30 @@
     private static final int MSG_TIMEOUT = 0;
     /** Received a callback from client. */
     private static final int MSG_CALLBACK = 1;
-    /** Run through list and start any ready tasks.*/
+    /** Run through list and start any ready jobs.*/
     private static final int MSG_SERVICE_BOUND = 2;
-    /** Cancel a task. */
+    /** Cancel a job. */
     private static final int MSG_CANCEL = 3;
-    /** Shutdown the Task. Used when the client crashes and we can't die gracefully.*/
+    /** Shutdown the job. Used when the client crashes and we can't die gracefully.*/
     private static final int MSG_SHUTDOWN_EXECUTION = 4;
 
     private final Handler mCallbackHandler;
-    /** Make callbacks to {@link TaskManagerService} to inform on task completion status. */
-    private final TaskCompletedListener mCompletedListener;
+    /** Make callbacks to {@link JobSchedulerService} to inform on job completion status. */
+    private final JobCompletedListener mCompletedListener;
     /** Used for service binding, etc. */
     private final Context mContext;
     private PowerManager.WakeLock mWakeLock;
 
     // Execution state.
-    private TaskParams mParams;
+    private JobParameters mParams;
     @VisibleForTesting
     int mVerb;
     private AtomicBoolean mCancelled = new AtomicBoolean();
 
-    /** All the information maintained about the task currently being executed. */
-    private TaskStatus mRunningTask;
+    /** All the information maintained about the job currently being executed. */
+    private JobStatus mRunningJob;
     /** Binder to the client service. */
-    ITaskService service;
+    IJobService service;
 
     private final Object mLock = new Object();
     /** Whether this context is free. */
@@ -109,45 +109,45 @@
     /** Track when job will timeout. */
     private long mTimeoutElapsed;
 
-    TaskServiceContext(TaskManagerService service, Looper looper) {
+    JobServiceContext(JobSchedulerService service, Looper looper) {
         this(service.getContext(), service, looper);
     }
 
     @VisibleForTesting
-    TaskServiceContext(Context context, TaskCompletedListener completedListener, Looper looper) {
+    JobServiceContext(Context context, JobCompletedListener completedListener, Looper looper) {
         mContext = context;
-        mCallbackHandler = new TaskServiceHandler(looper);
+        mCallbackHandler = new JobServiceHandler(looper);
         mCompletedListener = completedListener;
         mAvailable = true;
     }
 
     /**
-     * Give a task to this context for execution. Callers must first check {@link #isAvailable()}
+     * Give a job to this context for execution. Callers must first check {@link #isAvailable()}
      * to make sure this is a valid context.
-     * @param ts The status of the task that we are going to run.
-     * @return True if the task is valid and is running. False if the task cannot be executed.
+     * @param job The status of the job that we are going to run.
+     * @return True if the job is valid and is running. False if the job cannot be executed.
      */
-    boolean executeRunnableTask(TaskStatus ts) {
+    boolean executeRunnableJob(JobStatus job) {
         synchronized (mLock) {
             if (!mAvailable) {
                 Slog.e(TAG, "Starting new runnable but context is unavailable > Error.");
                 return false;
             }
 
-            mRunningTask = ts;
-            mParams = new TaskParams(ts.getTaskId(), ts.getExtras(), this);
+            mRunningJob = job;
+            mParams = new JobParameters(job.getJobId(), job.getExtras(), this);
             mExecutionStartTimeElapsed = SystemClock.elapsedRealtime();
 
             mVerb = VERB_BINDING;
-            final Intent intent = new Intent().setComponent(ts.getServiceComponent());
+            final Intent intent = new Intent().setComponent(job.getServiceComponent());
             boolean binding = mContext.bindServiceAsUser(intent, this,
                     Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND,
-                    new UserHandle(ts.getUserId()));
+                    new UserHandle(job.getUserId()));
             if (!binding) {
                 if (DEBUG) {
-                    Slog.d(TAG, ts.getServiceComponent().getShortClassName() + " unavailable.");
+                    Slog.d(TAG, job.getServiceComponent().getShortClassName() + " unavailable.");
                 }
-                mRunningTask = null;
+                mRunningJob = null;
                 mParams = null;
                 mExecutionStartTimeElapsed = 0L;
                 return false;
@@ -157,13 +157,13 @@
         }
     }
 
-    /** Used externally to query the running task. Will return null if there is no task running. */
-    TaskStatus getRunningTask() {
-        return mRunningTask;
+    /** Used externally to query the running job. Will return null if there is no job running. */
+    JobStatus getRunningJob() {
+        return mRunningJob;
     }
 
-    /** Called externally when a task that was scheduled for execution should be cancelled. */
-    void cancelExecutingTask() {
+    /** Called externally when a job that was scheduled for execution should be cancelled. */
+    void cancelExecutingJob() {
         mCallbackHandler.obtainMessage(MSG_CANCEL).sendToTarget();
     }
 
@@ -185,29 +185,29 @@
     }
 
     @Override
-    public void taskFinished(int taskId, boolean reschedule) {
+    public void jobFinished(int jobId, boolean reschedule) {
         if (!verifyCallingUid()) {
             return;
         }
-        mCallbackHandler.obtainMessage(MSG_CALLBACK, taskId, reschedule ? 1 : 0)
+        mCallbackHandler.obtainMessage(MSG_CALLBACK, jobId, reschedule ? 1 : 0)
                 .sendToTarget();
     }
 
     @Override
-    public void acknowledgeStopMessage(int taskId, boolean reschedule) {
+    public void acknowledgeStopMessage(int jobId, boolean reschedule) {
         if (!verifyCallingUid()) {
             return;
         }
-        mCallbackHandler.obtainMessage(MSG_CALLBACK, taskId, reschedule ? 1 : 0)
+        mCallbackHandler.obtainMessage(MSG_CALLBACK, jobId, reschedule ? 1 : 0)
                 .sendToTarget();
     }
 
     @Override
-    public void acknowledgeStartMessage(int taskId, boolean ongoing) {
+    public void acknowledgeStartMessage(int jobId, boolean ongoing) {
         if (!verifyCallingUid()) {
             return;
         }
-        mCallbackHandler.obtainMessage(MSG_CALLBACK, taskId, ongoing ? 1 : 0).sendToTarget();
+        mCallbackHandler.obtainMessage(MSG_CALLBACK, jobId, ongoing ? 1 : 0).sendToTarget();
     }
 
     /**
@@ -219,25 +219,25 @@
      */
     @Override
     public void onServiceConnected(ComponentName name, IBinder service) {
-        if (!name.equals(mRunningTask.getServiceComponent())) {
+        if (!name.equals(mRunningJob.getServiceComponent())) {
             mCallbackHandler.obtainMessage(MSG_SHUTDOWN_EXECUTION).sendToTarget();
             return;
         }
-        this.service = ITaskService.Stub.asInterface(service);
+        this.service = IJobService.Stub.asInterface(service);
         // Remove all timeouts.
         mCallbackHandler.removeMessages(MSG_TIMEOUT);
         final PowerManager pm =
                 (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
-                TM_WAKELOCK_PREFIX + mRunningTask.getServiceComponent().getPackageName());
-        mWakeLock.setWorkSource(new WorkSource(mRunningTask.getUid()));
+                JS_WAKELOCK_PREFIX + mRunningJob.getServiceComponent().getPackageName());
+        mWakeLock.setWorkSource(new WorkSource(mRunningJob.getUid()));
         mWakeLock.setReferenceCounted(false);
         mWakeLock.acquire();
         mCallbackHandler.obtainMessage(MSG_SERVICE_BOUND).sendToTarget();
     }
 
     /**
-     * If the client service crashes we reschedule this task and clean up.
+     * If the client service crashes we reschedule this job and clean up.
      * @param name The concrete component name of the service whose
      */
     @Override
@@ -251,7 +251,7 @@
      * @return True if the binder calling is coming from the client we expect.
      */
     private boolean verifyCallingUid() {
-        if (mRunningTask == null || Binder.getCallingUid() != mRunningTask.getUid()) {
+        if (mRunningJob == null || Binder.getCallingUid() != mRunningJob.getUid()) {
             if (DEBUG) {
                 Slog.d(TAG, "Stale callback received, ignoring.");
             }
@@ -261,12 +261,12 @@
     }
 
     /**
-     * Handles the lifecycle of the TaskService binding/callbacks, etc. The convention within this
+     * Handles the lifecycle of the JobService binding/callbacks, etc. The convention within this
      * class is to append 'H' to each function name that can only be called on this handler. This
      * isn't strictly necessary because all of these functions are private, but helps clarity.
      */
-    private class TaskServiceHandler extends Handler {
-        TaskServiceHandler(Looper looper) {
+    private class JobServiceHandler extends Handler {
+        JobServiceHandler(Looper looper) {
             super(looper);
         }
 
@@ -278,7 +278,7 @@
                     break;
                 case MSG_CALLBACK:
                     if (DEBUG) {
-                        Slog.d(TAG, "MSG_CALLBACK of : " + mRunningTask + " v:" +
+                        Slog.d(TAG, "MSG_CALLBACK of : " + mRunningJob + " v:" +
                                 VERB_STRINGS[mVerb]);
                     }
                     removeMessages(MSG_TIMEOUT);
@@ -292,7 +292,7 @@
                         handleFinishedH(reschedule);
                     } else {
                         if (DEBUG) {
-                            Slog.d(TAG, "Unrecognised callback: " + mRunningTask);
+                            Slog.d(TAG, "Unrecognised callback: " + mRunningJob);
                         }
                     }
                     break;
@@ -303,42 +303,42 @@
                     handleOpTimeoutH();
                     break;
                 case MSG_SHUTDOWN_EXECUTION:
-                    closeAndCleanupTaskH(true /* needsReschedule */);
+                    closeAndCleanupJobH(true /* needsReschedule */);
                     break;
                 default:
                     Log.e(TAG, "Unrecognised message: " + message);
             }
         }
 
-        /** Start the task on the service. */
+        /** Start the job on the service. */
         private void handleServiceBoundH() {
             if (mVerb != VERB_BINDING) {
-                Slog.e(TAG, "Sending onStartTask for a task that isn't pending. "
+                Slog.e(TAG, "Sending onStartJob for a job that isn't pending. "
                         + VERB_STRINGS[mVerb]);
-                closeAndCleanupTaskH(false /* reschedule */);
+                closeAndCleanupJobH(false /* reschedule */);
                 return;
             }
             if (mCancelled.get()) {
                 if (DEBUG) {
-                    Slog.d(TAG, "Task cancelled while waiting for bind to complete. "
-                            + mRunningTask);
+                    Slog.d(TAG, "Job cancelled while waiting for bind to complete. "
+                            + mRunningJob);
                 }
-                closeAndCleanupTaskH(true /* reschedule */);
+                closeAndCleanupJobH(true /* reschedule */);
                 return;
             }
             try {
                 mVerb = VERB_STARTING;
                 scheduleOpTimeOut();
-                service.startTask(mParams);
+                service.startJob(mParams);
             } catch (RemoteException e) {
                 Log.e(TAG, "Error sending onStart message to '" +
-                        mRunningTask.getServiceComponent().getShortClassName() + "' ", e);
+                        mRunningJob.getServiceComponent().getShortClassName() + "' ", e);
             }
         }
 
         /**
          * State behaviours.
-         * VERB_STARTING   -> Successful start, change task to VERB_EXECUTING and post timeout.
+         * VERB_STARTING   -> Successful start, change job to VERB_EXECUTING and post timeout.
          *     _PENDING    -> Error
          *     _EXECUTING  -> Error
          *     _STOPPING   -> Error
@@ -348,7 +348,7 @@
                 case VERB_STARTING:
                     mVerb = VERB_EXECUTING;
                     if (!workOngoing) {
-                        // Task is finished already so fast-forward to handleFinished.
+                        // Job is finished already so fast-forward to handleFinished.
                         handleFinishedH(false);
                         return;
                     }
@@ -360,14 +360,14 @@
                     scheduleOpTimeOut();
                     break;
                 default:
-                    Log.e(TAG, "Handling started task but task wasn't starting! Was "
+                    Log.e(TAG, "Handling started job but job wasn't starting! Was "
                             + VERB_STRINGS[mVerb] + ".");
                     return;
             }
         }
 
         /**
-         * VERB_EXECUTING  -> Client called taskFinished(), clean up and notify done.
+         * VERB_EXECUTING  -> Client called jobFinished(), clean up and notify done.
          *     _STOPPING   -> Successful finish, clean up and notify done.
          *     _STARTING   -> Error
          *     _PENDING    -> Error
@@ -376,20 +376,20 @@
             switch (mVerb) {
                 case VERB_EXECUTING:
                 case VERB_STOPPING:
-                    closeAndCleanupTaskH(reschedule);
+                    closeAndCleanupJobH(reschedule);
                     break;
                 default:
-                    Slog.e(TAG, "Got an execution complete message for a task that wasn't being" +
+                    Slog.e(TAG, "Got an execution complete message for a job that wasn't being" +
                             "executed. Was " + VERB_STRINGS[mVerb] + ".");
             }
         }
 
         /**
-         * A task can be in various states when a cancel request comes in:
+         * A job can be in various states when a cancel request comes in:
          * VERB_BINDING    -> Cancelled before bind completed. Mark as cancelled and wait for
          *                    {@link #onServiceConnected(android.content.ComponentName, android.os.IBinder)}
          *     _STARTING   -> Mark as cancelled and wait for
-         *                    {@link TaskServiceContext#acknowledgeStartMessage(int, boolean)}
+         *                    {@link JobServiceContext#acknowledgeStartMessage(int, boolean)}
          *     _EXECUTING  -> call {@link #sendStopMessageH}}.
          *     _ENDING     -> No point in doing anything here, so we ignore.
          */
@@ -406,48 +406,48 @@
                     // Nada.
                     break;
                 default:
-                    Slog.e(TAG, "Cancelling a task without a valid verb: " + mVerb);
+                    Slog.e(TAG, "Cancelling a job without a valid verb: " + mVerb);
                     break;
             }
         }
 
         /** Process MSG_TIMEOUT here. */
         private void handleOpTimeoutH() {
-            if (Log.isLoggable(TaskManagerService.TAG, Log.DEBUG)) {
+            if (Log.isLoggable(JobSchedulerService.TAG, Log.DEBUG)) {
                 Log.d(TAG, "MSG_TIMEOUT of " +
-                        mRunningTask.getServiceComponent().getShortClassName() + " : "
-                        + mParams.getTaskId());
+                        mRunningJob.getServiceComponent().getShortClassName() + " : "
+                        + mParams.getJobId());
             }
 
-            final int taskId = mParams.getTaskId();
+            final int jobId = mParams.getJobId();
             switch (mVerb) {
                 case VERB_STARTING:
                     // Client unresponsive - wedged or failed to respond in time. We don't really
-                    // know what happened so let's log it and notify the TaskManager
+                    // know what happened so let's log it and notify the JobScheduler
                     // FINISHED/NO-RETRY.
-                    Log.e(TAG, "No response from client for onStartTask '" +
-                            mRunningTask.getServiceComponent().getShortClassName() + "' tId: "
-                            + taskId);
-                    closeAndCleanupTaskH(false /* needsReschedule */);
+                    Log.e(TAG, "No response from client for onStartJob '" +
+                            mRunningJob.getServiceComponent().getShortClassName() + "' tId: "
+                            + jobId);
+                    closeAndCleanupJobH(false /* needsReschedule */);
                     break;
                 case VERB_STOPPING:
-                    // At least we got somewhere, so fail but ask the TaskManager to reschedule.
-                    Log.e(TAG, "No response from client for onStopTask, '" +
-                            mRunningTask.getServiceComponent().getShortClassName() + "' tId: "
-                            + taskId);
-                    closeAndCleanupTaskH(true /* needsReschedule */);
+                    // At least we got somewhere, so fail but ask the JobScheduler to reschedule.
+                    Log.e(TAG, "No response from client for onStopJob, '" +
+                            mRunningJob.getServiceComponent().getShortClassName() + "' tId: "
+                            + jobId);
+                    closeAndCleanupJobH(true /* needsReschedule */);
                     break;
                 case VERB_EXECUTING:
                     // Not an error - client ran out of time.
-                    Log.i(TAG, "Client timed out while executing (no taskFinished received)." +
+                    Log.i(TAG, "Client timed out while executing (no jobFinished received)." +
                             " sending onStop. "  +
-                            mRunningTask.getServiceComponent().getShortClassName() + "' tId: "
-                            + taskId);
+                            mRunningJob.getServiceComponent().getShortClassName() + "' tId: "
+                            + jobId);
                     sendStopMessageH();
                     break;
                 default:
-                    Log.e(TAG, "Handling timeout for an unknown active task state: "
-                            + mRunningTask);
+                    Log.e(TAG, "Handling timeout for an unknown active job state: "
+                            + mRunningJob);
                     return;
             }
         }
@@ -459,35 +459,35 @@
         private void sendStopMessageH() {
             mCallbackHandler.removeMessages(MSG_TIMEOUT);
             if (mVerb != VERB_EXECUTING) {
-                Log.e(TAG, "Sending onStopTask for a task that isn't started. " + mRunningTask);
-                closeAndCleanupTaskH(false /* reschedule */);
+                Log.e(TAG, "Sending onStopJob for a job that isn't started. " + mRunningJob);
+                closeAndCleanupJobH(false /* reschedule */);
                 return;
             }
             try {
                 mVerb = VERB_STOPPING;
                 scheduleOpTimeOut();
-                service.stopTask(mParams);
+                service.stopJob(mParams);
             } catch (RemoteException e) {
-                Log.e(TAG, "Error sending onStopTask to client.", e);
-                closeAndCleanupTaskH(false /* reschedule */);
+                Log.e(TAG, "Error sending onStopJob to client.", e);
+                closeAndCleanupJobH(false /* reschedule */);
             }
         }
 
         /**
-         * The provided task has finished, either by calling
-         * {@link android.app.task.TaskService#taskFinished(android.app.task.TaskParams, boolean)}
+         * The provided job has finished, either by calling
+         * {@link android.app.job.JobService#jobFinished(android.app.job.JobParameters, boolean)}
          * or from acknowledging the stop message we sent. Either way, we're done tracking it and
          * we want to clean up internally.
          */
-        private void closeAndCleanupTaskH(boolean reschedule) {
+        private void closeAndCleanupJobH(boolean reschedule) {
             removeMessages(MSG_TIMEOUT);
             synchronized (mLock) {
                 mWakeLock.release();
-                mContext.unbindService(TaskServiceContext.this);
-                mCompletedListener.onTaskCompleted(mRunningTask, reschedule);
+                mContext.unbindService(JobServiceContext.this);
+                mCompletedListener.onJobCompleted(mRunningJob, reschedule);
 
                 mWakeLock = null;
-                mRunningTask = null;
+                mRunningJob = null;
                 mParams = null;
                 mVerb = -1;
                 mCancelled.set(false);
@@ -508,8 +508,8 @@
                     EXECUTING_TIMESLICE_MILLIS : OP_TIMEOUT_MILLIS;
             if (DEBUG) {
                 Slog.d(TAG, "Scheduling time out for '" +
-                        mRunningTask.getServiceComponent().getShortClassName() + "' tId: " +
-                        mParams.getTaskId() + ", in " + (timeoutMillis / 1000) + " s");
+                        mRunningJob.getServiceComponent().getShortClassName() + "' tId: " +
+                        mParams.getJobId() + ", in " + (timeoutMillis / 1000) + " s");
             }
             Message m = mCallbackHandler.obtainMessage(MSG_TIMEOUT);
             mCallbackHandler.sendMessageDelayed(m, timeoutMillis);
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
new file mode 100644
index 0000000..3ea7171
--- /dev/null
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -0,0 +1,663 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job;
+
+import android.content.ComponentName;
+import android.app.job.JobInfo;
+import android.content.Context;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.PersistableBundle;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.AtomicFile;
+import android.util.ArraySet;
+import android.util.Pair;
+import android.util.Slog;
+import android.util.Xml;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.server.IoThread;
+import com.android.server.job.controllers.JobStatus;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+/**
+ * Maintain a list of classes, and accessor methods/logic for these jobs.
+ * This class offers the following functionality:
+ *     - When a job is added, it will determine if the job requirements have changed (update) and
+ *       whether the controllers need to be updated.
+ *     - Persists JobInfos, figures out when to to rewrite the JobInfo to disk.
+ *     - Handles rescheduling of jobs.
+ *       - When a periodic job is executed and must be re-added.
+ *       - When a job fails and the client requests that it be retried with backoff.
+ *       - This class <strong>is not</strong> thread-safe.
+ *
+ * Note on locking:
+ *      All callers to this class must <strong>lock on the class object they are calling</strong>.
+ *      This is important b/c {@link com.android.server.job.JobStore.WriteJobsMapToDiskRunnable}
+ *      and {@link com.android.server.job.JobStore.ReadJobMapFromDiskRunnable} lock on that
+ *      object.
+ */
+public class JobStore {
+    private static final String TAG = "JobStore";
+    private static final boolean DEBUG = JobSchedulerService.DEBUG;
+
+    /** Threshold to adjust how often we want to write to the db. */
+    private static final int MAX_OPS_BEFORE_WRITE = 1;
+    final ArraySet<JobStatus> mJobSet;
+    final Context mContext;
+
+    private int mDirtyOperations;
+
+    private static final Object sSingletonLock = new Object();
+    private final AtomicFile mJobsFile;
+    /** Handler backed by IoThread for writing to disk. */
+    private final Handler mIoHandler = IoThread.getHandler();
+    private static JobStore sSingleton;
+
+    /** Used by the {@link JobSchedulerService} to instantiate the JobStore. */
+    static JobStore initAndGet(JobSchedulerService jobManagerService) {
+        synchronized (sSingletonLock) {
+            if (sSingleton == null) {
+                sSingleton = new JobStore(jobManagerService.getContext(),
+                        Environment.getDataDirectory(), jobManagerService);
+            }
+            return sSingleton;
+        }
+    }
+
+    @VisibleForTesting
+    public static JobStore initAndGetForTesting(Context context, File dataDir,
+                                                 JobMapReadFinishedListener callback) {
+        return new JobStore(context, dataDir, callback);
+    }
+
+    private JobStore(Context context, File dataDir, JobMapReadFinishedListener callback) {
+        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>();
+
+        readJobMapFromDiskAsync(callback);
+    }
+
+    /**
+     * 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.
+     */
+    public boolean add(JobStatus jobStatus) {
+        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;
+    }
+
+    /**
+     * Whether this jobStatus object already exists in the JobStore.
+     */
+    public boolean containsJobIdForUid(int jobId, int uId) {
+        for (JobStatus ts : mJobSet) {
+            if (ts.getUid() == uId && ts.getJobId() == jobId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public int size() {
+        return mJobSet.size();
+    }
+
+    /**
+     * Remove the provided job. Will also delete the job if it was persisted.
+     * @return Whether or not the job existed to be removed.
+     */
+    public boolean remove(JobStatus jobStatus) {
+        boolean removed = mJobSet.remove(jobStatus);
+        if (!removed) {
+            if (DEBUG) {
+                Slog.d(TAG, "Couldn't remove job: didn't exist: " + jobStatus);
+            }
+            return false;
+        }
+        maybeWriteStatusToDiskAsync();
+        return removed;
+    }
+
+    @VisibleForTesting
+    public void clear() {
+        mJobSet.clear();
+        maybeWriteStatusToDiskAsync();
+    }
+
+    public List<JobStatus> getJobsByUser(int userHandle) {
+        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;
+    }
+
+    /**
+     * @param uid Uid of the requesting app.
+     * @return All JobStatus objects for a given uid from the master list.
+     */
+    public List<JobStatus> getJobsByUid(int uid) {
+        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;
+    }
+
+    /**
+     * @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.
+     */
+    public JobStatus getJobByUidAndJobId(int uid, int jobId) {
+        Iterator<JobStatus> it = mJobSet.iterator();
+        while (it.hasNext()) {
+            JobStatus ts = it.next();
+            if (ts.getUid() == uid && ts.getJobId() == jobid) {
+                return ts;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @return The live array of JobStatus objects.
+     */
+    public ArraySet<JobStatus> getJobs() {
+        return mJobSet;
+    }
+
+    /** Version of the db schema. */
+    private static final int JOBS_FILE_VERSION = 0;
+    /** Tag corresponds to constraints this job needs. */
+    private static final String XML_TAG_PARAMS_CONSTRAINTS = "constraints";
+    /** Tag corresponds to execution parameters. */
+    private static final String XML_TAG_PERIODIC = "periodic";
+    private static final String XML_TAG_ONEOFF = "one-off";
+    private static final String XML_TAG_EXTRAS = "extras";
+
+    /**
+     * 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
+     */
+    private void maybeWriteStatusToDiskAsync() {
+        mDirtyOperations++;
+        if (mDirtyOperations >= MAX_OPS_BEFORE_WRITE) {
+            if (DEBUG) {
+                Slog.v(TAG, "Writing jobs to disk.");
+            }
+            mIoHandler.post(new WriteJobsMapToDiskRunnable());
+        }
+    }
+
+    private void readJobMapFromDiskAsync(JobMapReadFinishedListener callback) {
+        mIoHandler.post(new ReadJobMapFromDiskRunnable(callback));
+    }
+
+    public void readJobMapFromDisk(JobMapReadFinishedListener callback) {
+        new ReadJobMapFromDiskRunnable(callback).run();
+    }
+
+    /**
+     * Runnable that writes {@link #mJobSet} out to xml.
+     * NOTE: This Runnable locks on JobStore.this
+     */
+    private class WriteJobsMapToDiskRunnable implements Runnable {
+        @Override
+        public void run() {
+            final long startElapsed = SystemClock.elapsedRealtime();
+            synchronized (JobStore.this) {
+                writeJobsMapImpl();
+            }
+            if (JobSchedulerService.DEBUG) {
+                Slog.v(TAG, "Finished writing, took " + (SystemClock.elapsedRealtime()
+                        - startElapsed) + "ms");
+            }
+        }
+
+        private void writeJobsMapImpl() {
+            try {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                XmlSerializer out = new FastXmlSerializer();
+                out.setOutput(baos, "utf-8");
+                out.startDocument(null, true);
+                out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+
+                out.startTag(null, "job-info");
+                out.attribute(null, "version", Integer.toString(JOBS_FILE_VERSION));
+                for (int i = 0; i < mJobSet.size(); i++) {
+                    final JobStatus jobStatus = mJobSet.valueAt(i);
+                    if (DEBUG) {
+                        Slog.d(TAG, "Saving job " + jobStatus.getJobId());
+                    }
+                    out.startTag(null, "job");
+                    addIdentifierAttributesToJobTag(out, jobStatus);
+                    writeConstraintsToXml(out, jobStatus);
+                    writeExecutionCriteriaToXml(out, jobStatus);
+                    writeBundleToXml(jobStatus.getExtras(), out);
+                    out.endTag(null, "job");
+                }
+                out.endTag(null, "job-info");
+                out.endDocument();
+
+                // Write out to disk in one fell sweep.
+                FileOutputStream fos = mJobsFile.startWrite();
+                fos.write(baos.toByteArray());
+                mJobsFile.finishWrite(fos);
+                mDirtyOperations = 0;
+            } catch (IOException e) {
+                if (DEBUG) {
+                    Slog.v(TAG, "Error writing out job data.", e);
+                }
+            } catch (XmlPullParserException e) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Error persisting bundle.", e);
+                }
+            }
+        }
+
+        /** Write out a tag with data comprising the required fields of this job and its client. */
+        private void addIdentifierAttributesToJobTag(XmlSerializer out, JobStatus jobStatus)
+                throws IOException {
+            out.attribute(null, "jobid", Integer.toString(jobStatus.getJobId()));
+            out.attribute(null, "package", jobStatus.getServiceComponent().getPackageName());
+            out.attribute(null, "class", jobStatus.getServiceComponent().getClassName());
+            out.attribute(null, "uid", Integer.toString(jobStatus.getUid()));
+        }
+
+        private void writeBundleToXml(PersistableBundle extras, XmlSerializer out)
+                throws IOException, XmlPullParserException {
+            out.startTag(null, XML_TAG_EXTRAS);
+            extras.saveToXml(out);
+            out.endTag(null, XML_TAG_EXTRAS);
+        }
+        /**
+         * Write out a tag with data identifying this job's constraints. If the constraint isn't here
+         * it doesn't apply.
+         */
+        private void writeConstraintsToXml(XmlSerializer out, JobStatus jobStatus) throws IOException {
+            out.startTag(null, XML_TAG_PARAMS_CONSTRAINTS);
+            if (jobStatus.hasUnmeteredConstraint()) {
+                out.attribute(null, "unmetered", Boolean.toString(true));
+            }
+            if (jobStatus.hasConnectivityConstraint()) {
+                out.attribute(null, "connectivity", Boolean.toString(true));
+            }
+            if (jobStatus.hasIdleConstraint()) {
+                out.attribute(null, "idle", Boolean.toString(true));
+            }
+            if (jobStatus.hasChargingConstraint()) {
+                out.attribute(null, "charging", Boolean.toString(true));
+            }
+            out.endTag(null, XML_TAG_PARAMS_CONSTRAINTS);
+        }
+
+        private void writeExecutionCriteriaToXml(XmlSerializer out, JobStatus jobStatus)
+                throws IOException {
+            final JobInfo job = jobStatus.getJob();
+            if (jobStatus.getJob().isPeriodic()) {
+                out.startTag(null, XML_TAG_PERIODIC);
+                out.attribute(null, "period", Long.toString(job.getIntervalMillis()));
+            } else {
+                out.startTag(null, XML_TAG_ONEOFF);
+            }
+
+            if (jobStatus.hasDeadlineConstraint()) {
+                // Wall clock deadline.
+                final long deadlineWallclock =  System.currentTimeMillis() +
+                        (jobStatus.getLatestRunTimeElapsed() - SystemClock.elapsedRealtime());
+                out.attribute(null, "deadline", Long.toString(deadlineWallclock));
+            }
+            if (jobStatus.hasTimingDelayConstraint()) {
+                final long delayWallclock = System.currentTimeMillis() +
+                        (jobStatus.getEarliestRunTime() - SystemClock.elapsedRealtime());
+                out.attribute(null, "delay", Long.toString(delayWallclock));
+            }
+
+            // Only write out back-off policy if it differs from the default.
+            // This also helps the case where the job is idle -> these aren't allowed to specify
+            // back-off.
+            if (jobStatus.getJob().getInitialBackoffMillis() != JobInfo.DEFAULT_INITIAL_BACKOFF_MILLIS
+                    || jobStatus.getJob().getBackoffPolicy() != JobInfo.DEFAULT_BACKOFF_POLICY) {
+                out.attribute(null, "backoff-policy", Integer.toString(job.getBackoffPolicy()));
+                out.attribute(null, "initial-backoff", Long.toString(job.getInitialBackoffMillis()));
+            }
+            if (job.isPeriodic()) {
+                out.endTag(null, XML_TAG_PERIODIC);
+            } else {
+                out.endTag(null, XML_TAG_ONEOFF);
+            }
+        }
+    }
+
+    /**
+     * Runnable that reads list of persisted job from xml.
+     * NOTE: This Runnable locks on JobStore.this
+     */
+    private class ReadJobMapFromDiskRunnable implements Runnable {
+        private JobMapReadFinishedListener mCallback;
+        public ReadJobMapFromDiskRunnable(JobMapReadFinishedListener callback) {
+            mCallback = callback;
+        }
+
+        @Override
+        public void run() {
+            try {
+                List<JobStatus> jobs;
+                FileInputStream fis = mJobsFile.openRead();
+                synchronized (JobStore.this) {
+                    jobs = readJobMapImpl(fis);
+                }
+                fis.close();
+                if (jobs != null) {
+                    mCallback.onJobMapReadFinished(jobs);
+                }
+            } catch (FileNotFoundException e) {
+                if (JobSchedulerService.DEBUG) {
+                    Slog.d(TAG, "Could not find jobs file, probably there was nothing to load.");
+                }
+            } catch (XmlPullParserException e) {
+                if (JobSchedulerService.DEBUG) {
+                    Slog.d(TAG, "Error parsing xml.", e);
+                }
+            } catch (IOException e) {
+                if (JobSchedulerService.DEBUG) {
+                    Slog.d(TAG, "Error parsing xml.", e);
+                }
+            }
+        }
+
+        private List<JobStatus> readJobMapImpl(FileInputStream fis) throws XmlPullParserException, IOException {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(fis, null);
+
+            int eventType = parser.getEventType();
+            while (eventType != XmlPullParser.START_TAG &&
+                    eventType != XmlPullParser.END_DOCUMENT) {
+                eventType = parser.next();
+                Slog.d(TAG, parser.getName());
+            }
+            if (eventType == XmlPullParser.END_DOCUMENT) {
+                if (DEBUG) {
+                    Slog.d(TAG, "No persisted jobs.");
+                }
+                return null;
+            }
+
+            String tagName = parser.getName();
+            if ("job-info".equals(tagName)) {
+                final List<JobStatus> jobs = new ArrayList<JobStatus>();
+                // Read in version info.
+                try {
+                    int version = Integer.valueOf(parser.getAttributeValue(null, "version"));
+                    if (version != JOBS_FILE_VERSION) {
+                        Slog.d(TAG, "Invalid version number, aborting jobs file read.");
+                        return null;
+                    }
+                } catch (NumberFormatException e) {
+                    Slog.e(TAG, "Invalid version number, aborting jobs file read.");
+                    return null;
+                }
+                eventType = parser.next();
+                do {
+                    // Read each <job/>
+                    if (eventType == XmlPullParser.START_TAG) {
+                        tagName = parser.getName();
+                        // Start reading job.
+                        if ("job".equals(tagName)) {
+                            JobStatus persistedJob = restoreJobFromXml(parser);
+                            if (persistedJob != null) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Read out " + persistedJob);
+                                }
+                                jobs.add(persistedJob);
+                            } else {
+                                Slog.d(TAG, "Error reading job from file.");
+                            }
+                        }
+                    }
+                    eventType = parser.next();
+                } while (eventType != XmlPullParser.END_DOCUMENT);
+                return jobs;
+            }
+            return null;
+        }
+
+        /**
+         * @param parser Xml parser at the beginning of a "<job/>" tag. The next "parser.next()" call
+         *               will take the parser into the body of the job tag.
+         * @return Newly instantiated job holding all the information we just read out of the xml tag.
+         */
+        private JobStatus restoreJobFromXml(XmlPullParser parser) throws XmlPullParserException,
+                IOException {
+            JobInfo.Builder jobBuilder;
+            int uid;
+
+            // Read out job identifier attributes.
+            try {
+                jobBuilder = buildBuilderFromXml(parser);
+                uid = Integer.valueOf(parser.getAttributeValue(null, "uid"));
+            } catch (NumberFormatException e) {
+                Slog.e(TAG, "Error parsing job's required fields, skipping");
+                return null;
+            }
+
+            int eventType;
+            // Read out constraints tag.
+            do {
+                eventType = parser.next();
+            } while (eventType == XmlPullParser.TEXT);  // Push through to next START_TAG.
+
+            if (!(eventType == XmlPullParser.START_TAG &&
+                    XML_TAG_PARAMS_CONSTRAINTS.equals(parser.getName()))) {
+                // Expecting a <constraints> start tag.
+                return null;
+            }
+            try {
+                buildConstraintsFromXml(jobBuilder, parser);
+            } catch (NumberFormatException e) {
+                Slog.d(TAG, "Error reading constraints, skipping.");
+                return null;
+            }
+            parser.next(); // Consume </constraints>
+
+            // Read out execution parameters tag.
+            do {
+                eventType = parser.next();
+            } while (eventType == XmlPullParser.TEXT);
+            if (eventType != XmlPullParser.START_TAG) {
+                return null;
+            }
+
+            Pair<Long, Long> runtimes;
+            try {
+                runtimes = buildExecutionTimesFromXml(parser);
+            } catch (NumberFormatException e) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Error parsing execution time parameters, skipping.");
+                }
+                return null;
+            }
+
+            if (XML_TAG_PERIODIC.equals(parser.getName())) {
+                try {
+                    String val = parser.getAttributeValue(null, "period");
+                    jobBuilder.setPeriodic(Long.valueOf(val));
+                } catch (NumberFormatException e) {
+                    Slog.d(TAG, "Error reading periodic execution criteria, skipping.");
+                    return null;
+                }
+            } else if (XML_TAG_ONEOFF.equals(parser.getName())) {
+                try {
+                    if (runtimes.first != JobStatus.NO_EARLIEST_RUNTIME) {
+                        jobBuilder.setMinimumLatency(runtimes.first - SystemClock.elapsedRealtime());
+                    }
+                    if (runtimes.second != JobStatus.NO_LATEST_RUNTIME) {
+                        jobBuilder.setOverrideDeadline(
+                                runtimes.second - SystemClock.elapsedRealtime());
+                    }
+                } catch (NumberFormatException e) {
+                    Slog.d(TAG, "Error reading job execution criteria, skipping.");
+                    return null;
+                }
+            } else {
+                if (DEBUG) {
+                    Slog.d(TAG, "Invalid parameter tag, skipping - " + parser.getName());
+                }
+                // Expecting a parameters start tag.
+                return null;
+            }
+            maybeBuildBackoffPolicyFromXml(jobBuilder, parser);
+
+            parser.nextTag(); // Consume parameters end tag.
+
+            // Read out extras Bundle.
+            do {
+                eventType = parser.next();
+            } while (eventType == XmlPullParser.TEXT);
+            if (!(eventType == XmlPullParser.START_TAG && XML_TAG_EXTRAS.equals(parser.getName()))) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Error reading extras, skipping.");
+                }
+                return null;
+            }
+
+            PersistableBundle extras = PersistableBundle.restoreFromXml(parser);
+            jobBuilder.setExtras(extras);
+            parser.nextTag(); // Consume </extras>
+
+            return new JobStatus(jobBuilder.build(), uid, runtimes.first, runtimes.second);
+        }
+
+        private JobInfo.Builder buildBuilderFromXml(XmlPullParser parser) throws NumberFormatException {
+            // Pull out required fields from <job> attributes.
+            int jobId = Integer.valueOf(parser.getAttributeValue(null, "jobid"));
+            String packageName = parser.getAttributeValue(null, "package");
+            String className = parser.getAttributeValue(null, "class");
+            ComponentName cname = new ComponentName(packageName, className);
+
+            return new JobInfo.Builder(jobId, cname);
+        }
+
+        private void buildConstraintsFromXml(JobInfo.Builder jobBuilder, XmlPullParser parser) {
+            String val = parser.getAttributeValue(null, "unmetered");
+            if (val != null) {
+                jobBuilder.setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED);
+            }
+            val = parser.getAttributeValue(null, "connectivity");
+            if (val != null) {
+                jobBuilder.setRequiredNetworkCapabilities(JobInfo.NetworkType.ANY);
+            }
+            val = parser.getAttributeValue(null, "idle");
+            if (val != null) {
+                jobBuilder.setRequiresDeviceIdle(true);
+            }
+            val = parser.getAttributeValue(null, "charging");
+            if (val != null) {
+                jobBuilder.setRequiresCharging(true);
+            }
+        }
+
+        /**
+         * Builds the back-off policy out of the params tag. These attributes may not exist, depending
+         * on whether the back-off was set when the job was first scheduled.
+         */
+        private void maybeBuildBackoffPolicyFromXml(JobInfo.Builder jobBuilder, XmlPullParser parser) {
+            String val = parser.getAttributeValue(null, "initial-backoff");
+            if (val != null) {
+                long initialBackoff = Long.valueOf(val);
+                val = parser.getAttributeValue(null, "backoff-policy");
+                int backoffPolicy = Integer.valueOf(val);  // Will throw NFE which we catch higher up.
+                jobBuilder.setBackoffCriteria(initialBackoff, backoffPolicy);
+            }
+        }
+
+        /**
+         * Convenience function to read out and convert deadline and delay from xml into elapsed real
+         * time.
+         * @return A {@link android.util.Pair}, where the first value is the earliest elapsed runtime
+         * and the second is the latest elapsed runtime.
+         */
+        private Pair<Long, Long> buildExecutionTimesFromXml(XmlPullParser parser)
+                throws NumberFormatException {
+            // Pull out execution time data.
+            final long nowWallclock = System.currentTimeMillis();
+            final long nowElapsed = SystemClock.elapsedRealtime();
+
+            long earliestRunTimeElapsed = JobStatus.NO_EARLIEST_RUNTIME;
+            long latestRunTimeElapsed = JobStatus.NO_LATEST_RUNTIME;
+            String val = parser.getAttributeValue(null, "deadline");
+            if (val != null) {
+                long latestRuntimeWallclock = Long.valueOf(val);
+                long maxDelayElapsed =
+                        Math.max(latestRuntimeWallclock - nowWallclock, 0);
+                latestRunTimeElapsed = nowElapsed + maxDelayElapsed;
+            }
+            val = parser.getAttributeValue(null, "delay");
+            if (val != null) {
+                long earliestRuntimeWallclock = Long.valueOf(val);
+                long minDelayElapsed =
+                        Math.max(earliestRuntimeWallclock - nowWallclock, 0);
+                earliestRunTimeElapsed = nowElapsed + minDelayElapsed;
+
+            }
+            return Pair.create(earliestRunTimeElapsed, latestRunTimeElapsed);
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/job/StateChangedListener.java b/services/core/java/com/android/server/job/StateChangedListener.java
new file mode 100644
index 0000000..90c203a
--- /dev/null
+++ b/services/core/java/com/android/server/job/StateChangedListener.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job;
+
+import com.android.server.job.controllers.JobStatus;
+
+/**
+ * Interface through which a {@link com.android.server.job.controllers.StateController} informs
+ * the {@link com.android.server.job.JobSchedulerService} that there are some tasks potentially
+ * ready to be run.
+ */
+public interface StateChangedListener {
+    /**
+     * Called by the controller to notify the JobManager that it should check on the state of a
+     * task.
+     */
+    public void onControllerStateChanged();
+
+    /**
+     * Called by the controller to notify the JobManager that regardless of the state of the task,
+     * it must be run immediately.
+     * @param jobStatus The state of the task which is to be run immediately.
+     */
+    public void onRunJobNow(JobStatus jobStatus);
+}
diff --git a/services/core/java/com/android/server/task/controllers/BatteryController.java b/services/core/java/com/android/server/job/controllers/BatteryController.java
similarity index 94%
rename from services/core/java/com/android/server/task/controllers/BatteryController.java
rename to services/core/java/com/android/server/job/controllers/BatteryController.java
index 443527f..010de5c 100644
--- a/services/core/java/com/android/server/task/controllers/BatteryController.java
+++ b/services/core/java/com/android/server/job/controllers/BatteryController.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.server.task.controllers;
+package com.android.server.job.controllers;
 
 import android.app.AlarmManager;
 import android.app.PendingIntent;
@@ -32,8 +32,8 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.BatteryService;
-import com.android.server.task.StateChangedListener;
-import com.android.server.task.TaskManagerService;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.job.StateChangedListener;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -54,10 +54,10 @@
     /** Wait this long after phone is plugged in before doing any work. */
     private static final long STABLE_CHARGING_THRESHOLD_MILLIS = 2 * 60 * 1000; // 2 minutes.
 
-    private List<TaskStatus> mTrackedTasks = new ArrayList<TaskStatus>();
+    private List<JobStatus> mTrackedTasks = new ArrayList<JobStatus>();
     private ChargingTracker mChargeTracker;
 
-    public static BatteryController get(TaskManagerService taskManagerService) {
+    public static BatteryController get(JobSchedulerService taskManagerService) {
         synchronized (sCreationLock) {
             if (sController == null) {
                 sController = new BatteryController(taskManagerService,
@@ -85,7 +85,7 @@
     }
 
     @Override
-    public void maybeStartTrackingTask(TaskStatus taskStatus) {
+    public void maybeStartTrackingJob(JobStatus taskStatus) {
         if (taskStatus.hasChargingConstraint()) {
             synchronized (mTrackedTasks) {
                 mTrackedTasks.add(taskStatus);
@@ -96,7 +96,7 @@
     }
 
     @Override
-    public void maybeStopTrackingTask(TaskStatus taskStatus) {
+    public void maybeStopTrackingJob(JobStatus taskStatus) {
         if (taskStatus.hasChargingConstraint()) {
             synchronized (mTrackedTasks) {
                 mTrackedTasks.remove(taskStatus);
@@ -108,7 +108,7 @@
         final boolean stablePower = mChargeTracker.isOnStablePower();
         boolean reportChange = false;
         synchronized (mTrackedTasks) {
-            for (TaskStatus ts : mTrackedTasks) {
+            for (JobStatus ts : mTrackedTasks) {
                 boolean previous = ts.chargingConstraintSatisfied.getAndSet(stablePower);
                 if (previous != stablePower) {
                     reportChange = true;
diff --git a/services/core/java/com/android/server/task/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
similarity index 75%
rename from services/core/java/com/android/server/task/controllers/ConnectivityController.java
rename to services/core/java/com/android/server/job/controllers/ConnectivityController.java
index c1ab0f0..7e79ff7 100644
--- a/services/core/java/com/android/server/task/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.server.task.controllers;
+package com.android.server.job.controllers;
 
 
 import android.content.BroadcastReceiver;
@@ -28,8 +28,8 @@
 import android.util.Slog;
 
 import com.android.server.ConnectivityService;
-import com.android.server.task.StateChangedListener;
-import com.android.server.task.TaskManagerService;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.job.StateChangedListener;
 
 import java.io.PrintWriter;
 import java.util.LinkedList;
@@ -42,9 +42,9 @@
  */
 public class ConnectivityController extends StateController implements
         ConnectivityManager.OnNetworkActiveListener {
-    private static final String TAG = "TaskManager.Conn";
+    private static final String TAG = "JobScheduler.Conn";
 
-    private final List<TaskStatus> mTrackedTasks = new LinkedList<TaskStatus>();
+    private final List<JobStatus> mTrackedJobs = new LinkedList<JobStatus>();
     private final BroadcastReceiver mConnectivityChangedReceiver =
             new ConnectivityChangedReceiver();
     /** Singleton. */
@@ -55,10 +55,10 @@
     /** Track whether the latest active network is connected. */
     private boolean mNetworkConnected;
 
-    public static ConnectivityController get(TaskManagerService taskManager) {
+    public static ConnectivityController get(JobSchedulerService jms) {
         synchronized (sCreationLock) {
             if (mSingleton == null) {
-                mSingleton = new ConnectivityController(taskManager, taskManager.getContext());
+                mSingleton = new ConnectivityController(jms, jms.getContext());
             }
             return mSingleton;
         }
@@ -82,21 +82,21 @@
     }
 
     @Override
-    public void maybeStartTrackingTask(TaskStatus taskStatus) {
-        if (taskStatus.hasConnectivityConstraint() || taskStatus.hasUnmeteredConstraint()) {
-            synchronized (mTrackedTasks) {
-                taskStatus.connectivityConstraintSatisfied.set(mNetworkConnected);
-                taskStatus.unmeteredConstraintSatisfied.set(mNetworkUnmetered);
-                mTrackedTasks.add(taskStatus);
+    public void maybeStartTrackingJob(JobStatus jobStatus) {
+        if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()) {
+            synchronized (mTrackedJobs) {
+                jobStatus.connectivityConstraintSatisfied.set(mNetworkConnected);
+                jobStatus.unmeteredConstraintSatisfied.set(mNetworkUnmetered);
+                mTrackedJobs.add(jobStatus);
             }
         }
     }
 
     @Override
-    public void maybeStopTrackingTask(TaskStatus taskStatus) {
-        if (taskStatus.hasConnectivityConstraint() || taskStatus.hasUnmeteredConstraint()) {
-            synchronized (mTrackedTasks) {
-                mTrackedTasks.remove(taskStatus);
+    public void maybeStopTrackingJob(JobStatus jobStatus) {
+        if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()) {
+            synchronized (mTrackedJobs) {
+                mTrackedJobs.remove(jobStatus);
             }
         }
     }
@@ -104,16 +104,16 @@
     /**
      * @param userId Id of the user for whom we are updating the connectivity state.
      */
-    private void updateTrackedTasks(int userId) {
-        synchronized (mTrackedTasks) {
+    private void updateTrackedJobs(int userId) {
+        synchronized (mTrackedJobs) {
             boolean changed = false;
-            for (TaskStatus ts : mTrackedTasks) {
-                if (ts.getUserId() != userId) {
+            for (JobStatus js : mTrackedJobs) {
+                if (js.getUserId() != userId) {
                     continue;
                 }
                 boolean prevIsConnected =
-                        ts.connectivityConstraintSatisfied.getAndSet(mNetworkConnected);
-                boolean prevIsMetered = ts.unmeteredConstraintSatisfied.getAndSet(mNetworkUnmetered);
+                        js.connectivityConstraintSatisfied.getAndSet(mNetworkConnected);
+                boolean prevIsMetered = js.unmeteredConstraintSatisfied.getAndSet(mNetworkUnmetered);
                 if (prevIsConnected != mNetworkConnected || prevIsMetered != mNetworkUnmetered) {
                     changed = true;
                 }
@@ -125,16 +125,16 @@
     }
 
     /**
-     * We know the network has just come up. We want to run any tasks that are ready.
+     * We know the network has just come up. We want to run any jobs that are ready.
      */
     public synchronized void onNetworkActive() {
-        synchronized (mTrackedTasks) {
-            for (TaskStatus ts : mTrackedTasks) {
-                if (ts.isReady()) {
+        synchronized (mTrackedJobs) {
+            for (JobStatus js : mTrackedJobs) {
+                if (js.isReady()) {
                     if (DEBUG) {
-                        Slog.d(TAG, "Running " + ts + " due to network activity.");
+                        Slog.d(TAG, "Running " + js + " due to network activity.");
                     }
-                    mStateChangedListener.onRunTaskNow(ts);
+                    mStateChangedListener.onRunJobNow(js);
                 }
             }
         }
@@ -169,7 +169,7 @@
                 if (activeNetwork == null) {
                     mNetworkUnmetered = false;
                     mNetworkConnected = false;
-                    updateTrackedTasks(userid);
+                    updateTrackedJobs(userid);
                 } else if (activeNetwork.getType() == networkType) {
                     mNetworkUnmetered = false;
                     mNetworkConnected = !intent.getBooleanExtra(
@@ -177,7 +177,7 @@
                     if (mNetworkConnected) {  // No point making the call if we know there's no conn.
                         mNetworkUnmetered = !connManager.isActiveNetworkMetered();
                     }
-                    updateTrackedTasks(userid);
+                    updateTrackedJobs(userid);
                 }
             } else {
                 if (DEBUG) {
@@ -191,10 +191,10 @@
     public void dumpControllerState(PrintWriter pw) {
         pw.println("Conn.");
         pw.println("connected: " + mNetworkConnected + " unmetered: " + mNetworkUnmetered);
-        for (TaskStatus ts: mTrackedTasks) {
-            pw.println(String.valueOf(ts.hashCode()).substring(0, 3) + ".."
-                    + ": C=" + ts.hasConnectivityConstraint()
-                    + ", UM=" + ts.hasUnmeteredConstraint());
+        for (JobStatus js: mTrackedJobs) {
+            pw.println(String.valueOf(js.hashCode()).substring(0, 3) + ".."
+                    + ": C=" + js.hasConnectivityConstraint()
+                    + ", UM=" + js.hasUnmeteredConstraint());
         }
     }
 }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/task/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
similarity index 92%
rename from services/core/java/com/android/server/task/controllers/IdleController.java
rename to services/core/java/com/android/server/job/controllers/IdleController.java
index e749b00..07ffe4d 100644
--- a/services/core/java/com/android/server/task/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.server.task.controllers;
+package com.android.server.job.controllers;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -29,8 +29,8 @@
 import android.os.SystemClock;
 import android.util.Slog;
 
-import com.android.server.task.StateChangedListener;
-import com.android.server.task.TaskManagerService;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.job.StateChangedListener;
 
 public class IdleController extends StateController {
     private static final String TAG = "IdleController";
@@ -43,14 +43,14 @@
     private static final String ACTION_TRIGGER_IDLE =
             "com.android.server.task.controllers.IdleController.ACTION_TRIGGER_IDLE";
 
-    final ArrayList<TaskStatus> mTrackedTasks = new ArrayList<TaskStatus>();
+    final ArrayList<JobStatus> mTrackedTasks = new ArrayList<JobStatus>();
     IdlenessTracker mIdleTracker;
 
     // Singleton factory
     private static Object sCreationLock = new Object();
     private static volatile IdleController sController;
 
-    public static IdleController get(TaskManagerService service) {
+    public static IdleController get(JobSchedulerService service) {
         synchronized (sCreationLock) {
             if (sController == null) {
                 sController = new IdleController(service, service.getContext());
@@ -68,7 +68,7 @@
      * StateController interface
      */
     @Override
-    public void maybeStartTrackingTask(TaskStatus taskStatus) {
+    public void maybeStartTrackingJob(JobStatus taskStatus) {
         if (taskStatus.hasIdleConstraint()) {
             synchronized (mTrackedTasks) {
                 mTrackedTasks.add(taskStatus);
@@ -78,7 +78,7 @@
     }
 
     @Override
-    public void maybeStopTrackingTask(TaskStatus taskStatus) {
+    public void maybeStopTrackingJob(JobStatus taskStatus) {
         synchronized (mTrackedTasks) {
             mTrackedTasks.remove(taskStatus);
         }
@@ -89,7 +89,7 @@
      */
     void reportNewIdleState(boolean isIdle) {
         synchronized (mTrackedTasks) {
-            for (TaskStatus task : mTrackedTasks) {
+            for (JobStatus task : mTrackedTasks) {
                 task.idleConstraintSatisfied.set(isIdle);
             }
         }
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
new file mode 100644
index 0000000..15a6b25
--- /dev/null
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job.controllers;
+
+import android.app.job.JobInfo;
+import android.content.ComponentName;
+import android.os.PersistableBundle;
+import android.os.SystemClock;
+import android.os.UserHandle;
+
+import java.io.PrintWriter;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Uniquely identifies a job internally.
+ * Created from the public {@link android.app.job.JobInfo} object when it lands on the scheduler.
+ * Contains current state of the requirements of the job, as well as a function to evaluate
+ * whether it's ready to run.
+ * This object is shared among the various controllers - hence why the different fields are atomic.
+ * This isn't strictly necessary because each controller is only interested in a specific field,
+ * and the receivers that are listening for global state change will all run on the main looper,
+ * but we don't enforce that so this is safer.
+ * @hide
+ */
+public class JobStatus {
+    public static final long NO_LATEST_RUNTIME = Long.MAX_VALUE;
+    public static final long NO_EARLIEST_RUNTIME = 0L;
+
+    final JobInfo job;
+    final int uId;
+
+    /** At reschedule time we need to know whether to update job on disk. */
+    final boolean persisted;
+
+    // Constraints.
+    final AtomicBoolean chargingConstraintSatisfied = new AtomicBoolean();
+    final AtomicBoolean timeDelayConstraintSatisfied = new AtomicBoolean();
+    final AtomicBoolean deadlineConstraintSatisfied = new AtomicBoolean();
+    final AtomicBoolean idleConstraintSatisfied = new AtomicBoolean();
+    final AtomicBoolean unmeteredConstraintSatisfied = new AtomicBoolean();
+    final AtomicBoolean connectivityConstraintSatisfied = new AtomicBoolean();
+
+    /**
+     * Earliest point in the future at which this job will be eligible to run. A value of 0
+     * indicates there is no delay constraint. See {@link #hasTimingDelayConstraint()}.
+     */
+    private long earliestRunTimeElapsedMillis;
+    /**
+     * Latest point in the future at which this job must be run. A value of {@link Long#MAX_VALUE}
+     * indicates there is no deadline constraint. See {@link #hasDeadlineConstraint()}.
+     */
+    private long latestRunTimeElapsedMillis;
+    /** How many times this job has failed, used to compute back-off. */
+    private final int numFailures;
+
+    /** Provide a handle to the service that this job will be run on. */
+    public int getServiceToken() {
+        return uId;
+    }
+
+    private JobStatus(JobInfo job, int uId, boolean persisted, int numFailures) {
+        this.job = job;
+        this.uId = uId;
+        this.numFailures = numFailures;
+        this.persisted = persisted;
+    }
+
+    /** Create a newly scheduled job. */
+    public JobStatus(JobInfo job, int uId, boolean persisted) {
+        this(job, uId, persisted, 0);
+
+        final long elapsedNow = SystemClock.elapsedRealtime();
+
+        if (job.isPeriodic()) {
+            earliestRunTimeElapsedMillis = elapsedNow;
+            latestRunTimeElapsedMillis = elapsedNow + job.getIntervalMillis();
+        } else {
+            earliestRunTimeElapsedMillis = job.hasEarlyConstraint() ?
+                    elapsedNow + job.getMinLatencyMillis() : NO_EARLIEST_RUNTIME;
+            latestRunTimeElapsedMillis = job.hasLateConstraint() ?
+                    elapsedNow + job.getMaxExecutionDelayMillis() : NO_LATEST_RUNTIME;
+        }
+    }
+
+    /**
+     * Create a new JobStatus that was loaded from disk. We ignore the provided
+     * {@link android.app.job.JobInfo} time criteria because we can load a persisted periodic job
+     * from the {@link com.android.server.job.JobStore} and still want to respect its
+     * wallclock runtime rather than resetting it on every boot.
+     * We consider a freshly loaded job to no longer be in back-off.
+     */
+    public JobStatus(JobInfo job, int uId, long earliestRunTimeElapsedMillis,
+                      long latestRunTimeElapsedMillis) {
+        this(job, uId, true, 0);
+
+        this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis;
+        this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis;
+    }
+
+    /** Create a new job to be rescheduled with the provided parameters. */
+    public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis,
+                      long newLatestRuntimeElapsedMillis, int backoffAttempt) {
+        this(rescheduling.job, rescheduling.getUid(), rescheduling.isPersisted(), backoffAttempt);
+
+        earliestRunTimeElapsedMillis = newEarliestRuntimeElapsedMillis;
+        latestRunTimeElapsedMillis = newLatestRuntimeElapsedMillis;
+    }
+
+    public JobInfo getJob() {
+        return job;
+    }
+
+    public int getJobId() {
+        return job.getId();
+    }
+
+    public int getNumFailures() {
+        return numFailures;
+    }
+
+    public ComponentName getServiceComponent() {
+        return job.getService();
+    }
+
+    public int getUserId() {
+        return UserHandle.getUserId(uId);
+    }
+
+    public int getUid() {
+        return uId;
+    }
+
+    public PersistableBundle getExtras() {
+        return job.getExtras();
+    }
+
+    public boolean hasConnectivityConstraint() {
+        return job.getNetworkCapabilities() == JobInfo.NetworkType.ANY;
+    }
+
+    public boolean hasUnmeteredConstraint() {
+        return job.getNetworkCapabilities() == JobInfo.NetworkType.UNMETERED;
+    }
+
+    public boolean hasChargingConstraint() {
+        return job.isRequireCharging();
+    }
+
+    public boolean hasTimingDelayConstraint() {
+        return earliestRunTimeElapsedMillis != NO_EARLIEST_RUNTIME;
+    }
+
+    public boolean hasDeadlineConstraint() {
+        return latestRunTimeElapsedMillis != NO_LATEST_RUNTIME;
+    }
+
+    public boolean hasIdleConstraint() {
+        return job.isRequireDeviceIdle();
+    }
+
+    public long getEarliestRunTime() {
+        return earliestRunTimeElapsedMillis;
+    }
+
+    public long getLatestRunTimeElapsed() {
+        return latestRunTimeElapsedMillis;
+    }
+
+    public boolean isPersisted() {
+        return persisted;
+    }
+    /**
+     * @return Whether or not this job is ready to run, based on its requirements.
+     */
+    public synchronized boolean isReady() {
+        return (!hasChargingConstraint() || chargingConstraintSatisfied.get())
+                && (!hasTimingDelayConstraint() || timeDelayConstraintSatisfied.get())
+                && (!hasConnectivityConstraint() || connectivityConstraintSatisfied.get())
+                && (!hasUnmeteredConstraint() || unmeteredConstraintSatisfied.get())
+                && (!hasIdleConstraint() || idleConstraintSatisfied.get())
+                // Also ready if the deadline has expired - special case.
+                || (hasDeadlineConstraint() && deadlineConstraintSatisfied.get());
+    }
+
+    public boolean matches(int uid, int jobId) {
+        return this.job.getId() == jobId && this.uId == uid;
+    }
+
+    @Override
+    public String toString() {
+        return String.valueOf(hashCode()).substring(0, 3) + ".."
+                + ":[" + job.getService().getPackageName() + ",jId=" + job.getId()
+                + ",R=(" + earliestRunTimeElapsedMillis + "," + latestRunTimeElapsedMillis + ")"
+                + ",N=" + job.getNetworkCapabilities() + ",C=" + job.isRequireCharging()
+                + ",I=" + job.isRequireDeviceIdle() + ",F=" + numFailures
+                + (isReady() ? "(READY)" : "")
+                + "]";
+    }
+    // Dumpsys infrastructure
+    public void dump(PrintWriter pw, String prefix) {
+        pw.println(this.toString());
+    }
+}
diff --git a/services/core/java/com/android/server/task/controllers/StateController.java b/services/core/java/com/android/server/job/controllers/StateController.java
similarity index 70%
rename from services/core/java/com/android/server/task/controllers/StateController.java
rename to services/core/java/com/android/server/job/controllers/StateController.java
index a7f52f5..81658bf 100644
--- a/services/core/java/com/android/server/task/controllers/StateController.java
+++ b/services/core/java/com/android/server/job/controllers/StateController.java
@@ -14,18 +14,18 @@
  * limitations under the License
  */
 
-package com.android.server.task.controllers;
+package com.android.server.job.controllers;
 
 import android.content.Context;
 
-import com.android.server.task.StateChangedListener;
-import com.android.server.task.TaskManagerService;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.job.StateChangedListener;
 
 import java.io.PrintWriter;
 
 /**
- * Incorporates shared controller logic between the various controllers of the TaskManager.
- * These are solely responsible for tracking a list of tasks, and notifying the TM when these
+ * Incorporates shared controller logic between the various controllers of the JobManager.
+ * These are solely responsible for tracking a list of jobs, and notifying the JM when these
  * are ready to run, or whether they must be stopped.
  */
 public abstract class StateController {
@@ -39,16 +39,16 @@
     }
 
     /**
-     * Implement the logic here to decide whether a task should be tracked by this controller.
-     * This logic is put here so the TaskManger can be completely agnostic of Controller logic.
+     * Implement the logic here to decide whether a job should be tracked by this controller.
+     * This logic is put here so the JobManger can be completely agnostic of Controller logic.
      * Also called when updating a task, so implementing controllers have to be aware of
      * preexisting tasks.
      */
-    public abstract void maybeStartTrackingTask(TaskStatus taskStatus);
+    public abstract void maybeStartTrackingJob(JobStatus jobStatus);
     /**
      * Remove task - this will happen if the task is cancelled, completed, etc.
      */
-    public abstract void maybeStopTrackingTask(TaskStatus taskStatus);
+    public abstract void maybeStopTrackingJob(JobStatus jobStatus);
 
     public abstract void dumpControllerState(PrintWriter pw);
 
diff --git a/services/core/java/com/android/server/task/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
similarity index 61%
rename from services/core/java/com/android/server/task/controllers/TimeController.java
rename to services/core/java/com/android/server/job/controllers/TimeController.java
index b75036c..e46226c 100644
--- a/services/core/java/com/android/server/task/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.server.task.controllers;
+package com.android.server.job.controllers;
 
 import android.app.AlarmManager;
 import android.app.PendingIntent;
@@ -25,8 +25,8 @@
 import android.os.SystemClock;
 import android.util.Slog;
 
-import com.android.server.task.StateChangedListener;
-import com.android.server.task.TaskManagerService;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.job.StateChangedListener;
 
 import java.io.PrintWriter;
 import java.util.Iterator;
@@ -35,35 +35,35 @@
 import java.util.ListIterator;
 
 /**
- * This class sets an alarm for the next expiring task, and determines whether a task's minimum
+ * This class sets an alarm for the next expiring job, and determines whether a job's minimum
  * delay has been satisfied.
  */
 public class TimeController extends StateController {
-    private static final String TAG = "TaskManager.Time";
-    private static final String ACTION_TASK_EXPIRED =
-            "android.content.taskmanager.TASK_DEADLINE_EXPIRED";
-    private static final String ACTION_TASK_DELAY_EXPIRED =
-            "android.content.taskmanager.TASK_DELAY_EXPIRED";
+    private static final String TAG = "JobScheduler.Time";
+    private static final String ACTION_JOB_EXPIRED =
+            "android.content.jobscheduler.JOB_DEADLINE_EXPIRED";
+    private static final String ACTION_JOB_DELAY_EXPIRED =
+            "android.content.jobscheduler.JOB_DELAY_EXPIRED";
 
-    /** Set an alarm for the next task expiry. */
+    /** Set an alarm for the next job expiry. */
     private final PendingIntent mDeadlineExpiredAlarmIntent;
-    /** Set an alarm for the next task delay expiry. This*/
+    /** Set an alarm for the next job delay expiry. This*/
     private final PendingIntent mNextDelayExpiredAlarmIntent;
     /** Constant time determining how near in the future we'll set an alarm for. */
     private static final long MIN_WAKEUP_INTERVAL_MILLIS = 15 * 1000;
 
-    private long mNextTaskExpiredElapsedMillis;
+    private long mNextJobExpiredElapsedMillis;
     private long mNextDelayExpiredElapsedMillis;
 
     private AlarmManager mAlarmService = null;
-    /** List of tracked tasks, sorted asc. by deadline */
-    private final List<TaskStatus> mTrackedTasks = new LinkedList<TaskStatus>();
+    /** List of tracked jobs, sorted asc. by deadline */
+    private final List<JobStatus> mTrackedJobs = new LinkedList<JobStatus>();
     /** Singleton. */
     private static TimeController mSingleton;
 
-    public static synchronized TimeController get(TaskManagerService taskManager) {
+    public static synchronized TimeController get(JobSchedulerService jms) {
         if (mSingleton == null) {
-            mSingleton = new TimeController(taskManager, taskManager.getContext());
+            mSingleton = new TimeController(jms, jms.getContext());
         }
         return mSingleton;
     }
@@ -72,66 +72,66 @@
         super(stateChangedListener, context);
         mDeadlineExpiredAlarmIntent =
                 PendingIntent.getBroadcast(mContext, 0 /* ignored */,
-                        new Intent(ACTION_TASK_EXPIRED), 0);
+                        new Intent(ACTION_JOB_EXPIRED), 0);
         mNextDelayExpiredAlarmIntent =
                 PendingIntent.getBroadcast(mContext, 0 /* ignored */,
-                        new Intent(ACTION_TASK_DELAY_EXPIRED), 0);
-        mNextTaskExpiredElapsedMillis = Long.MAX_VALUE;
+                        new Intent(ACTION_JOB_DELAY_EXPIRED), 0);
+        mNextJobExpiredElapsedMillis = Long.MAX_VALUE;
         mNextDelayExpiredElapsedMillis = Long.MAX_VALUE;
 
         // Register BR for these intents.
-        IntentFilter intentFilter = new IntentFilter(ACTION_TASK_EXPIRED);
-        intentFilter.addAction(ACTION_TASK_DELAY_EXPIRED);
+        IntentFilter intentFilter = new IntentFilter(ACTION_JOB_EXPIRED);
+        intentFilter.addAction(ACTION_JOB_DELAY_EXPIRED);
         mContext.registerReceiver(mAlarmExpiredReceiver, intentFilter);
     }
 
     /**
-     * Check if the task has a timing constraint, and if so determine where to insert it in our
+     * Check if the job has a timing constraint, and if so determine where to insert it in our
      * list.
      */
     @Override
-    public synchronized void maybeStartTrackingTask(TaskStatus task) {
-        if (task.hasTimingDelayConstraint() || task.hasDeadlineConstraint()) {
-            maybeStopTrackingTask(task);
-            ListIterator<TaskStatus> it = mTrackedTasks.listIterator(mTrackedTasks.size());
+    public synchronized void maybeStartTrackingJob(JobStatus job) {
+        if (job.hasTimingDelayConstraint() || job.hasDeadlineConstraint()) {
+            maybeStopTrackingJob(job);
+            ListIterator<JobStatus> it = mTrackedJobs.listIterator(mTrackedJobs.size());
             while (it.hasPrevious()) {
-                TaskStatus ts = it.previous();
-                if (ts.getLatestRunTimeElapsed() < task.getLatestRunTimeElapsed()) {
+                JobStatus ts = it.previous();
+                if (ts.getLatestRunTimeElapsed() < job.getLatestRunTimeElapsed()) {
                     // Insert
                     break;
                 }
             }
-            it.add(task);
+            it.add(job);
             maybeUpdateAlarms(
-                    task.hasTimingDelayConstraint() ? task.getEarliestRunTime() : Long.MAX_VALUE,
-                    task.hasDeadlineConstraint() ? task.getLatestRunTimeElapsed() : Long.MAX_VALUE);
+                    job.hasTimingDelayConstraint() ? job.getEarliestRunTime() : Long.MAX_VALUE,
+                    job.hasDeadlineConstraint() ? job.getLatestRunTimeElapsed() : Long.MAX_VALUE);
         }
     }
 
     /**
-     * When we stop tracking a task, we only need to update our alarms if the task we're no longer
+     * When we stop tracking a job, we only need to update our alarms if the job we're no longer
      * tracking was the one our alarms were based off of.
      * Really an == comparison should be enough, but why play with fate? We'll do <=.
      */
     @Override
-    public synchronized void maybeStopTrackingTask(TaskStatus taskStatus) {
-        if (mTrackedTasks.remove(taskStatus)) {
+    public synchronized void maybeStopTrackingJob(JobStatus job) {
+        if (mTrackedJobs.remove(job)) {
             checkExpiredDelaysAndResetAlarm();
             checkExpiredDeadlinesAndResetAlarm();
         }
     }
 
     /**
-     * Determines whether this controller can stop tracking the given task.
-     * The controller is no longer interested in a task once its time constraint is satisfied, and
-     * the task's deadline is fulfilled - unlike other controllers a time constraint can't toggle
+     * Determines whether this controller can stop tracking the given job.
+     * The controller is no longer interested in a job once its time constraint is satisfied, and
+     * the job's deadline is fulfilled - unlike other controllers a time constraint can't toggle
      * back and forth.
      */
-    private boolean canStopTrackingTask(TaskStatus taskStatus) {
-        return (!taskStatus.hasTimingDelayConstraint() ||
-                taskStatus.timeDelayConstraintSatisfied.get()) &&
-                (!taskStatus.hasDeadlineConstraint() ||
-                        taskStatus.deadlineConstraintSatisfied.get());
+    private boolean canStopTrackingJob(JobStatus job) {
+        return (!job.hasTimingDelayConstraint() ||
+                job.timeDelayConstraintSatisfied.get()) &&
+                (!job.hasDeadlineConstraint() ||
+                        job.deadlineConstraintSatisfied.get());
     }
 
     private void ensureAlarmService() {
@@ -141,27 +141,27 @@
     }
 
     /**
-     * Checks list of tasks for ones that have an expired deadline, sending them to the TaskManager
+     * Checks list of jobs for ones that have an expired deadline, sending them to the JobScheduler
      * if so, removing them from this list, and updating the alarm for the next expiry time.
      */
     private synchronized void checkExpiredDeadlinesAndResetAlarm() {
         long nextExpiryTime = Long.MAX_VALUE;
         final long nowElapsedMillis = SystemClock.elapsedRealtime();
 
-        Iterator<TaskStatus> it = mTrackedTasks.iterator();
+        Iterator<JobStatus> it = mTrackedJobs.iterator();
         while (it.hasNext()) {
-            TaskStatus ts = it.next();
-            if (!ts.hasDeadlineConstraint()) {
+            JobStatus job = it.next();
+            if (!job.hasDeadlineConstraint()) {
                 continue;
             }
-            final long taskDeadline = ts.getLatestRunTimeElapsed();
+            final long jobDeadline = job.getLatestRunTimeElapsed();
 
-            if (taskDeadline <= nowElapsedMillis) {
-                ts.deadlineConstraintSatisfied.set(true);
-                mStateChangedListener.onRunTaskNow(ts);
+            if (jobDeadline <= nowElapsedMillis) {
+                job.deadlineConstraintSatisfied.set(true);
+                mStateChangedListener.onRunJobNow(job);
                 it.remove();
             } else {  // Sorted by expiry time, so take the next one and stop.
-                nextExpiryTime = taskDeadline;
+                nextExpiryTime = jobDeadline;
                 break;
             }
         }
@@ -169,31 +169,31 @@
     }
 
     /**
-     * Handles alarm that notifies us that a task's delay has expired. Iterates through the list of
-     * tracked tasks and marks them as ready as appropriate.
+     * Handles alarm that notifies us that a job's delay has expired. Iterates through the list of
+     * tracked jobs and marks them as ready as appropriate.
      */
     private synchronized void checkExpiredDelaysAndResetAlarm() {
         final long nowElapsedMillis = SystemClock.elapsedRealtime();
         long nextDelayTime = Long.MAX_VALUE;
         boolean ready = false;
-        Iterator<TaskStatus> it = mTrackedTasks.iterator();
+        Iterator<JobStatus> it = mTrackedJobs.iterator();
         while (it.hasNext()) {
-            final TaskStatus ts = it.next();
-            if (!ts.hasTimingDelayConstraint()) {
+            final JobStatus job = it.next();
+            if (!job.hasTimingDelayConstraint()) {
                 continue;
             }
-            final long taskDelayTime = ts.getEarliestRunTime();
-            if (taskDelayTime <= nowElapsedMillis) {
-                ts.timeDelayConstraintSatisfied.set(true);
-                if (canStopTrackingTask(ts)) {
+            final long jobDelayTime = job.getEarliestRunTime();
+            if (jobDelayTime <= nowElapsedMillis) {
+                job.timeDelayConstraintSatisfied.set(true);
+                if (canStopTrackingJob(job)) {
                     it.remove();
                 }
-                if (ts.isReady()) {
+                if (job.isReady()) {
                     ready = true;
                 }
             } else {  // Keep going through list to get next delay time.
-                if (nextDelayTime > taskDelayTime) {
-                    nextDelayTime = taskDelayTime;
+                if (nextDelayTime > jobDelayTime) {
+                    nextDelayTime = jobDelayTime;
                 }
             }
         }
@@ -207,13 +207,13 @@
         if (delayExpiredElapsed < mNextDelayExpiredElapsedMillis) {
             setDelayExpiredAlarm(delayExpiredElapsed);
         }
-        if (deadlineExpiredElapsed < mNextTaskExpiredElapsedMillis) {
+        if (deadlineExpiredElapsed < mNextJobExpiredElapsedMillis) {
             setDeadlineExpiredAlarm(deadlineExpiredElapsed);
         }
     }
 
     /**
-     * Set an alarm with the {@link android.app.AlarmManager} for the next time at which a task's
+     * Set an alarm with the {@link android.app.AlarmManager} for the next time at which a job's
      * delay will expire.
      * This alarm <b>will not</b> wake up the phone.
      */
@@ -228,7 +228,7 @@
     }
 
     /**
-     * Set an alarm with the {@link android.app.AlarmManager} for the next time at which a task's
+     * Set an alarm with the {@link android.app.AlarmManager} for the next time at which a job's
      * deadline will expire.
      * This alarm <b>will</b> wake up the phone.
      */
@@ -238,8 +238,8 @@
         if (alarmTimeElapsedMillis < earliestWakeupTimeElapsed) {
             alarmTimeElapsedMillis = earliestWakeupTimeElapsed;
         }
-        mNextTaskExpiredElapsedMillis = alarmTimeElapsedMillis;
-        updateAlarmWithPendingIntent(mDeadlineExpiredAlarmIntent, mNextTaskExpiredElapsedMillis);
+        mNextJobExpiredElapsedMillis = alarmTimeElapsedMillis;
+        updateAlarmWithPendingIntent(mDeadlineExpiredAlarmIntent, mNextJobExpiredElapsedMillis);
     }
 
     private void updateAlarmWithPendingIntent(PendingIntent pi, long alarmTimeElapsed) {
@@ -260,11 +260,11 @@
             if (DEBUG) {
                 Slog.d(TAG, "Just received alarm: " + intent.getAction());
             }
-            // An task has just expired, so we run through the list of tasks that we have and
+            // A job has just expired, so we run through the list of jobs that we have and
             // notify our StateChangedListener.
-            if (ACTION_TASK_EXPIRED.equals(intent.getAction())) {
+            if (ACTION_JOB_EXPIRED.equals(intent.getAction())) {
                 checkExpiredDeadlinesAndResetAlarm();
-            } else if (ACTION_TASK_DELAY_EXPIRED.equals(intent.getAction())) {
+            } else if (ACTION_JOB_DELAY_EXPIRED.equals(intent.getAction())) {
                 checkExpiredDelaysAndResetAlarm();
             }
         }
@@ -276,10 +276,10 @@
         pw.println("Alarms (" + SystemClock.elapsedRealtime() + ")");
         pw.println(
                 "Next delay alarm in " + (mNextDelayExpiredElapsedMillis - nowElapsed)/1000 + "s");
-        pw.println("Next deadline alarm in " + (mNextTaskExpiredElapsedMillis - nowElapsed)/1000
+        pw.println("Next deadline alarm in " + (mNextJobExpiredElapsedMillis - nowElapsed)/1000
                 + "s");
         pw.println("Tracking:");
-        for (TaskStatus ts : mTrackedTasks) {
+        for (JobStatus ts : mTrackedJobs) {
             pw.println(String.valueOf(ts.hashCode()).substring(0, 3) + ".."
                     + ": (" + (ts.hasTimingDelayConstraint() ? ts.getEarliestRunTime() : "N/A")
                     + ", " + (ts.hasDeadlineConstraint() ?ts.getLatestRunTimeElapsed() : "N/A")
diff --git a/services/core/java/com/android/server/task/StateChangedListener.java b/services/core/java/com/android/server/task/StateChangedListener.java
deleted file mode 100644
index ab5cc7c..0000000
--- a/services/core/java/com/android/server/task/StateChangedListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.task;
-
-import com.android.server.task.controllers.TaskStatus;
-
-/**
- * Interface through which a {@link com.android.server.task.controllers.StateController} informs
- * the {@link com.android.server.task.TaskManagerService} that there are some tasks potentially
- * ready to be run.
- */
-public interface StateChangedListener {
-    /**
-     * Called by the controller to notify the TaskManager that it should check on the state of a
-     * task.
-     */
-    public void onControllerStateChanged();
-
-    /**
-     * Called by the controller to notify the TaskManager that regardless of the state of the task,
-     * it must be run immediately.
-     * @param taskStatus The state of the task which is to be run immediately.
-     */
-    public void onRunTaskNow(TaskStatus taskStatus);
-}
diff --git a/services/core/java/com/android/server/task/TaskManagerService.java b/services/core/java/com/android/server/task/TaskManagerService.java
deleted file mode 100644
index 0c55a1d..0000000
--- a/services/core/java/com/android/server/task/TaskManagerService.java
+++ /dev/null
@@ -1,764 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.task;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import android.app.task.ITaskManager;
-import android.app.task.Task;
-import android.app.task.TaskManager;
-import android.content.BroadcastReceiver;
-import android.app.task.TaskService;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ServiceInfo;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import com.android.server.task.controllers.BatteryController;
-import com.android.server.task.controllers.ConnectivityController;
-import com.android.server.task.controllers.IdleController;
-import com.android.server.task.controllers.StateController;
-import com.android.server.task.controllers.TaskStatus;
-import com.android.server.task.controllers.TimeController;
-
-import java.util.LinkedList;
-
-/**
- * Responsible for taking tasks representing work to be performed by a client app, and determining
- * based on the criteria specified when that task should be run against the client application's
- * endpoint.
- * Implements logic for scheduling, and rescheduling tasks. The TaskManagerService knows nothing
- * about constraints, or the state of active tasks. It receives callbacks from the various
- * controllers and completed tasks and operates accordingly.
- *
- * Note on locking: Any operations that manipulate {@link #mTasks} need to lock on that object.
- * Any function with the suffix 'Locked' also needs to lock on {@link #mTasks}.
- * @hide
- */
-public class TaskManagerService extends com.android.server.SystemService
-        implements StateChangedListener, TaskCompletedListener, TaskMapReadFinishedListener {
-    // TODO: Switch this off for final version.
-    static final boolean DEBUG = true;
-    /** The number of concurrent tasks we run at one time. */
-    private static final int MAX_TASK_CONTEXTS_COUNT = 3;
-    static final String TAG = "TaskManager";
-    /** Master list of tasks. */
-    private final TaskStore mTasks;
-
-    static final int MSG_TASK_EXPIRED = 0;
-    static final int MSG_CHECK_TASKS = 1;
-
-    // Policy constants
-    /**
-     * Minimum # of idle tasks that must be ready in order to force the TM to schedule things
-     * early.
-     */
-    private static final int MIN_IDLE_COUNT = 1;
-    /**
-     * Minimum # of connectivity tasks that must be ready in order to force the TM to schedule
-     * things early.
-     */
-    private static final int MIN_CONNECTIVITY_COUNT = 2;
-    /**
-     * Minimum # of tasks (with no particular constraints) for which the TM will be happy running
-     * some work early.
-     */
-    private static final int MIN_READY_TASKS_COUNT = 4;
-
-    /**
-     * Track Services that have currently active or pending tasks. The index is provided by
-     * {@link TaskStatus#getServiceToken()}
-     */
-    private final List<TaskServiceContext> mActiveServices = new LinkedList<TaskServiceContext>();
-    /** List of controllers that will notify this service of updates to tasks. */
-    private List<StateController> mControllers;
-    /**
-     * Queue of pending tasks. The TaskServiceContext class will receive tasks from this list
-     * when ready to execute them.
-     */
-    private final LinkedList<TaskStatus> mPendingTasks = new LinkedList<TaskStatus>();
-
-    private final TaskHandler mHandler;
-    private final TaskManagerStub mTaskManagerStub;
-    /**
-     * Cleans up outstanding jobs when a package is removed. Even if it's being replaced later we
-     * still clean up. On reinstall the package will have a new uid.
-     */
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Slog.d(TAG, "Receieved: " + intent.getAction());
-            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
-                int uidRemoved = intent.getIntExtra(Intent.EXTRA_UID, -1);
-                if (DEBUG) {
-                    Slog.d(TAG, "Removing jobs for uid: " + uidRemoved);
-                }
-                cancelTasksForUid(uidRemoved);
-            } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
-                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                if (DEBUG) {
-                    Slog.d(TAG, "Removing jobs for user: " + userId);
-                }
-                cancelTasksForUser(userId);
-            }
-        }
-    };
-
-    /**
-     * Entry point from client to schedule the provided task.
-     * This cancels the task if it's already been scheduled, and replaces it with the one provided.
-     * @param task Task object containing execution parameters
-     * @param uId The package identifier of the application this task is for.
-     * @param canPersistTask Whether or not the client has the appropriate permissions for
-     *                       persisting this task.
-     * @return Result of this operation. See <code>TaskManager#RESULT_*</code> return codes.
-     */
-    public int schedule(Task task, int uId, boolean canPersistTask) {
-        TaskStatus taskStatus = new TaskStatus(task, uId, canPersistTask);
-        cancelTask(uId, task.getId());
-        startTrackingTask(taskStatus);
-        return TaskManager.RESULT_SUCCESS;
-    }
-
-    public List<Task> getPendingTasks(int uid) {
-        ArrayList<Task> outList = new ArrayList<Task>();
-        synchronized (mTasks) {
-            for (TaskStatus ts : mTasks.getTasks()) {
-                if (ts.getUid() == uid) {
-                    outList.add(ts.getTask());
-                }
-            }
-        }
-        return outList;
-    }
-
-    private void cancelTasksForUser(int userHandle) {
-        synchronized (mTasks) {
-            List<TaskStatus> tasksForUser = mTasks.getTasksByUser(userHandle);
-            for (TaskStatus toRemove : tasksForUser) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Cancelling: " + toRemove);
-                }
-                cancelTaskLocked(toRemove);
-            }
-        }
-    }
-
-    /**
-     * Entry point from client to cancel all tasks originating from their uid.
-     * This will remove the task from the master list, and cancel the task if it was staged for
-     * execution or being executed.
-     * @param uid To check against for removal of a task.
-     */
-    public void cancelTasksForUid(int uid) {
-        // Remove from master list.
-        synchronized (mTasks) {
-            List<TaskStatus> tasksForUid = mTasks.getTasksByUid(uid);
-            for (TaskStatus toRemove : tasksForUid) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Cancelling: " + toRemove);
-                }
-                cancelTaskLocked(toRemove);
-            }
-        }
-    }
-
-    /**
-     * Entry point from client to cancel the task corresponding to the taskId provided.
-     * This will remove the task from the master list, and cancel the task if it was staged for
-     * execution or being executed.
-     * @param uid Uid of the calling client.
-     * @param taskId Id of the task, provided at schedule-time.
-     */
-    public void cancelTask(int uid, int taskId) {
-        TaskStatus toCancel;
-        synchronized (mTasks) {
-            toCancel = mTasks.getTaskByUidAndTaskId(uid, taskId);
-            if (toCancel != null) {
-                cancelTaskLocked(toCancel);
-            }
-        }
-    }
-
-    private void cancelTaskLocked(TaskStatus cancelled) {
-        // Remove from store.
-        stopTrackingTask(cancelled);
-        // Remove from pending queue.
-        mPendingTasks.remove(cancelled);
-        // Cancel if running.
-        stopTaskOnServiceContextLocked(cancelled);
-    }
-
-    /**
-     * Initializes the system service.
-     * <p>
-     * Subclasses must define a single argument constructor that accepts the context
-     * and passes it to super.
-     * </p>
-     *
-     * @param context The system server context.
-     */
-    public TaskManagerService(Context context) {
-        super(context);
-        // Create the controllers.
-        mControllers = new LinkedList<StateController>();
-        mControllers.add(ConnectivityController.get(this));
-        mControllers.add(TimeController.get(this));
-        mControllers.add(IdleController.get(this));
-        mControllers.add(BatteryController.get(this));
-
-        mHandler = new TaskHandler(context.getMainLooper());
-        mTaskManagerStub = new TaskManagerStub();
-        // Create the "runners".
-        for (int i = 0; i < MAX_TASK_CONTEXTS_COUNT; i++) {
-            mActiveServices.add(
-                    new TaskServiceContext(this, context.getMainLooper()));
-        }
-        mTasks = TaskStore.initAndGet(this);
-    }
-
-    @Override
-    public void onStart() {
-        publishBinderService(Context.TASK_SERVICE, mTaskManagerStub);
-    }
-
-    @Override
-    public void onBootPhase(int phase) {
-        if (PHASE_SYSTEM_SERVICES_READY == phase) {
-            // Register br for package removals and user removals.
-            final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
-            filter.addDataScheme("package");
-            getContext().registerReceiverAsUser(
-                    mBroadcastReceiver, UserHandle.ALL, filter, null, null);
-            final IntentFilter userFilter = new IntentFilter(Intent.ACTION_USER_REMOVED);
-            getContext().registerReceiverAsUser(
-                    mBroadcastReceiver, UserHandle.ALL, userFilter, null, null);
-        }
-    }
-
-    /**
-     * Called when we have a task status object that we need to insert in our
-     * {@link com.android.server.task.TaskStore}, and make sure all the relevant controllers know
-     * about.
-     */
-    private void startTrackingTask(TaskStatus taskStatus) {
-        boolean update;
-        synchronized (mTasks) {
-            update = mTasks.add(taskStatus);
-        }
-        for (StateController controller : mControllers) {
-            if (update) {
-                controller.maybeStopTrackingTask(taskStatus);
-            }
-            controller.maybeStartTrackingTask(taskStatus);
-        }
-    }
-
-    /**
-     * Called when we want to remove a TaskStatus object that we've finished executing. Returns the
-     * object removed.
-     */
-    private boolean stopTrackingTask(TaskStatus taskStatus) {
-        boolean removed;
-        synchronized (mTasks) {
-            // Remove from store as well as controllers.
-            removed = mTasks.remove(taskStatus);
-        }
-        if (removed) {
-            for (StateController controller : mControllers) {
-                controller.maybeStopTrackingTask(taskStatus);
-            }
-        }
-        return removed;
-    }
-
-    private boolean stopTaskOnServiceContextLocked(TaskStatus ts) {
-        for (TaskServiceContext tsc : mActiveServices) {
-            final TaskStatus executing = tsc.getRunningTask();
-            if (executing != null && executing.matches(ts.getUid(), ts.getTaskId())) {
-                tsc.cancelExecutingTask();
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @param ts TaskStatus we are querying against.
-     * @return Whether or not the task represented by the status object is currently being run or
-     * is pending.
-     */
-    private boolean isCurrentlyActiveLocked(TaskStatus ts) {
-        for (TaskServiceContext serviceContext : mActiveServices) {
-            final TaskStatus running = serviceContext.getRunningTask();
-            if (running != null && running.matches(ts.getUid(), ts.getTaskId())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * A task is rescheduled with exponential back-off if the client requests this from their
-     * execution logic.
-     * A caveat is for idle-mode tasks, for which the idle-mode constraint will usurp the
-     * timeliness of the reschedule. For an idle-mode task, no deadline is given.
-     * @param failureToReschedule Provided task status that we will reschedule.
-     * @return A newly instantiated TaskStatus with the same constraints as the last task except
-     * with adjusted timing constraints.
-     */
-    private TaskStatus getRescheduleTaskForFailure(TaskStatus failureToReschedule) {
-        final long elapsedNowMillis = SystemClock.elapsedRealtime();
-        final Task task = failureToReschedule.getTask();
-
-        final long initialBackoffMillis = task.getInitialBackoffMillis();
-        final int backoffAttempt = failureToReschedule.getNumFailures() + 1;
-        long newEarliestRuntimeElapsed = elapsedNowMillis;
-
-        switch (task.getBackoffPolicy()) {
-            case Task.BackoffPolicy.LINEAR:
-                newEarliestRuntimeElapsed += initialBackoffMillis * backoffAttempt;
-                break;
-            default:
-                if (DEBUG) {
-                    Slog.v(TAG, "Unrecognised back-off policy, defaulting to exponential.");
-                }
-            case Task.BackoffPolicy.EXPONENTIAL:
-                newEarliestRuntimeElapsed +=
-                        Math.pow(initialBackoffMillis * 0.001, backoffAttempt) * 1000;
-                break;
-        }
-        newEarliestRuntimeElapsed =
-                Math.min(newEarliestRuntimeElapsed, Task.MAX_BACKOFF_DELAY_MILLIS);
-        return new TaskStatus(failureToReschedule, newEarliestRuntimeElapsed,
-                TaskStatus.NO_LATEST_RUNTIME, backoffAttempt);
-    }
-
-    /**
-     * Called after a periodic has executed so we can to re-add it. We take the last execution time
-     * of the task to be the time of completion (i.e. the time at which this function is called).
-     * This could be inaccurate b/c the task can run for as long as
-     * {@link com.android.server.task.TaskServiceContext#EXECUTING_TIMESLICE_MILLIS}, but will lead
-     * to underscheduling at least, rather than if we had taken the last execution time to be the
-     * start of the execution.
-     * @return A new task representing the execution criteria for this instantiation of the
-     * recurring task.
-     */
-    private TaskStatus getRescheduleTaskForPeriodic(TaskStatus periodicToReschedule) {
-        final long elapsedNow = SystemClock.elapsedRealtime();
-        // Compute how much of the period is remaining.
-        long runEarly = Math.max(periodicToReschedule.getLatestRunTimeElapsed() - elapsedNow, 0);
-        long newEarliestRunTimeElapsed = elapsedNow + runEarly;
-        long period = periodicToReschedule.getTask().getIntervalMillis();
-        long newLatestRuntimeElapsed = newEarliestRunTimeElapsed + period;
-
-        if (DEBUG) {
-            Slog.v(TAG, "Rescheduling executed periodic. New execution window [" +
-                    newEarliestRunTimeElapsed/1000 + ", " + newLatestRuntimeElapsed/1000 + "]s");
-        }
-        return new TaskStatus(periodicToReschedule, newEarliestRunTimeElapsed,
-                newLatestRuntimeElapsed, 0 /* backoffAttempt */);
-    }
-
-    // TaskCompletedListener implementations.
-
-    /**
-     * A task just finished executing. We fetch the
-     * {@link com.android.server.task.controllers.TaskStatus} from the store and depending on
-     * whether we want to reschedule we readd it to the controllers.
-     * @param taskStatus Completed task.
-     * @param needsReschedule Whether the implementing class should reschedule this task.
-     */
-    @Override
-    public void onTaskCompleted(TaskStatus taskStatus, boolean needsReschedule) {
-        if (DEBUG) {
-            Slog.d(TAG, "Completed " + taskStatus + ", reschedule=" + needsReschedule);
-        }
-        if (!stopTrackingTask(taskStatus)) {
-            if (DEBUG) {
-                Slog.e(TAG, "Error removing task: could not find task to remove. Was task " +
-                        "removed while executing?");
-            }
-            return;
-        }
-        if (needsReschedule) {
-            TaskStatus rescheduled = getRescheduleTaskForFailure(taskStatus);
-            startTrackingTask(rescheduled);
-        } else if (taskStatus.getTask().isPeriodic()) {
-            TaskStatus rescheduledPeriodic = getRescheduleTaskForPeriodic(taskStatus);
-            startTrackingTask(rescheduledPeriodic);
-        }
-        mHandler.obtainMessage(MSG_CHECK_TASKS).sendToTarget();
-    }
-
-    // StateChangedListener implementations.
-
-    /**
-     * Off-board work to our handler thread as quickly as possible, b/c this call is probably being
-     * made on the main thread.
-     * For now this takes the task and if it's ready to run it will run it. In future we might not
-     * provide the task, so that the StateChangedListener has to run through its list of tasks to
-     * see which are ready. This will further decouple the controllers from the execution logic.
-     */
-    @Override
-    public void onControllerStateChanged() {
-        // Post a message to to run through the list of tasks and start/stop any that are eligible.
-        mHandler.obtainMessage(MSG_CHECK_TASKS).sendToTarget();
-    }
-
-    @Override
-    public void onRunTaskNow(TaskStatus taskStatus) {
-        mHandler.obtainMessage(MSG_TASK_EXPIRED, taskStatus).sendToTarget();
-    }
-
-    /**
-     * Disk I/O is finished, take the list of tasks we read from disk and add them to our
-     * {@link TaskStore}.
-     * This is run on the {@link com.android.server.IoThread} instance, which is a separate thread,
-     * and is called once at boot.
-     */
-    @Override
-    public void onTaskMapReadFinished(List<TaskStatus> tasks) {
-        synchronized (mTasks) {
-            for (TaskStatus ts : tasks) {
-                if (mTasks.containsTaskIdForUid(ts.getTaskId(), ts.getUid())) {
-                    // An app with BOOT_COMPLETED *might* have decided to reschedule their task, in
-                    // the same amount of time it took us to read it from disk. If this is the case
-                    // we leave it be.
-                    continue;
-                }
-                startTrackingTask(ts);
-            }
-        }
-    }
-
-    private class TaskHandler extends Handler {
-
-        public TaskHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message message) {
-            switch (message.what) {
-                case MSG_TASK_EXPIRED:
-                    synchronized (mTasks) {
-                        TaskStatus runNow = (TaskStatus) message.obj;
-                        if (!mPendingTasks.contains(runNow)) {
-                            mPendingTasks.add(runNow);
-                        }
-                    }
-                    queueReadyTasksForExecutionH();
-                    break;
-                case MSG_CHECK_TASKS:
-                    // Check the list of tasks and run some of them if we feel inclined.
-                    maybeQueueReadyTasksForExecutionH();
-                    break;
-            }
-            maybeRunPendingTasksH();
-            // Don't remove TASK_EXPIRED in case one came along while processing the queue.
-            removeMessages(MSG_CHECK_TASKS);
-        }
-
-        /**
-         * Run through list of tasks and execute all possible - at least one is expired so we do
-         * as many as we can.
-         */
-        private void queueReadyTasksForExecutionH() {
-            synchronized (mTasks) {
-                for (TaskStatus ts : mTasks.getTasks()) {
-                    if (isReadyToBeExecutedLocked(ts)) {
-                        mPendingTasks.add(ts);
-                    } else if (isReadyToBeCancelledLocked(ts)) {
-                        stopTaskOnServiceContextLocked(ts);
-                    }
-                }
-            }
-        }
-
-        /**
-         * The state of at least one task has changed. Here is where we could enforce various
-         * policies on when we want to execute tasks.
-         * Right now the policy is such:
-         * If >1 of the ready tasks is idle mode we send all of them off
-         * if more than 2 network connectivity tasks are ready we send them all off.
-         * If more than 4 tasks total are ready we send them all off.
-         * TODO: It would be nice to consolidate these sort of high-level policies somewhere.
-         */
-        private void maybeQueueReadyTasksForExecutionH() {
-            synchronized (mTasks) {
-                int idleCount = 0;
-                int backoffCount = 0;
-                int connectivityCount = 0;
-                List<TaskStatus> runnableTasks = new ArrayList<TaskStatus>();
-                for (TaskStatus ts : mTasks.getTasks()) {
-                    if (isReadyToBeExecutedLocked(ts)) {
-                        if (ts.getNumFailures() > 0) {
-                            backoffCount++;
-                        }
-                        if (ts.hasIdleConstraint()) {
-                            idleCount++;
-                        }
-                        if (ts.hasConnectivityConstraint() || ts.hasUnmeteredConstraint()) {
-                            connectivityCount++;
-                        }
-                        runnableTasks.add(ts);
-                    } else if (isReadyToBeCancelledLocked(ts)) {
-                        stopTaskOnServiceContextLocked(ts);
-                    }
-                }
-                if (backoffCount > 0 || idleCount >= MIN_IDLE_COUNT ||
-                        connectivityCount >= MIN_CONNECTIVITY_COUNT ||
-                        runnableTasks.size() >= MIN_READY_TASKS_COUNT) {
-                    for (TaskStatus ts : runnableTasks) {
-                        mPendingTasks.add(ts);
-                    }
-                }
-            }
-        }
-
-        /**
-         * Criteria for moving a job into the pending queue:
-         *      - It's ready.
-         *      - It's not pending.
-         *      - It's not already running on a TSC.
-         */
-        private boolean isReadyToBeExecutedLocked(TaskStatus ts) {
-              return ts.isReady() && !mPendingTasks.contains(ts) && !isCurrentlyActiveLocked(ts);
-        }
-
-        /**
-         * Criteria for cancelling an active job:
-         *      - It's not ready
-         *      - It's running on a TSC.
-         */
-        private boolean isReadyToBeCancelledLocked(TaskStatus ts) {
-            return !ts.isReady() && isCurrentlyActiveLocked(ts);
-        }
-
-        /**
-         * Reconcile jobs in the pending queue against available execution contexts.
-         * A controller can force a task into the pending queue even if it's already running, but
-         * here is where we decide whether to actually execute it.
-         */
-        private void maybeRunPendingTasksH() {
-            synchronized (mTasks) {
-                Iterator<TaskStatus> it = mPendingTasks.iterator();
-                while (it.hasNext()) {
-                    TaskStatus nextPending = it.next();
-                    TaskServiceContext availableContext = null;
-                    for (TaskServiceContext tsc : mActiveServices) {
-                        final TaskStatus running = tsc.getRunningTask();
-                        if (running != null && running.matches(nextPending.getUid(),
-                                nextPending.getTaskId())) {
-                            // Already running this tId for this uId, skip.
-                            availableContext = null;
-                            break;
-                        }
-                        if (tsc.isAvailable()) {
-                            availableContext = tsc;
-                        }
-                    }
-                    if (availableContext != null) {
-                        if (!availableContext.executeRunnableTask(nextPending)) {
-                            if (DEBUG) {
-                                Slog.d(TAG, "Error executing " + nextPending);
-                            }
-                            mTasks.remove(nextPending);
-                        }
-                        it.remove();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Binder stub trampoline implementation
-     */
-    final class TaskManagerStub extends ITaskManager.Stub {
-        /** Cache determination of whether a given app can persist tasks
-         * key is uid of the calling app; value is undetermined/true/false
-         */
-        private final SparseArray<Boolean> mPersistCache = new SparseArray<Boolean>();
-
-        // Enforce that only the app itself (or shared uid participant) can schedule a
-        // task that runs one of the app's services, as well as verifying that the
-        // named service properly requires the BIND_TASK_SERVICE permission
-        private void enforceValidJobRequest(int uid, Task job) {
-            final PackageManager pm = getContext().getPackageManager();
-            final ComponentName service = job.getService();
-            try {
-                ServiceInfo si = pm.getServiceInfo(service, 0);
-                if (si.applicationInfo.uid != uid) {
-                    throw new IllegalArgumentException("uid " + uid +
-                            " cannot schedule job in " + service.getPackageName());
-                }
-                if (!TaskService.PERMISSION_BIND.equals(si.permission)) {
-                    throw new IllegalArgumentException("Scheduled service " + service
-                            + " does not require android.permission.BIND_TASK_SERVICE permission");
-                }
-            } catch (NameNotFoundException e) {
-                throw new IllegalArgumentException("No such service: " + service);
-            }
-        }
-
-        private boolean canPersistJobs(int pid, int uid) {
-            // If we get this far we're good to go; all we need to do now is check
-            // whether the app is allowed to persist its scheduled work.
-            final boolean canPersist;
-            synchronized (mPersistCache) {
-                Boolean cached = mPersistCache.get(uid);
-                if (cached != null) {
-                    canPersist = cached.booleanValue();
-                } else {
-                    // Persisting tasks is tantamount to running at boot, so we permit
-                    // it when the app has declared that it uses the RECEIVE_BOOT_COMPLETED
-                    // permission
-                    int result = getContext().checkPermission(
-                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED, pid, uid);
-                    canPersist = (result == PackageManager.PERMISSION_GRANTED);
-                    mPersistCache.put(uid, canPersist);
-                }
-            }
-            return canPersist;
-        }
-
-        // ITaskManager implementation
-        @Override
-        public int schedule(Task task) throws RemoteException {
-            if (DEBUG) {
-                Slog.d(TAG, "Scheduling task: " + task);
-            }
-            final int pid = Binder.getCallingPid();
-            final int uid = Binder.getCallingUid();
-
-            enforceValidJobRequest(uid, task);
-            final boolean canPersist = canPersistJobs(pid, uid);
-
-            long ident = Binder.clearCallingIdentity();
-            try {
-                return TaskManagerService.this.schedule(task, uid, canPersist);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
-
-        @Override
-        public List<Task> getAllPendingTasks() throws RemoteException {
-            final int uid = Binder.getCallingUid();
-
-            long ident = Binder.clearCallingIdentity();
-            try {
-                return TaskManagerService.this.getPendingTasks(uid);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
-
-        @Override
-        public void cancelAll() throws RemoteException {
-            final int uid = Binder.getCallingUid();
-
-            long ident = Binder.clearCallingIdentity();
-            try {
-                TaskManagerService.this.cancelTasksForUid(uid);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
-
-        @Override
-        public void cancel(int taskId) throws RemoteException {
-            final int uid = Binder.getCallingUid();
-
-            long ident = Binder.clearCallingIdentity();
-            try {
-                TaskManagerService.this.cancelTask(uid, taskId);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
-
-        /**
-         * "dumpsys" infrastructure
-         */
-        @Override
-        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-            getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
-
-            long identityToken = Binder.clearCallingIdentity();
-            try {
-                TaskManagerService.this.dumpInternal(pw);
-            } finally {
-                Binder.restoreCallingIdentity(identityToken);
-            }
-        }
-    };
-
-    void dumpInternal(PrintWriter pw) {
-        synchronized (mTasks) {
-            pw.println("Registered tasks:");
-            if (mTasks.size() > 0) {
-                for (TaskStatus ts : mTasks.getTasks()) {
-                    ts.dump(pw, "  ");
-                }
-            } else {
-                pw.println();
-                pw.println("No tasks scheduled.");
-            }
-            for (StateController controller : mControllers) {
-                pw.println();
-                controller.dumpControllerState(pw);
-            }
-            pw.println();
-            pw.println("Pending");
-            for (TaskStatus taskStatus : mPendingTasks) {
-                pw.println(taskStatus.hashCode());
-            }
-            pw.println();
-            pw.println("Active jobs:");
-            for (TaskServiceContext tsc : mActiveServices) {
-                if (tsc.isAvailable()) {
-                    continue;
-                } else {
-                    pw.println(tsc.getRunningTask().hashCode() + " for: " +
-                            (SystemClock.elapsedRealtime()
-                                    - tsc.getExecutionStartTimeElapsed())/1000 + "s " +
-                            "timeout: " + tsc.getTimeoutElapsed());
-                }
-            }
-        }
-        pw.println();
-    }
-}
diff --git a/services/core/java/com/android/server/task/TaskStore.java b/services/core/java/com/android/server/task/TaskStore.java
deleted file mode 100644
index 9e095e7..0000000
--- a/services/core/java/com/android/server/task/TaskStore.java
+++ /dev/null
@@ -1,663 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.task;
-
-import android.content.ComponentName;
-import android.app.task.Task;
-import android.content.Context;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.PersistableBundle;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.AtomicFile;
-import android.util.ArraySet;
-import android.util.Pair;
-import android.util.Slog;
-import android.util.Xml;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FastXmlSerializer;
-import com.android.server.IoThread;
-import com.android.server.task.controllers.TaskStatus;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
-/**
- * Maintain a list of classes, and accessor methods/logic for these tasks.
- * This class offers the following functionality:
- *     - When a task is added, it will determine if the task requirements have changed (update) and
- *       whether the controllers need to be updated.
- *     - Persists Tasks, figures out when to to rewrite the Task to disk.
- *     - Handles rescheduling of tasks.
- *       - When a periodic task is executed and must be re-added.
- *       - When a task fails and the client requests that it be retried with backoff.
- *       - This class <strong>is not</strong> thread-safe.
- *
- * Note on locking:
- *      All callers to this class must <strong>lock on the class object they are calling</strong>.
- *      This is important b/c {@link com.android.server.task.TaskStore.WriteTasksMapToDiskRunnable}
- *      and {@link com.android.server.task.TaskStore.ReadTaskMapFromDiskRunnable} lock on that
- *      object.
- */
-public class TaskStore {
-    private static final String TAG = "TaskManagerStore";
-    private static final boolean DEBUG = TaskManagerService.DEBUG;
-
-    /** Threshold to adjust how often we want to write to the db. */
-    private static final int MAX_OPS_BEFORE_WRITE = 1;
-    final ArraySet<TaskStatus> mTasksSet;
-    final Context mContext;
-
-    private int mDirtyOperations;
-
-    private static final Object sSingletonLock = new Object();
-    private final AtomicFile mTasksFile;
-    /** Handler backed by IoThread for writing to disk. */
-    private final Handler mIoHandler = IoThread.getHandler();
-    private static TaskStore sSingleton;
-
-    /** Used by the {@Link TaskManagerService} to instantiate the TaskStore. */
-    static TaskStore initAndGet(TaskManagerService taskManagerService) {
-        synchronized (sSingletonLock) {
-            if (sSingleton == null) {
-                sSingleton = new TaskStore(taskManagerService.getContext(),
-                        Environment.getDataDirectory(), taskManagerService);
-            }
-            return sSingleton;
-        }
-    }
-
-    @VisibleForTesting
-    public static TaskStore initAndGetForTesting(Context context, File dataDir,
-                                                 TaskMapReadFinishedListener callback) {
-        return new TaskStore(context, dataDir, callback);
-    }
-
-    private TaskStore(Context context, File dataDir, TaskMapReadFinishedListener callback) {
-        mContext = context;
-        mDirtyOperations = 0;
-
-        File systemDir = new File(dataDir, "system");
-        File taskDir = new File(systemDir, "task");
-        taskDir.mkdirs();
-        mTasksFile = new AtomicFile(new File(taskDir, "tasks.xml"));
-
-        mTasksSet = new ArraySet<TaskStatus>();
-
-        readTaskMapFromDiskAsync(callback);
-    }
-
-    /**
-     * Add a task to the master list, persisting it if necessary. If the TaskStatus already exists,
-     * it will be replaced.
-     * @param taskStatus Task to add.
-     * @return Whether or not an equivalent TaskStatus was replaced by this operation.
-     */
-    public boolean add(TaskStatus taskStatus) {
-        boolean replaced = mTasksSet.remove(taskStatus);
-        mTasksSet.add(taskStatus);
-        if (taskStatus.isPersisted()) {
-            maybeWriteStatusToDiskAsync();
-        }
-        if (DEBUG) {
-            Slog.d(TAG, "Added task status to store: " + taskStatus);
-        }
-        return replaced;
-    }
-
-    /**
-     * Whether this taskStatus object already exists in the TaskStore.
-     */
-    public boolean containsTaskIdForUid(int taskId, int uId) {
-        for (TaskStatus ts : mTasksSet) {
-            if (ts.getUid() == uId && ts.getTaskId() == taskId) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public int size() {
-        return mTasksSet.size();
-    }
-
-    /**
-     * Remove the provided task. Will also delete the task if it was persisted.
-     * @return Whether or not the task existed to be removed.
-     */
-    public boolean remove(TaskStatus taskStatus) {
-        boolean removed = mTasksSet.remove(taskStatus);
-        if (!removed) {
-            if (DEBUG) {
-                Slog.d(TAG, "Couldn't remove task: didn't exist: " + taskStatus);
-            }
-            return false;
-        }
-        maybeWriteStatusToDiskAsync();
-        return removed;
-    }
-
-    @VisibleForTesting
-    public void clear() {
-        mTasksSet.clear();
-        maybeWriteStatusToDiskAsync();
-    }
-
-    public List<TaskStatus> getTasksByUser(int userHandle) {
-        List<TaskStatus> matchingTasks = new ArrayList<TaskStatus>();
-        Iterator<TaskStatus> it = mTasksSet.iterator();
-        while (it.hasNext()) {
-            TaskStatus ts = it.next();
-            if (UserHandle.getUserId(ts.getUid()) == userHandle) {
-                matchingTasks.add(ts);
-            }
-        }
-        return matchingTasks;
-    }
-
-    /**
-     * @param uid Uid of the requesting app.
-     * @return All TaskStatus objects for a given uid from the master list.
-     */
-    public List<TaskStatus> getTasksByUid(int uid) {
-        List<TaskStatus> matchingTasks = new ArrayList<TaskStatus>();
-        Iterator<TaskStatus> it = mTasksSet.iterator();
-        while (it.hasNext()) {
-            TaskStatus ts = it.next();
-            if (ts.getUid() == uid) {
-                matchingTasks.add(ts);
-            }
-        }
-        return matchingTasks;
-    }
-
-    /**
-     * @param uid Uid of the requesting app.
-     * @param taskId Task id, specified at schedule-time.
-     * @return the TaskStatus that matches the provided uId and taskId, or null if none found.
-     */
-    public TaskStatus getTaskByUidAndTaskId(int uid, int taskId) {
-        Iterator<TaskStatus> it = mTasksSet.iterator();
-        while (it.hasNext()) {
-            TaskStatus ts = it.next();
-            if (ts.getUid() == uid && ts.getTaskId() == taskId) {
-                return ts;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @return The live array of TaskStatus objects.
-     */
-    public ArraySet<TaskStatus> getTasks() {
-        return mTasksSet;
-    }
-
-    /** Version of the db schema. */
-    private static final int TASKS_FILE_VERSION = 0;
-    /** Tag corresponds to constraints this task needs. */
-    private static final String XML_TAG_PARAMS_CONSTRAINTS = "constraints";
-    /** Tag corresponds to execution parameters. */
-    private static final String XML_TAG_PERIODIC = "periodic";
-    private static final String XML_TAG_ONEOFF = "one-off";
-    private static final String XML_TAG_EXTRAS = "extras";
-
-    /**
-     * Every time the state changes we write all the tasks in one swathe, 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
-     */
-    private void maybeWriteStatusToDiskAsync() {
-        mDirtyOperations++;
-        if (mDirtyOperations >= MAX_OPS_BEFORE_WRITE) {
-            if (DEBUG) {
-                Slog.v(TAG, "Writing tasks to disk.");
-            }
-            mIoHandler.post(new WriteTasksMapToDiskRunnable());
-        }
-    }
-
-    private void readTaskMapFromDiskAsync(TaskMapReadFinishedListener callback) {
-        mIoHandler.post(new ReadTaskMapFromDiskRunnable(callback));
-    }
-
-    public void readTaskMapFromDisk(TaskMapReadFinishedListener callback) {
-        new ReadTaskMapFromDiskRunnable(callback).run();
-    }
-
-    /**
-     * Runnable that writes {@link #mTasksSet} out to xml.
-     * NOTE: This Runnable locks on TaskStore.this
-     */
-    private class WriteTasksMapToDiskRunnable implements Runnable {
-        @Override
-        public void run() {
-            final long startElapsed = SystemClock.elapsedRealtime();
-            synchronized (TaskStore.this) {
-                writeTasksMapImpl();
-            }
-            if (TaskManagerService.DEBUG) {
-                Slog.v(TAG, "Finished writing, took " + (SystemClock.elapsedRealtime()
-                        - startElapsed) + "ms");
-            }
-        }
-
-        private void writeTasksMapImpl() {
-            try {
-                ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                XmlSerializer out = new FastXmlSerializer();
-                out.setOutput(baos, "utf-8");
-                out.startDocument(null, true);
-                out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
-
-                out.startTag(null, "task-info");
-                out.attribute(null, "version", Integer.toString(TASKS_FILE_VERSION));
-                for (int i = 0; i < mTasksSet.size(); i++) {
-                    final TaskStatus taskStatus = mTasksSet.valueAt(i);
-                    if (DEBUG) {
-                        Slog.d(TAG, "Saving task " + taskStatus.getTaskId());
-                    }
-                    out.startTag(null, "task");
-                    addIdentifierAttributesToTaskTag(out, taskStatus);
-                    writeConstraintsToXml(out, taskStatus);
-                    writeExecutionCriteriaToXml(out, taskStatus);
-                    writeBundleToXml(taskStatus.getExtras(), out);
-                    out.endTag(null, "task");
-                }
-                out.endTag(null, "task-info");
-                out.endDocument();
-
-                // Write out to disk in one fell sweep.
-                FileOutputStream fos = mTasksFile.startWrite();
-                fos.write(baos.toByteArray());
-                mTasksFile.finishWrite(fos);
-                mDirtyOperations = 0;
-            } catch (IOException e) {
-                if (DEBUG) {
-                    Slog.v(TAG, "Error writing out task data.", e);
-                }
-            } catch (XmlPullParserException e) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Error persisting bundle.", e);
-                }
-            }
-        }
-
-        /** Write out a tag with data comprising the required fields of this task and its client. */
-        private void addIdentifierAttributesToTaskTag(XmlSerializer out, TaskStatus taskStatus)
-                throws IOException {
-            out.attribute(null, "taskid", Integer.toString(taskStatus.getTaskId()));
-            out.attribute(null, "package", taskStatus.getServiceComponent().getPackageName());
-            out.attribute(null, "class", taskStatus.getServiceComponent().getClassName());
-            out.attribute(null, "uid", Integer.toString(taskStatus.getUid()));
-        }
-
-        private void writeBundleToXml(PersistableBundle extras, XmlSerializer out)
-                throws IOException, XmlPullParserException {
-            out.startTag(null, XML_TAG_EXTRAS);
-            extras.saveToXml(out);
-            out.endTag(null, XML_TAG_EXTRAS);
-        }
-        /**
-         * Write out a tag with data identifying this tasks constraints. If the constraint isn't here
-         * it doesn't apply.
-         */
-        private void writeConstraintsToXml(XmlSerializer out, TaskStatus taskStatus) throws IOException {
-            out.startTag(null, XML_TAG_PARAMS_CONSTRAINTS);
-            if (taskStatus.hasUnmeteredConstraint()) {
-                out.attribute(null, "unmetered", Boolean.toString(true));
-            }
-            if (taskStatus.hasConnectivityConstraint()) {
-                out.attribute(null, "connectivity", Boolean.toString(true));
-            }
-            if (taskStatus.hasIdleConstraint()) {
-                out.attribute(null, "idle", Boolean.toString(true));
-            }
-            if (taskStatus.hasChargingConstraint()) {
-                out.attribute(null, "charging", Boolean.toString(true));
-            }
-            out.endTag(null, XML_TAG_PARAMS_CONSTRAINTS);
-        }
-
-        private void writeExecutionCriteriaToXml(XmlSerializer out, TaskStatus taskStatus)
-                throws IOException {
-            final Task task = taskStatus.getTask();
-            if (taskStatus.getTask().isPeriodic()) {
-                out.startTag(null, XML_TAG_PERIODIC);
-                out.attribute(null, "period", Long.toString(task.getIntervalMillis()));
-            } else {
-                out.startTag(null, XML_TAG_ONEOFF);
-            }
-
-            if (taskStatus.hasDeadlineConstraint()) {
-                // Wall clock deadline.
-                final long deadlineWallclock =  System.currentTimeMillis() +
-                        (taskStatus.getLatestRunTimeElapsed() - SystemClock.elapsedRealtime());
-                out.attribute(null, "deadline", Long.toString(deadlineWallclock));
-            }
-            if (taskStatus.hasTimingDelayConstraint()) {
-                final long delayWallclock = System.currentTimeMillis() +
-                        (taskStatus.getEarliestRunTime() - SystemClock.elapsedRealtime());
-                out.attribute(null, "delay", Long.toString(delayWallclock));
-            }
-
-            // Only write out back-off policy if it differs from the default.
-            // This also helps the case where the task is idle -> these aren't allowed to specify
-            // back-off.
-            if (taskStatus.getTask().getInitialBackoffMillis() != Task.DEFAULT_INITIAL_BACKOFF_MILLIS
-                    || taskStatus.getTask().getBackoffPolicy() != Task.DEFAULT_BACKOFF_POLICY) {
-                out.attribute(null, "backoff-policy", Integer.toString(task.getBackoffPolicy()));
-                out.attribute(null, "initial-backoff", Long.toString(task.getInitialBackoffMillis()));
-            }
-            if (task.isPeriodic()) {
-                out.endTag(null, XML_TAG_PERIODIC);
-            } else {
-                out.endTag(null, XML_TAG_ONEOFF);
-            }
-        }
-    }
-
-    /**
-     * Runnable that reads list of persisted task from xml.
-     * NOTE: This Runnable locks on TaskStore.this
-     */
-    private class ReadTaskMapFromDiskRunnable implements Runnable {
-        private TaskMapReadFinishedListener mCallback;
-        public ReadTaskMapFromDiskRunnable(TaskMapReadFinishedListener callback) {
-            mCallback = callback;
-        }
-
-        @Override
-        public void run() {
-            try {
-                List<TaskStatus> tasks;
-                FileInputStream fis = mTasksFile.openRead();
-                synchronized (TaskStore.this) {
-                    tasks = readTaskMapImpl(fis);
-                }
-                fis.close();
-                if (tasks != null) {
-                    mCallback.onTaskMapReadFinished(tasks);
-                }
-            } catch (FileNotFoundException e) {
-                if (TaskManagerService.DEBUG) {
-                    Slog.d(TAG, "Could not find tasks file, probably there was nothing to load.");
-                }
-            } catch (XmlPullParserException e) {
-                if (TaskManagerService.DEBUG) {
-                    Slog.d(TAG, "Error parsing xml.", e);
-                }
-            } catch (IOException e) {
-                if (TaskManagerService.DEBUG) {
-                    Slog.d(TAG, "Error parsing xml.", e);
-                }
-            }
-        }
-
-        private List<TaskStatus> readTaskMapImpl(FileInputStream fis) throws XmlPullParserException, IOException {
-            XmlPullParser parser = Xml.newPullParser();
-            parser.setInput(fis, null);
-
-            int eventType = parser.getEventType();
-            while (eventType != XmlPullParser.START_TAG &&
-                    eventType != XmlPullParser.END_DOCUMENT) {
-                eventType = parser.next();
-                Slog.d(TAG, parser.getName());
-            }
-            if (eventType == XmlPullParser.END_DOCUMENT) {
-                if (DEBUG) {
-                    Slog.d(TAG, "No persisted tasks.");
-                }
-                return null;
-            }
-
-            String tagName = parser.getName();
-            if ("task-info".equals(tagName)) {
-                final List<TaskStatus> tasks = new ArrayList<TaskStatus>();
-                // Read in version info.
-                try {
-                    int version = Integer.valueOf(parser.getAttributeValue(null, "version"));
-                    if (version != TASKS_FILE_VERSION) {
-                        Slog.d(TAG, "Invalid version number, aborting tasks file read.");
-                        return null;
-                    }
-                } catch (NumberFormatException e) {
-                    Slog.e(TAG, "Invalid version number, aborting tasks file read.");
-                    return null;
-                }
-                eventType = parser.next();
-                do {
-                    // Read each <task/>
-                    if (eventType == XmlPullParser.START_TAG) {
-                        tagName = parser.getName();
-                        // Start reading task.
-                        if ("task".equals(tagName)) {
-                            TaskStatus persistedTask = restoreTaskFromXml(parser);
-                            if (persistedTask != null) {
-                                if (DEBUG) {
-                                    Slog.d(TAG, "Read out " + persistedTask);
-                                }
-                                tasks.add(persistedTask);
-                            } else {
-                                Slog.d(TAG, "Error reading task from file.");
-                            }
-                        }
-                    }
-                    eventType = parser.next();
-                } while (eventType != XmlPullParser.END_DOCUMENT);
-                return tasks;
-            }
-            return null;
-        }
-
-        /**
-         * @param parser Xml parser at the beginning of a "<task/>" tag. The next "parser.next()" call
-         *               will take the parser into the body of the task tag.
-         * @return Newly instantiated task holding all the information we just read out of the xml tag.
-         */
-        private TaskStatus restoreTaskFromXml(XmlPullParser parser) throws XmlPullParserException,
-                IOException {
-            Task.Builder taskBuilder;
-            int uid;
-
-            // Read out task identifier attributes.
-            try {
-                taskBuilder = buildBuilderFromXml(parser);
-                uid = Integer.valueOf(parser.getAttributeValue(null, "uid"));
-            } catch (NumberFormatException e) {
-                Slog.e(TAG, "Error parsing task's required fields, skipping");
-                return null;
-            }
-
-            int eventType;
-            // Read out constraints tag.
-            do {
-                eventType = parser.next();
-            } while (eventType == XmlPullParser.TEXT);  // Push through to next START_TAG.
-
-            if (!(eventType == XmlPullParser.START_TAG &&
-                    XML_TAG_PARAMS_CONSTRAINTS.equals(parser.getName()))) {
-                // Expecting a <constraints> start tag.
-                return null;
-            }
-            try {
-                buildConstraintsFromXml(taskBuilder, parser);
-            } catch (NumberFormatException e) {
-                Slog.d(TAG, "Error reading constraints, skipping.");
-                return null;
-            }
-            parser.next(); // Consume </constraints>
-
-            // Read out execution parameters tag.
-            do {
-                eventType = parser.next();
-            } while (eventType == XmlPullParser.TEXT);
-            if (eventType != XmlPullParser.START_TAG) {
-                return null;
-            }
-
-            Pair<Long, Long> runtimes;
-            try {
-                runtimes = buildExecutionTimesFromXml(parser);
-            } catch (NumberFormatException e) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Error parsing execution time parameters, skipping.");
-                }
-                return null;
-            }
-
-            if (XML_TAG_PERIODIC.equals(parser.getName())) {
-                try {
-                    String val = parser.getAttributeValue(null, "period");
-                    taskBuilder.setPeriodic(Long.valueOf(val));
-                } catch (NumberFormatException e) {
-                    Slog.d(TAG, "Error reading periodic execution criteria, skipping.");
-                    return null;
-                }
-            } else if (XML_TAG_ONEOFF.equals(parser.getName())) {
-                try {
-                    if (runtimes.first != TaskStatus.NO_EARLIEST_RUNTIME) {
-                        taskBuilder.setMinimumLatency(runtimes.first - SystemClock.elapsedRealtime());
-                    }
-                    if (runtimes.second != TaskStatus.NO_LATEST_RUNTIME) {
-                        taskBuilder.setOverrideDeadline(
-                                runtimes.second - SystemClock.elapsedRealtime());
-                    }
-                } catch (NumberFormatException e) {
-                    Slog.d(TAG, "Error reading task execution criteria, skipping.");
-                    return null;
-                }
-            } else {
-                if (DEBUG) {
-                    Slog.d(TAG, "Invalid parameter tag, skipping - " + parser.getName());
-                }
-                // Expecting a parameters start tag.
-                return null;
-            }
-            maybeBuildBackoffPolicyFromXml(taskBuilder, parser);
-
-            parser.nextTag(); // Consume parameters end tag.
-
-            // Read out extras Bundle.
-            do {
-                eventType = parser.next();
-            } while (eventType == XmlPullParser.TEXT);
-            if (!(eventType == XmlPullParser.START_TAG && XML_TAG_EXTRAS.equals(parser.getName()))) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Error reading extras, skipping.");
-                }
-                return null;
-            }
-
-            PersistableBundle extras = PersistableBundle.restoreFromXml(parser);
-            taskBuilder.setExtras(extras);
-            parser.nextTag(); // Consume </extras>
-
-            return new TaskStatus(taskBuilder.build(), uid, runtimes.first, runtimes.second);
-        }
-
-        private Task.Builder buildBuilderFromXml(XmlPullParser parser) throws NumberFormatException {
-            // Pull out required fields from <task> attributes.
-            int taskId = Integer.valueOf(parser.getAttributeValue(null, "taskid"));
-            String packageName = parser.getAttributeValue(null, "package");
-            String className = parser.getAttributeValue(null, "class");
-            ComponentName cname = new ComponentName(packageName, className);
-
-            return new Task.Builder(taskId, cname);
-        }
-
-        private void buildConstraintsFromXml(Task.Builder taskBuilder, XmlPullParser parser) {
-            String val = parser.getAttributeValue(null, "unmetered");
-            if (val != null) {
-                taskBuilder.setRequiredNetworkCapabilities(Task.NetworkType.UNMETERED);
-            }
-            val = parser.getAttributeValue(null, "connectivity");
-            if (val != null) {
-                taskBuilder.setRequiredNetworkCapabilities(Task.NetworkType.ANY);
-            }
-            val = parser.getAttributeValue(null, "idle");
-            if (val != null) {
-                taskBuilder.setRequiresDeviceIdle(true);
-            }
-            val = parser.getAttributeValue(null, "charging");
-            if (val != null) {
-                taskBuilder.setRequiresCharging(true);
-            }
-        }
-
-        /**
-         * Builds the back-off policy out of the params tag. These attributes may not exist, depending
-         * on whether the back-off was set when the task was first scheduled.
-         */
-        private void maybeBuildBackoffPolicyFromXml(Task.Builder taskBuilder, XmlPullParser parser) {
-            String val = parser.getAttributeValue(null, "initial-backoff");
-            if (val != null) {
-                long initialBackoff = Long.valueOf(val);
-                val = parser.getAttributeValue(null, "backoff-policy");
-                int backoffPolicy = Integer.valueOf(val);  // Will throw NFE which we catch higher up.
-                taskBuilder.setBackoffCriteria(initialBackoff, backoffPolicy);
-            }
-        }
-
-        /**
-         * Convenience function to read out and convert deadline and delay from xml into elapsed real
-         * time.
-         * @return A {@link android.util.Pair}, where the first value is the earliest elapsed runtime
-         * and the second is the latest elapsed runtime.
-         */
-        private Pair<Long, Long> buildExecutionTimesFromXml(XmlPullParser parser)
-                throws NumberFormatException {
-            // Pull out execution time data.
-            final long nowWallclock = System.currentTimeMillis();
-            final long nowElapsed = SystemClock.elapsedRealtime();
-
-            long earliestRunTimeElapsed = TaskStatus.NO_EARLIEST_RUNTIME;
-            long latestRunTimeElapsed = TaskStatus.NO_LATEST_RUNTIME;
-            String val = parser.getAttributeValue(null, "deadline");
-            if (val != null) {
-                long latestRuntimeWallclock = Long.valueOf(val);
-                long maxDelayElapsed =
-                        Math.max(latestRuntimeWallclock - nowWallclock, 0);
-                latestRunTimeElapsed = nowElapsed + maxDelayElapsed;
-            }
-            val = parser.getAttributeValue(null, "delay");
-            if (val != null) {
-                long earliestRuntimeWallclock = Long.valueOf(val);
-                long minDelayElapsed =
-                        Math.max(earliestRuntimeWallclock - nowWallclock, 0);
-                earliestRunTimeElapsed = nowElapsed + minDelayElapsed;
-
-            }
-            return Pair.create(earliestRunTimeElapsed, latestRunTimeElapsed);
-        }
-    }
-}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/task/controllers/TaskStatus.java b/services/core/java/com/android/server/task/controllers/TaskStatus.java
deleted file mode 100644
index a286737..0000000
--- a/services/core/java/com/android/server/task/controllers/TaskStatus.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.task.controllers;
-
-import android.app.task.Task;
-import android.content.ComponentName;
-import android.os.PersistableBundle;
-import android.os.SystemClock;
-import android.os.UserHandle;
-
-import java.io.PrintWriter;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Uniquely identifies a task internally.
- * Created from the public {@link android.app.task.Task} object when it lands on the scheduler.
- * Contains current state of the requirements of the task, as well as a function to evaluate
- * whether it's ready to run.
- * This object is shared among the various controllers - hence why the different fields are atomic.
- * This isn't strictly necessary because each controller is only interested in a specific field,
- * and the receivers that are listening for global state change will all run on the main looper,
- * but we don't enforce that so this is safer.
- * @hide
- */
-public class TaskStatus {
-    public static final long NO_LATEST_RUNTIME = Long.MAX_VALUE;
-    public static final long NO_EARLIEST_RUNTIME = 0L;
-
-    final Task task;
-    final int uId;
-
-    /** At reschedule time we need to know whether to update task on disk. */
-    final boolean persisted;
-
-    // Constraints.
-    final AtomicBoolean chargingConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean timeDelayConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean deadlineConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean idleConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean unmeteredConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean connectivityConstraintSatisfied = new AtomicBoolean();
-
-    /**
-     * Earliest point in the future at which this task will be eligible to run. A value of 0
-     * indicates there is no delay constraint. See {@link #hasTimingDelayConstraint()}.
-     */
-    private long earliestRunTimeElapsedMillis;
-    /**
-     * Latest point in the future at which this task must be run. A value of {@link Long#MAX_VALUE}
-     * indicates there is no deadline constraint. See {@link #hasDeadlineConstraint()}.
-     */
-    private long latestRunTimeElapsedMillis;
-    /** How many times this task has failed, used to compute back-off. */
-    private final int numFailures;
-
-    /** Provide a handle to the service that this task will be run on. */
-    public int getServiceToken() {
-        return uId;
-    }
-
-    private TaskStatus(Task task, int uId, boolean persisted, int numFailures) {
-        this.task = task;
-        this.uId = uId;
-        this.numFailures = numFailures;
-        this.persisted = persisted;
-    }
-
-    /** Create a newly scheduled task. */
-    public TaskStatus(Task task, int uId, boolean persisted) {
-        this(task, uId, persisted, 0);
-
-        final long elapsedNow = SystemClock.elapsedRealtime();
-
-        if (task.isPeriodic()) {
-            earliestRunTimeElapsedMillis = elapsedNow;
-            latestRunTimeElapsedMillis = elapsedNow + task.getIntervalMillis();
-        } else {
-            earliestRunTimeElapsedMillis = task.hasEarlyConstraint() ?
-                    elapsedNow + task.getMinLatencyMillis() : NO_EARLIEST_RUNTIME;
-            latestRunTimeElapsedMillis = task.hasLateConstraint() ?
-                    elapsedNow + task.getMaxExecutionDelayMillis() : NO_LATEST_RUNTIME;
-        }
-    }
-
-    /**
-     * Create a new TaskStatus that was loaded from disk. We ignore the provided
-     * {@link android.app.task.Task} time criteria because we can load a persisted periodic task
-     * from the {@link com.android.server.task.TaskStore} and still want to respect its
-     * wallclock runtime rather than resetting it on every boot.
-     * We consider a freshly loaded task to no longer be in back-off.
-     */
-    public TaskStatus(Task task, int uId, long earliestRunTimeElapsedMillis,
-                      long latestRunTimeElapsedMillis) {
-        this(task, uId, true, 0);
-
-        this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis;
-        this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis;
-    }
-
-    /** Create a new task to be rescheduled with the provided parameters. */
-    public TaskStatus(TaskStatus rescheduling, long newEarliestRuntimeElapsedMillis,
-                      long newLatestRuntimeElapsedMillis, int backoffAttempt) {
-        this(rescheduling.task, rescheduling.getUid(), rescheduling.isPersisted(), backoffAttempt);
-
-        earliestRunTimeElapsedMillis = newEarliestRuntimeElapsedMillis;
-        latestRunTimeElapsedMillis = newLatestRuntimeElapsedMillis;
-    }
-
-    public Task getTask() {
-        return task;
-    }
-
-    public int getTaskId() {
-        return task.getId();
-    }
-
-    public int getNumFailures() {
-        return numFailures;
-    }
-
-    public ComponentName getServiceComponent() {
-        return task.getService();
-    }
-
-    public int getUserId() {
-        return UserHandle.getUserId(uId);
-    }
-
-    public int getUid() {
-        return uId;
-    }
-
-    public PersistableBundle getExtras() {
-        return task.getExtras();
-    }
-
-    public boolean hasConnectivityConstraint() {
-        return task.getNetworkCapabilities() == Task.NetworkType.ANY;
-    }
-
-    public boolean hasUnmeteredConstraint() {
-        return task.getNetworkCapabilities() == Task.NetworkType.UNMETERED;
-    }
-
-    public boolean hasChargingConstraint() {
-        return task.isRequireCharging();
-    }
-
-    public boolean hasTimingDelayConstraint() {
-        return earliestRunTimeElapsedMillis != NO_EARLIEST_RUNTIME;
-    }
-
-    public boolean hasDeadlineConstraint() {
-        return latestRunTimeElapsedMillis != NO_LATEST_RUNTIME;
-    }
-
-    public boolean hasIdleConstraint() {
-        return task.isRequireDeviceIdle();
-    }
-
-    public long getEarliestRunTime() {
-        return earliestRunTimeElapsedMillis;
-    }
-
-    public long getLatestRunTimeElapsed() {
-        return latestRunTimeElapsedMillis;
-    }
-
-    public boolean isPersisted() {
-        return persisted;
-    }
-    /**
-     * @return Whether or not this task is ready to run, based on its requirements.
-     */
-    public synchronized boolean isReady() {
-        return (!hasChargingConstraint() || chargingConstraintSatisfied.get())
-                && (!hasTimingDelayConstraint() || timeDelayConstraintSatisfied.get())
-                && (!hasConnectivityConstraint() || connectivityConstraintSatisfied.get())
-                && (!hasUnmeteredConstraint() || unmeteredConstraintSatisfied.get())
-                && (!hasIdleConstraint() || idleConstraintSatisfied.get())
-                // Also ready if the deadline has expired - special case.
-                || (hasDeadlineConstraint() && deadlineConstraintSatisfied.get());
-    }
-
-    /*@Override
-    public int hashCode() {
-        int result = getServiceComponent().hashCode();
-        result = 31 * result + task.getId();
-        result = 31 * result + uId;
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof TaskStatus)) return false;
-
-        TaskStatus that = (TaskStatus) o;
-        return ((task.getId() == that.task.getId())
-                && (uId == that.uId)
-                && (getServiceComponent().equals(that.getServiceComponent())));
-    }*/
-
-    public boolean matches(int uid, int taskId) {
-        return this.task.getId() == taskId && this.uId == uid;
-    }
-
-    @Override
-    public String toString() {
-        return String.valueOf(hashCode()).substring(0, 3) + ".."
-                + ":[" + task.getService().getPackageName() + ",tId=" + task.getId()
-                + ",R=(" + earliestRunTimeElapsedMillis + "," + latestRunTimeElapsedMillis + ")"
-                + ",N=" + task.getNetworkCapabilities() + ",C=" + task.isRequireCharging()
-                + ",I=" + task.isRequireDeviceIdle() + ",F=" + numFailures
-                + (isReady() ? "(READY)" : "")
-                + "]";
-    }
-    // Dumpsys infrastructure
-    public void dump(PrintWriter pw, String prefix) {
-        pw.println(this.toString());
-    }
-}
