Add logging to statsd for job constraint changes.

Bug: 117846754
Bug: 111423978
Bug: 120941744
Test: `make statsd_testdrive &&
./out/host/linux-x86/bin/statsd_testdrive 150` and check output

Change-Id: Iadfdb07171b8d4f99b8f57008cc7c1fc2865bb8e
This commit is contained in:
Kweku Adams
2018-12-11 20:06:45 -08:00
parent 36d048c3ff
commit 8845d01b72
5 changed files with 146 additions and 25 deletions

View File

@@ -33,6 +33,7 @@ import "frameworks/base/core/proto/android/net/networkcapabilities.proto";
import "frameworks/base/core/proto/android/os/enums.proto";
import "frameworks/base/core/proto/android/server/connectivity/data_stall_event.proto";
import "frameworks/base/core/proto/android/server/enums.proto";
import "frameworks/base/core/proto/android/server/job/enums.proto";
import "frameworks/base/core/proto/android/server/location/enums.proto";
import "frameworks/base/core/proto/android/service/procstats_enum.proto";
import "frameworks/base/core/proto/android/service/usb.proto";
@@ -213,6 +214,7 @@ message Atom {
WatchdogRollbackOccurred watchdog_rollback_occurred = 147;
BiometricHalDeathReported biometric_hal_death_reported = 148;
BubbleUIChanged bubble_ui_changed = 149;
ScheduledJobConstraintChanged scheduled_job_constraint_changed = 150;
}
// Pulled events will start at field 10000.
@@ -4699,3 +4701,24 @@ message BubbleUIChanged {
optional float normalized_x_position = 7;
optional float normalized_y_position = 8;
}
/**
* Logs that a constraint for a scheduled job has changed.
*
* Logged from:
* frameworks/base/services/core/java/com/android/server/job/controllers/JobStatus.java
*/
message ScheduledJobConstraintChanged {
repeated AttributionNode attribution_node = 1;
// Name of the job.
optional string job_name = 2;
optional com.android.server.job.ConstraintEnum constraint = 3;
enum State {
UNSATISFIED = 0;
SATISFIED = 1;
}
optional State state = 4;
}

View File

@@ -18,6 +18,9 @@ syntax = "proto2";
package android.app.job;
// This file is for JobScheduler enums inside the app directory. If you're
// adding enums for system-server-side code, use the file in
// frameworks/base/core/proto/android/server/job.
option java_outer_classname = "JobProtoEnums";
option java_multiple_files = true;

View File

@@ -0,0 +1,43 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
syntax = "proto2";
package com.android.server.job;
// This file is for JobScheduler enums inside the server directory. If you're
// adding enums for app-side code, use the file in
// frameworks/base/core/proto/android/app/job.
option java_outer_classname = "JobServerProtoEnums";
option java_multiple_files = true;
// Set of constraints that a job potentially needs satisfied before it can run.
// Defined in
// frameworks/base/services/core/java/com/android/server/job/controllers/JobStatus.java
enum ConstraintEnum {
CONSTRAINT_UNKNOWN = 0;
CONSTRAINT_CHARGING = 1;
CONSTRAINT_BATTERY_NOT_LOW = 2;
CONSTRAINT_STORAGE_NOT_LOW = 3;
CONSTRAINT_TIMING_DELAY = 4;
CONSTRAINT_DEADLINE = 5;
CONSTRAINT_IDLE = 6;
CONSTRAINT_CONNECTIVITY = 7;
CONSTRAINT_CONTENT_TRIGGER = 8;
CONSTRAINT_DEVICE_NOT_DOZING = 9;
CONSTRAINT_WITHIN_QUOTA = 10;
CONSTRAINT_BACKGROUND_NOT_RESTRICTED = 11;
}

View File

@@ -29,6 +29,7 @@ import "frameworks/base/core/proto/android/net/networkrequest.proto";
import "frameworks/base/core/proto/android/os/bundle.proto";
import "frameworks/base/core/proto/android/os/persistablebundle.proto";
import "frameworks/base/core/proto/android/server/forceappstandbytracker.proto";
import "frameworks/base/core/proto/android/server/job/enums.proto";
import "frameworks/base/libs/incident/proto/android/privacy.proto";
// Next tag: 21
@@ -757,21 +758,9 @@ message JobStatusDumpProto {
}
optional JobInfo job_info = 6;
enum Constraint {
CONSTRAINT_CHARGING = 1;
CONSTRAINT_BATTERY_NOT_LOW = 2;
CONSTRAINT_STORAGE_NOT_LOW = 3;
CONSTRAINT_TIMING_DELAY = 4;
CONSTRAINT_DEADLINE = 5;
CONSTRAINT_IDLE = 6;
CONSTRAINT_CONNECTIVITY = 7;
CONSTRAINT_CONTENT_TRIGGER = 8;
CONSTRAINT_DEVICE_NOT_DOZING = 9;
CONSTRAINT_WITHIN_QUOTA = 10;
}
repeated Constraint required_constraints = 7;
repeated Constraint satisfied_constraints = 8;
repeated Constraint unsatisfied_constraints = 9;
repeated ConstraintEnum required_constraints = 7;
repeated ConstraintEnum satisfied_constraints = 8;
repeated ConstraintEnum unsatisfied_constraints = 9;
optional bool is_doze_whitelisted = 10;
optional bool is_uid_active = 26;

View File

@@ -33,6 +33,7 @@ import android.text.format.Time;
import android.util.ArraySet;
import android.util.Pair;
import android.util.Slog;
import android.util.StatsLog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
@@ -40,6 +41,7 @@ import com.android.server.LocalServices;
import com.android.server.job.GrantedUriPermissions;
import com.android.server.job.JobSchedulerInternal;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.JobServerProtoEnums;
import com.android.server.job.JobStatusDumpProto;
import com.android.server.job.JobStatusShortInfoProto;
@@ -80,6 +82,28 @@ public final class JobStatus {
static final int CONSTRAINT_WITHIN_QUOTA = 1 << 24;
static final int CONSTRAINT_BACKGROUND_NOT_RESTRICTED = 1<<22;
/**
* The constraints that we want to log to statsd.
*
* Constraints that can be inferred from other atoms have been excluded to avoid logging too
* much information and to reduce redundancy:
*
* * CONSTRAINT_CHARGING can be inferred with PluggedStateChanged (Atom #32)
* * CONSTRAINT_BATTERY_NOT_LOW can be inferred with BatteryLevelChanged (Atom #30)
* * CONSTRAINT_CONNECTIVITY can be partially inferred with ConnectivityStateChanged
* (Atom #98) and BatterySaverModeStateChanged (Atom #20).
* * CONSTRAINT_DEVICE_NOT_DOZING can be mostly inferred with DeviceIdleModeStateChanged
* (Atom #21)
* * CONSTRAINT_BACKGROUND_NOT_RESTRICTED can be inferred with BatterySaverModeStateChanged
* (Atom #20)
*/
private static final int STATSD_CONSTRAINTS_TO_LOG = CONSTRAINT_CONTENT_TRIGGER
| CONSTRAINT_DEADLINE
| CONSTRAINT_IDLE
| CONSTRAINT_STORAGE_NOT_LOW
| CONSTRAINT_TIMING_DELAY
| CONSTRAINT_WITHIN_QUOTA;
// Soft override: ignore constraints like time that don't affect API availability
public static final int OVERRIDE_SOFT = 1;
// Full override: ignore all constraints including API-affecting like connectivity
@@ -976,6 +1000,12 @@ public final class JobStatus {
}
satisfiedConstraints = (satisfiedConstraints&~constraint) | (state ? constraint : 0);
mSatisfiedConstraintsOfInterest = satisfiedConstraints & CONSTRAINTS_OF_INTEREST;
if ((STATSD_CONSTRAINTS_TO_LOG & constraint) != 0) {
StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED,
sourceUid, null, getBatteryName(), getProtoConstraint(constraint),
state ? StatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__SATISFIED
: StatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__UNSATISFIED);
}
return true;
}
@@ -1228,37 +1258,70 @@ public final class JobStatus {
}
}
/** Returns a {@link JobServerProtoEnums.Constraint} enum value for the given constraint. */
private int getProtoConstraint(int constraint) {
switch (constraint) {
case CONSTRAINT_BACKGROUND_NOT_RESTRICTED:
return JobServerProtoEnums.CONSTRAINT_BACKGROUND_NOT_RESTRICTED;
case CONSTRAINT_BATTERY_NOT_LOW:
return JobServerProtoEnums.CONSTRAINT_BATTERY_NOT_LOW;
case CONSTRAINT_CHARGING:
return JobServerProtoEnums.CONSTRAINT_CHARGING;
case CONSTRAINT_CONNECTIVITY:
return JobServerProtoEnums.CONSTRAINT_CONNECTIVITY;
case CONSTRAINT_CONTENT_TRIGGER:
return JobServerProtoEnums.CONSTRAINT_CONTENT_TRIGGER;
case CONSTRAINT_DEADLINE:
return JobServerProtoEnums.CONSTRAINT_DEADLINE;
case CONSTRAINT_DEVICE_NOT_DOZING:
return JobServerProtoEnums.CONSTRAINT_DEVICE_NOT_DOZING;
case CONSTRAINT_IDLE:
return JobServerProtoEnums.CONSTRAINT_IDLE;
case CONSTRAINT_STORAGE_NOT_LOW:
return JobServerProtoEnums.CONSTRAINT_STORAGE_NOT_LOW;
case CONSTRAINT_TIMING_DELAY:
return JobServerProtoEnums.CONSTRAINT_TIMING_DELAY;
case CONSTRAINT_WITHIN_QUOTA:
return JobServerProtoEnums.CONSTRAINT_WITHIN_QUOTA;
default:
return JobServerProtoEnums.CONSTRAINT_UNKNOWN;
}
}
/** Writes constraints to the given repeating proto field. */
void dumpConstraints(ProtoOutputStream proto, long fieldId, int constraints) {
if ((constraints & CONSTRAINT_CHARGING) != 0) {
proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_CHARGING);
proto.write(fieldId, JobServerProtoEnums.CONSTRAINT_CHARGING);
}
if ((constraints & CONSTRAINT_BATTERY_NOT_LOW) != 0) {
proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_BATTERY_NOT_LOW);
proto.write(fieldId, JobServerProtoEnums.CONSTRAINT_BATTERY_NOT_LOW);
}
if ((constraints & CONSTRAINT_STORAGE_NOT_LOW) != 0) {
proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_STORAGE_NOT_LOW);
proto.write(fieldId, JobServerProtoEnums.CONSTRAINT_STORAGE_NOT_LOW);
}
if ((constraints & CONSTRAINT_TIMING_DELAY) != 0) {
proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_TIMING_DELAY);
proto.write(fieldId, JobServerProtoEnums.CONSTRAINT_TIMING_DELAY);
}
if ((constraints & CONSTRAINT_DEADLINE) != 0) {
proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_DEADLINE);
proto.write(fieldId, JobServerProtoEnums.CONSTRAINT_DEADLINE);
}
if ((constraints & CONSTRAINT_IDLE) != 0) {
proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_IDLE);
proto.write(fieldId, JobServerProtoEnums.CONSTRAINT_IDLE);
}
if ((constraints & CONSTRAINT_CONNECTIVITY) != 0) {
proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_CONNECTIVITY);
proto.write(fieldId, JobServerProtoEnums.CONSTRAINT_CONNECTIVITY);
}
if ((constraints & CONSTRAINT_CONTENT_TRIGGER) != 0) {
proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_CONTENT_TRIGGER);
proto.write(fieldId, JobServerProtoEnums.CONSTRAINT_CONTENT_TRIGGER);
}
if ((constraints & CONSTRAINT_DEVICE_NOT_DOZING) != 0) {
proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_DEVICE_NOT_DOZING);
proto.write(fieldId, JobServerProtoEnums.CONSTRAINT_DEVICE_NOT_DOZING);
}
if ((constraints & CONSTRAINT_WITHIN_QUOTA) != 0) {
proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_WITHIN_QUOTA);
proto.write(fieldId, JobServerProtoEnums.CONSTRAINT_WITHIN_QUOTA);
}
if ((constraints & CONSTRAINT_BACKGROUND_NOT_RESTRICTED) != 0) {
proto.write(fieldId, JobServerProtoEnums.CONSTRAINT_BACKGROUND_NOT_RESTRICTED);
}
}