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

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

Merge "DO NOT MERGE Race condition in JobServiceContext" into mnc-dr-dev

parents 48234936 f5e04525
Loading
Loading
Loading
Loading
+26 −10
Original line number Diff line number Diff line
@@ -108,7 +108,13 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne
    int mVerb;
    private AtomicBoolean mCancelled = new AtomicBoolean();

    /** All the information maintained about the job currently being executed. */
    /**
     * All the information maintained about the job currently being executed.
     *
     * Any reads (dereferences) not done from the handler thread must be synchronized on
     * {@link #mLock}.
     * Writes can only be done from the handler thread, or {@link #executeRunnableJob(JobStatus)}.
     */
    private JobStatus mRunningJob;
    /** Binder to the client service. */
    IJobService service;
@@ -192,7 +198,8 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne
     */
    JobStatus getRunningJob() {
        synchronized (mLock) {
            return mRunningJob;
            return mRunningJob == null ?
                    null : new JobStatus(mRunningJob);
        }
    }

@@ -253,15 +260,22 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne
     */
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        if (!name.equals(mRunningJob.getServiceComponent())) {
        JobStatus runningJob;
        synchronized (mLock) {
            // This isn't strictly necessary b/c the JobServiceHandler is running on the main
            // looper and at this point we can't get any binder callbacks from the client. Better
            // safe than sorry.
            runningJob = mRunningJob;
        }
        if (runningJob == null || !name.equals(runningJob.getServiceComponent())) {
            mCallbackHandler.obtainMessage(MSG_SHUTDOWN_EXECUTION).sendToTarget();
            return;
        }
        this.service = IJobService.Stub.asInterface(service);
        final PowerManager pm =
                (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mRunningJob.getTag());
        mWakeLock.setWorkSource(new WorkSource(mRunningJob.getUid()));
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, runningJob.getTag());
        mWakeLock.setWorkSource(new WorkSource(runningJob.getUid()));
        mWakeLock.setReferenceCounted(false);
        mWakeLock.acquire();
        mCallbackHandler.obtainMessage(MSG_SERVICE_BOUND).sendToTarget();
@@ -279,6 +293,7 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne
     * @return True if the binder calling is coming from the client we expect.
     */
    private boolean verifyCallingUid() {
        synchronized (mLock) {
            if (mRunningJob == null || Binder.getCallingUid() != mRunningJob.getUid()) {
                if (DEBUG) {
                    Slog.d(TAG, "Stale callback received, ignoring.");
@@ -287,6 +302,7 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne
            }
            return true;
        }
    }

    /**
     * Handles the lifecycle of the JobService binding/callbacks, etc. The convention within this
+7 −0
Original line number Diff line number Diff line
@@ -82,6 +82,13 @@ public class JobStatus {
        this.numFailures = numFailures;
    }

    /** Copy constructor. */
    public JobStatus(JobStatus jobStatus) {
        this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getNumFailures());
        this.earliestRunTimeElapsedMillis = jobStatus.getEarliestRunTime();
        this.latestRunTimeElapsedMillis = jobStatus.getLatestRunTimeElapsed();
    }

    /** Create a newly scheduled job. */
    public JobStatus(JobInfo job, int uId) {
        this(job, uId, 0);