Merge "[MS68.1] Register usage callback from NetworkPolicyManagerService"

This commit is contained in:
Junyu Lai
2022-01-25 13:30:57 +00:00
committed by Gerrit Code Review
4 changed files with 37 additions and 31 deletions

View File

@@ -729,7 +729,8 @@ public class NetworkStatsManager {
* {@link #unregisterUsageCallback} is called. * {@link #unregisterUsageCallback} is called.
* *
* @param template Template used to match networks. See {@link NetworkTemplate}. * @param template Template used to match networks. See {@link NetworkTemplate}.
* @param thresholdBytes Threshold in bytes to be notified on. * @param thresholdBytes Threshold in bytes to be notified on. The provided value that lower
* than 2MiB will be clamped for non-privileged callers.
* @param executor The executor on which callback will be invoked. The provided {@link Executor} * @param executor The executor on which callback will be invoked. The provided {@link Executor}
* must run callback sequentially, otherwise the order of callbacks cannot be * must run callback sequentially, otherwise the order of callbacks cannot be
* guaranteed. * guaranteed.

View File

@@ -76,7 +76,7 @@ class NetworkStatsObservers {
*/ */
public DataUsageRequest register(DataUsageRequest inputRequest, IUsageCallback callback, public DataUsageRequest register(DataUsageRequest inputRequest, IUsageCallback callback,
int callingUid, @NetworkStatsAccess.Level int accessLevel) { int callingUid, @NetworkStatsAccess.Level int accessLevel) {
DataUsageRequest request = buildRequest(inputRequest); DataUsageRequest request = buildRequest(inputRequest, callingUid);
RequestInfo requestInfo = buildRequestInfo(request, callback, callingUid, RequestInfo requestInfo = buildRequestInfo(request, callback, callingUid,
accessLevel); accessLevel);
@@ -194,10 +194,12 @@ class NetworkStatsObservers {
} }
} }
private DataUsageRequest buildRequest(DataUsageRequest request) { private DataUsageRequest buildRequest(DataUsageRequest request, int callingUid) {
// Cap the minimum threshold to a safe default to avoid too many callbacks // For non-system uid, cap the minimum threshold to a safe default to avoid too
long thresholdInBytes = Math.max(MIN_THRESHOLD_BYTES, request.thresholdInBytes); // many callbacks.
if (thresholdInBytes < request.thresholdInBytes) { long thresholdInBytes = (callingUid == Process.SYSTEM_UID ? request.thresholdInBytes
: Math.max(MIN_THRESHOLD_BYTES, request.thresholdInBytes));
if (thresholdInBytes > request.thresholdInBytes) {
Log.w(TAG, "Threshold was too low for " + request Log.w(TAG, "Threshold was too low for " + request
+ ". Overriding to a safer default of " + thresholdInBytes + " bytes"); + ". Overriding to a safer default of " + thresholdInBytes + " bytes");
} }

View File

@@ -24,7 +24,6 @@ import static android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS;
import static android.Manifest.permission.NETWORK_SETTINGS; import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.NETWORK_STACK;
import static android.Manifest.permission.OBSERVE_NETWORK_POLICY; import static android.Manifest.permission.OBSERVE_NETWORK_POLICY;
import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
import static android.Manifest.permission.READ_PHONE_STATE; import static android.Manifest.permission.READ_PHONE_STATE;
import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_IMMUTABLE;
@@ -130,7 +129,6 @@ import static com.android.internal.util.XmlUtils.writeIntAttribute;
import static com.android.internal.util.XmlUtils.writeLongAttribute; import static com.android.internal.util.XmlUtils.writeLongAttribute;
import static com.android.internal.util.XmlUtils.writeStringAttribute; import static com.android.internal.util.XmlUtils.writeStringAttribute;
import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT; import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT;
import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.END_TAG; import static org.xmlpull.v1.XmlPullParser.END_TAG;
@@ -1012,10 +1010,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
userFilter.addAction(ACTION_USER_REMOVED); userFilter.addAction(ACTION_USER_REMOVED);
mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler); mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
// listen for stats update events // listen for stats updated callbacks for interested network types.
final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED); mNetworkStats.registerUsageCallback(new NetworkTemplate.Builder(MATCH_MOBILE).build(),
mContext.registerReceiver( 0 /* thresholdBytes */, new HandlerExecutor(mHandler), mStatsCallback);
mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler); mNetworkStats.registerUsageCallback(new NetworkTemplate.Builder(MATCH_WIFI).build(),
0 /* thresholdBytes */, new HandlerExecutor(mHandler), mStatsCallback);
// listen for restrict background changes from notifications // listen for restrict background changes from notifications
final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND); final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
@@ -1220,19 +1219,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}; };
/** /**
* Receiver that watches for {@link NetworkStatsManager} updates, which we * Listener that watches for {@link NetworkStatsManager} updates, which
* use to check against {@link NetworkPolicy#warningBytes}. * NetworkPolicyManagerService uses to check against {@link NetworkPolicy#warningBytes}.
*/ */
private final NetworkStatsBroadcastReceiver mStatsReceiver = private final StatsCallback mStatsCallback = new StatsCallback();
new NetworkStatsBroadcastReceiver(); private class StatsCallback extends NetworkStatsManager.UsageCallback {
private class NetworkStatsBroadcastReceiver extends BroadcastReceiver { private boolean mIsAnyCallbackReceived = false;
private boolean mIsAnyIntentReceived = false;
@Override
public void onReceive(Context context, Intent intent) {
// on background handler thread, and verified
// READ_NETWORK_USAGE_HISTORY permission above.
mIsAnyIntentReceived = true; @Override
public void onThresholdReached(int networkType, String subscriberId) {
mIsAnyCallbackReceived = true;
synchronized (mNetworkPoliciesSecondLock) { synchronized (mNetworkPoliciesSecondLock) {
updateNetworkRulesNL(); updateNetworkRulesNL();
@@ -1242,11 +1238,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
/** /**
* Return whether any {@code ACTION_NETWORK_STATS_UPDATED} intent is received. * Return whether any callback is received.
* Used to determine if NetworkStatsService is ready. * Used to determine if NetworkStatsService is ready.
*/ */
public boolean isAnyIntentReceived() { public boolean isAnyCallbackReceived() {
return mIsAnyIntentReceived; return mIsAnyCallbackReceived;
} }
}; };
@@ -1473,7 +1469,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// Skip if not ready. NetworkStatsService will block public API calls until it is // Skip if not ready. NetworkStatsService will block public API calls until it is
// ready. To prevent NPMS be blocked on that, skip and fail fast instead. // ready. To prevent NPMS be blocked on that, skip and fail fast instead.
if (!mStatsReceiver.isAnyIntentReceived()) return null; if (!mStatsCallback.isAnyCallbackReceived()) return null;
final List<NetworkStats.Bucket> stats = mDeps.getNetworkUidBytes(template, start, end); final List<NetworkStats.Bucket> stats = mDeps.getNetworkUidBytes(template, start, end);
for (final NetworkStats.Bucket entry : stats) { for (final NetworkStats.Bucket entry : stats) {
@@ -5470,7 +5466,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private long getTotalBytes(NetworkTemplate template, long start, long end) { private long getTotalBytes(NetworkTemplate template, long start, long end) {
// Skip if not ready. NetworkStatsService will block public API calls until it is // Skip if not ready. NetworkStatsService will block public API calls until it is
// ready. To prevent NPMS be blocked on that, skip and fail fast instead. // ready. To prevent NPMS be blocked on that, skip and fail fast instead.
if (!mStatsReceiver.isAnyIntentReceived()) return 0; if (!mStatsCallback.isAnyCallbackReceived()) return 0;
return mDeps.getNetworkTotalBytes(template, start, end); return mDeps.getNetworkTotalBytes(template, start, end);
} }

View File

@@ -51,6 +51,7 @@ import static android.net.NetworkPolicyManager.uidRulesToString;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.net.NetworkStats.METERED_NO; import static android.net.NetworkStats.METERED_NO;
import static android.net.NetworkStats.METERED_YES; import static android.net.NetworkStats.METERED_YES;
import static android.net.NetworkTemplate.MATCH_MOBILE;
import static android.net.NetworkTemplate.buildTemplateCarrierMetered; import static android.net.NetworkTemplate.buildTemplateCarrierMetered;
import static android.net.NetworkTemplate.buildTemplateWifi; import static android.net.NetworkTemplate.buildTemplateWifi;
import static android.net.TrafficStats.MB_IN_BYTES; import static android.net.TrafficStats.MB_IN_BYTES;
@@ -71,7 +72,6 @@ import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOO
import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID; import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING; import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
import static com.android.server.net.NetworkPolicyManagerService.UidBlockedState.getEffectiveBlockedReasons; import static com.android.server.net.NetworkPolicyManagerService.UidBlockedState.getEffectiveBlockedReasons;
import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
@@ -95,6 +95,7 @@ import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset; import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -495,8 +496,14 @@ public class NetworkPolicyManagerServiceTest {
verify(mNetworkManager).registerObserver(networkObserver.capture()); verify(mNetworkManager).registerObserver(networkObserver.capture());
mNetworkObserver = networkObserver.getValue(); mNetworkObserver = networkObserver.getValue();
// Simulate NetworkStatsService broadcast stats updated to signal its readiness. // Catch UsageCallback during systemReady(). Simulate NetworkStatsService triggered
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_UPDATED)); // stats updated callback to signal its readiness.
final ArgumentCaptor<NetworkStatsManager.UsageCallback> usageObserver =
ArgumentCaptor.forClass(NetworkStatsManager.UsageCallback.class);
verify(mStatsManager, times(2))
.registerUsageCallback(any(), anyLong(), any(), usageObserver.capture());
usageObserver.getValue().onThresholdReached(
new NetworkTemplate.Builder(MATCH_MOBILE).build());
NetworkPolicy defaultPolicy = mService.buildDefaultCarrierPolicy(0, ""); NetworkPolicy defaultPolicy = mService.buildDefaultCarrierPolicy(0, "");
mDefaultWarningBytes = defaultPolicy.warningBytes; mDefaultWarningBytes = defaultPolicy.warningBytes;