Log AppBatteryTracker to statsd atom APP_BACKGROUND_RESTRICTIONS_INFO.

Log per-uid battery usage percentage in last 24 hours.
Log total battery usage, background battey usage, foreground service
battery usage.

Bug: NA.
Test: manual test, adb logcat | grep getBatteryTrackerInfoProtoLocked.
Change-Id: I2c17fcfa2343103ecc8ad899db2ca4f89428abfb
This commit is contained in:
Hui Yu
2022-03-29 17:33:31 -07:00
parent 6ad5af88f2
commit bf7ac2254b
2 changed files with 290 additions and 0 deletions

View File

@@ -0,0 +1,199 @@
/*
* Copyright (C) 2022 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 android.os;
option java_multiple_files = true;
// This message is used for statsd logging and should be kept in sync with
// frameworks/proto_logging/stats/atoms.proto
/**
* Logs information about app background restrictions.
*
* Logged from:
* frameworks/base/services/core/java/com/android/server/am/AppRestrictionController.java
*/
message AppBackgroundRestrictionsInfo {
// the uid of the app.
optional int32 uid = 1;
enum RestrictionLevel {
LEVEL_UNKNOWN = 0;
LEVEL_UNRESTRICTED = 1;
LEVEL_EXEMPTED = 2;
LEVEL_ADAPTIVE_BUCKET = 3;
LEVEL_RESTRICTED_BUCKET = 4;
LEVEL_BACKGROUND_RESTRICTED = 5;
LEVEL_HIBERNATION = 6;
}
// indicates the app background restriction level.
optional RestrictionLevel restriction_level = 2;
enum Threshold {
THRESHOLD_UNKNOWN = 0;
THRESHOLD_RESTRICTED = 1; // app was background restricted by the system.
THRESHOLD_USER = 2; // app was background restricted by user action.
}
// indicates which threshold caused the app to be put into bg restriction.
optional Threshold threshold = 3;
enum StateTracker {
UNKNOWN_TRACKER = 0;
BATTERY_TRACKER = 1;
BATTERY_EXEMPTION_TRACKER = 2;
FGS_TRACKER = 3;
MEDIA_SESSION_TRACKER = 4;
PERMISSION_TRACKER = 5;
BROADCAST_EVENTS_TRACKER = 6;
BIND_SERVICE_EVENTS_TRACKER = 7;
}
// indicates the reason/tracker which caused the app to hit the threshold.
optional StateTracker tracker = 4;
message FgsTrackerInfo {
// indicates whether an fgs notification was visible for this app or not.
optional bool fgs_notification_visible = 1;
// total FGS duration for this app.
optional int64 fgs_duration = 2;
}
optional FgsTrackerInfo fgs_tracker_info = 5;
message BatteryTrackerInfo {
// total battery usage within last 24h (percentage)
optional int32 battery_24h = 1;
// background battery usage (percentage)
optional int32 battery_usage_background = 2;
// FGS battery usage (percentage)
optional int32 battery_usage_fgs = 3;
}
optional BatteryTrackerInfo battery_tracker_info = 6;
message BroadcastEventsTrackerInfo {
// the number of broadcasts sent by this app.
optional int32 broadcasts_sent = 1;
}
optional BroadcastEventsTrackerInfo broadcast_events_tracker_info = 7;
message BindServiceEventsTrackerInfo {
// the number of bind service requests by this app.
optional int32 bind_service_requests = 1;
}
optional BindServiceEventsTrackerInfo bind_service_events_tracker_info =
8;
// The reasons listed below are defined in PowerExemptionManager.java
enum ExemptionReason {
// range 0-9 is reserved for default reasons
REASON_UNKNOWN = 0;
REASON_DENIED = 1;
REASON_OTHER = 2;
// range 10-49 is reserved for BG-FGS-launch allowed proc states
REASON_PROC_STATE_PERSISTENT = 10;
REASON_PROC_STATE_PERSISTENT_UI = 11;
REASON_PROC_STATE_TOP = 12;
REASON_PROC_STATE_BTOP = 13;
REASON_PROC_STATE_FGS = 14;
REASON_PROC_STATE_BFGS = 15;
// range 50-99 is reserved for BG-FGS-launch allowed reasons
REASON_UID_VISIBLE = 50;
REASON_SYSTEM_UID = 51;
REASON_ACTIVITY_STARTER = 52;
REASON_START_ACTIVITY_FLAG = 53;
REASON_FGS_BINDING = 54;
REASON_DEVICE_OWNER = 55;
REASON_PROFILE_OWNER = 56;
REASON_COMPANION_DEVICE_MANAGER = 57;
REASON_BACKGROUND_ACTIVITY_PERMISSION = 58;
REASON_BACKGROUND_FGS_PERMISSION = 59;
REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION = 60;
REASON_INSTR_BACKGROUND_FGS_PERMISSION = 61;
REASON_SYSTEM_ALERT_WINDOW_PERMISSION = 62;
REASON_DEVICE_DEMO_MODE = 63;
REASON_ALLOWLISTED_PACKAGE = 65;
REASON_APPOP = 66;
REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD = 67;
REASON_OP_ACTIVATE_VPN = 68;
REASON_OP_ACTIVATE_PLATFORM_VPN = 69;
REASON_TEMP_ALLOWED_WHILE_IN_USE = 70;
REASON_CURRENT_INPUT_METHOD = 71;
// range 100-199 is reserved for public reasons
REASON_GEOFENCING = 100;
REASON_PUSH_MESSAGING = 101;
REASON_PUSH_MESSAGING_OVER_QUOTA = 102;
REASON_ACTIVITY_RECOGNITION = 103;
REASON_ACCOUNT_TRANSFER = 104;
// range 200-299 is reserved for broadcast actions
REASON_BOOT_COMPLETED = 200;
REASON_PRE_BOOT_COMPLETED = 201;
REASON_LOCKED_BOOT_COMPLETED = 202;
REASON_BLUETOOTH_BROADCAST = 203;
REASON_TIMEZONE_CHANGED = 204;
REASON_TIME_CHANGED = 205;
REASON_LOCALE_CHANGED = 206;
REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED = 207;
REASON_REFRESH_SAFETY_SOURCES = 208;
// range 300-399 is reserved for other internal reasons
REASON_SYSTEM_ALLOW_LISTED = 300;
REASON_ALARM_MANAGER_ALARM_CLOCK = 301;
REASON_ALARM_MANAGER_WHILE_IDLE = 302;
REASON_SERVICE_LAUNCH = 303;
REASON_KEY_CHAIN = 304;
REASON_PACKAGE_VERIFIER = 305;
REASON_SYNC_MANAGER = 306;
REASON_DOMAIN_VERIFICATION_V1 = 307;
REASON_DOMAIN_VERIFICATION_V2 = 308;
REASON_VPN = 309;
REASON_NOTIFICATION_SERVICE = 310;
REASON_PACKAGE_REPLACED = 311;
REASON_LOCATION_PROVIDER = 312;
REASON_MEDIA_BUTTON = 313;
REASON_EVENT_SMS = 314;
REASON_EVENT_MMS = 315;
REASON_SHELL = 316;
REASON_MEDIA_SESSION_CALLBACK = 317;
REASON_ROLE_DIALER = 318;
REASON_ROLE_EMERGENCY = 319;
REASON_SYSTEM_MODULE = 320;
REASON_CARRIER_PRIVILEGED_APP = 321;
// app requested to be exempt
REASON_OPT_OUT_REQUESTED = 1000;
}
// indicates if the app is exempt from background restrictions and the reason if applicable.
optional ExemptionReason exemption_reason = 9;
enum OptimizationLevel {
UNKNOWN = 0;
OPTIMIZED = 1;
BACKGROUND_RESTRICTED = 2;
NOT_OPTIMIZED = 3;
}
// the user choice for the optimization level of the app.
optional OptimizationLevel opt_level = 10;
enum TargetSdk {
SDK_UNKNOWN = 0;
SDK_PRE_S = 1;
SDK_S = 2;
SDK_T = 3;
}
// indicates the target sdk level for this app.
optional TargetSdk target_sdk = 11;
// indicates if the current device is a low ram device.
optional bool low_mem_device = 12;
}

View File

@@ -49,6 +49,7 @@ import android.content.Context;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.AppBackgroundRestrictionsInfo;
import android.os.AppBatteryStatsProto;
import android.os.BatteryConsumer;
import android.os.BatteryConsumer.Dimensions;
@@ -72,6 +73,7 @@ import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.am.AppBatteryTracker.AppBatteryPolicy;
import com.android.server.am.AppRestrictionController.UidBatteryUsageProvider;
import com.android.server.pm.UserManagerInternal;
@@ -168,6 +170,12 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
@GuardedBy("mLock")
private long mLastUidBatteryUsageStartTs;
/**
* elapseRealTime of last time the AppBatteryTracker is reported to statsd.
*/
@GuardedBy("mLock")
private long mLastReportTime = 0;
// For debug only.
private final SparseArray<BatteryUsage> mDebugUidPercentages = new SparseArray<>();
@@ -216,9 +224,92 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
mBgHandler.postDelayed(mBgBatteryUsageStatsPolling, delay);
}
}
logAppBatteryTrackerIfNeeded();
}
}
/**
* Log per-uid BatteryTrackerInfo to statsd every 24 hours (as the window specified in
* {@link AppBatteryPolicy#mBgCurrentDrainWindowMs})
*/
private void logAppBatteryTrackerIfNeeded() {
final long now = SystemClock.elapsedRealtime();
synchronized (mLock) {
final AppBatteryPolicy bgPolicy = mInjector.getPolicy();
if (now - mLastReportTime < bgPolicy.mBgCurrentDrainWindowMs) {
return;
} else {
mLastReportTime = now;
}
}
updateBatteryUsageStatsIfNecessary(mInjector.currentTimeMillis(), true);
synchronized (mLock) {
for (int i = 0, size = mUidBatteryUsageInWindow.size(); i < size; i++) {
final int uid = mUidBatteryUsageInWindow.keyAt(i);
if (!UserHandle.isCore(uid) && !UserHandle.isApp(uid)) {
continue;
}
if (BATTERY_USAGE_NONE.equals(mUidBatteryUsageInWindow.valueAt(i))) {
continue;
}
FrameworkStatsLog.write(FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO,
uid,
FrameworkStatsLog
.APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_UNKNOWN,
FrameworkStatsLog
.APP_BACKGROUND_RESTRICTIONS_INFO__THRESHOLD__THRESHOLD_UNKNOWN,
FrameworkStatsLog
.APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__UNKNOWN_TRACKER,
null /*byte[] fgs_tracker_info*/,
getBatteryTrackerInfoProtoLocked(uid) /*byte[] battery_tracker_info*/,
null /*byte[] broadcast_events_tracker_info*/,
null /*byte[] bind_service_events_tracker_info*/,
FrameworkStatsLog
.APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_UNKNOWN,
FrameworkStatsLog
.APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__UNKNOWN,
FrameworkStatsLog
.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_UNKNOWN,
isLowRamDeviceStatic());
}
}
}
/**
* Get the BatteryTrackerInfo proto of a UID.
* @param uid
* @return byte array of the proto.
*/
@NonNull byte[] getBatteryTrackerInfoProtoLocked(int uid) {
final ImmutableBatteryUsage temp = mUidBatteryUsageInWindow.get(uid);
if (temp == null) {
return new byte[0];
}
final BatteryUsage bgUsage = temp.calcPercentage(uid, mInjector.getPolicy());
final double allUsage = bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_UNSPECIFIED]
+ bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_FOREGROUND]
+ bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_BACKGROUND]
+ bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_FOREGROUND_SERVICE]
+ bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_CACHED];
final double usageBackground =
bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_BACKGROUND];
final double usageFgs =
bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_FOREGROUND_SERVICE];
Slog.d(TAG, "getBatteryTrackerInfoProtoLocked uid:" + uid
+ " allUsage:" + String.format("%4.2f%%", allUsage)
+ " usageBackground:" + String.format("%4.2f%%", usageBackground)
+ " usageFgs:" + String.format("%4.2f%%", usageFgs));
final ProtoOutputStream proto = new ProtoOutputStream();
proto.write(AppBackgroundRestrictionsInfo.BatteryTrackerInfo.BATTERY_24H,
allUsage * 10000);
proto.write(AppBackgroundRestrictionsInfo.BatteryTrackerInfo.BATTERY_USAGE_BACKGROUND,
usageBackground * 10000);
proto.write(AppBackgroundRestrictionsInfo.BatteryTrackerInfo.BATTERY_USAGE_FGS,
usageFgs * 10000);
proto.flush();
return proto.getBytes();
}
@Override
void onUserStarted(final @UserIdInt int userId) {
synchronized (mLock) {