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

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

Snap for 10255078 from 6d543f9f to udc-qpr1-release

Change-Id: Ifc6f59d9ba501b0a5880abe50c97b9e41d72a763
parents 30ba9b97 6d543f9f
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -1631,7 +1631,8 @@ public class JobSchedulerService extends com.android.server.SystemService
                    jobStatus.getEstimatedNetworkDownloadBytes(),
                    jobStatus.getEstimatedNetworkUploadBytes(),
                    jobStatus.getWorkCount(),
                    ActivityManager.processStateAmToProto(mUidProcStates.get(jobStatus.getUid())));
                    ActivityManager.processStateAmToProto(mUidProcStates.get(jobStatus.getUid())),
                    jobStatus.getNamespaceHash());

            // If the job is immediately ready to run, then we can just immediately
            // put it in the pending list and try to schedule it.  This is especially
@@ -2059,7 +2060,8 @@ public class JobSchedulerService extends com.android.server.SystemService
                    cancelled.getEstimatedNetworkDownloadBytes(),
                    cancelled.getEstimatedNetworkUploadBytes(),
                    cancelled.getWorkCount(),
                    ActivityManager.processStateAmToProto(mUidProcStates.get(cancelled.getUid())));
                    ActivityManager.processStateAmToProto(mUidProcStates.get(cancelled.getUid())),
                    cancelled.getNamespaceHash());
        }
        // If this is a replacement, bring in the new version of the job
        if (incomingJob != null) {
+4 −2
Original line number Diff line number Diff line
@@ -499,7 +499,8 @@ public final class JobServiceContext implements ServiceConnection {
                    job.getEstimatedNetworkDownloadBytes(),
                    job.getEstimatedNetworkUploadBytes(),
                    job.getWorkCount(),
                    ActivityManager.processStateAmToProto(mService.getUidProcState(job.getUid())));
                    ActivityManager.processStateAmToProto(mService.getUidProcState(job.getUid())),
                    job.getNamespaceHash());
            sEnqueuedJwiAtJobStart.logSampleWithUid(job.getUid(), job.getWorkCount());
            final String sourcePackage = job.getSourcePackageName();
            if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
@@ -1557,7 +1558,8 @@ public final class JobServiceContext implements ServiceConnection {
                completedJob.getEstimatedNetworkUploadBytes(),
                completedJob.getWorkCount(),
                ActivityManager
                        .processStateAmToProto(mService.getUidProcState(completedJob.getUid())));
                        .processStateAmToProto(mService.getUidProcState(completedJob.getUid())),
                completedJob.getNamespaceHash());
        if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
            Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_SYSTEM_SERVER, "JobScheduler",
                    getId());
+70 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.MediaStore;
import android.text.format.DateFormat;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.Pair;
@@ -51,6 +52,7 @@ import android.util.Slog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FrameworkStatsLog;
@@ -65,10 +67,12 @@ import com.android.server.job.JobStatusShortInfoProto;
import dalvik.annotation.optimization.NeverCompile;

import java.io.PrintWriter;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;
import java.util.Random;
import java.util.function.Predicate;

/**
@@ -88,6 +92,13 @@ public final class JobStatus {
    private static final String TAG = "JobScheduler.JobStatus";
    static final boolean DEBUG = JobSchedulerService.DEBUG;

    private static MessageDigest sMessageDigest;
    /** Cache of namespace to hash to reduce how often we need to generate the namespace hash. */
    @GuardedBy("sNamespaceHashCache")
    private static final ArrayMap<String, String> sNamespaceHashCache = new ArrayMap<>();
    /** Maximum size of {@link #sNamespaceHashCache}. */
    private static final int MAX_NAMESPACE_CACHE_SIZE = 128;

    private static final int NUM_CONSTRAINT_CHANGE_HISTORY = 10;

    public static final long NO_LATEST_RUNTIME = Long.MAX_VALUE;
@@ -231,6 +242,8 @@ public final class JobStatus {
    final String sourceTag;
    @Nullable
    private final String mNamespace;
    @Nullable
    private final String mNamespaceHash;
    /** An ID that can be used to uniquely identify the job when logging statsd metrics. */
    private final long mLoggingJobId;

@@ -570,6 +583,7 @@ public final class JobStatus {
        this.callingUid = callingUid;
        this.standbyBucket = standbyBucket;
        mNamespace = namespace;
        mNamespaceHash = generateNamespaceHash(namespace);
        mLoggingJobId = generateLoggingId(namespace, job.getId());

        int tempSourceUid = -1;
@@ -814,6 +828,56 @@ public final class JobStatus {
        return ((long) namespace.hashCode()) << 31 | jobId;
    }

    @Nullable
    private static String generateNamespaceHash(@Nullable String namespace) {
        if (namespace == null) {
            return null;
        }
        if (namespace.trim().isEmpty()) {
            // Input is composed of all spaces (or nothing at all).
            return namespace;
        }
        synchronized (sNamespaceHashCache) {
            final int idx = sNamespaceHashCache.indexOfKey(namespace);
            if (idx >= 0) {
                return sNamespaceHashCache.valueAt(idx);
            }
        }
        String hash = null;
        try {
            // .hashCode() can result in conflicts that would make distinguishing between
            // namespaces hard and reduce the accuracy of certain metrics. Use SHA-256
            // to generate the hash since the probability of collision is extremely low.
            if (sMessageDigest == null) {
                sMessageDigest = MessageDigest.getInstance("SHA-256");
            }
            final byte[] digest = sMessageDigest.digest(namespace.getBytes());
            // Convert to hexadecimal representation
            StringBuilder hexBuilder = new StringBuilder(digest.length);
            for (byte byteChar : digest) {
                hexBuilder.append(String.format("%02X", byteChar));
            }
            hash = hexBuilder.toString();
        } catch (Exception e) {
            Slog.wtf(TAG, "Couldn't hash input", e);
        }
        if (hash == null) {
            // If we get to this point, something went wrong with the MessageDigest above.
            // Don't return the raw input value (which would defeat the purpose of hashing).
            return "failed_namespace_hash";
        }
        hash = hash.intern();
        synchronized (sNamespaceHashCache) {
            if (sNamespaceHashCache.size() >= MAX_NAMESPACE_CACHE_SIZE) {
                // Drop a random mapping instead of dropping at a predefined index to avoid
                // potentially always dropping the same mapping.
                sNamespaceHashCache.removeAt((new Random()).nextInt(MAX_NAMESPACE_CACHE_SIZE));
            }
            sNamespaceHashCache.put(namespace, hash);
        }
        return hash;
    }

    public void enqueueWorkLocked(JobWorkItem work) {
        if (pendingWork == null) {
            pendingWork = new ArrayList<>();
@@ -1117,10 +1181,16 @@ public final class JobStatus {
        return true;
    }

    @Nullable
    public String getNamespace() {
        return mNamespace;
    }

    @Nullable
    public String getNamespaceHash() {
        return mNamespaceHash;
    }

    public String getSourceTag() {
        return sourceTag;
    }
+2 −2
Original line number Diff line number Diff line
@@ -568,13 +568,13 @@ public abstract class Animator implements Cloneable {
     * repetition. lastPlayTime is similar and is used to calculate how many repeats have been
     * done between the two times.
     */
    void animateValuesInRange(long currentPlayTime, long lastPlayTime, boolean notify) {}
    void animateValuesInRange(long currentPlayTime, long lastPlayTime) {}

    /**
     * Internal use only. This animates any animation that has ended since lastPlayTime.
     * If an animation hasn't been finished, no change will be made.
     */
    void animateSkipToEnds(long currentPlayTime, long lastPlayTime, boolean notify) {}
    void animateSkipToEnds(long currentPlayTime, long lastPlayTime) {}

    /**
     * Internal use only. Adds all start times (after delay) to and end times to times.
+13 −10
Original line number Diff line number Diff line
@@ -111,19 +111,20 @@ public class AnimatorInflater {
            float pathErrorScale) throws NotFoundException {
        final ConfigurationBoundResourceCache<Animator> animatorCache = resources
                .getAnimatorCache();
        Animator animator = animatorCache.getInstance(id, resources, theme);
        if (animator != null) {
        ConfigurationBoundResourceCache.Entry<Animator> animatorEntry =
                animatorCache.getInstance(id, resources, theme);
        if (animatorEntry.hasValue()) {
            if (DBG_ANIMATOR_INFLATER) {
                Log.d(TAG, "loaded animator from cache, " + resources.getResourceName(id));
            }
            return animator;
            return animatorEntry.getValue();
        } else if (DBG_ANIMATOR_INFLATER) {
            Log.d(TAG, "cache miss for animator " + resources.getResourceName(id));
        }
        XmlResourceParser parser = null;
        try {
            parser = resources.getAnimation(id);
            animator = createAnimatorFromXml(resources, theme, parser, pathErrorScale);
            Animator animator = createAnimatorFromXml(resources, theme, parser, pathErrorScale);
            if (animator != null) {
                animator.appendChangingConfigurations(getChangingConfigs(resources, id));
                final ConstantState<Animator> constantState = animator.createConstantState();
@@ -131,7 +132,7 @@ public class AnimatorInflater {
                    if (DBG_ANIMATOR_INFLATER) {
                        Log.d(TAG, "caching animator for res " + resources.getResourceName(id));
                    }
                    animatorCache.put(id, theme, constantState);
                    animatorCache.put(id, theme, constantState, animatorEntry.getGeneration());
                    // create a new animator so that cached version is never used by the user
                    animator = constantState.newInstance(resources, theme);
                }
@@ -160,20 +161,22 @@ public class AnimatorInflater {
        final ConfigurationBoundResourceCache<StateListAnimator> cache = resources
                .getStateListAnimatorCache();
        final Theme theme = context.getTheme();
        StateListAnimator animator = cache.getInstance(id, resources, theme);
        if (animator != null) {
            return animator;
        ConfigurationBoundResourceCache.Entry<StateListAnimator> animatorEntry =
                cache.getInstance(id, resources, theme);
        if (animatorEntry.hasValue()) {
            return animatorEntry.getValue();
        }
        XmlResourceParser parser = null;
        try {
            parser = resources.getAnimation(id);
            animator = createStateListAnimatorFromXml(context, parser, Xml.asAttributeSet(parser));
            StateListAnimator animator =
                    createStateListAnimatorFromXml(context, parser, Xml.asAttributeSet(parser));
            if (animator != null) {
                animator.appendChangingConfigurations(getChangingConfigs(resources, id));
                final ConstantState<StateListAnimator> constantState = animator
                        .createConstantState();
                if (constantState != null) {
                    cache.put(id, theme, constantState);
                    cache.put(id, theme, constantState, animatorEntry.getGeneration());
                    // return a clone so that the animator in constant state is never used.
                    animator = constantState.newInstance(resources, theme);
                }
Loading