待机联网唤醒时间点
App Processor wakeup
May 27 2025
15:32:27 - 15:32:27
+59m23s294ms to +59m23s294ms
1 occurences
App Processor wakeup | Number of times
com.tencent.android.qqdownloader | 1
这种现象,一般查看netpolicy就可以知道原因了:
2025-05-27T15:37:32:480 - Firewall rule changed: 10225-background-allow
2025-05-27T15:37:32:480 - Firewall rule changed: 10225-standby-default
2025-05-27T15:32:32:474 - temp-power-save whitelist for 10225 changed to: true; reason=SYNC_MANAGER <sync by top app>
2025-05-27T15:32:37:677 - 10225:BTOP:LCMNFUA:29081
2025-05-27T15:11:19:166 - Firewall rule changed: 10225-background-allow
源码
doze模式下的联网防火墙管理
NetworkPolicyManagerService:onTempPowerSaveWhitelistChange->NetworkPolicyLogger.tempPowerSaveWlChanged()
NetworkPolicyLogger:tempPowerSaveWlChanged() -> NetworkPolicyLogger:getTempPowerSaveWlChangedLog()
doze模式下的联网防火墙管理
NetworkPolicyManagerService.java
1. setDeviceIdleMode() -> handleDeviceIdleModeChangedUL(mDeviceIdleMode)
2. handleDeviceIdleModeChangedUL(mDeviceIdleMode) 主要做2件事情
->2.1 updateRulesForDeviceIdleUL() 重要应用的联网允许
-->2.1.1 updateRulesForAllowlistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE,mUidFirewallDozableRules)
--->2.1.1.1 updateRulesForAllowlistedAppIds(uidRules, mPowerSaveTempWhitelistAppIds, user.id) 临时白名单设置允许联网
---->2.1.1.1.1 uidRules.put(uid, FIREWALL_RULE_ALLOW)
--->2.1.1.2 updateRulesForAllowlistedAppIds(uidRules, mPowerSaveWhitelistAppIds, user.id) 白名单设置允许联网
---->2.1.1.2.1 uidRules.put(uid, FIREWALL_RULE_ALLOW)
--->2.1.1.3 uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW); 基于isProcStateAllowedWhileIdleOrPowerSaveMode进程重要度的动态白名单设置设置允许联网
--->2.1.1.4 setUidFirewallRulesUL(chain, uidRules, CHAIN_TOGGLE_ENABLE);临时白名单、白名单、重要进程和省电模式白名单设置允许联网
---->2.1.1.4.1 mNetworkManager.setFirewallUidRules(chain, uids, rules) 设置联网防火墙规则,设置上述名单为运行联网
---->2.1.1.4.2 setUidFirewallRulesUL->NetworkPolicyLogger.firewallRulesChanged(chain, uids, rules) 打印允许联网得
->2.2 updateRulesForPowerRestrictionsUL(uid):每个应用联网规则的限制与运行状态更新和通知
-->2.2.1 updateRulesForPowerRestrictionsUL(uid, PROCESS_STATE_UNKNOWN)
--->2.2.1.1 updateRulesForPowerRestrictionsUL(uid, isUidIdle(uid, uidProcState))
----> 2.2.1.1.1 updateRulesForPowerRestrictionsULInner(uid, isUidIdle)
-----> 2.2.1.1.1.1 handleBlockedReasonsChanged(uid,newEffectiveBlockedReasons,oldEffectiveBlockedReasons)
------> 2.2.1.1.1.1.1 mActivityManagerInternal.onUidBlockedReasonsChanged(uid, newEffectiveBlockedReasons)
------> 2.2.1.1.1.1.2 postBlockedReasonsChangedMsg(uid, newEffectiveBlockedReasons, oldEffectiveBlockedReasons)
-----> 2.2.1.1.1.2 postUidRulesChangedMsg(uid, uidRules)
从源码可以得知:即使应用宝非Doze白名单,也可以通过消息通知和前台服务进程的绑定关系,将自身进程在tempwhitelist和appIdle进行动态豁免。例如下述主要是AMS的process状态进行豁免,一般只需要FOREGROUND属性即可动态豁免联网
/** @hide */
public static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(
int procState, @ProcessCapability int capability) {
if (procState == PROCESS_STATE_UNKNOWN) {
return false;
}
// bv fadi add for DozePlus 20250528 start
if (NetPolicyStub.getInstance().isProcStateRestrictWhileIdleOrPowerSaveMode(uid
,uidState.procState)) {
return false;
}
// bv fadi add for DozePlus 20250528 end
return procState <= FOREGROUND_THRESHOLD_STATE
|| (capability & ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0;
}
/** @hide */
public static boolean isProcStateAllowedWhileInLowPowerStandby(@Nullable UidState uidState) {
if (uidState == null) {
return false;
}
// bv fadi add for DozePlus 20250528 start
if (NetPolicyStub.getInstance().isProcStateRestrictWhileInLowPowerStandby(uid
, uidState.procState)) {
return false;
}
// bv fadi add for DozePlus 20250528 end
return uidState.procState <= TOP_THRESHOLD_STATE;
}
/**
* This is currently only used as an implementation detail for
* {@link com.android.server.net.NetworkPolicyManagerService}.
* Only put here to be together with other isProcStateAllowed* methods.
*
* @hide
*/
public static boolean isProcStateAllowedNetworkWhileBackground(@Nullable UidState uidState) {
if (uidState == null) {
return false;
}
// bv fadi add for DozePlus 20250528 start
if (NetPolicyStub.getInstance().isProcStateRestrictNetworkWhileBackground(uid
,uidState.procState)) {
return false;
}
// bv fadi add for DozePlus 20250528 end
return uidState.procState < BACKGROUND_THRESHOLD_STATE
|| (uidState.capability & PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0;
}
/** @hide */
public static boolean isProcStateAllowedWhileOnRestrictBackground(int procState,
@ProcessCapability int capabilities) {
if (procState == PROCESS_STATE_UNKNOWN) {
return false;
}
// bv fadi add for DozePlus 20250528 start
if (NetPolicyStub.getInstance().isProcStateRestrictWhileOnRestrictBackground(uid
,uidState.procState)) {
return false;
}
// bv fadi add for DozePlus 20250528 end
return procState <= FOREGROUND_THRESHOLD_STATE
// This is meant to be a user-initiated job, and therefore gets similar network
// access to FGS.
|| (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
&& (capabilities
& ActivityManager.PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK) != 0);
}
对比总结
函数名称 | 目标场景 | 豁免条件 | 严格程度 |
isProcStateAllowedWhileIdleOrPowerSaveMode | 省电/Doze模式 | 前台进程 或 有电源相关网络能力 | 中 |
isProcStateAllowedWhileInLowPowerStandby | 低电量待机模式 | 仅顶级进程(如锁屏) | 极高 |
isProcStateAllowedNetworkWhileBackground | 普通后台限制 | 非纯后台进程 或 有网络特权 | 低 |
isProcStateAllowedWhileOnRestrictBackground | 用户手动限制后台数据 | 前台进程 或 用户发起的后台任务( |
经过上述优化,进程10225的应用宝进程在Doze模式下,被成功的限制网络能力了。
05-29 15:20:19.009 1605 1898 D NetPolicyStubImpl: setUidFirewallRuleUL uid=10225,chain=metered_deny_admin,allow=false
05-29 15:20:19.009 1605 1898 D NetPolicyStubImpl: setUidFirewallRuleUL uid=10225,chain=metered_deny_user,allow=false
05-29 15:20:19.009 1605 1898 D NetPolicyStubImpl: setUidFirewallRuleUL uid=10225,chain=metered_allow,allow=false
05-29 15:20:19.010 1605 1898 D NetPolicyStubImpl: NetPolicyStubImpl_UidOptimizedEvent:uid=10225,uid=10225 doze
05-29 15:20:19.010 1605 1898 D NetPolicyStubImpl: NetPolicyStubImpl_ProcStateRestrictWhileIdleOrPowerSaveMode:uid=10225,uid=10225 doze
05-29 15:20:19.010 1605 1898 D NetPolicyStubImpl: setUidFirewallRuleUL uid=10225,chain=standby,allow=false
05-29 15:20:19.012 1605 1898 D NetPolicyStubImpl: NetPolicyStubImpl_ProcStateRestrictWhileIdleOrPowerSaveMode:uid=10225,uid=10225 doze
05-29 15:20:19.012 1605 1898 D NetPolicyStubImpl: setUidFirewallRuleUL uid=10225,chain=dozable,allow=false
05-29 15:20:19.012 1605 1898 D NetPolicyStubImpl: NetPolicyStubImpl_UidOptimizedEvent:uid=10225,uid=10225 doze
05-29 15:20:19.012 1605 1898 D NetPolicyStubImpl: NetPolicyStubImpl_ProcStateRestrictWhileIdleOrPowerSaveMode:uid=10225,uid=10225 doze
05-29 15:20:19.012 1605 1898 D NetPolicyStubImpl: NetPolicyStubImpl_ProcStateRestrictWhileInLowPowerStandby:uid=10225,uid=10225 doze
05-29 15:20:19.012 1605 1898 D NetPolicyStubImpl: NetPolicyStubImpl_ProcStateWhileOnRestrictBackground:uid=10225,uid=10225 doze
05-29 15:20:19.013 1605 1898 D NetPolicyStubImpl: updateRulesForPowerRestrictionsUL(10225), isIdle: true, mRestrictPower: false, mDeviceIdleMode: true, isForeground=false, isTop=false, isWhitelisted=false, oldUidBlockedState={blocked=DOZE|APP_STANDBY|APP_BACKGROUND,allowed=NONE,effective=DOZE|APP_STANDBY|APP_BACKGROUND}, newUidBlockedState={blocked=DOZE|APP_STANDBY|APP_BACKGROUND,allowed=NONE,effective=DOZE|APP_STANDBY|APP_BACKGROUND}
GetAddrInfoHandler::run: {104 262248 104 983144 10225 0} # DNS查询请求
GetAddrInfoHandler::run: network access blocked # 防火墙规则(如 iptables)或系统策略(如 Doze 模式)已生效,但拦截发生在 DNS 查询阶段,尚未到达实际网络传输层
alps/packages/modules/DnsResolver/DnsProxyListener.cpp
void DnsProxyListener::GetAddrInfoHandler::run() {
LOG(INFO) << "GetAddrInfoHandler::run: {" << mNetContext.toString() << "}";
...
const bool isUidBlocked = isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid);
if (isUidBlocked) {
LOG(INFO) << "GetAddrInfoHandler::run: network access blocked";
rv = EAI_FAIL;
...
}
/**
* 检查指定UID的网络访问是否被阻止
* @param uid 目标用户ID(应用UID)
* @param netId 网络标识符(如WiFi/移动数据等)
* @return true表示网络访问被阻止,false表示允许访问
*
* 核心逻辑:
* 1. 检查全局拦截功能是否启用
* 2. 排除DNS特权网络
* 3. 尊重实验性功能开关
* 4. 最终调用厂商实现判断
*/
bool isUidNetworkingBlocked(uid_t uid, unsigned netId) {
// 1. 检查基础拦截功能是否可用(ADnsHelper_isUidNetworkingBlocked为函数指针)
if (!ADnsHelper_isUidNetworkingBlocked) return false;
// 2. 特殊网络豁免检查(DNS特权网络)
// 当网络启用enforceDnsUid时,DNS查询使用AID_DNS(1053)而非应用UID
// 这类网络不受常规UID拦截规则限制(如企业VPN场景)
if (resolv_is_enforceDnsUid_enabled_network(netId)) return false;
// 3. 实验性功能开关检查
// 通过getFlag动态控制功能开关,默认值1表示开启(兼容性兜底)
if (!android::net::Experiments::getInstance()->getFlag(
"fail_fast_on_uid_network_blocking", 1 /* default_value */)) {
return false;
}
// 4. 调用厂商具体实现(参数说明):
// - uid: 待检查的应用UID
// - resolv_is_metered_network(netId): 判断是否为计量网络(如移动数据)
// 返回值1表示拦截,0表示放行
return (*ADnsHelper_isUngNetworkingBlocked)(uid, resolv_is_metered_network(netId)) == 1;
}
从BugReport看,Doze模式下没有应用宝联网行为了。主要是常规的gms唤醒了
当然应用宝耗电异常不仅仅联网防火墙会管控,还有持锁、alarm、job和sync等,一般管控的方法拦截关联启动限制保活或冻结就好了(只要规避应用宝下载场景,其他的场景大胆限制就好了)。