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

Commit 8845d01b authored by Kweku Adams's avatar Kweku Adams
Browse files

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
parent 36d048c3
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -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;
}
+3 −0
Original line number Diff line number Diff line
@@ -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;

+43 −0
Original line number Diff line number Diff line
/*
 * 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;
}
+4 −15
Original line number Diff line number Diff line
@@ -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;

+73 −10
Original line number Diff line number Diff line
@@ -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);
        }
    }