Loading core/java/android/app/TaskManagerImpl.java +17 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } } } core/java/android/app/task/Task.java +8 −3 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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(); Loading @@ -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; Loading @@ -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); Loading services/core/java/com/android/server/task/StateChangedListener.java +1 −1 Original line number Diff line number Diff line Loading @@ -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); } services/core/java/com/android/server/task/TaskManagerService.java +214 −131 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/task/TaskServiceContext.java +61 −43 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. */ Loading Loading @@ -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); Loading @@ -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()); Loading @@ -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() { Loading @@ -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()) { Loading Loading @@ -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(); } Loading Loading @@ -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); Loading @@ -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); } Loading Loading @@ -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(); Loading Loading @@ -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 */); } } Loading @@ -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); Loading @@ -474,7 +492,6 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon mVerb = -1; mCancelled.set(false); service = null; synchronized (mAvailableLock) { mAvailable = true; } } Loading @@ -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
core/java/android/app/TaskManagerImpl.java +17 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } } }
core/java/android/app/task/Task.java +8 −3 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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(); Loading @@ -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; Loading @@ -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); Loading
services/core/java/com/android/server/task/StateChangedListener.java +1 −1 Original line number Diff line number Diff line Loading @@ -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); }
services/core/java/com/android/server/task/TaskManagerService.java +214 −131 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/task/TaskServiceContext.java +61 −43 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. */ Loading Loading @@ -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); Loading @@ -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()); Loading @@ -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() { Loading @@ -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()) { Loading Loading @@ -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(); } Loading Loading @@ -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); Loading @@ -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); } Loading Loading @@ -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(); Loading Loading @@ -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 */); } } Loading @@ -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); Loading @@ -474,7 +492,6 @@ public class TaskServiceContext extends ITaskCallback.Stub implements ServiceCon mVerb = -1; mCancelled.set(false); service = null; synchronized (mAvailableLock) { mAvailable = true; } } Loading @@ -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; } } }