Android powersave模式网络限制流程

  • 由 b178903294创建, 最后修改于9月 01, 2020

当用户在settings打开省电模式的开关后,系统会进入到省电模式,在各种方面进行限制以尽可能的省电。今天我们来分析一下,省电模式限制网络连接的逻辑。

 

前言:首先分析一下打开省电模式按钮之后发生了什么:

 

1、先来看一下Battery saver的switch开关,当我们打开Battery saver的时候

 

 

 

//packages/apps/Settings/src/com/android/settings/fuelgauge/BatterySaverSettings.java

private void trySetPowerSaveMode(boolean mode) {

    if (!mPowerManager.setPowerSaveMode(mode)) {

        

}

 

2.当应用调用了PMS的setPowerSaveMode进行省电模式,会进入PowerManagerService.java,里面主要包括权限检查和进一步设置

 

//PowerManagerService.java

public boolean setPowerSaveMode(boolean mode) {

    //这个操作需要调用者用有DEVICE_POWER权限

    mContext.enforceCallingOrSelfPermission(

            android.Manifest.permission.DEVICE_POWER, null);

    //......

    //进行省电模式内部设置

    return setLowPowerModeInternal(mode);

}

3.省电模式内部设置setLowPowerModeInternal,里面包含省电模式标志位LOW_POWER_MODE的设置,省电模式mLowPowerModeSetting的设置

private boolean setLowPowerModeInternal(boolean mode) {

        ……

        //此时会设置省电模式标志位LOW_POWER_MODE设置

        Settings.Global.putInt(mContext.getContentResolver(),

                Settings.Global.LOW_POWER_MODE, mode ? 1 0);

        mLowPowerModeSetting = mode;//省电模式设置

        ……

        updateLowPowerModeLocked();//省电模式

        return true;

}

4.

更新省电模式相关设置updateLowPowerModeLocked,该函数包括了大部分省电模式的逻辑处理。

1) 如果在充电中或者”非低电而且没有开完机”情况下是不允许进入省电模式

2) 自动打开省电模式的条件是:不在充电状态 && 设置了自动进入省电模式 && 用户没有主动在低电下关闭低电模式 && 低电状态

3) 只要手动设置省电模式mLowPowerModeSetting,或者自动进入省电模式,那么省电模式lowPowerModeEnabled将会给打开

4) 进行Power HAL的设置,android默认的default Power HAL是power.default.so,里面的内容默认都是置空,也就是没有任何操作。

5) 进行省电模式模式切换前会发生一个ACTION_POWER_SAVE_MODE_CHANGING的广播,然后回调所有监听了省电模式的监听器,最后切换成功后会发生ACTION_POWER_SAVE_MODE_CHANGED的广播。

6) 会将mLowPowerModeListeners低电模式的监听onLowPowerModeChanged全部回调一遍

 展开源码

 

 

 

正文   

       看看powersave怎么控制网络的

 

一、网络限制的开启与规则更新

 

1.首先回调下面的LowPowerModeObserver 将mRestrictPower赋值为true此时则打开了乐网络限制模式,调用updateRulesForRestrictPowerUL()进行规则更新

frameworks/base/services/core/java/com/android/server/net/NetworkPolicyManagerService.java

mPowerManagerInternal.registerLowPowerModeObserver(

                            new PowerManagerInternal.LowPowerModeListener() {

                                @Override

                                public int getServiceType() {

                                    return ServiceType.NETWORK_FIREWALL;

                                }

 

                                @Override

                                public void onLowPowerModeChanged(PowerSaveState result) {

                                    final boolean enabled = result.batterySaverEnabled;

                                    if (LOGD) {

                                        Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")");

                                    }

                                    synchronized (mUidRulesFirstLock) {

                                        if (mRestrictPower != enabled) {

                                            mRestrictPower = enabled;

                                            updateRulesForRestrictPowerUL();

                                        }

                                    }

                                }

                            });

updateRulesForRestrictPowerUL() 有分别调用了三个函数进行不同规则的更新:

 

// TODO: rename / document to make it clear these are global (not app-specific) rules

private void updateRulesForRestrictPowerUL() {

    Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL");

    try {

        updateRulesForDeviceIdleUL();  //调用updateRulesForWhitelistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE, mUidFirewallDozableRules); 开关网络限制  并更新 updateRulesForDeviceIdleUL规则       

        updateRulesForPowerSaveUL();   //调用updateRulesForWhitelistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE,mUidFirewallPowerSaveRules); 开关网络限制     更新updateRulesForPowerSaveUL规则

        updateRulesForAllAppsUL(TYPE_RESTRICT_POWER); // 设置mUidRules 并通过INetworkManagementService 设置setUidMeteredNetworkWhitelist 允许网络状态查询.

    finally {

        Trace.traceEnd(Trace.TRACE_TAG_NETWORK);

    }

}

下面我们来分析updateRulesForWhitelistedPowerSaveUL  开关 powersave流程

// NOTE: since both fw_dozable and fw_powersave uses the same map

// (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.

private void updateRulesForWhitelistedPowerSaveUL(boolean enabled, int chain,

        SparseIntArray rules) {

    if (chain != FIREWALL_CHAIN_POWERSAVE && enabled) { // EASICLASS-13069  seewo bijunqiang allows internet use in LowPowerMode

        // Sync the whitelists before enabling the chain.  We don't care about the rules if

        // we are disabling the chain.

        final SparseIntArray uidRules = rules;

        uidRules.clear();

        final List<UserInfo> users = mUserManager.getUsers();

        for (int ui = users.size() - 1; ui >= 0; ui--) {

            UserInfo user = users.get(ui);

            updateRulesForWhitelistedAppIds(uidRules, mPowerSaveTempWhitelistAppIds, user.id);

            updateRulesForWhitelistedAppIds(uidRules, mPowerSaveWhitelistAppIds, user.id);  //更新规则

            if (chain == FIREWALL_CHAIN_POWERSAVE) {

                updateRulesForWhitelistedAppIds(uidRules,

                        mPowerSaveWhitelistExceptIdleAppIds, user.id);

            }

        }

        for (int i = mUidState.size() - 1; i >= 0; i--) {

            if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) {

                uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW);

            }

        }

        setUidFirewallRulesUL(chain, uidRules, CHAIN_TOGGLE_ENABLE);  //开启

    else {

        setUidFirewallRulesUL(chain, null, CHAIN_TOGGLE_DISABLE);   //关闭

    }

通过调用setUidFirewallRulesUL进行开关

private void setUidFirewallRulesUL(int chain, @Nullable SparseIntArray uidRules,

            @ChainToggleType int toggle) {

        if (uidRules != null) {

            setUidFirewallRulesUL(chain, uidRules);

        }

        if (toggle != CHAIN_TOGGLE_NONE) {

            enableFirewallChainUL(chain, toggle == CHAIN_TOGGLE_ENABLE);

        }

    }

继续调用enableFirewallChainUL

/**

¦* Add or remove a uid to the firewall blacklist for all network ifaces.

¦*/

private void enableFirewallChainUL(int chain, boolean enable) {

    if (mFirewallChainStates.indexOfKey(chain) >= 0 &&

            mFirewallChainStates.get(chain) == enable) {

        // All is the same, nothing to do.

        return;

    }

    mFirewallChainStates.put(chain, enable);

    try {

        mNetworkManager.setFirewallChainEnabled(chain, enable);

        mLogger.firewallChainEnabled(chain, enable);

    catch (IllegalStateException e) {

        Log.wtf(TAG, "problem enable firewall chain", e);

    catch (RemoteException e) {

        // ignored; service lives in system_server

    }

}

继续调用 mNetworkManager.setFirewallChainEnabled(chain, enable);

 

NetworkManagementService.java

@Override

   public void setFirewallChainEnabled(int chain, boolean enable) {

       enforceSystemUid();

       

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值