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

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

Merge "Add timeout when waiting to bind to JobService" into lmp-dev

parents 327f7ebc 75fc5258
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -21,14 +21,23 @@ import java.util.List;
import android.content.Context;

/**
 * Class for scheduling various types of jobs with the scheduling framework on the device.
 * This is an API for scheduling various types of jobs against the framework that will be executed
 * in your application's own process.
 * <p>
 * See {@link android.app.job.JobInfo} for more description of the types of jobs that can be run
 * and how to construct them.
 * and how to construct them. You will construct these JobInfo objects and pass them to the
 * JobScheduler with {@link #schedule(JobInfo)}. When the criteria declared are met, the
 * system will execute this job on your application's {@link android.app.job.JobService}.
 * You identify which JobService is meant to execute the logic for your job when you create the
 * JobInfo with {@link android.app.job.JobInfo.Builder#Builder(int, android.content.ComponentName)}.
 * </p>
 * <p>
 * The framework will be intelligent about when you receive your callbacks, and attempt to batch
 * and defer them as much as possible. Typically if you don't specify a deadline on your job, it
 * can be run at any moment depending on the current state of the JobScheduler's internal queue,
 * however it might be deferred as long as until the next time the device is connected to a power
 * source.
 * </p>
 * <p>You do not
 * instantiate this class directly; instead, retrieve it through
 * {@link android.content.Context#getSystemService
+17 −6
Original line number Diff line number Diff line
@@ -199,9 +199,6 @@ public class JobSchedulerService extends com.android.server.SystemService
            List<JobStatus> jobsForUser = mJobs.getJobsByUser(userHandle);
            for (int i=0; i<jobsForUser.size(); i++) {
                JobStatus toRemove = jobsForUser.get(i);
                if (DEBUG) {
                    Slog.d(TAG, "Cancelling: " + toRemove);
                }
                cancelJobLocked(toRemove);
            }
        }
@@ -219,9 +216,6 @@ public class JobSchedulerService extends com.android.server.SystemService
            List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid);
            for (int i=0; i<jobsForUid.size(); i++) {
                JobStatus toRemove = jobsForUid.get(i);
                if (DEBUG) {
                    Slog.d(TAG, "Cancelling: " + toRemove);
                }
                cancelJobLocked(toRemove);
            }
        }
@@ -547,14 +541,28 @@ public class JobSchedulerService extends com.android.server.SystemService
        private void queueReadyJobsForExecutionH() {
            synchronized (mJobs) {
                ArraySet<JobStatus> jobs = mJobs.getJobs();
                if (DEBUG) {
                    Slog.d(TAG, "queuing all ready jobs for execution:");
                }
                for (int i=0; i<jobs.size(); i++) {
                    JobStatus job = jobs.valueAt(i);
                    if (isReadyToBeExecutedLocked(job)) {
                        if (DEBUG) {
                            Slog.d(TAG, "    queued " + job.toShortString());
                        }
                        mPendingJobs.add(job);
                    } else if (isReadyToBeCancelledLocked(job)) {
                        stopJobOnServiceContextLocked(job);
                    }
                }
                if (DEBUG) {
                    final int queuedJobs = mPendingJobs.size();
                    if (queuedJobs == 0) {
                        Slog.d(TAG, "No jobs pending.");
                    } else {
                        Slog.d(TAG, queuedJobs + " jobs queued.");
                    }
                }
            }
        }

@@ -657,6 +665,9 @@ public class JobSchedulerService extends com.android.server.SystemService
        private void maybeRunPendingJobsH() {
            synchronized (mJobs) {
                Iterator<JobStatus> it = mPendingJobs.iterator();
                if (DEBUG) {
                    Slog.d(TAG, "pending queue: " + mPendingJobs.size() + " jobs.");
                }
                while (it.hasNext()) {
                    JobStatus nextPending = it.next();
                    JobServiceContext availableContext = null;
+36 −37
Original line number Diff line number Diff line
@@ -157,6 +157,7 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne
            mExecutionStartTimeElapsed = SystemClock.elapsedRealtime();

            mVerb = VERB_BINDING;
            scheduleOpTimeOut();
            final Intent intent = new Intent().setComponent(job.getServiceComponent());
            boolean binding = mContext.bindServiceAsUser(intent, this,
                    Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND,
@@ -253,8 +254,6 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne
            return;
        }
        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, mRunningJob.getTag());
@@ -299,6 +298,7 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne
        public void handleMessage(Message message) {
            switch (message.what) {
                case MSG_SERVICE_BOUND:
                    removeMessages(MSG_TIMEOUT);
                    handleServiceBoundH();
                    break;
                case MSG_CALLBACK:
@@ -337,6 +337,9 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne

        /** Start the job on the service. */
        private void handleServiceBoundH() {
            if (DEBUG) {
                Slog.d(TAG, "MSG_SERVICE_BOUND for " + mRunningJob.toShortString());
            }
            if (mVerb != VERB_BINDING) {
                Slog.e(TAG, "Sending onStartJob for a job that isn't pending. "
                        + VERB_STRINGS[mVerb]);
@@ -456,42 +459,36 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne

        /** Process MSG_TIMEOUT here. */
        private void handleOpTimeoutH() {
            if (JobSchedulerService.DEBUG) {
                Slog.d(TAG, "MSG_TIMEOUT of " +
                        mRunningJob.getServiceComponent().getShortClassName() + " : "
                        + mParams.getJobId());
            }

            final int jobId = mParams.getJobId();
            switch (mVerb) {
                case VERB_BINDING:
                    Slog.e(TAG, "Time-out while trying to bind " + mRunningJob.toShortString() +
                            ", dropping.");
                    closeAndCleanupJobH(false /* needsReschedule */);
                    break;
                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 JobScheduler
                    // FINISHED/NO-RETRY.
                    Slog.e(TAG, "No response from client for onStartJob '" +
                            mRunningJob.getServiceComponent().getShortClassName() + "' jId: "
                            + jobId);
                            mRunningJob.toShortString());
                    closeAndCleanupJobH(false /* needsReschedule */);
                    break;
                case VERB_STOPPING:
                    // At least we got somewhere, so fail but ask the JobScheduler to reschedule.
                    Slog.e(TAG, "No response from client for onStopJob, '" +
                            mRunningJob.getServiceComponent().getShortClassName() + "' jId: "
                            + jobId);
                            mRunningJob.toShortString());
                    closeAndCleanupJobH(true /* needsReschedule */);
                    break;
                case VERB_EXECUTING:
                    // Not an error - client ran out of time.
                    Slog.i(TAG, "Client timed out while executing (no jobFinished received)." +
                            " sending onStop. "  +
                            mRunningJob.getServiceComponent().getShortClassName() + "' jId: "
                            + jobId);
                            " sending onStop. "  + mRunningJob.toShortString());
                    sendStopMessageH();
                    break;
                default:
                    Slog.e(TAG, "Handling timeout for an unknown active job state: "
                            + mRunningJob);
                    return;
                    Slog.e(TAG, "Handling timeout for an invalid job state: " +
                            mRunningJob.toShortString() + ", dropping.");
                    closeAndCleanupJobH(false /* needsReschedule */);
            }
        }

@@ -530,7 +527,9 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne
                } catch (RemoteException e) {
                    // Whatever.
                }
                if (mWakeLock != null) {
                    mWakeLock.release();
                }
                mContext.unbindService(JobServiceContext.this);
                mWakeLock = null;
                mRunningJob = null;
@@ -547,6 +546,7 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne
            removeMessages(MSG_SHUTDOWN_EXECUTION);
            mCompletedListener.onJobCompleted(completedJob, reschedule);
        }
    }

    /**
     * Called when sending a message to the client, over whose execution we have no control. If
@@ -568,4 +568,3 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne
        mTimeoutElapsed = SystemClock.elapsedRealtime() + timeoutMillis;
    }
}
}