summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hui Yu <huiyu@google.com> 2022-04-05 16:23:28 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-04-05 16:23:28 +0000
commit29b5a95a86a19fb52378d45ee6b2a29c2c41d67f (patch)
tree9c36b30e2cb79df255d93bf78ed59731500f6cdc
parentab6aaa765b9892eed0e8af45d3148b34ea0f4e62 (diff)
parentbf7ac2254b6ce95c034e0bda7af3a1d9ff007d6d (diff)
Merge "Log AppBatteryTracker to statsd atom APP_BACKGROUND_RESTRICTIONS_INFO." into tm-dev
-rw-r--r--core/proto/android/os/appbackgroundrestrictioninfo.proto199
-rw-r--r--services/core/java/com/android/server/am/AppBatteryTracker.java91
2 files changed, 290 insertions, 0 deletions
diff --git a/core/proto/android/os/appbackgroundrestrictioninfo.proto b/core/proto/android/os/appbackgroundrestrictioninfo.proto
new file mode 100644
index 000000000000..8445641694dc
--- /dev/null
+++ b/core/proto/android/os/appbackgroundrestrictioninfo.proto
@@ -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;
+}
+
diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index 032b129c4256..64ff532b026a 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -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;
@@ -74,6 +75,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.TrackerType;
import com.android.server.am.AppRestrictionController.UidBatteryUsageProvider;
@@ -175,6 +177,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<ImmutableBatteryUsage> mDebugUidPercentages = new SparseArray<>();
@@ -228,9 +236,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) {