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

Commit f53c295a authored by Matthew Williams's avatar Matthew Williams Committed by Android Git Automerger
Browse files

am 3b471117: Merge "Add OnNetworkActive to TaskManager and simplify locking." into lmp-preview-dev

* commit '3b4711176e77640d697e94137e65fa93c8363f5c':
  Add OnNetworkActive to TaskManager and simplify locking.
parents 1a2f7a1e 5553aeb2
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ package android.app;
import android.app.task.ITaskManager;
import android.app.task.Task;
import android.app.task.TaskManager;
import android.os.RemoteException;

import java.util.List;

@@ -37,26 +38,35 @@ public class TaskManagerImpl extends TaskManager {

    @Override
    public int schedule(Task task) {
        // TODO Auto-generated method stub
        return 0;
        try {
            return mBinder.schedule(task);
        } catch (RemoteException e) {
            return TaskManager.RESULT_FAILURE;
        }
    }

    @Override
    public void cancel(int taskId) {
        // TODO Auto-generated method stub
        try {
            mBinder.cancel(taskId);
        } catch (RemoteException e) {}

    }

    @Override
    public void cancelAll() {
        // TODO Auto-generated method stub
        try {
            mBinder.cancelAll();
        } catch (RemoteException e) {}

    }

    @Override
    public List<Task> getAllPendingTasks() {
        // TODO Auto-generated method stub
        try {
            return mBinder.getAllPendingTasks();
        } catch (RemoteException e) {
            return null;
        }

    }
}
+8 −3
Original line number Diff line number Diff line
@@ -48,6 +48,11 @@ public class Task implements Parcelable {
     * @hide
     */
    public static final int DEFAULT_BACKOFF_POLICY = BackoffPolicy.EXPONENTIAL;
    /**
     * Maximum backoff we allow for a job, in milliseconds.
     * @hide
     */
    public static final long MAX_BACKOFF_DELAY_MILLIS = 24 * 60 * 60 * 1000;  // 24 hours.

    /**
     * Linear: retry_time(failure_time, t) = failure_time + initial_retry_delay * t, t >= 1
@@ -185,7 +190,7 @@ public class Task implements Parcelable {
    private Task(Parcel in) {
        taskId = in.readInt();
        extras = in.readPersistableBundle();
        service = ComponentName.readFromParcel(in);
        service = in.readParcelable(null);
        requireCharging = in.readInt() == 1;
        requireDeviceIdle = in.readInt() == 1;
        networkCapabilities = in.readInt();
@@ -201,7 +206,7 @@ public class Task implements Parcelable {

    private Task(Task.Builder b) {
        taskId = b.mTaskId;
        extras = new PersistableBundle(b.mExtras);
        extras = b.mExtras;
        service = b.mTaskService;
        requireCharging = b.mRequiresCharging;
        requireDeviceIdle = b.mRequiresDeviceIdle;
@@ -225,7 +230,7 @@ public class Task implements Parcelable {
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(taskId);
        out.writePersistableBundle(extras);
        ComponentName.writeToParcel(service, out);
        out.writeParcelable(service, flags);
        out.writeInt(requireCharging ? 1 : 0);
        out.writeInt(requireDeviceIdle ? 1 : 0);
        out.writeInt(networkCapabilities);
+1 −1
Original line number Diff line number Diff line
@@ -35,5 +35,5 @@ public interface StateChangedListener {
     * it must be run immediately.
     * @param taskStatus The state of the task which is to be run immediately.
     */
    public void onTaskDeadlineExpired(TaskStatus taskStatus);
    public void onRunTaskNow(TaskStatus taskStatus);
}
+214 −131

File changed.

Preview size limit exceeded, changes collapsed.

+61 −43
Original line number Diff line number Diff line
@@ -31,11 +31,11 @@ import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -54,7 +54,7 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon
    private static final int defaultMaxActiveTasksPerService =
            ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
    /** Amount of time a task is allowed to execute for before being considered timed-out. */
    private static final long EXECUTING_TIMESLICE_MILLIS = 5 * 60 * 1000;
    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. */
    private static final long OP_TIMEOUT_MILLIS = 8 * 1000;
    /** String prefix for all wakelock names. */
@@ -100,10 +100,14 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon
    /** Binder to the client service. */
    ITaskService service;

    private final Object mAvailableLock = new Object();
    private final Object mLock = new Object();
    /** Whether this context is free. */
    @GuardedBy("mAvailableLock")
    @GuardedBy("mLock")
    private boolean mAvailable;
    /** Track start time. */
    private long mExecutionStartTimeElapsed;
    /** Track when job will timeout. */
    private long mTimeoutElapsed;

    TaskServiceContext(TaskManagerService service, Looper looper) {
        this(service.getContext(), service, looper);
@@ -114,32 +118,25 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon
        mContext = context;
        mCallbackHandler = new TaskServiceHandler(looper);
        mCompletedListener = completedListener;
        mAvailable = true;
    }

    /**
     * Give a task 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 was accepted and is going to run.
     * @return True if the task is valid and is running. False if the task cannot be executed.
     */
    boolean executeRunnableTask(TaskStatus ts) {
        synchronized (mAvailableLock) {
        synchronized (mLock) {
            if (!mAvailable) {
                Slog.e(TAG, "Starting new runnable but context is unavailable > Error.");
                return false;
            }
            mAvailable = false;
        }

        final PowerManager pm =
                (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                TM_WAKELOCK_PREFIX + ts.getServiceComponent().getPackageName());
        mWakeLock.setWorkSource(new WorkSource(ts.getUid()));
        mWakeLock.setReferenceCounted(false);

            mRunningTask = ts;
            mParams = new TaskParams(ts.getTaskId(), ts.getExtras(), this);
            mExecutionStartTimeElapsed = SystemClock.elapsedRealtime();

            mVerb = VERB_BINDING;
            final Intent intent = new Intent().setComponent(ts.getServiceComponent());
@@ -150,11 +147,15 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon
                if (DEBUG) {
                    Slog.d(TAG, ts.getServiceComponent().getShortClassName() + " unavailable.");
                }
                mRunningTask = null;
                mParams = null;
                mExecutionStartTimeElapsed = 0L;
                return false;
            }

            mAvailable = false;
            return true;
        }
    }

    /** Used externally to query the running task. Will return null if there is no task running. */
    TaskStatus getRunningTask() {
@@ -170,11 +171,19 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon
     * @return Whether this context is available to handle incoming work.
     */
    boolean isAvailable() {
        synchronized (mAvailableLock) {
        synchronized (mLock) {
            return mAvailable;
        }
    }

    long getExecutionStartTimeElapsed() {
        return mExecutionStartTimeElapsed;
    }

    long getTimeoutElapsed() {
        return mTimeoutElapsed;
    }

    @Override
    public void taskFinished(int taskId, boolean reschedule) {
        if (!verifyCallingUid()) {
@@ -217,6 +226,12 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon
        this.service = ITaskService.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()));
        mWakeLock.setReferenceCounted(false);
        mWakeLock.acquire();
        mCallbackHandler.obtainMessage(MSG_SERVICE_BOUND).sendToTarget();
    }
@@ -263,7 +278,8 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon
                    break;
                case MSG_CALLBACK:
                    if (DEBUG) {
                        Slog.d(TAG, "MSG_CALLBACK of : " + mRunningTask);
                        Slog.d(TAG, "MSG_CALLBACK of : " + mRunningTask + " v:" +
                                VERB_STRINGS[mVerb]);
                    }
                    removeMessages(MSG_TIMEOUT);

@@ -288,6 +304,7 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon
                    break;
                case MSG_SHUTDOWN_EXECUTION:
                    closeAndCleanupTaskH(true /* needsReschedule */);
                    break;
                default:
                    Log.e(TAG, "Unrecognised message: " + message);
            }
@@ -423,7 +440,7 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon
                case VERB_EXECUTING:
                    // Not an error - client ran out of time.
                    Log.i(TAG, "Client timed out while executing (no taskFinished received)." +
                            " Reporting failure and asking for reschedule. "  +
                            " sending onStop. "  +
                            mRunningTask.getServiceComponent().getShortClassName() + "' tId: "
                            + taskId);
                    sendStopMessageH();
@@ -452,7 +469,7 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon
                service.stopTask(mParams);
            } catch (RemoteException e) {
                Log.e(TAG, "Error sending onStopTask to client.", e);
                closeAndCleanupTaskH(false);
                closeAndCleanupTaskH(false /* reschedule */);
            }
        }

@@ -464,6 +481,7 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon
         */
        private void closeAndCleanupTaskH(boolean reschedule) {
            removeMessages(MSG_TIMEOUT);
            synchronized (mLock) {
                mWakeLock.release();
                mContext.unbindService(TaskServiceContext.this);
                mCompletedListener.onTaskCompleted(mRunningTask, reschedule);
@@ -474,7 +492,6 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon
                mVerb = -1;
                mCancelled.set(false);
                service = null;
            synchronized (mAvailableLock) {
                mAvailable = true;
            }
        }
@@ -496,6 +513,7 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon
            }
            Message m = mCallbackHandler.obtainMessage(MSG_TIMEOUT);
            mCallbackHandler.sendMessageDelayed(m, timeoutMillis);
            mTimeoutElapsed = SystemClock.elapsedRealtime() + timeoutMillis;
        }
    }
}
Loading