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

Commit a494f05f authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 7502225 from 4b61a185 to sc-release

Change-Id: I7b4dc39e866c909328a1cceae3fc775bb6d52ade
parents 451dd357 4b61a185
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -65,5 +65,8 @@ java_sdk_library {
    },
    jarjar_rules: "jarjar-rules.txt",
    apex_available: ["com.android.appsearch"],
    impl_library_visibility: [
        "//frameworks/base/apex/appsearch/service",
    ],
    unsafe_ignore_missing_latest_api: true, // TODO(b/146218515) should be removed
}
+21 −11
Original line number Diff line number Diff line
@@ -28,31 +28,41 @@ genrule {
}

java_library {
    name: "service-appsearch",
    srcs: [
        "java/**/*.java",
        ":statslog-appsearch-java-gen",
    name: "statslog-appsearch-lib",
    srcs: [":statslog-appsearch-java-gen"],
    libs: [
        "framework-statsd.stubs.module_lib",
    ],
    sdk_version: "system_server_current",
    apex_available: ["com.android.appsearch"],
}

java_library {
    name: "service-appsearch",
    srcs: ["java/**/*.java"],
    sdk_version: "system_server_current",
    static_libs: [
        "icing-java-proto-lite",
        "libicing-java",
        // This list must be kept in sync with jarjar.txt
        "statslog-appsearch-lib",
        // Entries below this line are outside of the appsearch package tree and must be kept in
        // sync with jarjar.txt
        "modules-utils-preconditions",
    ],
    libs: [
        "framework",
        "framework-appsearch",
        "framework-statsd.stubs.module_lib",
        "services.core",
        "services.usage",
        "framework-appsearch.impl",
        "unsupportedappusage", // TODO(b/181887768) should be removed
    ],
    required: [
        "libicing",
    ],
    defaults: ["framework-system-server-module-defaults"],
    permitted_packages: [
        "com.android.server.appsearch",
        "com.google.android.icing",
    ],
    jarjar_rules: "jarjar-rules.txt",
    visibility: [
        "//frameworks/base/apex/appsearch:__subpackages__",
        // These are required until appsearch is properly unbundled.
        "//frameworks/base/services/tests/mockingservicestests",
        "//frameworks/base/services/tests/servicestests",
+4 −1
Original line number Diff line number Diff line
# Rename all icing classes to match our module name. OEMs could start using icing lib for some other
# purpose in system service, which would cause class collisions when loading our apex into the
# system service.
rule com.google.protobuf.** com.android.server.appsearch.protobuf.@1
rule com.google.android.icing.proto.** com.android.server.appsearch.proto.@1
rule com.google.android.icing.proto.** com.android.server.appsearch.icing.proto.@1

# Rename all com.android.internal.util classes to prevent class name collisions
# between this module and the other versions of the utility classes linked into
+4 −1
Original line number Diff line number Diff line
@@ -82,7 +82,10 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/** TODO(b/142567528): add comments when implement this class */
/**
 * The main service implementation which contains AppSearch's platform functionality.
 * @hide
 */
public class AppSearchManagerService extends SystemService {
    private static final String TAG = "AppSearchManagerService";
    private final Context mContext;
+101 −25
Original line number Diff line number Diff line
@@ -73,7 +73,9 @@ import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.SparseLongArray;
import android.util.SparseSetArray;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
@@ -686,26 +688,92 @@ public class JobSchedulerService extends com.android.server.SystemService
    final Constants mConstants;
    final ConstantsObserver mConstantsObserver;

    private static final Comparator<JobStatus> sPendingJobComparator = (o1, o2) -> {
    @VisibleForTesting
    class PendingJobComparator implements Comparator<JobStatus> {
        private final SparseBooleanArray mUidHasEjCache = new SparseBooleanArray();
        private final SparseLongArray mEarliestRegEnqueueTimeCache = new SparseLongArray();

        /**
         * Refresh sorting determinants based on the current state of {@link #mPendingJobs}.
         */
        @GuardedBy("mLock")
        @VisibleForTesting
        void refreshLocked() {
            mUidHasEjCache.clear();
            mEarliestRegEnqueueTimeCache.clear();
            for (int i = 0; i < mPendingJobs.size(); ++i) {
                final JobStatus job = mPendingJobs.get(i);
                final int uid = job.getSourceUid();
                if (job.isRequestedExpeditedJob()) {
                    mUidHasEjCache.put(uid, true);
                } else {
                    final long earliestEnqueueTime =
                            mEarliestRegEnqueueTimeCache.get(uid, Long.MAX_VALUE);
                    mEarliestRegEnqueueTimeCache.put(uid,
                            Math.min(earliestEnqueueTime, job.enqueueTime));
                }
            }
        }

        @Override
        public int compare(JobStatus o1, JobStatus o2) {
            if (o1 == o2) {
                return 0;
            }
            // Jobs with an override state set (via adb) should be put first as tests/developers
            // expect the jobs to run immediately.
            if (o1.overrideState != o2.overrideState) {
            // Higher override state (OVERRIDE_FULL) should be before lower state (OVERRIDE_SOFT)
                // Higher override state (OVERRIDE_FULL) should be before lower state
                // (OVERRIDE_SOFT)
                return o2.overrideState - o1.overrideState;
            }
            final boolean o1EJ = o1.isRequestedExpeditedJob();
            final boolean o2EJ = o2.isRequestedExpeditedJob();
            if (o1.getSourceUid() == o2.getSourceUid()) {
            final boolean o1FGJ = o1.isRequestedExpeditedJob();
            if (o1FGJ != o2.isRequestedExpeditedJob()) {
                if (o1EJ != o2EJ) {
                    // Attempt to run requested expedited jobs ahead of regular jobs, regardless of
                    // expedited job quota.
                return o1FGJ ? -1 : 1;
                    return o1EJ ? -1 : 1;
                }
            }
            final boolean uid1HasEj = mUidHasEjCache.get(o1.getSourceUid());
            final boolean uid2HasEj = mUidHasEjCache.get(o2.getSourceUid());
            if ((uid1HasEj || uid2HasEj) && (o1EJ || o2EJ)) {
                // We MUST prioritize EJs ahead of regular jobs within a single app. Since we do
                // that, in order to satisfy the transitivity constraint of the comparator, if
                // any UID has an EJ, we must ensure that the EJ is ordered ahead of the regular
                // job of a different app IF the app with an EJ had another job that came before
                // the differing app. For example, if app A has regJob1 at t1 and eJob3 at t3 and
                // app B has regJob2 at t2, eJob3 must be ordered before regJob2 because it will be
                // ordered before regJob1.
                // Regular jobs don't need to jump the line.

                final long uid1EarliestRegEnqueueTime = Math.min(o1.enqueueTime,
                        mEarliestRegEnqueueTimeCache.get(o1.getSourceUid(), Long.MAX_VALUE));
                final long uid2EarliestRegEnqueueTime = Math.min(o2.enqueueTime,
                        mEarliestRegEnqueueTimeCache.get(o2.getSourceUid(), Long.MAX_VALUE));

                if (o1EJ && o2EJ) {
                    if (uid1EarliestRegEnqueueTime < uid2EarliestRegEnqueueTime) {
                        return -1;
                    } else if (uid1EarliestRegEnqueueTime > uid2EarliestRegEnqueueTime) {
                        return 1;
                    }
                } else if (o1EJ && uid1EarliestRegEnqueueTime < o2.enqueueTime) {
                    return -1;
                } else if (o2EJ && uid2EarliestRegEnqueueTime < o1.enqueueTime) {
                    return 1;
                }
            }
            if (o1.enqueueTime < o2.enqueueTime) {
                return -1;
            }
            return o1.enqueueTime > o2.enqueueTime ? 1 : 0;
    };
        }
    }

    @VisibleForTesting
    final PendingJobComparator mPendingJobComparator = new PendingJobComparator();

    static <T> void addOrderedItem(ArrayList<T> array, T newItem, Comparator<T> comparator) {
        int where = Collections.binarySearch(array, newItem, comparator);
@@ -1115,7 +1183,7 @@ public class JobSchedulerService extends com.android.server.SystemService
                // This is a new job, we can just immediately put it on the pending
                // list and try to run it.
                mJobPackageTracker.notePending(jobStatus);
                addOrderedItem(mPendingJobs, jobStatus, sPendingJobComparator);
                addOrderedItem(mPendingJobs, jobStatus, mPendingJobComparator);
                maybeRunPendingJobsLocked();
            } else {
                evaluateControllerStatesLocked(jobStatus);
@@ -1919,7 +1987,7 @@ public class JobSchedulerService extends com.android.server.SystemService
                        if (js != null) {
                            if (isReadyToBeExecutedLocked(js)) {
                                mJobPackageTracker.notePending(js);
                                addOrderedItem(mPendingJobs, js, sPendingJobComparator);
                                addOrderedItem(mPendingJobs, js, mPendingJobComparator);
                            }
                        } else {
                            Slog.e(TAG, "Given null job to check individually");
@@ -2064,6 +2132,7 @@ public class JobSchedulerService extends com.android.server.SystemService
     * Run through list of jobs and execute all possible - at least one is expired so we do
     * as many as we can.
     */
    @GuardedBy("mLock")
    private void queueReadyJobsForExecutionLocked() {
        // This method will check and capture all ready jobs, so we don't need to keep any messages
        // in the queue.
@@ -2079,7 +2148,7 @@ public class JobSchedulerService extends com.android.server.SystemService
        mPendingJobs.clear();
        stopNonReadyActiveJobsLocked();
        mJobs.forEachJob(mReadyQueueFunctor);
        mReadyQueueFunctor.postProcess();
        mReadyQueueFunctor.postProcessLocked();

        if (DEBUG) {
            final int queuedJobs = mPendingJobs.size();
@@ -2106,16 +2175,19 @@ public class JobSchedulerService extends com.android.server.SystemService
            }
        }

        public void postProcess() {
        @GuardedBy("mLock")
        private void postProcessLocked() {
            noteJobsPending(newReadyJobs);
            mPendingJobs.addAll(newReadyJobs);
            if (mPendingJobs.size() > 1) {
                mPendingJobs.sort(sPendingJobComparator);
                mPendingJobComparator.refreshLocked();
                mPendingJobs.sort(mPendingJobComparator);
            }

            newReadyJobs.clear();
        }
    }

    private final ReadyJobQueueFunctor mReadyQueueFunctor = new ReadyJobQueueFunctor();

    /**
@@ -2180,7 +2252,9 @@ public class JobSchedulerService extends com.android.server.SystemService
            }
        }

        public void postProcess() {
        @GuardedBy("mLock")
        @VisibleForTesting
        void postProcessLocked() {
            if (unbatchedCount > 0
                    || forceBatchedCount >= mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT) {
                if (DEBUG) {
@@ -2189,7 +2263,8 @@ public class JobSchedulerService extends com.android.server.SystemService
                noteJobsPending(runnableJobs);
                mPendingJobs.addAll(runnableJobs);
                if (mPendingJobs.size() > 1) {
                    mPendingJobs.sort(sPendingJobComparator);
                    mPendingJobComparator.refreshLocked();
                    mPendingJobs.sort(mPendingJobComparator);
                }
            } else {
                if (DEBUG) {
@@ -2210,6 +2285,7 @@ public class JobSchedulerService extends com.android.server.SystemService
    }
    private final MaybeReadyJobQueueFunctor mMaybeQueueFunctor = new MaybeReadyJobQueueFunctor();

    @GuardedBy("mLock")
    private void maybeQueueReadyJobsForExecutionLocked() {
        if (DEBUG) Slog.d(TAG, "Maybe queuing ready jobs...");

@@ -2217,7 +2293,7 @@ public class JobSchedulerService extends com.android.server.SystemService
        mPendingJobs.clear();
        stopNonReadyActiveJobsLocked();
        mJobs.forEachJob(mMaybeQueueFunctor);
        mMaybeQueueFunctor.postProcess();
        mMaybeQueueFunctor.postProcessLocked();
    }

    /** Returns true if both the calling and source users for the job are started. */
Loading