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

Commit 4172c224 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Use scheduleAsPackage."

parents cc3d628f 9cbbc05a
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -17,15 +17,23 @@
package com.android.server.job;

import android.annotation.Nullable;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.util.proto.ProtoOutputStream;

import java.util.List;

/**
 * JobScheduler local system service interface.
 * {@hide} Only for use within the system server.
 */
public interface JobSchedulerInternal {

    /**
     * Returns a list of jobs scheduled by the system service for itself.
     */
    List<JobInfo> getSystemScheduledOwnJobs(@Nullable String namespace);

    /**
     * Cancel the jobs for a given uid (e.g. when app data is cleared)
     *
+15 −0
Original line number Diff line number Diff line
@@ -3535,6 +3535,21 @@ public class JobSchedulerService extends com.android.server.SystemService

    final class LocalService implements JobSchedulerInternal {

        @Override
        public List<JobInfo> getSystemScheduledOwnJobs(@Nullable String namespace) {
            synchronized (mLock) {
                final List<JobInfo> ownJobs = new ArrayList<>();
                mJobs.forEachJob(Process.SYSTEM_UID, (job) -> {
                    if (job.getSourceUid() == Process.SYSTEM_UID
                            && Objects.equals(job.getNamespace(), namespace)
                            && "android".equals(job.getSourcePackageName())) {
                        ownJobs.add(job.getJob());
                    }
                });
                return ownJobs;
            }
        }

        @Override
        public void cancelJobsForUid(int uid, boolean includeProxiedJobs,
                @JobParameters.StopReason int reason, int internalReasonCode, String debugReason) {
+1 −0
Original line number Diff line number Diff line
@@ -85,4 +85,5 @@ message SyncStatusProto {
  repeated StatusInfo status = 1;

  optional bool is_job_namespace_migrated = 2;
  optional bool is_job_attribution_fixed = 3;
}
+47 −13
Original line number Diff line number Diff line
@@ -488,11 +488,14 @@ public class SyncManager {
     * migrated already.
     */
    private void migrateSyncJobNamespaceIfNeeded() {
        if (mSyncStorageEngine.isJobNamespaceMigrated()) {
        final boolean namespaceMigrated = mSyncStorageEngine.isJobNamespaceMigrated();
        final boolean attributionFixed = mSyncStorageEngine.isJobAttributionFixed();
        if (namespaceMigrated && attributionFixed) {
            return;
        }
        final JobScheduler jobSchedulerDefaultNamespace =
                mContext.getSystemService(JobScheduler.class);
        if (!namespaceMigrated) {
            final List<JobInfo> pendingJobs = jobSchedulerDefaultNamespace.getAllPendingJobs();
            // Wait until we've confirmed that all syncs have been migrated to the new namespace
            // before we persist successful migration to our status file. This is done to avoid
@@ -507,7 +510,8 @@ public class SyncManager {
                final SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
                if (op != null) {
                    // This is a sync. Move it over to SyncManager's namespace.
                mJobScheduler.schedule(job);
                    mJobScheduler.scheduleAsPackage(job,
                            op.owningPackage, op.target.userId, op.wakeLockName());
                    jobSchedulerDefaultNamespace.cancel(job.getId());
                    allSyncsMigrated = false;
                }
@@ -515,6 +519,36 @@ public class SyncManager {
            mSyncStorageEngine.setJobNamespaceMigrated(allSyncsMigrated);
        }

        // Fix attribution for any syncs that were previously scheduled using
        // JobScheduler.schedule() instead of JobScheduler.scheduleAsPackage().
        final List<JobInfo> namespacedJobs = LocalServices.getService(JobSchedulerInternal.class)
                .getSystemScheduledOwnJobs(mJobScheduler.getNamespace());
        // Wait until we've confirmed that all syncs have been proper attribution
        // before we persist attribution state to our status file. This is done to avoid
        // internal consistency issues if the devices reboots right after SyncManager has
        // rescheduled the job on its side but before JobScheduler has finished persisting
        // the updated jobs to disk. If JobScheduler hasn't persisted the update to disk,
        // then nothing that happened afterwards should have been persisted either, so there's
        // no concern over activity happening after the migration causing issues.
        // This case is done to fix issues for a subset of test devices.
        // TODO: remove this attribution check/fix code
        boolean allSyncsAttributed = true;
        for (int i = namespacedJobs.size() - 1; i >= 0; --i) {
            final JobInfo job = namespacedJobs.get(i);
            final SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
            if (op != null) {
                // This is a sync. Make sure it's properly attributed to the app
                // instead of the system.
                // Since the job ID stays the same, scheduleAsPackage will replace the scheduled
                // job, so we don't need to call cancel as well.
                mJobScheduler.scheduleAsPackage(job,
                        op.owningPackage, op.target.userId, op.wakeLockName());
                allSyncsAttributed = false;
            }
        }
        mSyncStorageEngine.setJobAttributionFixed(allSyncsAttributed);
    }

    private synchronized void verifyJobScheduler() {
        if (mJobScheduler != null) {
            return;
+20 −0
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ public class SyncStorageEngine {
    private volatile boolean mIsClockValid;

    private volatile boolean mIsJobNamespaceMigrated;
    private volatile boolean mIsJobAttributionFixed;

    static {
        sAuthorityRenames = new HashMap<String, String>();
@@ -852,6 +853,20 @@ public class SyncStorageEngine {
        return mIsJobNamespaceMigrated;
    }

    void setJobAttributionFixed(boolean fixed) {
        if (mIsJobAttributionFixed == fixed) {
            return;
        }
        mIsJobAttributionFixed = fixed;
        // This isn't urgent enough to write synchronously. Post it to the handler thread so
        // SyncManager can move on with whatever it was doing.
        mHandler.sendEmptyMessageDelayed(MSG_WRITE_STATUS, WRITE_STATUS_DELAY);
    }

    boolean isJobAttributionFixed() {
        return mIsJobAttributionFixed;
    }

    public Pair<Long, Long> getBackoff(EndPoint info) {
        synchronized (mAuthorities) {
            AuthorityInfo authority = getAuthorityLocked(info, "getBackoff");
@@ -2120,6 +2135,10 @@ public class SyncStorageEngine {
                    mIsJobNamespaceMigrated =
                            proto.readBoolean(SyncStatusProto.IS_JOB_NAMESPACE_MIGRATED);
                    break;
                case (int) SyncStatusProto.IS_JOB_ATTRIBUTION_FIXED:
                    mIsJobAttributionFixed =
                            proto.readBoolean(SyncStatusProto.IS_JOB_ATTRIBUTION_FIXED);
                    break;
                case ProtoInputStream.NO_MORE_FIELDS:
                    return;
            }
@@ -2389,6 +2408,7 @@ public class SyncStorageEngine {
        }

        proto.write(SyncStatusProto.IS_JOB_NAMESPACE_MIGRATED, mIsJobNamespaceMigrated);
        proto.write(SyncStatusProto.IS_JOB_ATTRIBUTION_FIXED, mIsJobAttributionFixed);

        proto.flush();
    }