diff --git a/Android.mk b/Android.mk
index 7c01ed9..52459ae 100644
--- a/Android.mk
+++ b/Android.mk
@@ -77,9 +77,9 @@
 	core/java/android/app/ISearchManagerCallback.aidl \
 	core/java/android/app/IServiceConnection.aidl \
 	core/java/android/app/IStopUserCallback.aidl \
-	core/java/android/app/task/ITaskCallback.aidl \
-	core/java/android/app/task/ITaskManager.aidl \
-	core/java/android/app/task/ITaskService.aidl \
+	core/java/android/app/job/IJobCallback.aidl \
+	core/java/android/app/job/IJobScheduler.aidl \
+	core/java/android/app/job/IJobService.aidl \
 	core/java/android/app/IThumbnailRetriever.aidl \
 	core/java/android/app/ITransientNotification.aidl \
 	core/java/android/app/IUiAutomationConnection.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index f3bb9b6..5b027b3 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -197,3 +197,6 @@
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/classes/android/app/task)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/app/task)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/classes/android/app/TaskManager)
diff --git a/api/current.txt b/api/current.txt
index 7d8e796..60d5e067 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5356,23 +5356,9 @@
 
 }
 
-package android.app.maintenance {
+package android.app.job {
 
-  public abstract class IdleService extends android.app.Service {
-    ctor public IdleService();
-    method public final void finishIdle();
-    method public final android.os.IBinder onBind(android.content.Intent);
-    method public abstract boolean onIdleStart();
-    method public abstract void onIdleStop();
-    field public static final java.lang.String PERMISSION_BIND = "android.permission.BIND_IDLE_SERVICE";
-    field public static final java.lang.String SERVICE_INTERFACE = "android.service.idle.IdleService";
-  }
-
-}
-
-package android.app.task {
-
-  public class Task implements android.os.Parcelable {
+  public class JobInfo implements android.os.Parcelable {
     method public int describeContents();
     method public int getBackoffPolicy();
     method public android.os.PersistableBundle getExtras();
@@ -5390,55 +5376,69 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public static abstract interface Task.BackoffPolicy {
+  public static abstract interface JobInfo.BackoffPolicy {
     field public static final int EXPONENTIAL = 1; // 0x1
     field public static final int LINEAR = 0; // 0x0
   }
 
-  public static final class Task.Builder {
-    ctor public Task.Builder(int, android.content.ComponentName);
-    method public android.app.task.Task build();
-    method public android.app.task.Task.Builder setBackoffCriteria(long, int);
-    method public android.app.task.Task.Builder setExtras(android.os.PersistableBundle);
-    method public android.app.task.Task.Builder setMinimumLatency(long);
-    method public android.app.task.Task.Builder setOverrideDeadline(long);
-    method public android.app.task.Task.Builder setPeriodic(long);
-    method public android.app.task.Task.Builder setRequiredNetworkCapabilities(int);
-    method public android.app.task.Task.Builder setRequiresCharging(boolean);
-    method public android.app.task.Task.Builder setRequiresDeviceIdle(boolean);
+  public static final class JobInfo.Builder {
+    ctor public JobInfo.Builder(int, android.content.ComponentName);
+    method public android.app.job.JobInfo build();
+    method public android.app.job.JobInfo.Builder setBackoffCriteria(long, int);
+    method public android.app.job.JobInfo.Builder setExtras(android.os.PersistableBundle);
+    method public android.app.job.JobInfo.Builder setMinimumLatency(long);
+    method public android.app.job.JobInfo.Builder setOverrideDeadline(long);
+    method public android.app.job.JobInfo.Builder setPeriodic(long);
+    method public android.app.job.JobInfo.Builder setRequiredNetworkCapabilities(int);
+    method public android.app.job.JobInfo.Builder setRequiresCharging(boolean);
+    method public android.app.job.JobInfo.Builder setRequiresDeviceIdle(boolean);
   }
 
-  public static abstract interface Task.NetworkType {
+  public static abstract interface JobInfo.NetworkType {
     field public static final int ANY = 1; // 0x1
     field public static final int NONE = 0; // 0x0
     field public static final int UNMETERED = 2; // 0x2
   }
 
-  public abstract class TaskManager {
-    ctor public TaskManager();
-    method public abstract void cancel(int);
-    method public abstract void cancelAll();
-    method public abstract java.util.List<android.app.task.Task> getAllPendingTasks();
-    method public abstract int schedule(android.app.task.Task);
-    field public static final int RESULT_FAILURE = 0; // 0x0
-    field public static final int RESULT_SUCCESS = 1; // 0x1
-  }
-
-  public class TaskParams implements android.os.Parcelable {
+  public class JobParameters implements android.os.Parcelable {
     method public int describeContents();
     method public android.os.PersistableBundle getExtras();
-    method public int getTaskId();
+    method public int getJobId();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public abstract class TaskService extends android.app.Service {
-    ctor public TaskService();
+  public abstract class JobScheduler {
+    ctor public JobScheduler();
+    method public abstract void cancel(int);
+    method public abstract void cancelAll();
+    method public abstract java.util.List<android.app.job.JobInfo> getAllPendingJobs();
+    method public abstract int schedule(android.app.job.JobInfo);
+    field public static final int RESULT_FAILURE = 0; // 0x0
+    field public static final int RESULT_SUCCESS = 1; // 0x1
+  }
+
+  public abstract class JobService extends android.app.Service {
+    ctor public JobService();
+    method public final void jobFinished(android.app.job.JobParameters, boolean);
     method public final android.os.IBinder onBind(android.content.Intent);
-    method public abstract boolean onStartTask(android.app.task.TaskParams);
-    method public abstract boolean onStopTask(android.app.task.TaskParams);
-    method public final void taskFinished(android.app.task.TaskParams, boolean);
-    field public static final java.lang.String PERMISSION_BIND = "android.permission.BIND_TASK_SERVICE";
+    method public abstract boolean onStartJob(android.app.job.JobParameters);
+    method public abstract boolean onStopJob(android.app.job.JobParameters);
+    field public static final java.lang.String PERMISSION_BIND = "android.permission.BIND_JOB_SERVICE";
+  }
+
+}
+
+package android.app.maintenance {
+
+  public abstract class IdleService extends android.app.Service {
+    ctor public IdleService();
+    method public final void finishIdle();
+    method public final android.os.IBinder onBind(android.content.Intent);
+    method public abstract boolean onIdleStart();
+    method public abstract void onIdleStop();
+    field public static final java.lang.String PERMISSION_BIND = "android.permission.BIND_IDLE_SERVICE";
+    field public static final java.lang.String SERVICE_INTERFACE = "android.service.idle.IdleService";
   }
 
 }
@@ -7006,6 +7006,7 @@
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
+    field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
     field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
     field public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater";
@@ -7026,7 +7027,6 @@
     field public static final java.lang.String SEARCH_SERVICE = "search";
     field public static final java.lang.String SENSOR_SERVICE = "sensor";
     field public static final java.lang.String STORAGE_SERVICE = "storage";
-    field public static final java.lang.String TASK_SERVICE = "task";
     field public static final java.lang.String TELEPHONY_SERVICE = "phone";
     field public static final java.lang.String TEXT_SERVICES_MANAGER_SERVICE = "textservices";
     field public static final java.lang.String TV_INPUT_SERVICE = "tv_input";
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 5bbc43c..c5190d3 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -133,7 +133,7 @@
 import android.accounts.AccountManager;
 import android.accounts.IAccountManager;
 import android.app.admin.DevicePolicyManager;
-import android.app.task.ITaskManager;
+import android.app.job.IJobScheduler;
 import android.app.trust.TrustManager;
 
 import com.android.internal.annotations.GuardedBy;
@@ -697,10 +697,10 @@
                 return new UsageStatsManager(ctx.getOuterContext());
         }});
 
-        registerService(TASK_SERVICE, new ServiceFetcher() {
+        registerService(JOB_SCHEDULER_SERVICE, new ServiceFetcher() {
             public Object createService(ContextImpl ctx) {
-                IBinder b = ServiceManager.getService(TASK_SERVICE);
-                return new TaskManagerImpl(ITaskManager.Stub.asInterface(b));
+                IBinder b = ServiceManager.getService(JOB_SCHEDULER_SERVICE);
+                return new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b));
             }});
     }
 
diff --git a/core/java/android/app/TaskManagerImpl.java b/core/java/android/app/JobSchedulerImpl.java
similarity index 67%
rename from core/java/android/app/TaskManagerImpl.java
rename to core/java/android/app/JobSchedulerImpl.java
index fe29fb7..09038d5 100644
--- a/core/java/android/app/TaskManagerImpl.java
+++ b/core/java/android/app/JobSchedulerImpl.java
@@ -17,38 +17,38 @@
 // in android.app so ContextImpl has package access
 package android.app;
 
-import android.app.task.ITaskManager;
-import android.app.task.Task;
-import android.app.task.TaskManager;
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.app.job.IJobScheduler;
 import android.os.RemoteException;
 
 import java.util.List;
 
 
 /**
- * Concrete implementation of the TaskManager interface
+ * Concrete implementation of the JobScheduler interface
  * @hide 
  */
-public class TaskManagerImpl extends TaskManager {
-    ITaskManager mBinder;
+public class JobSchedulerImpl extends JobScheduler {
+    IJobScheduler mBinder;
 
-    /* package */ TaskManagerImpl(ITaskManager binder) {
+    /* package */ JobSchedulerImpl(IJobScheduler binder) {
         mBinder = binder;
     }
 
     @Override
-    public int schedule(Task task) {
+    public int schedule(JobInfo job) {
         try {
-            return mBinder.schedule(task);
+            return mBinder.schedule(job);
         } catch (RemoteException e) {
-            return TaskManager.RESULT_FAILURE;
+            return JobScheduler.RESULT_FAILURE;
         }
     }
 
     @Override
-    public void cancel(int taskId) {
+    public void cancel(int jobId) {
         try {
-            mBinder.cancel(taskId);
+            mBinder.cancel(jobId);
         } catch (RemoteException e) {}
 
     }
@@ -62,9 +62,9 @@
     }
 
     @Override
-    public List<Task> getAllPendingTasks() {
+    public List<JobInfo> getAllPendingJobs() {
         try {
-            return mBinder.getAllPendingTasks();
+            return mBinder.getAllPendingJobs();
         } catch (RemoteException e) {
             return null;
         }
diff --git a/core/java/android/app/job/IJobCallback.aidl b/core/java/android/app/job/IJobCallback.aidl
new file mode 100644
index 0000000..2d3948f
--- /dev/null
+++ b/core/java/android/app/job/IJobCallback.aidl
@@ -0,0 +1,53 @@
+/**
+ * Copyright 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 android.app.job;
+
+/**
+ * The server side of the JobScheduler IPC protocols.  The app-side implementation
+ * invokes on this interface to indicate completion of the (asynchronous) instructions
+ * issued by the server.
+ *
+ * In all cases, the 'who' parameter is the caller's service binder, used to track
+ * which Job Service instance is reporting.
+ *
+ * {@hide}
+ */
+interface IJobCallback {
+    /**
+     * Immediate callback to the system after sending a start signal, used to quickly detect ANR.
+     *
+     * @param jobId Unique integer used to identify this job.
+     * @param ongoing True to indicate that the client is processing the job. False if the job is
+     * complete
+     */
+    void acknowledgeStartMessage(int jobId, boolean ongoing);
+    /**
+     * Immediate callback to the system after sending a stop signal, used to quickly detect ANR.
+     *
+     * @param jobId Unique integer used to identify this job.
+     * @param reschedule Whether or not to reschedule this job.
+     */
+    void acknowledgeStopMessage(int jobId, boolean reschedule);
+    /*
+     * Tell the job manager that the client is done with its execution, so that it can go on to
+     * the next one and stop attributing wakelock time to us etc.
+     *
+     * @param jobId Unique integer used to identify this job.
+     * @param reschedule Whether or not to reschedule this job.
+     */
+    void jobFinished(int jobId, boolean reschedule);
+}
diff --git a/core/java/android/app/task/ITaskManager.aidl b/core/java/android/app/job/IJobScheduler.aidl
similarity index 71%
rename from core/java/android/app/task/ITaskManager.aidl
rename to core/java/android/app/job/IJobScheduler.aidl
index b56c78a..f1258ae 100644
--- a/core/java/android/app/task/ITaskManager.aidl
+++ b/core/java/android/app/job/IJobScheduler.aidl
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-package android.app.task;
+package android.app.job;
 
-import android.app.task.Task;
+import android.app.job.JobInfo;
 
  /**
-  * IPC interface that supports the app-facing {@link #TaskManager} api.
+  * IPC interface that supports the app-facing {@link #JobScheduler} api.
   * {@hide}
   */
-interface ITaskManager {
-    int schedule(in Task task);
-    void cancel(int taskId);
+interface IJobScheduler {
+    int schedule(in JobInfo job);
+    void cancel(int jobId);
     void cancelAll();
-    List<Task> getAllPendingTasks();
+    List<JobInfo> getAllPendingJobs();
 }
diff --git a/core/java/android/app/task/ITaskService.aidl b/core/java/android/app/job/IJobService.aidl
similarity index 62%
rename from core/java/android/app/task/ITaskService.aidl
rename to core/java/android/app/job/IJobService.aidl
index 87b0191..63f8b81 100644
--- a/core/java/android/app/task/ITaskService.aidl
+++ b/core/java/android/app/job/IJobService.aidl
@@ -14,22 +14,19 @@
  * limitations under the License.
  */
 
-package android.app.task;
+package android.app.job;
 
-import android.app.task.ITaskCallback;
-import android.app.task.TaskParams;
-
-import android.os.Bundle;
+import android.app.job.JobParameters;
 
 /**
  * Interface that the framework uses to communicate with application code that implements a
- * TaskService.  End user code does not implement this interface directly; instead, the app's
- * service implementation will extend android.app.task.TaskService.
+ * JobService.  End user code does not implement this interface directly; instead, the app's
+ * service implementation will extend android.app.job.JobService.
  * {@hide}
  */
-oneway interface ITaskService {
-    /** Begin execution of application's task. */
-    void startTask(in TaskParams taskParams);
+oneway interface IJobService {
+    /** Begin execution of application's job. */
+    void startJob(in JobParameters jobParams);
     /** Stop execution of application's task. */
-    void stopTask(in TaskParams taskParams);
+    void stopJob(in JobParameters jobParams);
 }
diff --git a/core/java/android/app/task/Task.aidl b/core/java/android/app/job/JobInfo.aidl
similarity index 92%
rename from core/java/android/app/task/Task.aidl
rename to core/java/android/app/job/JobInfo.aidl
index 1f25439..7b198a8 100644
--- a/core/java/android/app/task/Task.aidl
+++ b/core/java/android/app/job/JobInfo.aidl
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-package android.app.task;
+package android.app.job;
 
-parcelable Task;
- 
\ No newline at end of file
+parcelable JobInfo;
diff --git a/core/java/android/app/task/Task.java b/core/java/android/app/job/JobInfo.java
similarity index 74%
rename from core/java/android/app/task/Task.java
rename to core/java/android/app/job/JobInfo.java
index 0e660b3..a22e4cd 100644
--- a/core/java/android/app/task/Task.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package android.app.task;
+package android.app.job;
 
 import android.content.ComponentName;
 import android.os.Bundle;
@@ -23,22 +23,22 @@
 import android.os.PersistableBundle;
 
 /**
- * Container of data passed to the {@link android.app.task.TaskManager} fully encapsulating the
+ * Container of data passed to the {@link android.app.job.JobScheduler} fully encapsulating the
  * parameters required to schedule work against the calling application. These are constructed
- * using the {@link Task.Builder}.
+ * using the {@link JobInfo.Builder}.
  */
-public class Task implements Parcelable {
+public class JobInfo implements Parcelable {
     public interface NetworkType {
         /** Default. */
         public final int NONE = 0;
-        /** This task requires network connectivity. */
+        /** This job requires network connectivity. */
         public final int ANY = 1;
-        /** This task requires network connectivity that is unmetered. */
+        /** This job requires network connectivity that is unmetered. */
         public final int UNMETERED = 2;
     }
 
     /**
-     * Amount of backoff a task has initially by default, in milliseconds.
+     * Amount of backoff a job has initially by default, in milliseconds.
      * @hide.
      */
     public static final long DEFAULT_INITIAL_BACKOFF_MILLIS = 5000L;
@@ -63,7 +63,7 @@
         public final int EXPONENTIAL = 1;
     }
 
-    private final int taskId;
+    private final int jobId;
     // TODO: Change this to use PersistableBundle when that lands in master.
     private final PersistableBundle extras;
     private final ComponentName service;
@@ -80,10 +80,10 @@
     private final int backoffPolicy;
 
     /**
-     * Unique task id associated with this class. This is assigned to your task by the scheduler.
+     * Unique job id associated with this class. This is assigned to your job by the scheduler.
      */
     public int getId() {
-        return taskId;
+        return jobId;
     }
 
     /**
@@ -94,43 +94,43 @@
     }
 
     /**
-     * Name of the service endpoint that will be called back into by the TaskManager.
+     * Name of the service endpoint that will be called back into by the JobScheduler.
      */
     public ComponentName getService() {
         return service;
     }
 
     /**
-     * Whether this task needs the device to be plugged in.
+     * Whether this job needs the device to be plugged in.
      */
     public boolean isRequireCharging() {
         return requireCharging;
     }
 
     /**
-     * Whether this task needs the device to be in an Idle maintenance window.
+     * Whether this job needs the device to be in an Idle maintenance window.
      */
     public boolean isRequireDeviceIdle() {
         return requireDeviceIdle;
     }
 
     /**
-     * See {@link android.app.task.Task.NetworkType} for a description of this value.
+     * See {@link android.app.job.JobInfo.NetworkType} for a description of this value.
      */
     public int getNetworkCapabilities() {
         return networkCapabilities;
     }
 
     /**
-     * Set for a task that does not recur periodically, to specify a delay after which the task
-     * will be eligible for execution. This value is not set if the task recurs periodically.
+     * Set for a job that does not recur periodically, to specify a delay after which the job
+     * will be eligible for execution. This value is not set if the job recurs periodically.
      */
     public long getMinLatencyMillis() {
         return minLatencyMillis;
     }
 
     /**
-     * See {@link Builder#setOverrideDeadline(long)}. This value is not set if the task recurs
+     * See {@link Builder#setOverrideDeadline(long)}. This value is not set if the job recurs
      * periodically.
      */
     public long getMaxExecutionDelayMillis() {
@@ -138,23 +138,23 @@
     }
 
     /**
-     * Track whether this task will repeat with a given period.
+     * Track whether this job will repeat with a given period.
      */
     public boolean isPeriodic() {
         return isPeriodic;
     }
 
     /**
-     * Set to the interval between occurrences of this task. This value is <b>not</b> set if the
-     * task does not recur periodically.
+     * Set to the interval between occurrences of this job. This value is <b>not</b> set if the
+     * job does not recur periodically.
      */
     public long getIntervalMillis() {
         return intervalMillis;
     }
 
     /**
-     * The amount of time the TaskManager will wait before rescheduling a failed task. This value
-     * will be increased depending on the backoff policy specified at task creation time. Defaults
+     * The amount of time the JobScheduler will wait before rescheduling a failed job. This value
+     * will be increased depending on the backoff policy specified at job creation time. Defaults
      * to 5 seconds.
      */
     public long getInitialBackoffMillis() {
@@ -162,7 +162,7 @@
     }
 
     /**
-     * See {@link android.app.task.Task.BackoffPolicy} for an explanation of the values this field
+     * See {@link android.app.job.JobInfo.BackoffPolicy} for an explanation of the values this field
      * can take. This defaults to exponential.
      */
     public int getBackoffPolicy() {
@@ -187,8 +187,8 @@
         return hasLateConstraint;
     }
 
-    private Task(Parcel in) {
-        taskId = in.readInt();
+    private JobInfo(Parcel in) {
+        jobId = in.readInt();
         extras = in.readPersistableBundle();
         service = in.readParcelable(null);
         requireCharging = in.readInt() == 1;
@@ -204,10 +204,10 @@
         hasLateConstraint = in.readInt() == 1;
     }
 
-    private Task(Task.Builder b) {
-        taskId = b.mTaskId;
+    private JobInfo(JobInfo.Builder b) {
+        jobId = b.mJobId;
         extras = b.mExtras;
-        service = b.mTaskService;
+        service = b.mJobService;
         requireCharging = b.mRequiresCharging;
         requireDeviceIdle = b.mRequiresDeviceIdle;
         networkCapabilities = b.mNetworkCapabilities;
@@ -228,7 +228,7 @@
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(taskId);
+        out.writeInt(jobId);
         out.writePersistableBundle(extras);
         out.writeParcelable(service, flags);
         out.writeInt(requireCharging ? 1 : 0);
@@ -244,23 +244,23 @@
         out.writeInt(hasLateConstraint ? 1 : 0);
     }
 
-    public static final Creator<Task> CREATOR = new Creator<Task>() {
+    public static final Creator<JobInfo> CREATOR = new Creator<JobInfo>() {
         @Override
-        public Task createFromParcel(Parcel in) {
-            return new Task(in);
+        public JobInfo createFromParcel(Parcel in) {
+            return new JobInfo(in);
         }
 
         @Override
-        public Task[] newArray(int size) {
-            return new Task[size];
+        public JobInfo[] newArray(int size) {
+            return new JobInfo[size];
         }
     };
 
-    /** Builder class for constructing {@link Task} objects. */
+    /** Builder class for constructing {@link JobInfo} objects. */
     public static final class Builder {
-        private int mTaskId;
+        private int mJobId;
         private PersistableBundle mExtras = PersistableBundle.EMPTY;
-        private ComponentName mTaskService;
+        private ComponentName mJobService;
         // Requirements.
         private boolean mRequiresCharging;
         private boolean mRequiresDeviceIdle;
@@ -280,15 +280,15 @@
         private boolean mBackoffPolicySet = false;
 
         /**
-         * @param taskId Application-provided id for this task. Subsequent calls to cancel, or
-         *               tasks created with the same taskId, will update the pre-existing task with
+         * @param jobId Application-provided id for this job. Subsequent calls to cancel, or
+         *               jobs created with the same jobId, will update the pre-existing job with
          *               the same id.
-         * @param taskService The endpoint that you implement that will receive the callback from the
-         *            TaskManager.
+         * @param jobService The endpoint that you implement that will receive the callback from the
+         *            JobScheduler.
          */
-        public Builder(int taskId, ComponentName taskService) {
-            mTaskService = taskService;
-            mTaskId = taskId;
+        public Builder(int jobId, ComponentName jobService) {
+            mJobService = jobService;
+            mJobId = jobId;
         }
 
         /**
@@ -302,10 +302,10 @@
 
         /**
          * Set some description of the kind of network capabilities you would like to have. This
-         * will be a parameter defined in {@link android.app.task.Task.NetworkType}.
+         * will be a parameter defined in {@link android.app.job.JobInfo.NetworkType}.
          * Not calling this function means the network is not necessary.
          * Bear in mind that calling this function defines network as a strict requirement for your
-         * task if the network requested is not available your task will never run. See
+         * job if the network requested is not available your job will never run. See
          * {@link #setOverrideDeadline(long)} to change this behaviour.
          */
         public Builder setRequiredNetworkCapabilities(int networkCapabilities) {
@@ -313,10 +313,10 @@
             return this;
         }
 
-        /*
-         * Specify that to run this task, the device needs to be plugged in. This defaults to
+        /**
+         * Specify that to run this job, the device needs to be plugged in. This defaults to
          * false.
-         * @param requireCharging Whether or not the device is plugged in.
+         * @param requiresCharging Whether or not the device is plugged in.
          */
         public Builder setRequiresCharging(boolean requiresCharging) {
             mRequiresCharging = requiresCharging;
@@ -324,11 +324,11 @@
         }
 
         /**
-         * Specify that to run, the task needs the device to be in idle mode. This defaults to
+         * Specify that to run, the job needs the device to be in idle mode. This defaults to
          * false.
          * <p>Idle mode is a loose definition provided by the system, which means that the device
          * is not in use, and has not been in use for some time. As such, it is a good time to
-         * perform resource heavy tasks. Bear in mind that battery usage will still be attributed
+         * perform resource heavy jobs. Bear in mind that battery usage will still be attributed
          * to your application, and surfaced to the user in battery stats.</p>
          * @param requiresDeviceIdle Whether or not the device need be within an idle maintenance
          *                           window.
@@ -339,17 +339,17 @@
         }
 
         /**
-         * Specify that this task should recur with the provided interval, not more than once per
-         * period. You have no control over when within this interval this task will be executed,
+         * Specify that this job should recur with the provided interval, not more than once per
+         * period. You have no control over when within this interval this job will be executed,
          * only the guarantee that it will be executed at most once within this interval.
-         * A periodic task will be repeated until the phone is turned off, however it will only be
+         * A periodic job will be repeated until the phone is turned off, however it will only be
          * persisted beyond boot if the client app has declared the
          * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission. You can schedule
-         * periodic tasks without this permission, they simply will cease to exist after the phone
+         * periodic jobs without this permission, they simply will cease to exist after the phone
          * restarts.
          * Setting this function on the builder with {@link #setMinimumLatency(long)} or
          * {@link #setOverrideDeadline(long)} will result in an error.
-         * @param intervalMillis Millisecond interval for which this task will repeat.
+         * @param intervalMillis Millisecond interval for which this job will repeat.
          */
         public Builder setPeriodic(long intervalMillis) {
             mIsPeriodic = true;
@@ -359,11 +359,11 @@
         }
 
         /**
-         * Specify that this task should be delayed by the provided amount of time.
-         * Because it doesn't make sense setting this property on a periodic task, doing so will
+         * Specify that this job should be delayed by the provided amount of time.
+         * Because it doesn't make sense setting this property on a periodic job, doing so will
          * throw an {@link java.lang.IllegalArgumentException} when
-         * {@link android.app.task.Task.Builder#build()} is called.
-         * @param minLatencyMillis Milliseconds before which this task will not be considered for
+         * {@link android.app.job.JobInfo.Builder#build()} is called.
+         * @param minLatencyMillis Milliseconds before which this job will not be considered for
          *                         execution.
          */
         public Builder setMinimumLatency(long minLatencyMillis) {
@@ -373,11 +373,11 @@
         }
 
         /**
-         * Set deadline which is the maximum scheduling latency. The task will be run by this
+         * Set deadline which is the maximum scheduling latency. The job will be run by this
          * deadline even if other requirements are not met. Because it doesn't make sense setting
-         * this property on a periodic task, doing so will throw an
+         * this property on a periodic job, doing so will throw an
          * {@link java.lang.IllegalArgumentException} when
-         * {@link android.app.task.Task.Builder#build()} is called.
+         * {@link android.app.job.JobInfo.Builder#build()} is called.
          */
         public Builder setOverrideDeadline(long maxExecutionDelayMillis) {
             mMaxExecutionDelayMillis = maxExecutionDelayMillis;
@@ -389,13 +389,13 @@
          * Set up the back-off/retry policy.
          * This defaults to some respectable values: {5 seconds, Exponential}. We cap back-off at
          * 1hr.
-         * Note that trying to set a backoff criteria for a task with
+         * Note that trying to set a backoff criteria for a job with
          * {@link #setRequiresDeviceIdle(boolean)} will throw an exception when you call build().
-         * This is because back-off typically does not make sense for these types of tasks. See
-         * {@link android.app.task.TaskService#taskFinished(android.app.task.TaskParams, boolean)}
-         * for more description of the return value for the case of a task executing while in idle
+         * This is because back-off typically does not make sense for these types of jobs. See
+         * {@link android.app.job.JobService#jobFinished(android.app.job.JobParameters, boolean)}
+         * for more description of the return value for the case of a job executing while in idle
          * mode.
-         * @param initialBackoffMillis Millisecond time interval to wait initially when task has
+         * @param initialBackoffMillis Millisecond time interval to wait initially when job has
          *                             failed.
          * @param backoffPolicy is one of {@link BackoffPolicy}
          */
@@ -407,25 +407,25 @@
         }
 
         /**
-         * @return The task object to hand to the TaskManager. This object is immutable.
+         * @return The job object to hand to the JobScheduler. This object is immutable.
          */
-        public Task build() {
+        public JobInfo build() {
             mExtras = new PersistableBundle(mExtras);  // Make our own copy.
-            // Check that a deadline was not set on a periodic task.
+            // Check that a deadline was not set on a periodic job.
             if (mIsPeriodic && (mMaxExecutionDelayMillis != 0L)) {
                 throw new IllegalArgumentException("Can't call setOverrideDeadline() on a " +
-                        "periodic task.");
+                        "periodic job.");
             }
             if (mIsPeriodic && (mMinLatencyMillis != 0L)) {
                 throw new IllegalArgumentException("Can't call setMinimumLatency() on a " +
-                        "periodic task");
+                        "periodic job");
             }
             if (mBackoffPolicySet && mRequiresDeviceIdle) {
-                throw new IllegalArgumentException("An idle mode task will not respect any" +
+                throw new IllegalArgumentException("An idle mode job will not respect any" +
                         " back-off policy, so calling setBackoffCriteria with" +
                         " setRequiresDeviceIdle is an error.");
             }
-            return new Task(this);
+            return new JobInfo(this);
         }
     }
 
diff --git a/core/java/android/app/task/TaskParams.aidl b/core/java/android/app/job/JobParameters.aidl
similarity index 91%
rename from core/java/android/app/task/TaskParams.aidl
rename to core/java/android/app/job/JobParameters.aidl
index 9b25855..e7551b9 100644
--- a/core/java/android/app/task/TaskParams.aidl
+++ b/core/java/android/app/job/JobParameters.aidl
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.app.task;
+package android.app.job;
 
-parcelable TaskParams;
\ No newline at end of file
+parcelable JobParameters;
diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java
new file mode 100644
index 0000000..724856a
--- /dev/null
+++ b/core/java/android/app/job/JobParameters.java
@@ -0,0 +1,93 @@
+/*
+ * 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 android.app.job;
+
+import android.app.job.IJobCallback;
+import android.app.job.IJobCallback.Stub;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.PersistableBundle;
+
+/**
+ * Contains the parameters used to configure/identify your job. You do not create this object
+ * yourself, instead it is handed in to your application by the System.
+ */
+public class JobParameters implements Parcelable {
+
+    private final int jobId;
+    private final PersistableBundle extras;
+    private final IBinder callback;
+
+    /** @hide */
+    public JobParameters(int jobId, PersistableBundle extras, IBinder callback) {
+        this.jobId = jobId;
+        this.extras = extras;
+        this.callback = callback;
+    }
+
+    /**
+     * @return The unique id of this job, specified at creation time.
+     */
+    public int getJobId() {
+        return jobId;
+    }
+
+    /**
+     * @return The extras you passed in when constructing this job with
+     * {@link android.app.job.JobInfo.Builder#setExtras(android.os.PersistableBundle)}. This will
+     * never be null. If you did not set any extras this will be an empty bundle.
+     */
+    public PersistableBundle getExtras() {
+        return extras;
+    }
+
+    /** @hide */
+    public IJobCallback getCallback() {
+        return IJobCallback.Stub.asInterface(callback);
+    }
+
+    private JobParameters(Parcel in) {
+        jobId = in.readInt();
+        extras = in.readPersistableBundle();
+        callback = in.readStrongBinder();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(jobId);
+        dest.writePersistableBundle(extras);
+        dest.writeStrongBinder(callback);
+    }
+
+    public static final Creator<JobParameters> CREATOR = new Creator<JobParameters>() {
+        @Override
+        public JobParameters createFromParcel(Parcel in) {
+            return new JobParameters(in);
+        }
+
+        @Override
+        public JobParameters[] newArray(int size) {
+            return new JobParameters[size];
+        }
+    };
+}
diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java
new file mode 100644
index 0000000..7fe192c
--- /dev/null
+++ b/core/java/android/app/job/JobScheduler.java
@@ -0,0 +1,72 @@
+/*
+ * 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 android.app.job;
+
+import java.util.List;
+
+import android.content.Context;
+
+/**
+ * Class for scheduling various types of jobs with the scheduling framework on the device.
+ *
+ * <p>You do not
+ * instantiate this class directly; instead, retrieve it through
+ * {@link android.content.Context#getSystemService
+ * Context.getSystemService(Context.JOB_SCHEDULER_SERVICE)}.
+ */
+public abstract class JobScheduler {
+    /**
+     * Returned from {@link #schedule(JobInfo)} when an invalid parameter was supplied. This can occur
+     * if the run-time for your job is too short, or perhaps the system can't resolve the
+     * requisite {@link JobService} in your package.
+     */
+    public static final int RESULT_FAILURE = 0;
+    /**
+     * Returned from {@link #schedule(JobInfo)} if this application has made too many requests for
+     * work over too short a time.
+     */
+    // TODO: Determine if this is necessary.
+    public static final int RESULT_SUCCESS = 1;
+
+    /**
+     * @param job The job you wish scheduled. See
+     * {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs
+     * you can schedule.
+     * @return If >0, this int returns the jobId of the successfully scheduled job.
+     * Otherwise you have to compare the return value to the error codes defined in this class.
+     */
+    public abstract int schedule(JobInfo job);
+
+    /**
+     * Cancel a job that is pending in the JobScheduler.
+     * @param jobId unique identifier for this job. Obtain this value from the jobs returned by
+     * {@link #getAllPendingJobs()}.
+     * @return
+     */
+    public abstract void cancel(int jobId);
+
+    /**
+     * Cancel all jobs that have been registered with the JobScheduler by this package.
+     */
+    public abstract void cancelAll();
+
+    /**
+     * @return a list of all the jobs registered by this package that have not yet been executed.
+     */
+    public abstract List<JobInfo> getAllPendingJobs();
+
+}
diff --git a/core/java/android/app/job/JobService.java b/core/java/android/app/job/JobService.java
new file mode 100644
index 0000000..eea0268
--- /dev/null
+++ b/core/java/android/app/job/JobService.java
@@ -0,0 +1,260 @@
+/*
+ * 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 android.app.job;
+
+import android.app.Service;
+import android.app.job.IJobCallback;
+import android.app.job.IJobService;
+import android.app.job.IJobService.Stub;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+/**
+ * <p>Entry point for the callback from the {@link android.app.job.JobScheduler}.</p>
+ * <p>This is the base class that handles asynchronous requests that were previously scheduled. You
+ * are responsible for overriding {@link JobService#onStartJob(JobParameters)}, which is where
+ * you will implement your job logic.</p>
+ * <p>This service executes each incoming job on a {@link android.os.Handler} running on your
+ * application's main thread. This means that you <b>must</b> offload your execution logic to
+ * another thread/handler/{@link android.os.AsyncTask} of your choosing. Not doing so will result
+ * in blocking any future callbacks from the JobManager - specifically
+ * {@link #onStopJob(android.app.job.JobParameters)}, which is meant to inform you that the
+ * scheduling requirements are no longer being met.</p>
+ */
+public abstract class JobService extends Service {
+    private static final String TAG = "JobService";
+
+    /**
+     * Job services must be protected with this permission:
+     *
+     * <pre class="prettyprint">
+     *     <service android:name="MyJobService"
+     *              android:permission="android.permission.BIND_JOB_SERVICE" >
+     *         ...
+     *     </service>
+     * </pre>
+     *
+     * <p>If a job service is declared in the manifest but not protected with this
+     * permission, that service will be ignored by the OS.
+     */
+    public static final String PERMISSION_BIND =
+            "android.permission.BIND_JOB_SERVICE";
+
+    /**
+     * Identifier for a message that will result in a call to
+     * {@link #onStartJob(android.app.job.JobParameters)}.
+     */
+    private final int MSG_EXECUTE_JOB = 0;
+    /**
+     * Message that will result in a call to {@link #onStopJob(android.app.job.JobParameters)}.
+     */
+    private final int MSG_STOP_JOB = 1;
+    /**
+     * Message that the client has completed execution of this job.
+     */
+    private final int MSG_JOB_FINISHED = 2;
+
+    /** Lock object for {@link #mHandler}. */
+    private final Object mHandlerLock = new Object();
+
+    /**
+     * Handler we post jobs to. Responsible for calling into the client logic, and handling the
+     * callback to the system.
+     */
+    @GuardedBy("mHandlerLock")
+    JobHandler mHandler;
+
+    /** Binder for this service. */
+    IJobService mBinder = new IJobService.Stub() {
+        @Override
+        public void startJob(JobParameters jobParams) {
+            ensureHandler();
+            Message m = Message.obtain(mHandler, MSG_EXECUTE_JOB, jobParams);
+            m.sendToTarget();
+        }
+        @Override
+        public void stopJob(JobParameters jobParams) {
+            ensureHandler();
+            Message m = Message.obtain(mHandler, MSG_STOP_JOB, jobParams);
+            m.sendToTarget();
+        }
+    };
+
+    /** @hide */
+    void ensureHandler() {
+        synchronized (mHandlerLock) {
+            if (mHandler == null) {
+                mHandler = new JobHandler(getMainLooper());
+            }
+        }
+    }
+
+    /**
+     * Runs on application's main thread - callbacks are meant to offboard work to some other
+     * (app-specified) mechanism.
+     * @hide
+     */
+    class JobHandler extends Handler {
+        JobHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            final JobParameters params = (JobParameters) msg.obj;
+            switch (msg.what) {
+                case MSG_EXECUTE_JOB:
+                    try {
+                        boolean workOngoing = JobService.this.onStartJob(params);
+                        ackStartMessage(params, workOngoing);
+                    } catch (Exception e) {
+                        Log.e(TAG, "Error while executing job: " + params.getJobId());
+                        throw new RuntimeException(e);
+                    }
+                    break;
+                case MSG_STOP_JOB:
+                    try {
+                        boolean ret = JobService.this.onStopJob(params);
+                        ackStopMessage(params, ret);
+                    } catch (Exception e) {
+                        Log.e(TAG, "Application unable to handle onStopJob.", e);
+                        throw new RuntimeException(e);
+                    }
+                    break;
+                case MSG_JOB_FINISHED:
+                    final boolean needsReschedule = (msg.arg2 == 1);
+                    IJobCallback callback = params.getCallback();
+                    if (callback != null) {
+                        try {
+                            callback.jobFinished(params.getJobId(), needsReschedule);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Error reporting job finish to system: binder has gone" +
+                                    "away.");
+                        }
+                    } else {
+                        Log.e(TAG, "finishJob() called for a nonexistent job id.");
+                    }
+                    break;
+                default:
+                    Log.e(TAG, "Unrecognised message received.");
+                    break;
+            }
+        }
+
+        private void ackStartMessage(JobParameters params, boolean workOngoing) {
+            final IJobCallback callback = params.getCallback();
+            final int jobId = params.getJobId();
+            if (callback != null) {
+                try {
+                     callback.acknowledgeStartMessage(jobId, workOngoing);
+                } catch(RemoteException e) {
+                    Log.e(TAG, "System unreachable for starting job.");
+                }
+            } else {
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "Attempting to ack a job that has already been processed.");
+                }
+            }
+        }
+
+        private void ackStopMessage(JobParameters params, boolean reschedule) {
+            final IJobCallback callback = params.getCallback();
+            final int jobId = params.getJobId();
+            if (callback != null) {
+                try {
+                    callback.acknowledgeStopMessage(jobId, reschedule);
+                } catch(RemoteException e) {
+                    Log.e(TAG, "System unreachable for stopping job.");
+                }
+            } else {
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "Attempting to ack a job that has already been processed.");
+                }
+            }
+        }
+    }
+
+    /** @hide */
+    public final IBinder onBind(Intent intent) {
+        return mBinder.asBinder();
+    }
+
+    /**
+     * Override this method with the callback logic for your job. Any such logic needs to be
+     * performed on a separate thread, as this function is executed on your application's main
+     * thread.
+     *
+     * @param params Parameters specifying info about this job, including the extras bundle you
+     *               optionally provided at job-creation time.
+     * @return True if your service needs to process the work (on a separate thread). False if
+     * there's no more work to be done for this job.
+     */
+    public abstract boolean onStartJob(JobParameters params);
+
+    /**
+     * This method is called if the system has determined that you must stop execution of your job
+     * even before you've had a chance to call {@link #jobFinished(JobParameters, boolean)}.
+     *
+     * <p>This will happen if the requirements specified at schedule time are no longer met. For
+     * example you may have requested WiFi with
+     * {@link android.app.job.JobInfo.Builder#setRequiredNetworkCapabilities(int)}, yet while your
+     * job was executing the user toggled WiFi. Another example is if you had specified
+     * {@link android.app.job.JobInfo.Builder#setRequiresDeviceIdle(boolean)}, and the phone left its
+     * idle maintenance window. You are solely responsible for the behaviour of your application
+     * upon receipt of this message; your app will likely start to misbehave if you ignore it. One
+     * immediate repercussion is that the system will cease holding a wakelock for you.</p>
+     *
+     * @param params Parameters specifying info about this job.
+     * @return True to indicate to the JobManager whether you'd like to reschedule this job based
+     * on the retry criteria provided at job creation-time. False to drop the job. Regardless of
+     * the value returned, your job must stop executing.
+     */
+    public abstract boolean onStopJob(JobParameters params);
+
+    /**
+     * Callback to inform the JobManager you've finished executing. This can be called from any
+     * thread, as it will ultimately be run on your application's main thread. When the system
+     * receives this message it will release the wakelock being held.
+     * <p>
+     *     You can specify post-execution behaviour to the scheduler here with
+     *     <code>needsReschedule </code>. This will apply a back-off timer to your job based on
+     *     the default, or what was set with
+     *     {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)}. The original
+     *     requirements are always honoured even for a backed-off job. Note that a job running in
+     *     idle mode will not be backed-off. Instead what will happen is the job will be re-added
+     *     to the queue and re-executed within a future idle maintenance window.
+     * </p>
+     *
+     * @param params Parameters specifying system-provided info about this job, this was given to
+     *               your application in {@link #onStartJob(JobParameters)}.
+     * @param needsReschedule True if this job is complete, false if you want the JobManager to
+     *                        reschedule you.
+     */
+    public final void jobFinished(JobParameters params, boolean needsReschedule) {
+        ensureHandler();
+        Message m = Message.obtain(mHandler, MSG_JOB_FINISHED, params);
+        m.arg2 = needsReschedule ? 1 : 0;
+        m.sendToTarget();
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/app/task/ITaskCallback.aidl b/core/java/android/app/task/ITaskCallback.aidl
deleted file mode 100644
index d8a32fd..0000000
--- a/core/java/android/app/task/ITaskCallback.aidl
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Copyright 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 android.app.task;
-
-import android.app.task.ITaskService;
-import android.app.task.TaskParams;
-
-/**
- * The server side of the TaskManager IPC protocols.  The app-side implementation
- * invokes on this interface to indicate completion of the (asynchronous) instructions
- * issued by the server.
- *
- * In all cases, the 'who' parameter is the caller's service binder, used to track
- * which Task Service instance is reporting.
- *
- * {@hide}
- */
-interface ITaskCallback {
-    /**
-     * Immediate callback to the system after sending a start signal, used to quickly detect ANR.
-     *
-     * @param taskId Unique integer used to identify this task.
-     * @param ongoing True to indicate that the client is processing the task. False if the task is
-     * complete
-     */
-    void acknowledgeStartMessage(int taskId, boolean ongoing);
-    /**
-     * Immediate callback to the system after sending a stop signal, used to quickly detect ANR.
-     *
-     * @param taskId Unique integer used to identify this task.
-     * @param rescheulde Whether or not to reschedule this task.
-     */
-    void acknowledgeStopMessage(int taskId, boolean reschedule);
-    /*
-     * Tell the task manager that the client is done with its execution, so that it can go on to
-     * the next one and stop attributing wakelock time to us etc.
-     *
-     * @param taskId Unique integer used to identify this task.
-     * @param reschedule Whether or not to reschedule this task.
-     */
-    void taskFinished(int taskId, boolean reschedule);
-}
diff --git a/core/java/android/app/task/TaskManager.java b/core/java/android/app/task/TaskManager.java
deleted file mode 100644
index 00f57da..0000000
--- a/core/java/android/app/task/TaskManager.java
+++ /dev/null
@@ -1,72 +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 android.app.task;
-
-import java.util.List;
-
-import android.content.Context;
-
-/**
- * Class for scheduling various types of tasks with the scheduling framework on the device.
- *
- * <p>You do not
- * instantiate this class directly; instead, retrieve it through
- * {@link android.content.Context#getSystemService
- * Context.getSystemService(Context.TASK_SERVICE)}.
- */
-public abstract class TaskManager {
-    /*
-     * Returned from {@link #schedule(Task)} when an invalid parameter was supplied. This can occur
-     * if the run-time for your task is too short, or perhaps the system can't resolve the
-     * requisite {@link TaskService} in your package.
-     */
-    public static final int RESULT_FAILURE = 0;
-    /**
-     * Returned from {@link #schedule(Task)} if this application has made too many requests for
-     * work over too short a time.
-     */
-    // TODO: Determine if this is necessary.
-    public static final int RESULT_SUCCESS = 1;
-
-    /**
-     * @param task The task you wish scheduled. See
-     * {@link android.app.task.Task.Builder Task.Builder} for more detail on the sorts of tasks
-     * you can schedule.
-     * @return If >0, this int returns the taskId of the successfully scheduled task.
-     * Otherwise you have to compare the return value to the error codes defined in this class.
-     */
-    public abstract int schedule(Task task);
-
-    /**
-     * Cancel a task that is pending in the TaskManager.
-     * @param taskId unique identifier for this task. Obtain this value from the tasks returned by
-     * {@link #getAllPendingTasks()}.
-     * @return
-     */
-    public abstract void cancel(int taskId);
-
-    /**
-     * Cancel all tasks that have been registered with the TaskManager by this package.
-     */
-    public abstract void cancelAll();
-
-    /**
-     * @return a list of all the tasks registered by this package that have not yet been executed.
-     */
-    public abstract List<Task> getAllPendingTasks();
-
-}
diff --git a/core/java/android/app/task/TaskParams.java b/core/java/android/app/task/TaskParams.java
deleted file mode 100644
index f4908c6..0000000
--- a/core/java/android/app/task/TaskParams.java
+++ /dev/null
@@ -1,91 +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 android.app.task;
-
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-
-/**
- * Contains the parameters used to configure/identify your task. You do not create this object
- * yourself, instead it is handed in to your application by the System.
- */
-public class TaskParams implements Parcelable {
-
-    private final int taskId;
-    private final PersistableBundle extras;
-    private final IBinder callback;
-
-    /** @hide */
-    public TaskParams(int taskId, PersistableBundle extras, IBinder callback) {
-        this.taskId = taskId;
-        this.extras = extras;
-        this.callback = callback;
-    }
-
-    /**
-     * @return The unique id of this task, specified at creation time.
-     */
-    public int getTaskId() {
-        return taskId;
-    }
-
-    /**
-     * @return The extras you passed in when constructing this task with
-     * {@link android.app.task.Task.Builder#setExtras(android.os.PersistableBundle)}. This will
-     * never be null. If you did not set any extras this will be an empty bundle.
-     */
-    public PersistableBundle getExtras() {
-        return extras;
-    }
-
-    /** @hide */
-    public ITaskCallback getCallback() {
-        return ITaskCallback.Stub.asInterface(callback);
-    }
-
-    private TaskParams(Parcel in) {
-        taskId = in.readInt();
-        extras = in.readPersistableBundle();
-        callback = in.readStrongBinder();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(taskId);
-        dest.writePersistableBundle(extras);
-        dest.writeStrongBinder(callback);
-    }
-
-    public static final Creator<TaskParams> CREATOR = new Creator<TaskParams>() {
-        @Override
-        public TaskParams createFromParcel(Parcel in) {
-            return new TaskParams(in);
-        }
-
-        @Override
-        public TaskParams[] newArray(int size) {
-            return new TaskParams[size];
-        }
-    };
-}
diff --git a/core/java/android/app/task/TaskService.java b/core/java/android/app/task/TaskService.java
deleted file mode 100644
index 8ce4484..0000000
--- a/core/java/android/app/task/TaskService.java
+++ /dev/null
@@ -1,257 +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 android.app.task;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-/**
- * <p>Entry point for the callback from the {@link android.app.task.TaskManager}.</p>
- * <p>This is the base class that handles asynchronous requests that were previously scheduled. You
- * are responsible for overriding {@link TaskService#onStartTask(TaskParams)}, which is where
- * you will implement your task logic.</p>
- * <p>This service executes each incoming task on a {@link android.os.Handler} running on your
- * application's main thread. This means that you <b>must</b> offload your execution logic to
- * another thread/handler/{@link android.os.AsyncTask} of your choosing. Not doing so will result
- * in blocking any future callbacks from the TaskManager - specifically
- * {@link #onStopTask(android.app.task.TaskParams)}, which is meant to inform you that the
- * scheduling requirements are no longer being met.</p>
- */
-public abstract class TaskService extends Service {
-    private static final String TAG = "TaskService";
-
-    /**
-     * Task services must be protected with this permission:
-     *
-     * <pre class="prettyprint">
-     *     <service android:name="MyTaskService"
-     *              android:permission="android.permission.BIND_TASK_SERVICE" >
-     *         ...
-     *     </service>
-     * </pre>
-     *
-     * <p>If a task service is declared in the manifest but not protected with this
-     * permission, that service will be ignored by the OS.
-     */
-    public static final String PERMISSION_BIND =
-            "android.permission.BIND_TASK_SERVICE";
-
-    /**
-     * Identifier for a message that will result in a call to
-     * {@link #onStartTask(android.app.task.TaskParams)}.
-     */
-    private final int MSG_EXECUTE_TASK = 0;
-    /**
-     * Message that will result in a call to {@link #onStopTask(android.app.task.TaskParams)}.
-     */
-    private final int MSG_STOP_TASK = 1;
-    /**
-     * Message that the client has completed execution of this task.
-     */
-    private final int MSG_TASK_FINISHED = 2;
-
-    /** Lock object for {@link #mHandler}. */
-    private final Object mHandlerLock = new Object();
-
-    /**
-     * Handler we post tasks to. Responsible for calling into the client logic, and handling the
-     * callback to the system.
-     */
-    @GuardedBy("mHandlerLock")
-    TaskHandler mHandler;
-
-    /** Binder for this service. */
-    ITaskService mBinder = new ITaskService.Stub() {
-        @Override
-        public void startTask(TaskParams taskParams) {
-            ensureHandler();
-            Message m = Message.obtain(mHandler, MSG_EXECUTE_TASK, taskParams);
-            m.sendToTarget();
-        }
-        @Override
-        public void stopTask(TaskParams taskParams) {
-            ensureHandler();
-            Message m = Message.obtain(mHandler, MSG_STOP_TASK, taskParams);
-            m.sendToTarget();
-        }
-    };
-
-    /** @hide */
-    void ensureHandler() {
-        synchronized (mHandlerLock) {
-            if (mHandler == null) {
-                mHandler = new TaskHandler(getMainLooper());
-            }
-        }
-    }
-
-    /**
-     * Runs on application's main thread - callbacks are meant to offboard work to some other
-     * (app-specified) mechanism.
-     * @hide
-     */
-    class TaskHandler extends Handler {
-        TaskHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            final TaskParams params = (TaskParams) msg.obj;
-            switch (msg.what) {
-                case MSG_EXECUTE_TASK:
-                    try {
-                        boolean workOngoing = TaskService.this.onStartTask(params);
-                        ackStartMessage(params, workOngoing);
-                    } catch (Exception e) {
-                        Log.e(TAG, "Error while executing task: " + params.getTaskId());
-                        throw new RuntimeException(e);
-                    }
-                    break;
-                case MSG_STOP_TASK:
-                    try {
-                        boolean ret = TaskService.this.onStopTask(params);
-                        ackStopMessage(params, ret);
-                    } catch (Exception e) {
-                        Log.e(TAG, "Application unable to handle onStopTask.", e);
-                        throw new RuntimeException(e);
-                    }
-                    break;
-                case MSG_TASK_FINISHED:
-                    final boolean needsReschedule = (msg.arg2 == 1);
-                    ITaskCallback callback = params.getCallback();
-                    if (callback != null) {
-                        try {
-                            callback.taskFinished(params.getTaskId(), needsReschedule);
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "Error reporting task finish to system: binder has gone" +
-                                    "away.");
-                        }
-                    } else {
-                        Log.e(TAG, "finishTask() called for a nonexistent task id.");
-                    }
-                    break;
-                default:
-                    Log.e(TAG, "Unrecognised message received.");
-                    break;
-            }
-        }
-
-        private void ackStartMessage(TaskParams params, boolean workOngoing) {
-            final ITaskCallback callback = params.getCallback();
-            final int taskId = params.getTaskId();
-            if (callback != null) {
-                try {
-                     callback.acknowledgeStartMessage(taskId, workOngoing);
-                } catch(RemoteException e) {
-                    Log.e(TAG, "System unreachable for starting task.");
-                }
-            } else {
-                if (Log.isLoggable(TAG, Log.DEBUG)) {
-                    Log.d(TAG, "Attempting to ack a task that has already been processed.");
-                }
-            }
-        }
-
-        private void ackStopMessage(TaskParams params, boolean reschedule) {
-            final ITaskCallback callback = params.getCallback();
-            final int taskId = params.getTaskId();
-            if (callback != null) {
-                try {
-                    callback.acknowledgeStopMessage(taskId, reschedule);
-                } catch(RemoteException e) {
-                    Log.e(TAG, "System unreachable for stopping task.");
-                }
-            } else {
-                if (Log.isLoggable(TAG, Log.DEBUG)) {
-                    Log.d(TAG, "Attempting to ack a task that has already been processed.");
-                }
-            }
-        }
-    }
-
-    /** @hide */
-    public final IBinder onBind(Intent intent) {
-        return mBinder.asBinder();
-    }
-
-    /**
-     * Override this method with the callback logic for your task. Any such logic needs to be
-     * performed on a separate thread, as this function is executed on your application's main
-     * thread.
-     *
-     * @param params Parameters specifying info about this task, including the extras bundle you
-     *               optionally provided at task-creation time.
-     * @return True if your service needs to process the work (on a separate thread). False if
-     * there's no more work to be done for this task.
-     */
-    public abstract boolean onStartTask(TaskParams params);
-
-    /**
-     * This method is called if the system has determined that you must stop execution of your task
-     * even before you've had a chance to call {@link #taskFinished(TaskParams, boolean)}.
-     *
-     * <p>This will happen if the requirements specified at schedule time are no longer met. For
-     * example you may have requested WiFi with
-     * {@link android.app.task.Task.Builder#setRequiredNetworkCapabilities(int)}, yet while your
-     * task was executing the user toggled WiFi. Another example is if you had specified
-     * {@link android.app.task.Task.Builder#setRequiresDeviceIdle(boolean)}, and the phone left its
-     * idle maintenance window. You are solely responsible for the behaviour of your application
-     * upon receipt of this message; your app will likely start to misbehave if you ignore it. One
-     * immediate repercussion is that the system will cease holding a wakelock for you.</p>
-     *
-     * @param params Parameters specifying info about this task.
-     * @return True to indicate to the TaskManager whether you'd like to reschedule this task based
-     * on the retry criteria provided at task creation-time. False to drop the task. Regardless of
-     * the value returned, your task must stop executing.
-     */
-    public abstract boolean onStopTask(TaskParams params);
-
-    /**
-     * Callback to inform the TaskManager you've finished executing. This can be called from any
-     * thread, as it will ultimately be run on your application's main thread. When the system
-     * receives this message it will release the wakelock being held.
-     * <p>
-     *     You can specify post-execution behaviour to the scheduler here with
-     *     <code>needsReschedule </code>. This will apply a back-off timer to your task based on
-     *     the default, or what was set with
-     *     {@link android.app.task.Task.Builder#setBackoffCriteria(long, int)}. The original
-     *     requirements are always honoured even for a backed-off task. Note that a task running in
-     *     idle mode will not be backed-off. Instead what will happen is the task will be re-added
-     *     to the queue and re-executed within a future idle maintenance window.
-     * </p>
-     *
-     * @param params Parameters specifying system-provided info about this task, this was given to
-     *               your application in {@link #onStartTask(TaskParams)}.
-     * @param needsReschedule True if this task is complete, false if you want the TaskManager to
-     *                        reschedule you.
-     */
-    public final void taskFinished(TaskParams params, boolean needsReschedule) {
-        ensureHandler();
-        Message m = Message.obtain(mHandler, MSG_TASK_FINISHED, params);
-        m.arg2 = needsReschedule ? 1 : 0;
-        m.sendToTarget();
-    }
-}
\ No newline at end of file
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 9fe9bce..cdcfd2e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2059,7 +2059,7 @@
             PRINT_SERVICE,
             MEDIA_SESSION_SERVICE,
             BATTERY_SERVICE,
-            TASK_SERVICE,
+            JOB_SCHEDULER_SERVICE,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ServiceName {}
@@ -2116,8 +2116,8 @@
      * <dd> A {@link android.app.DownloadManager} for requesting HTTP downloads
      * <dt> {@link #BATTERY_SERVICE} ("batterymanager")
      * <dd> A {@link android.os.BatteryManager} for managing battery state
-     * <dt> {@link #TASK_SERVICE} ("taskmanager")
-     * <dd>  A {@link android.app.task.TaskManager} for managing scheduled tasks
+     * <dt> {@link #JOB_SCHEDULER_SERVICE} ("taskmanager")
+     * <dd>  A {@link android.app.job.JobScheduler} for managing scheduled tasks
      * </dl>
      *
      * <p>Note:  System services obtained via this API may be closely associated with
@@ -2171,8 +2171,8 @@
      * @see android.app.DownloadManager
      * @see #BATTERY_SERVICE
      * @see android.os.BatteryManager
-     * @see #TASK_SERVICE
-     * @see android.app.task.TaskManager
+     * @see #JOB_SCHEDULER_SERVICE
+     * @see android.app.job.JobScheduler
      */
     public abstract Object getSystemService(@ServiceName @NonNull String name);
 
@@ -2761,12 +2761,12 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a {@link
-     * android.app.task.TaskManager} instance for managing occasional
+     * android.app.job.JobScheduler} instance for managing occasional
      * background tasks.
      * @see #getSystemService
-     * @see android.app.task.TaskManager
+     * @see android.app.job.JobScheduler
      */
-    public static final String TASK_SERVICE = "task";
+    public static final String JOB_SCHEDULER_SERVICE = "jobscheduler";
 
     /**
      * Determine whether the given permission is allowed for a particular
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 3696806..8768779 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1758,11 +1758,11 @@
 
     <!-- Allows the system to bind to an application's task services
          @hide -->
-    <permission android:name="android.permission.BIND_TASK_SERVICE"
+    <permission android:name="android.permission.BIND_JOB_SERVICE"
         android:protectionLevel="signature"
-        android:label="@string/permlab_bindTaskService"
-        android:description="@string/permdesc_bindTaskService" />
-    <uses-permission android:name="android.permission.BIND_TASK_SERVICE"/>
+        android:label="@string/permlab_bindJobService"
+        android:description="@string/permdesc_bindJobService" />
+    <uses-permission android:name="android.permission.BIND_JOB_SERVICE"/>
 
     <!-- ========================================= -->
     <!-- Permissions for special development tools -->
@@ -2877,8 +2877,8 @@
         </service>
 
         <service android:name="com.android.server.MountServiceIdler"
-                 android:exported="false"
-                 android:permission="android.permission.BIND_TASK_SERVICE" >
+                 android:exported="true"
+                 android:permission="android.permission.BIND_JOB_SERVICE" >
         </service>
 
     </application>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d521746..a224cd5 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1261,10 +1261,10 @@
          permission that an application must be granted by the user.  Instead, it
          is part of a mechanism that applications use to indicate to the system
          that they want to do scheduled background work.  -->
-    <string name="permlab_bindTaskService">run the application\'s scheduled background work</string>
+    <string name="permlab_bindJobService">run the application\'s scheduled background work</string>
     <!-- Description of an application permission, so that the user can understand
          what is being done if they are curious. -->
-    <string name="permdesc_bindTaskService">This permission allows the Android system to run the application in the background when requested.</string>
+    <string name="permdesc_bindJobService">This permission allows the Android system to run the application in the background when requested.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_diagnostic">read/write to resources owned by diag</string>
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());
-    }
-}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 2aa1220..db8c7a6 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -65,6 +65,7 @@
 import com.android.server.dreams.DreamManagerService;
 import com.android.server.hdmi.HdmiControlService;
 import com.android.server.input.InputManagerService;
+import com.android.server.job.JobSchedulerService;
 import com.android.server.lights.LightsManager;
 import com.android.server.lights.LightsService;
 import com.android.server.media.MediaRouterService;
@@ -83,7 +84,6 @@
 import com.android.server.search.SearchManagerService;
 import com.android.server.statusbar.StatusBarManagerService;
 import com.android.server.storage.DeviceStorageMonitorService;
-import com.android.server.task.TaskManagerService;
 import com.android.server.trust.TrustManagerService;
 import com.android.server.tv.TvInputManagerService;
 import com.android.server.twilight.TwilightService;
@@ -131,8 +131,8 @@
             "com.android.server.wifi.p2p.WifiP2pService";
     private static final String ETHERNET_SERVICE_CLASS =
             "com.android.server.ethernet.EthernetService";
-    private static final String TASK_SERVICE_CLASS =
-            "com.android.server.task.TaskManagerService";
+    private static final String JOB_SCHEDULER_SERVICE_CLASS =
+            "com.android.server.job.JobSchedulerService";
 
     private final int mFactoryTestMode;
     private Timer mProfilerSnapshotTimer;
@@ -832,7 +832,7 @@
 
             mSystemServiceManager.startService(UiModeManagerService.class);
 
-            mSystemServiceManager.startService(TaskManagerService.class);
+            mSystemServiceManager.startService(JobSchedulerService.class);
 
             if (!disableNonCoreServices) {
                 try {
diff --git a/services/tests/servicestests/src/com/android/server/task/TaskStoreTest.java b/services/tests/servicestests/src/com/android/server/task/TaskStoreTest.java
index e7f9ca0..23ea174 100644
--- a/services/tests/servicestests/src/com/android/server/task/TaskStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/task/TaskStoreTest.java
@@ -3,18 +3,20 @@
 
 import android.content.ComponentName;
 import android.content.Context;
-import android.app.task.Task;
-import android.app.task.Task.Builder;
+import android.app.job.JobInfo;
+import android.app.job.JobInfo.Builder;
 import android.os.PersistableBundle;
 import android.test.AndroidTestCase;
 import android.test.RenamingDelegatingContext;
 import android.util.Log;
 
-import com.android.server.task.controllers.TaskStatus;
+import com.android.server.job.JobMapReadFinishedListener;
+import com.android.server.job.JobStore;
+import com.android.server.job.controllers.JobStatus;
 
 import java.util.List;
 
-import static com.android.server.task.TaskStore.initAndGet;
+import static com.android.server.job.JobStore.initAndGet;
 /**
  * Test reading and writing correctly from file.
  */
@@ -26,12 +28,12 @@
     private ComponentName mComponent;
     private static final long IO_WAIT = 600L;
 
-    TaskStore mTaskStoreUnderTest;
+    JobStore mTaskStoreUnderTest;
     Context mTestContext;
-    TaskMapReadFinishedListener mTaskMapReadFinishedListenerStub =
-            new TaskMapReadFinishedListener() {
+    JobMapReadFinishedListener mTaskMapReadFinishedListenerStub =
+            new JobMapReadFinishedListener() {
         @Override
-        public void onTaskMapReadFinished(List<TaskStatus> tasks) {
+        public void onJobMapReadFinished(List<JobStatus> tasks) {
             // do nothing.
         }
     };
@@ -40,7 +42,7 @@
     public void setUp() throws Exception {
         mTestContext = new RenamingDelegatingContext(getContext(), TEST_PREFIX);
         Log.d(TAG, "Saving tasks to '" + mTestContext.getFilesDir() + "'");
-        mTaskStoreUnderTest = TaskStore.initAndGetForTesting(mTestContext,
+        mTaskStoreUnderTest = JobStore.initAndGetForTesting(mTestContext,
                 mTestContext.getFilesDir(), mTaskMapReadFinishedListenerStub);
         mComponent = new ComponentName(getContext().getPackageName(), StubClass.class.getName());
     }
@@ -56,23 +58,23 @@
         long runFromMillis = 2000L; // 2s
         long initialBackoff = 10000L; // 10s
 
-        final Task task = new Builder(taskId, mComponent)
+        final JobInfo task = new Builder(taskId, mComponent)
                 .setRequiresCharging(true)
-                .setRequiredNetworkCapabilities(Task.NetworkType.ANY)
-                .setBackoffCriteria(initialBackoff, Task.BackoffPolicy.EXPONENTIAL)
+                .setRequiredNetworkCapabilities(JobInfo.NetworkType.ANY)
+                .setBackoffCriteria(initialBackoff, JobInfo.BackoffPolicy.EXPONENTIAL)
                 .setOverrideDeadline(runByMillis)
                 .setMinimumLatency(runFromMillis)
                 .build();
-        final TaskStatus ts = new TaskStatus(task, SOME_UID, true /* persisted */);
+        final JobStatus ts = new JobStatus(task, SOME_UID, true /* persisted */);
         mTaskStoreUnderTest.add(ts);
         Thread.sleep(IO_WAIT);
         // Manually load tasks from xml file.
-        mTaskStoreUnderTest.readTaskMapFromDisk(new TaskMapReadFinishedListener() {
+        mTaskStoreUnderTest.readJobMapFromDisk(new JobMapReadFinishedListener() {
             @Override
-            public void onTaskMapReadFinished(List<TaskStatus> tasks) {
+            public void onJobMapReadFinished(List<JobStatus> tasks) {
                 assertEquals("Didn't get expected number of persisted tasks.", 1, tasks.size());
-                TaskStatus loadedTaskStatus = tasks.get(0);
-                assertTasksEqual(task, loadedTaskStatus.getTask());
+                JobStatus loadedTaskStatus = tasks.get(0);
+                assertTasksEqual(task, loadedTaskStatus.getJob());
                 assertEquals("Different uids.", SOME_UID, tasks.get(0).getUid());
                 compareTimestampsSubjectToIoLatency("Early run-times not the same after read.",
                         ts.getEarliestRunTime(), loadedTaskStatus.getEarliestRunTime());
@@ -84,30 +86,30 @@
     }
 
     public void testWritingTwoFilesToDisk() throws Exception {
-        final Task task1 = new Builder(8, mComponent)
+        final JobInfo task1 = new Builder(8, mComponent)
                 .setRequiresDeviceIdle(true)
                 .setPeriodic(10000L)
                 .setRequiresCharging(true)
                 .build();
-        final Task task2 = new Builder(12, mComponent)
+        final JobInfo task2 = new Builder(12, mComponent)
                 .setMinimumLatency(5000L)
-                .setBackoffCriteria(15000L, Task.BackoffPolicy.LINEAR)
+                .setBackoffCriteria(15000L, JobInfo.BackoffPolicy.LINEAR)
                 .setOverrideDeadline(30000L)
-                .setRequiredNetworkCapabilities(Task.NetworkType.UNMETERED)
+                .setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED)
                 .build();
-        final TaskStatus taskStatus1 = new TaskStatus(task1, SOME_UID, true /* persisted */);
-        final TaskStatus taskStatus2 = new TaskStatus(task2, SOME_UID, true /* persisted */);
+        final JobStatus taskStatus1 = new JobStatus(task1, SOME_UID, true /* persisted */);
+        final JobStatus taskStatus2 = new JobStatus(task2, SOME_UID, true /* persisted */);
         mTaskStoreUnderTest.add(taskStatus1);
         mTaskStoreUnderTest.add(taskStatus2);
         Thread.sleep(IO_WAIT);
-        mTaskStoreUnderTest.readTaskMapFromDisk(new TaskMapReadFinishedListener() {
+        mTaskStoreUnderTest.readJobMapFromDisk(new JobMapReadFinishedListener() {
             @Override
-            public void onTaskMapReadFinished(List<TaskStatus> tasks) {
+            public void onJobMapReadFinished(List<JobStatus> tasks) {
                 assertEquals("Incorrect # of persisted tasks.", 2, tasks.size());
-                TaskStatus loaded1 = tasks.get(0);
-                TaskStatus loaded2 = tasks.get(1);
-                assertTasksEqual(task1, loaded1.getTask());
-                assertTasksEqual(task2, loaded2.getTask());
+                JobStatus loaded1 = tasks.get(0);
+                JobStatus loaded2 = tasks.get(1);
+                assertTasksEqual(task1, loaded1.getJob());
+                assertTasksEqual(task2, loaded2.getJob());
 
                 // Check that the loaded task has the correct runtimes.
                 compareTimestampsSubjectToIoLatency("Early run-times not the same after read.",
@@ -124,7 +126,7 @@
     }
 
     public void testWritingTaskWithExtras() throws Exception {
-        Task.Builder b = new Builder(8, mComponent)
+        JobInfo.Builder b = new Builder(8, mComponent)
                 .setRequiresDeviceIdle(true)
                 .setPeriodic(10000L)
                 .setRequiresCharging(true);
@@ -134,17 +136,17 @@
         extras.putString("hi", "there");
         extras.putInt("into", 3);
         b.setExtras(extras);
-        final Task task = b.build();
-        TaskStatus taskStatus = new TaskStatus(task, SOME_UID, true /* persisted */);
+        final JobInfo task = b.build();
+        JobStatus taskStatus = new JobStatus(task, SOME_UID, true /* persisted */);
 
         mTaskStoreUnderTest.add(taskStatus);
         Thread.sleep(IO_WAIT);
-        mTaskStoreUnderTest.readTaskMapFromDisk(new TaskMapReadFinishedListener() {
+        mTaskStoreUnderTest.readJobMapFromDisk(new JobMapReadFinishedListener() {
             @Override
-            public void onTaskMapReadFinished(List<TaskStatus> tasks) {
+            public void onJobMapReadFinished(List<JobStatus> tasks) {
                 assertEquals("Incorrect # of persisted tasks.", 1, tasks.size());
-                TaskStatus loaded = tasks.get(0);
-                assertTasksEqual(task, loaded.getTask());
+                JobStatus loaded = tasks.get(0);
+                assertTasksEqual(task, loaded.getJob());
             }
         });
 
@@ -153,7 +155,7 @@
     /**
      * Helper function to throw an error if the provided task and TaskStatus objects are not equal.
      */
-    private void assertTasksEqual(Task first, Task second) {
+    private void assertTasksEqual(JobInfo first, JobInfo second) {
         assertEquals("Different task ids.", first.getId(), second.getId());
         assertEquals("Different components.", first.getService(), second.getService());
         assertEquals("Different periodic status.", first.isPeriodic(), second.isPeriodic());
@@ -168,11 +170,11 @@
         assertEquals("Invalid idle constraint.", first.isRequireDeviceIdle(),
                 second.isRequireDeviceIdle());
         assertEquals("Invalid unmetered constraint.",
-                first.getNetworkCapabilities() == Task.NetworkType.UNMETERED,
-                second.getNetworkCapabilities() == Task.NetworkType.UNMETERED);
+                first.getNetworkCapabilities() == JobInfo.NetworkType.UNMETERED,
+                second.getNetworkCapabilities() == JobInfo.NetworkType.UNMETERED);
         assertEquals("Invalid connectivity constraint.",
-                first.getNetworkCapabilities() == Task.NetworkType.ANY,
-                second.getNetworkCapabilities() == Task.NetworkType.ANY);
+                first.getNetworkCapabilities() == JobInfo.NetworkType.ANY,
+                second.getNetworkCapabilities() == JobInfo.NetworkType.ANY);
         assertEquals("Invalid deadline constraint.",
                 first.hasLateConstraint(),
                 second.hasLateConstraint());
diff --git a/services/tests/servicestests/src/com/android/server/task/controllers/BatteryControllerTest.java b/services/tests/servicestests/src/com/android/server/task/controllers/BatteryControllerTest.java
index 6617a05..9754e8c 100644
--- a/services/tests/servicestests/src/com/android/server/task/controllers/BatteryControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/task/controllers/BatteryControllerTest.java
@@ -21,9 +21,11 @@
 import android.content.Intent;
 import android.test.AndroidTestCase;
 
-import com.android.server.task.StateChangedListener;
+import com.android.server.job.StateChangedListener;
+import com.android.server.job.controllers.BatteryController;
+import com.android.server.job.controllers.JobStatus;
 
-import static com.android.server.task.controllers.BatteryController.getForTesting;
+import static com.android.server.job.controllers.BatteryController.getForTesting;
 
 import static org.mockito.Mockito.*;
 
@@ -40,7 +42,7 @@
         }
 
         @Override
-        public void onRunTaskNow(TaskStatus taskStatus) {
+        public void onRunJobNow(JobStatus taskStatus) {
 
         }
     };
diff --git a/tests/JobSchedulerTestApp/AndroidManifest.xml b/tests/JobSchedulerTestApp/AndroidManifest.xml
index 7431737..9654197 100644
--- a/tests/JobSchedulerTestApp/AndroidManifest.xml
+++ b/tests/JobSchedulerTestApp/AndroidManifest.xml
@@ -25,6 +25,7 @@
 
         <service
             android:name=".service.TestJobService"
+            android:permission="android.permission.BIND_JOB_SERVICE"
             android:exported="true"/>
     </application>
 
diff --git a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java
index 393c594..15050ef 100644
--- a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java
+++ b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java
@@ -17,8 +17,8 @@
 package com.android.demo.jobSchedulerApp;
 
 import android.app.Activity;
-import android.app.task.Task;
-import android.app.task.TaskParams;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.res.Resources;
@@ -80,10 +80,10 @@
     RadioButton mWiFiConnectivityRadioButton;
     RadioButton mAnyConnectivityRadioButton;
     ComponentName mServiceComponent;
-    /** Service object to interact scheduled tasks. */
+    /** Service object to interact scheduled jobs. */
     TestJobService mTestService;
 
-    private static int kTaskId = 0;
+    private static int kJobId = 0;
 
     Handler mHandler = new Handler(/* default looper */) {
         @Override
@@ -112,7 +112,7 @@
     }
 
     /**
-     * UI onclick listener to schedule a task. What this task is is defined in
+     * UI onclick listener to schedule a job. What this job is is defined in
      * TestJobService#scheduleJob()
      */
     public void scheduleJob(View v) {
@@ -120,7 +120,7 @@
             return;
         }
 
-        Task.Builder builder = new Task.Builder(kTaskId++, mServiceComponent);
+        JobInfo.Builder builder = new JobInfo.Builder(kJobId++, mServiceComponent);
 
         String delay = mDelayEditText.getText().toString();
         if (delay != null && !TextUtils.isEmpty(delay)) {
@@ -133,9 +133,9 @@
         boolean requiresUnmetered = mWiFiConnectivityRadioButton.isSelected();
         boolean requiresAnyConnectivity = mAnyConnectivityRadioButton.isSelected();
         if (requiresUnmetered) {
-            builder.setRequiredNetworkCapabilities(Task.NetworkType.UNMETERED);
+            builder.setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED);
         } else if (requiresAnyConnectivity) {
-            builder.setRequiredNetworkCapabilities(Task.NetworkType.ANY);
+            builder.setRequiredNetworkCapabilities(JobInfo.NetworkType.ANY);
         }
 
         mTestService.scheduleJob(builder.build());
@@ -143,24 +143,24 @@
     }
 
     /**
-     * UI onclick listener to call taskFinished() in our service.
+     * UI onclick listener to call jobFinished() in our service.
      */
     public void finishJob(View v) {
         if (!ensureTestService()) {
             return;
         }
-        mTestService.callTaskFinished();
+        mTestService.callJobFinished();
         mParamsTextView.setText("");
     }
 
-    public void onReceivedStartTask(TaskParams params) {
+    public void onReceivedStartJob(JobParameters params) {
         mShowStartView.setBackgroundColor(startJobColor);
         Message m = Message.obtain(mHandler, MSG_UNCOLOUR_START);
         mHandler.sendMessageDelayed(m, 1000L); // uncolour in 1 second.
-        mParamsTextView.setText("Executing: " + params.getTaskId() + " " + params.getExtras());
+        mParamsTextView.setText("Executing: " + params.getJobId() + " " + params.getExtras());
     }
 
-    public void onReceivedStopTask() {
+    public void onReceivedStopJob() {
         mShowStopView.setBackgroundColor(stopJobColor);
         Message m = Message.obtain(mHandler, MSG_UNCOLOUR_STOP);
         mHandler.sendMessageDelayed(m, 2000L); // uncolour in 1 second.
diff --git a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
index 7dd3cf1..bf8e887 100644
--- a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
+++ b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
@@ -16,28 +16,20 @@
 
 package com.android.demo.jobSchedulerApp.service;
 
-import android.app.Service;
-import android.app.task.Task;
-import android.app.task.TaskManager;
-import android.app.task.TaskParams;
-import android.app.task.TaskService;
-import android.content.ComponentName;
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.app.job.JobParameters;
+import android.app.job.JobService;
 import android.content.Context;
 import android.content.Intent;
-import android.os.Binder;
-import android.os.IBinder;
 import android.os.Message;
 import android.os.Messenger;
-import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.util.Log;
 
 import com.android.demo.jobSchedulerApp.MainActivity;
 
-import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.LinkedList;
-import java.util.List;
 
 
 /**
@@ -52,7 +44,7 @@
  * lifecycle of our and provide a handle to said SyncAdapter to the OS on
  * request.
  */
-public class TestJobService extends TaskService {
+public class TestJobService extends JobService {
     private static final String TAG = "SyncService";
 
     @Override
@@ -82,44 +74,44 @@
     }
 
     @Override
-    public boolean onStartTask(TaskParams params) {
-        taskParamsMap.add(params);
+    public boolean onStartJob(JobParameters params) {
+        jobParamsMap.add(params);
         if (mActivity != null) {
-            mActivity.onReceivedStartTask(params);
+            mActivity.onReceivedStartJob(params);
         }
-        Log.i(TAG, "on start task: " + params.getTaskId());
+        Log.i(TAG, "on start job: " + params.getJobId());
         return true;
     }
 
     @Override
-    public boolean onStopTask(TaskParams params) {
-        taskParamsMap.remove(params);
-        mActivity.onReceivedStopTask();
-        Log.i(TAG, "on stop task: " + params.getTaskId());
+    public boolean onStopJob(JobParameters params) {
+        jobParamsMap.remove(params);
+        mActivity.onReceivedStopJob();
+        Log.i(TAG, "on stop job: " + params.getJobId());
         return true;
     }
 
     MainActivity mActivity;
-    private final LinkedList<TaskParams> taskParamsMap = new LinkedList<TaskParams>();
+    private final LinkedList<JobParameters> jobParamsMap = new LinkedList<JobParameters>();
 
     public void setUiCallback(MainActivity activity) {
         mActivity = activity;
     }
 
     /** Send job to the JobScheduler. */
-    public void scheduleJob(Task t) {
+    public void scheduleJob(JobInfo t) {
         Log.d(TAG, "Scheduling job");
-        TaskManager tm =
-                (TaskManager) getSystemService(Context.TASK_SERVICE);
+        JobScheduler tm =
+                (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
         tm.schedule(t);
     }
 
-    public boolean callTaskFinished() {
-        TaskParams params = taskParamsMap.poll();
+    public boolean callJobFinished() {
+        JobParameters params = jobParamsMap.poll();
         if (params == null) {
             return false;
         } else {
-            taskFinished(params, false);
+            jobFinished(params, false);
             return true;
         }
     }
