概述
网络策略管理。例如控制app上网、数据流量测量控制等
adb查询
adb shell cmd netpolicy ***
adb shell dumpsys netpolicy ***
app接口
权限:android.permission.MANAGE_NETWORK_POLICY
NetworkPolicyManager policy = (NetworkPolicyManager) getSystemService(Context.NETWORK_POLICY_SERVICE)
或者
policy = NetworkPolicyManager.from(context);
1.app是否可以后台使用流量 调用的setUidPolicy
2.app后台使用流量,但又不限制流量 调用的addRestrictBackgroundWhitelistedUid
netpolicy服务启动
代码路径:
frameworks/base/services/core/java/com/android/server/SystemServer.java
frameworks/base/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
注:
10.0
1.SystemServer::SystemServer:run --> startOtherServices
private void startOtherServices() {
···
NetworkPolicyManagerService networkPolicy = null;
···
traceBeginAndSlog("StartNetworkPolicyManagerService");
try {
//初始化并注册服务
networkPolicy = new NetworkPolicyManagerService(context, mActivityManagerService,
networkManagement);
ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
···
} catch (Throwable e) {
reportWtf("starting NetworkPolicy Service", e);
}
traceEnd();
···
networkPolicy.bindConnectivityManager(connectivity);
···
final NetworkPolicyManagerService networkPolicyF = networkPolicy;
···
mActivityManagerService.systemReady(() -> {
···
//systemReady中初始化数据
CountDownLatch networkPolicyInitReadySignal = null;
if (networkPolicyF != null) {
networkPolicyInitReadySignal = networkPolicyF
.networkScoreAndNetworkManagementServiceReady();
}
···
//关注networkPolicyInitReadySignal的使用。CountDownLatch是多线程使用对象
traceBeginAndSlog("MakeNetworkPolicyServiceReady");
try {
if (networkPolicyF != null) {
networkPolicyF.systemReady(networkPolicyInitReadySignal);
}
} catch (Throwable e) {
reportWtf("making Network Policy Service ready", e);
}
traceEnd();
···
});
}
2.NetworkPolicyManagerService构造方法
public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
INetworkManagementService networkManagement, IPackageManager pm, Clock clock,
File systemDir, boolean suppressDefaultPolicy) {
···
mActivityManager = checkNotNull(activityManager, "missing activityManager");
mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
//初始doze对象
mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
Context.DEVICE_IDLE_CONTROLLER));
···
//初始化/data/system/netpolicy.xml
mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"), "net-policy");
mAppOps = context.getSystemService(AppOpsManager.class);
// Expose private service for system components to use.
//注册本地服务
LocalServices.addService(NetworkPolicyManagerInternal.class,
new NetworkPolicyManagerInternalImpl());
}
构造方法初始了Doze服务DeviceIdleController
3.ams.systemReady中初始化
//执行返回CountDownLatch对象
public CountDownLatch networkScoreAndNetworkManagementServiceReady() {
mNetworkManagerReady = true;
final CountDownLatch initCompleteSignal = new CountDownLatch(1);
mHandler.post(() -> initService(initCompleteSignal));
return initCompleteSignal;
}
//等待initService初始化完
public void systemReady(CountDownLatch initCompleteSignal) {
// wait for initService to complete
try {
if (!initCompleteSignal.await(30, TimeUnit.SECONDS)) {
throw new IllegalStateException("Service " + TAG +" init timeout");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException("Service " + TAG + " init interrupted", e);
}
}
这样做的目的:避免数据初始化异常。因为这是双线程操作,SystemServer调用的是一个线程,NetworkPolicy执行的mHandler是另外一个线程。
private void initService(CountDownLatch initCompleteSignal) {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "systemReady");
final int oldPriority = Process.getThreadPriority(Process.myTid());
try {
// Boost thread's priority during system server init
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
if (!isBandwidthControlEnabled()) {
Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy");
return;
}
//初始化App Standby本地服务
mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
mNetworkStats = LocalServices.getService(NetworkStatsManagerInternal.class);
//以下是各种监听
synchronized (mUidRulesFirstLock) {
synchronized (mNetworkPoliciesSecondLock) {
updatePowerSaveWhitelistUL();
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
//1.LowPowerMode监听,类型为NETWORK_FIREWALL
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();
}
}
}
});
mRestrictPower = mPowerManagerInternal.getLowPowerState(
ServiceType.NETWORK_FIREWALL).batterySaverEnabled;
mSystemReady = true;
waitForAdminData();
// read policy from disk
//从/data/system/netpolicy.xml读取数据并初始化数据列表
readPolicyAL();
// Update the restrictBackground if battery saver is turned on
mRestrictBackgroundBeforeBsm = mLoadedRestrictBackground;
mRestrictBackgroundPowerState = mPowerManagerInternal
.getLowPowerState(ServiceType.DATA_SAVER);
final boolean localRestrictBackground =
mRestrictBackgroundPowerState.batterySaverEnabled;
if (localRestrictBackground && !mLoadedRestrictBackground) {
mLoadedRestrictBackground = true;
}
//2.LowPowerMode监听,类型为DATA_SAVER
mPowerManagerInternal.registerLowPowerModeObserver(
new PowerManagerInternal.LowPowerModeListener() {
@Override
public int getServiceType() {
return ServiceType.DATA_SAVER;
}
@Override
public void onLowPowerModeChanged(PowerSaveState result) {
synchronized (mUidRulesFirstLock) {
updateRestrictBackgroundByLowPowerModeUL(result);
}
}
});
if (addDefaultRestrictBackgroundWhitelistUidsUL()) {
writePolicyAL();
}
setRestrictBackgroundUL(mLoadedRestrictBackground);
updateRulesForGlobalChangeAL(false);
updateNotificationsNL();
}
}
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
try {
//3.uid状态监听
mActivityManager.registerUidObserver(mUidObserver,
ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE,
NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE, "android");
//4.网络预警监听
mNetworkManager.registerObserver(mAlertObserver);
} catch (RemoteException e) {
// ignored; both services live in system_server
}
// listen for changes to power save whitelist
final IntentFilter whitelistFilter = new IntentFilter(
PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler);
// watch for network interfaces to be claimed
final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
// listen for package changes to update policy
final IntentFilter packageFilter = new IntentFilter();
packageFilter.addAction(ACTION_PACKAGE_ADDED);
packageFilter.addDataScheme("package");
mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler);
// listen for UID changes to update policy
mContext.registerReceiver(
mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler);
// listen for user changes to update policy
final IntentFilter userFilter = new IntentFilter();
userFilter.addAction(ACTION_USER_ADDED);
userFilter.addAction(ACTION_USER_REMOVED);
mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
// listen for stats update events
final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED);
mContext.registerReceiver(
mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
// listen for restrict background changes from notifications
final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler);
// Listen for snooze from notifications
mContext.registerReceiver(mSnoozeReceiver,
new IntentFilter(ACTION_SNOOZE_WARNING), MANAGE_NETWORK_POLICY, mHandler);
mContext.registerReceiver(mSnoozeReceiver,
new IntentFilter(ACTION_SNOOZE_RAPID), MANAGE_NETWORK_POLICY, mHandler);
// listen for configured wifi networks to be loaded
final IntentFilter wifiFilter =
new IntentFilter(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
mContext.registerReceiver(mWifiReceiver, wifiFilter, null, mHandler);
// listen for carrier config changes to update data cycle information
final IntentFilter carrierConfigFilter = new IntentFilter(
ACTION_CARRIER_CONFIG_CHANGED);
mContext.registerReceiver(mCarrierConfigReceiver, carrierConfigFilter, null, mHandler);
// M { ALPS04413692 due to MTK telephony modify, subscriberId maybe null
final IntentFilter simStateChangedFilter = new IntentFilter(
ACTION_SIM_STATE_CHANGED);
mContext.registerReceiver(mSimStateChangedReceiver, simStateChangedFilter,
null, mHandler);
// end
// listen for meteredness changes
mContext.getSystemService(ConnectivityManager.class).registerNetworkCallback(
new NetworkRequest.Builder().build(), mNetworkCallback);
//app Standby服务的监听
mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
// Listen for subscriber changes
mContext.getSystemService(SubscriptionManager.class).addOnSubscriptionsChangedListener(
new OnSubscriptionsChangedListener(mHandler.getLooper()) {
@Override
public void onSubscriptionsChanged() {
updateNetworksInternal();
}
});
// tell systemReady() that the service has been initialized
//初始化完成调用countDown
initCompleteSignal.countDown();
} finally {
// Restore the default priority after init is done
Process.setThreadPriority(oldPriority);
Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
}
}
NetworkPolicyManagerService在初始化服务过程中,就是一个集大成者:监听改变,从而做相关的权限管理
4.分析网络限制:app standby闲置达到上限,进行网络的回调
mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
private class AppIdleStateChangeListener
extends UsageStatsManagerInternal.AppIdleStateChangeListener {
@Override
public void onAppIdleStateChanged(String packageName, int userId, boolean idle, int bucket,
int reason) {
try {
final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
synchronized (mUidRulesFirstLock) {
···
updateRulesForPowerRestrictionsUL(uid);
}
} catch (NameNotFoundException nnfe) {
}
}
····
}
updateRuleForAppIdleUL --> setUidFirewallRule --> mNetworkManager.setFirewallUidRule
--> NetworkManagementService.setFirewallUidRule
网友评论