简化应用程序限制:
- 标准化一组应用限制级别
- 在后台设置功耗限制
- 提供保护有效用例的机制
- 提高及时通知的可靠性(FCM 配额)
- 豁免重要用例(音乐、导航等)
- 更好的工作优先级 监控并自动限制或显示滥用应用程序
- 在后台应用程序消耗 X%(即 2%)的电池电量时,移动它到受限存储分区
- 在 BG 和 FGS 状态下,应用程序消耗的电池电量占 Y%(即 4%)时,通过有关高功耗的通知警告用户
- 级别
- 无限制
- 优化(自适应存储分区)
- 受限存储分区(非常有限的后台工作)
- 后台限制(无 FGS,延迟 BOOT_COMPLETED) 免责声明:合理的阈值仍在研究中。
应用以android 13为目标平台,此变更才生效。用户可以在系统设置中的电池用量页面上限制以下选项:
/** @hide */
@IntDef(prefix = { "RESTRICTION_LEVEL_" }, value = {
RESTRICTION_LEVEL_UNKNOWN, // unknown
RESTRICTION_LEVEL_UNRESTRICTED, // never used
RESTRICTION_LEVEL_EXEMPTED, // 无限制
RESTRICTION_LEVEL_ADAPTIVE_BUCKET, // 优化
RESTRICTION_LEVEL_RESTRICTED_BUCKET, // 受限
RESTRICTION_LEVEL_BACKGROUND_RESTRICTED, // 后台限制,更严格
RESTRICTION_LEVEL_HIBERNATION,
RESTRICTION_LEVEL_MAX,
})
@Retention(RetentionPolicy.SOURCE)
public @interface RestrictionLevel{}
public static final int RESTRICTION_LEVEL_EXEMPTED = 20;
允许后台工作,这可能会消耗更多电量。
android.app.AppOpsManager#OP_RUN_ANY_IN_BACKGROUND 为ALLOWED,被添加到设备空闲允许列表中,仍然会有一部分限制。
根据用户与应用互动的方式,优化应用执行后台工作的能力。
/**
* The default background restriction level for all other apps, they'll be moved between
* various standby buckets, including
* {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_ACTIVE}, // 活跃
* {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_WORKING_SET}, //工作集
* {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_FREQUENT}, // 常用
* {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RARE}. // 极少使用
*
* @hide
*/
public static final int RESTRICTION_LEVEL_ADAPTIVE_BUCKET = 30;
如果用户当前正在使用某个应用或最近刚刚使用过该应用,则该应用位于活跃存储分区中。例如:
如果某个应用经常运行,但当前未处于活跃状态,则该应用位于工作集存储分区中。例如,用户多数时候都会启动的社交媒体应用很可能位于工作集内。如果以间接的方式使用应用,这些应用也会被提升到工作集存储分区。
如果某个应用位于工作集内,系统会对其运行作业和触发警报的频率施加轻微的限制。如需了解详情,请参阅电源管理限制。
如果某个应用会定期使用,但不一定每天使用,则该应用位于常用存储分区中。例如,用户在健身房运行的锻炼跟踪应用可能位于“常用”存储分区中。
如果某个应用位于“常用”存储分区中,则系统对其运行作业和触发警报的频率施加更严格的限制,还会对高优先级 FCM (Firebase Cloud Messaging)消息设置上限。如需了解详情,请参阅电源管理限制。
不经常使用的应用位于极少使用存储分区中。例如,用户只有在入住酒店时才会运行的酒店应用可能就位于“极少使用”存储分区中。
如果某个应用位于“极少使用”存储分区中,则系统对其运行作业、触发警报以及接收高优先级 FCM 消息的频率施加严格的限制。系统还会限制应用连接到互联网的能力。如需了解详情,请参阅电源管理限制。
更注重延长设备的电池续航时间,而不是实现应用的全面功能。对于应用可以在后台执行的操作施加了更多限制。
/**
* The background restriction level where the apps will be placed in the restricted bucket
* {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED}.
*
* @hide
*/
public static final int RESTRICTION_LEVEL_RESTRICTED_BUCKET = 40;
自 Android 9(API 级别 28)起,处于“受限”状态的应用具有以下限制:
当您的应用以 Android 13 为目标平台时,除非应用因其他原因启动,否则系统不会传送以下任何广播:
注意:如果用户在将您的应用置于“受限”状态之后启动了该应用,系统会暂时将该应用视为处于“优化”状态。当用户停止与您的应用互动并开始与另一个应用互动时,系统会将您的应用重新置于“受限”状态。
更严格的限制,除非处于Top,否则不允许启动前台Service。
/**
* The background restricted level, where apps would get more restrictions,
* such as not allowed to launch foreground services besides on TOP.
*
* @hide
*/
public static final int RESTRICTION_LEVEL_BACKGROUND_RESTRICTED = 50;
frameworks/base/services/core/java/com/android/server/am/AppRestrictionController.java
frameworks/base/services/core/java/com/android/server/am/AppBatteryTracker.java
commit e1217fdd9dfb9bce505ba3e6c5d3990c30c2e240
Author: Jing Ji <jji@google.com>
Date: Sat Feb 5 02:25:03 2022 -0800
Track the battery usage in different dimensions in AppBatteryTracker
So it could be configured to catch abusive battery usage by different
combination. It also supports configurable power components.
By default, when background only battery usage reaches a certain
threshold, it'll be put into restricted standby bucket; while after
that, when the sum of its background and foreground service battery
usage reaches to another threshold, the system will prompt the user.
Bug: 200326767
Bug: 203105544
Test: atest FrameworksMockingServicesTests:BackgroundRestrictionTest
Change-Id: I2887201c06cbe7c936eb52c9aa5beb5e326634b7
非满足豁免条件下,以下行为之一则将其放入受限存储分区
当用户与您的应用互动时(包括通过以下几种方式互动),系统会将应用从受限存储分区中移出,并放入另一个应用待机模式存储分区(限制级别中优化的四种存储分区):
Android 13 引入了一个新的系统通知,当您的应用在 24 小时内消耗了大量设备电池电量时,就会显示该通知。这个新通知会针对搭载 Android 13 的设备上的所有应用显示,无论应用采用何种目标 SDK 版本都不例外。
注意:如果系统在应用显示与前台服务相关的通知时检测到应用的电池用量较高,系统会等到用户关闭通知,或前台服务完成,并且仅在您的应用继续消耗大量设备电池电量时才会显示该通知(FGS & Noti 跳过)。
<array name="config_bg_current_drain_threshold_to_restricted_bucket">
<item>2.0item>
<item>4.0item>
array>
<array name="config_bg_current_drain_threshold_to_bg_restricted">
<item>4.0item>
<item>8.0item>
array>
// com.android.server.am.AppBatteryTracker.AppBatteryPolicy
/**
* List of the packages with significant background battery usage, key is the UID of
* the package and value is an array of the timestamps when the UID is found guilty and
* should be moved to the next level of restriction.
*/
@GuardedBy("mLock")
private final SparseArray<long[]> mHighBgBatteryPackages = new SparseArray<>(); // 对应下面两个index,时间戳大于0就说明是对应的限制级别
@NonNull
private final Object mLock;
private static final int TIME_STAMP_INDEX_RESTRICTED_BUCKET = 0; // 受限时间戳index
private static final int TIME_STAMP_INDEX_BG_RESTRICTED = 1; // 后台受限时间戳index
private static final int TIME_STAMP_INDEX_LAST = 2; // 数组大小
后台受限级别的情况下达到限制,弹出通知流程
在衡量应用对设备电池续航时间的影响时,系统会考虑应用在几个不同方面执行的操作,包括:
存在以下情况的应用不会受到 Android 13 中引入的任何省电措施的影响:
禁止应用在后台运行:
adb shell cmd appops set PACKAGE_NAME RUN_ANY_IN_BACKGROUND deny
将应用放入受限存储分区:
adb shell am set-standby-bucket PACKAGE_NAME restricted