android T 后台限制

简化应用程序限制:

  • 标准化一组应用限制级别
  • 在后台设置功耗限制
  • 提供保护有效用例的机制
    • 提高及时通知的可靠性(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;
活跃

如果用户当前正在使用某个应用或最近刚刚使用过该应用,则该应用位于活跃存储分区中。例如:

  • 该应用启动了一个 Activity
  • 该应用正在运行一项前台服务
  • 该应用具有与前台应用使用的内容提供程序相关联的同步适配器
  • 用户点按了应用通知
    如果某个应用位于“活跃”存储分区中,系统不会对应用的作业、警报或 FCM 消息施加任何限制。
工作集

如果某个应用经常运行,但当前未处于活跃状态,则该应用位于工作集存储分区中。例如,用户多数时候都会启动的社交媒体应用很可能位于工作集内。如果以间接的方式使用应用,这些应用也会被提升到工作集存储分区。
如果某个应用位于工作集内,系统会对其运行作业和触发警报的频率施加轻微的限制。如需了解详情,请参阅电源管理限制。

常用

如果某个应用会定期使用,但不一定每天使用,则该应用位于常用存储分区中。例如,用户在健身房运行的锻炼跟踪应用可能位于“常用”存储分区中。
如果某个应用位于“常用”存储分区中,则系统对其运行作业和触发警报的频率施加更严格的限制,还会对高优先级 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)起,处于“受限”状态的应用具有以下限制:

  • 无法启动前台服务
  • 现有的前台服务会从前台移除
  • 不会触发闹钟
  • 不会执行Job

当您的应用以 Android 13 为目标平台时,除非应用因其他原因启动,否则系统不会传送以下任何广播:

  • BOOT_COMPLETED
  • LOCKED_BOOT_COMPLETED

注意:如果用户在将您的应用置于“受限”状态之后启动了该应用,系统会暂时将该应用视为处于“优化”状态。当用户停止与您的应用互动并开始与另一个应用互动时,系统会将您的应用重新置于“受限”状态。

后台限制

更严格的限制,除非处于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;

受限模式的进入和退出

  1. 主要代码逻辑在下面两个android T新增类中
frameworks/base/services/core/java/com/android/server/am/AppRestrictionController.java
frameworks/base/services/core/java/com/android/server/am/AppBatteryTracker.java
  1. 提交代码记录:
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

进入

非满足豁免条件下,以下行为之一则将其放入受限存储分区

  • 用户有 8 天没有与您的应用互动。如果用户与另一个绑定到您应用的服务的应用互动,系统也会将您的应用视为“使用过”。
    注意:设备处于关闭状态的时间不会计入互动限制。
  • 您的应用在 24 小时内调用了过多的广播或绑定。
  • 您的应用在 24 小时内消耗了大量的设备电池电量。对于低 RAM 设备,此阈值可能会有所不同。
    在衡量应用对设备电池续航时间的影响时,系统会考虑应用在几个不同方面执行的操作,包括:
    • 作业(包括加急作业)
    • 广播接收器
    • 后台服务
    • 系统是否已缓存应用的进程

退出

当用户与您的应用互动时(包括通过以下几种方式互动),系统会将应用从受限存储分区中移出,并放入另一个应用待机模式存储分区(限制级别中优化的四种存储分区):

  • 用户点按您的应用发送的通知。
    注意:如果用户在不点按通知的情况下滑开通知,系统不会将该操作视为与您的应用“互动”。
  • 用户在属于您应用的 widget 中执行操作。
  • 用户通过按媒体按钮影响您应用的前台服务。
  • 用户在与 Android Automotive OS 互动时连接到您的应用(您的应用在此过程中使用了前台服务或
    CONNECTION_TYPE_PROJECTION)。
  • 您的应用在画中画 (PiP) 模式下可见。
  • 您的应用是屏幕上当前运行的应用之一。(主要适用于大屏设备。)

监控电池用量过高的应用

Android 13 引入了一个新的系统通知,当您的应用在 24 小时内消耗了大量设备电池电量时,就会显示该通知。这个新通知会针对搭载 Android 13 的设备上的所有应用显示,无论应用采用何种目标 SDK 版本都不例外。

注意:如果系统在应用显示与前台服务相关的通知时检测到应用的电池用量较高,系统会等到用户关闭通知,或前台服务完成,并且仅在您的应用继续消耗大量设备电池电量时才会显示该通知(FGS & Noti 跳过)。

  1. 后台消耗电量阈值:
  
    <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>
  1. 记录对应uid的受限/后台受限的时间戳
  • ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] <= 0 优化级别
  • ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] > 0 受限级别
  • ts[TIME_STAMP_INDEX_BG_RESTRICTED] > 0 后台受限级别
// 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 T 后台限制_第1张图片
在衡量应用对设备电池续航时间的影响时,系统会考虑应用在几个不同方面执行的操作,包括:

  • 前台服务,即使是有可见通知的服务
  • 工作任务,包括加急工作
  • 广播接收器
  • 后台服务
  • 应用的缓存
    如果针对您的应用显示了此通知,则至少在 24 小时后,才会再次在同一设备上显示该通知。

豁免

存在以下情况的应用不会受到 Android 13 中引入的任何省电措施的影响:

  • 系统应用和系统绑定应用
  • 配套设备应用
  • 处于演示模式的设备上运行的应用
  • 设备所有者应用
  • 资料所有者应用
  • 常驻应用
  • VPN 应用
  • 具有 ROLE_DIALER 角色的应用
  • 用户在系统设置中明确指定提供“无限制”功能的应用
    在以下情况下,您的应用可以免于进入“受限”应用待机模式存储分区,并可以绕过“8 天无活动”触发器:
  • 具有活跃的 widget
  • 至少被授予下列其中一种权限:
    • SCHEDULE_EXACT_ALARM
    • ACCESS_BACKGROUND_LOCATION
      在以下情况下,您的应用可以不受 Android 13 中引入的大多数省电措施的影响,但系统仍然会发送针对长时间运行的前台服务的通知:
  • 具有进行中的活跃 MediaSession
  • 被授予 ACCESS_FINE_LOCATION 权限

测试

禁止应用在后台运行:

adb shell cmd appops set PACKAGE_NAME RUN_ANY_IN_BACKGROUND deny

将应用放入受限存储分区:

adb shell am set-standby-bucket PACKAGE_NAME restricted

你可能感兴趣的:(AMS,android,framework)