网络策略会在开机的时候进行初始化,以及会在uid状态发生变化后作出改变。开启DataSaver功能也会作出策略上的变化。
这几种变化只是前面的入口不同,最后执行策略更新的方法是相同的。
在此仅分析了开启DataSaver功能和UID状态发生变化后的流程。
流程图大致如下
1. 从点击QS,开启DataSaver功能为入口
DataSaver.java#handleClick()
@Override
protected void handleClick() {
if (mState.value
|| Prefs.getBoolean(mContext, Prefs.Key.QS_DATA_SAVER_DIALOG_SHOWN, false)) {
// Do it right away.
toggleDataSaver();
return;
}
// Shows dialog first
SystemUIDialog dialog = new SystemUIDialog(mContext);
dialog.setTitle(com.android.internal.R.string.data_saver_enable_title);
dialog.setMessage(com.android.internal.R.string.data_saver_description);
dialog.setPositiveButton(com.android.internal.R.string.data_saver_enable_button,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
toggleDataSaver();
}
});
dialog.setNegativeButton(com.android.internal.R.string.cancel, null);
dialog.setShowForAllUsers(true);
dialog.show();
Prefs.putBoolean(mContext, Prefs.Key.QS_DATA_SAVER_DIALOG_SHOWN, true);
}
点击开关会触发 toggleDataSaver()方法
private void toggleDataSaver() {
mState.value = !mDataSaverController.isDataSaverEnabled();
mDataSaverController.setDataSaverEnabled(mState.value);
refreshState(mState.value); // 这里是去刷新UI
}
mDataSaverController是DataSaverController对象,其是一个接口,会走到实现类DataSaverControllerImpl中
DataSaverControllerImpl.java#setDataSaverEnabled()
public void setDataSaverEnabled(boolean enabled) {
mPolicyManager.setRestrictBackground(enabled);
try {
// 这里会去通知接口回调
mPolicyListener.onRestrictBackgroundChanged(enabled);
} catch (RemoteException e) {
}
}
mPolicyManager是PolicyManager对象,其会通过Binder执行到NetworkPolicyManagerService中
NetworkPolicyManagerService.java#setRestrictBackground()
@Override
public void setRestrictBackground(boolean restrictBackground) {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackground");
try {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
final long token = Binder.clearCallingIdentity();
try {
maybeRefreshTrustedTime();
synchronized (mUidRulesFirstLock) {
if (restrictBackground == mRestrictBackground) {
// Ideally, UI should never allow this scenario...
Slog.w(TAG, "setRestrictBackground: already " + restrictBackground);
return;
}
// 会去设置后台一些网络访问的规则
setRestrictBackgroundUL(restrictBackground);
}
} finally {
Binder.restoreCallingIdentity(token);
}
mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0)
.sendToTarget();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
}
}
NetworkPolicyManagerService#setRestrictBackgroundUL()
private void setRestrictBackgroundUL(boolean restrictBackground) {
Slog.d(TAG, "setRestrictBackgroundUL(): " + restrictBackground);
final boolean oldRestrictBackground = mRestrictBackground;
mRestrictBackground = restrictBackground;
// Must whitelist foreground apps before turning data saver mode on.
// TODO: there is no need to iterate through all apps here, just those in the foreground,
// so it could call AM to get the UIDs of such apps, and iterate through them instead.
// 先去根据白名单和黑名单更新每个应用的网络访问规则
updateRulesForRestrictBackgroundUL();
try {
if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) {
Slog.e(TAG, "Could not change Data Saver Mode on NMS to " + mRestri