Merge "Log namespace hash." into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f8df9f1dd2
@@ -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) {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user