Support passing a template to NetworkStatsManager queries.

Currently, NetworkStatsManager queries and callbacks only allow
selecting network traffic based on network identifiers:
networkType, subscriptionId and networkId.  The code ends up
converting these into a template under the hood.

Now that templates can express more fine-grained queries (e.g.,
select only roaming traffic, or select only traffic that's not
on the default network) add a hidden method to pass in a
template. This should have no security implications, as all the
access controls are performed in NetworkStatsService.

Bug: 35142602
Test: android.app.usage.cts.NetworkUsageStatsTest passes
Change-Id: Iab4afa26b34544299d2a9c501c1b0feb470e90a9
This commit is contained in:
Lorenzo Colitti
2018-01-22 21:00:49 +09:00
parent e47bf09f9b
commit 81bd73ba98

View File

@@ -131,6 +131,17 @@ public class NetworkStatsManager {
} }
} }
/** @hide */
public Bucket querySummaryForDevice(NetworkTemplate template,
long startTime, long endTime) throws SecurityException, RemoteException {
Bucket bucket = null;
NetworkStats stats = new NetworkStats(mContext, template, mFlags, startTime, endTime);
bucket = stats.getDeviceSummaryForNetwork();
stats.close();
return bucket;
}
/** /**
* Query network usage statistics summaries. Result is summarised data usage for the whole * Query network usage statistics summaries. Result is summarised data usage for the whole
* device. Result is a single Bucket aggregated over time, state, uid, tag, metered, and * device. Result is a single Bucket aggregated over time, state, uid, tag, metered, and
@@ -163,12 +174,7 @@ public class NetworkStatsManager {
return null; return null;
} }
Bucket bucket = null; return querySummaryForDevice(template, startTime, endTime);
NetworkStats stats = new NetworkStats(mContext, template, mFlags, startTime, endTime);
bucket = stats.getDeviceSummaryForNetwork();
stats.close();
return bucket;
} }
/** /**
@@ -340,6 +346,37 @@ public class NetworkStatsManager {
return result; return result;
} }
/** @hide */
public void registerUsageCallback(NetworkTemplate template, int networkType,
long thresholdBytes, UsageCallback callback, @Nullable Handler handler) {
checkNotNull(callback, "UsageCallback cannot be null");
final Looper looper;
if (handler == null) {
looper = Looper.myLooper();
} else {
looper = handler.getLooper();
}
DataUsageRequest request = new DataUsageRequest(DataUsageRequest.REQUEST_ID_UNSET,
template, thresholdBytes);
try {
CallbackHandler callbackHandler = new CallbackHandler(looper, networkType,
template.getSubscriberId(), callback);
callback.request = mService.registerUsageCallback(
mContext.getOpPackageName(), request, new Messenger(callbackHandler),
new Binder());
if (DBG) Log.d(TAG, "registerUsageCallback returned " + callback.request);
if (callback.request == null) {
Log.e(TAG, "Request from callback is null; should not happen");
}
} catch (RemoteException e) {
if (DBG) Log.d(TAG, "Remote exception when registering callback");
throw e.rethrowFromSystemServer();
}
}
/** /**
* Registers to receive notifications about data usage on specified networks. * Registers to receive notifications about data usage on specified networks.
* *
@@ -368,15 +405,7 @@ public class NetworkStatsManager {
*/ */
public void registerUsageCallback(int networkType, String subscriberId, long thresholdBytes, public void registerUsageCallback(int networkType, String subscriberId, long thresholdBytes,
UsageCallback callback, @Nullable Handler handler) { UsageCallback callback, @Nullable Handler handler) {
checkNotNull(callback, "UsageCallback cannot be null"); NetworkTemplate template = createTemplate(networkType, subscriberId);
final Looper looper;
if (handler == null) {
looper = Looper.myLooper();
} else {
looper = handler.getLooper();
}
if (DBG) { if (DBG) {
Log.d(TAG, "registerUsageCallback called with: {" Log.d(TAG, "registerUsageCallback called with: {"
+ " networkType=" + networkType + " networkType=" + networkType
@@ -384,25 +413,7 @@ public class NetworkStatsManager {
+ " thresholdBytes=" + thresholdBytes + " thresholdBytes=" + thresholdBytes
+ " }"); + " }");
} }
registerUsageCallback(template, networkType, thresholdBytes, callback, handler);
NetworkTemplate template = createTemplate(networkType, subscriberId);
DataUsageRequest request = new DataUsageRequest(DataUsageRequest.REQUEST_ID_UNSET,
template, thresholdBytes);
try {
CallbackHandler callbackHandler = new CallbackHandler(looper, networkType,
subscriberId, callback);
callback.request = mService.registerUsageCallback(
mContext.getOpPackageName(), request, new Messenger(callbackHandler),
new Binder());
if (DBG) Log.d(TAG, "registerUsageCallback returned " + callback.request);
if (callback.request == null) {
Log.e(TAG, "Request from callback is null; should not happen");
}
} catch (RemoteException e) {
if (DBG) Log.d(TAG, "Remote exception when registering callback");
throw e.rethrowFromSystemServer();
}
} }
/** /**