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

Commit afcece81 authored by Matthew Williams's avatar Matthew Williams Committed by Android (Google) Code Review
Browse files

Merge "Add persistence of tasks for TaskManager & BatteryController" into lmp-preview-dev

parents 71f507bb 3d86fd2b
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -5362,7 +5362,7 @@ package android.app.task {
  public class Task implements android.os.Parcelable {
    method public int describeContents();
    method public int getBackoffPolicy();
    method public android.os.Bundle getExtras();
    method public android.os.PersistableBundle getExtras();
    method public int getId();
    method public long getInitialBackoffMillis();
    method public long getIntervalMillis();
@@ -5386,7 +5386,7 @@ package android.app.task {
    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.Bundle);
    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);
@@ -5413,7 +5413,7 @@ package android.app.task {
  public class TaskParams implements android.os.Parcelable {
    method public int describeContents();
    method public android.os.Bundle getExtras();
    method public android.os.PersistableBundle getExtras();
    method public int getTaskId();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
+26 −20
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.ComponentName;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;

/**
 * Container of data passed to the {@link android.app.task.TaskManager} fully encapsulating the
@@ -36,6 +37,18 @@ public class Task implements Parcelable {
        public final int UNMETERED = 2;
    }

    /**
     * Amount of backoff a task has initially by default, in milliseconds.
     * @hide.
     */
    public static final long DEFAULT_INITIAL_BACKOFF_MILLIS = 5000L;

    /**
     * Default type of backoff.
     * @hide
     */
    public static final int DEFAULT_BACKOFF_POLICY = BackoffPolicy.EXPONENTIAL;

    /**
     * Linear: retry_time(failure_time, t) = failure_time + initial_retry_delay * t, t >= 1
     * Expon: retry_time(failure_time, t) = failure_time + initial_retry_delay ^ t, t >= 1
@@ -47,7 +60,7 @@ public class Task implements Parcelable {

    private final int taskId;
    // TODO: Change this to use PersistableBundle when that lands in master.
    private final Bundle extras;
    private final PersistableBundle extras;
    private final ComponentName service;
    private final boolean requireCharging;
    private final boolean requireDeviceIdle;
@@ -71,7 +84,7 @@ public class Task implements Parcelable {
    /**
     * Bundle of extras which are returned to your application at execution time.
     */
    public Bundle getExtras() {
    public PersistableBundle getExtras() {
        return extras;
    }

@@ -171,7 +184,7 @@ public class Task implements Parcelable {

    private Task(Parcel in) {
        taskId = in.readInt();
        extras = in.readBundle();
        extras = in.readPersistableBundle();
        service = ComponentName.readFromParcel(in);
        requireCharging = in.readInt() == 1;
        requireDeviceIdle = in.readInt() == 1;
@@ -188,7 +201,7 @@ public class Task implements Parcelable {

    private Task(Task.Builder b) {
        taskId = b.mTaskId;
        extras = new Bundle(b.mExtras);
        extras = new PersistableBundle(b.mExtras);
        service = b.mTaskService;
        requireCharging = b.mRequiresCharging;
        requireDeviceIdle = b.mRequiresDeviceIdle;
@@ -211,7 +224,7 @@ public class Task implements Parcelable {
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(taskId);
        out.writeBundle(extras);
        out.writePersistableBundle(extras);
        ComponentName.writeToParcel(service, out);
        out.writeInt(requireCharging ? 1 : 0);
        out.writeInt(requireDeviceIdle ? 1 : 0);
@@ -238,12 +251,10 @@ public class Task implements Parcelable {
        }
    };

    /**
     * Builder class for constructing {@link Task} objects.
     */
    /** Builder class for constructing {@link Task} objects. */
    public static final class Builder {
        private int mTaskId;
        private Bundle mExtras;
        private PersistableBundle mExtras = PersistableBundle.EMPTY;
        private ComponentName mTaskService;
        // Requirements.
        private boolean mRequiresCharging;
@@ -258,8 +269,8 @@ public class Task implements Parcelable {
        private boolean mHasLateConstraint;
        private long mIntervalMillis;
        // Back-off parameters.
        private long mInitialBackoffMillis = 5000L;
        private int mBackoffPolicy = BackoffPolicy.EXPONENTIAL;
        private long mInitialBackoffMillis = DEFAULT_INITIAL_BACKOFF_MILLIS;
        private int mBackoffPolicy = DEFAULT_BACKOFF_POLICY;
        /** Easy way to track whether the client has tried to set a back-off policy. */
        private boolean mBackoffPolicySet = false;

@@ -279,7 +290,7 @@ public class Task implements Parcelable {
         * Set optional extras. This is persisted, so we only allow primitive types.
         * @param extras Bundle containing extras you want the scheduler to hold on to for you.
         */
        public Builder setExtras(Bundle extras) {
        public Builder setExtras(PersistableBundle extras) {
            mExtras = extras;
            return this;
        }
@@ -394,18 +405,13 @@ public class Task implements Parcelable {
         * @return The task object to hand to the TaskManager. This object is immutable.
         */
        public Task build() {
            if (mExtras == null) {
                mExtras = Bundle.EMPTY;
            }
            if (mTaskId < 0) {
                throw new IllegalArgumentException("Task id must be greater than 0.");
            }
            mExtras = new PersistableBundle(mExtras);  // Make our own copy.
            // Check that a deadline was not set on a periodic task.
            if (mIsPeriodic && mHasLateConstraint) {
            if (mIsPeriodic && (mMaxExecutionDelayMillis != 0L)) {
                throw new IllegalArgumentException("Can't call setOverrideDeadline() on a " +
                        "periodic task.");
            }
            if (mIsPeriodic && mHasEarlyConstraint) {
            if (mIsPeriodic && (mMinLatencyMillis != 0L)) {
                throw new IllegalArgumentException("Can't call setMinimumLatency() on a " +
                        "periodic task");
            }
+7 −7
Original line number Diff line number Diff line
@@ -16,10 +16,10 @@

package android.app.task;

import android.os.Bundle;
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
@@ -28,11 +28,11 @@ import android.os.Parcelable;
public class TaskParams implements Parcelable {

    private final int taskId;
    private final Bundle extras;
    private final PersistableBundle extras;
    private final IBinder callback;

    /** @hide */
    public TaskParams(int taskId, Bundle extras, IBinder callback) {
    public TaskParams(int taskId, PersistableBundle extras, IBinder callback) {
        this.taskId = taskId;
        this.extras = extras;
        this.callback = callback;
@@ -47,10 +47,10 @@ public class TaskParams implements Parcelable {

    /**
     * @return The extras you passed in when constructing this task with
     * {@link android.app.task.Task.Builder#setExtras(android.os.Bundle)}. This will
     * {@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 Bundle getExtras() {
    public PersistableBundle getExtras() {
        return extras;
    }

@@ -61,7 +61,7 @@ public class TaskParams implements Parcelable {

    private TaskParams(Parcel in) {
        taskId = in.readInt();
        extras = in.readBundle();
        extras = in.readPersistableBundle();
        callback = in.readStrongBinder();
    }

@@ -73,7 +73,7 @@ public class TaskParams implements Parcelable {
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(taskId);
        dest.writeBundle(extras);
        dest.writePersistableBundle(extras);
        dest.writeStrongBinder(callback);
    }

+41 −15
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.os.SystemClock;
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;
@@ -48,12 +49,19 @@ 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, and
 * similarly for {@link #mActiveServices}. If both locks need to be held take mTasksSet first and then
 * mActiveService afterwards.
 * @hide
 */
public class TaskManagerService extends com.android.server.SystemService
        implements StateChangedListener, TaskCompletedListener {
        implements StateChangedListener, TaskCompletedListener, TaskMapReadFinishedListener {
    // TODO: Switch this off for final version.
    private static final boolean DEBUG = true;
    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";
@@ -113,8 +121,8 @@ public class TaskManagerService extends com.android.server.SystemService
     */
    public int schedule(Task task, int uId, boolean canPersistTask) {
        TaskStatus taskStatus = new TaskStatus(task, uId, canPersistTask);
        return startTrackingTask(taskStatus) ?
                TaskManager.RESULT_SUCCESS : TaskManager.RESULT_FAILURE;
        startTrackingTask(taskStatus);
        return TaskManager.RESULT_SUCCESS;
    }

    public List<Task> getPendingTasks(int uid) {
@@ -210,7 +218,7 @@ public class TaskManagerService extends com.android.server.SystemService
     */
    public TaskManagerService(Context context) {
        super(context);
        mTasks = new TaskStore(context);
        mTasks = TaskStore.initAndGet(this);
        mHandler = new TaskHandler(context.getMainLooper());
        mTaskManagerStub = new TaskManagerStub();
        // Create the "runners".
@@ -218,12 +226,12 @@ public class TaskManagerService extends com.android.server.SystemService
            mActiveServices.add(
                    new TaskServiceContext(this, context.getMainLooper()));
        }

        // Create the controllers.
        mControllers = new LinkedList<StateController>();
        mControllers.add(ConnectivityController.get(this));
        mControllers.add(TimeController.get(this));
        mControllers.add(IdleController.get(this));
        // TODO: Add BatteryStateController when implemented.
        mControllers.add(BatteryController.get(this));
    }

    @Override
@@ -236,18 +244,15 @@ public class TaskManagerService extends com.android.server.SystemService
     * {@link com.android.server.task.TaskStore}, and make sure all the relevant controllers know
     * about.
     */
    private boolean startTrackingTask(TaskStatus taskStatus) {
        boolean added = false;
    private void startTrackingTask(TaskStatus taskStatus) {
        synchronized (mTasks) {
            added = mTasks.add(taskStatus);
            mTasks.add(taskStatus);
        }
        if (added) {
        for (StateController controller : mControllers) {
            controller.maybeStartTrackingTask(taskStatus);

        }
    }
        return added;
    }

    /**
     * Called when we want to remove a TaskStatus object that we've finished executing. Returns the
@@ -404,6 +409,27 @@ public class TaskManagerService extends com.android.server.SystemService
        mHandler.obtainMessage(MSG_TASK_EXPIRED, taskStatus);
    }

    /**
     * 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.contains(ts)) {
                    // 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) {
+529 −45

File changed.

Preview size limit exceeded, changes collapsed.

Loading