Addressing API council comments on NetworkStatsManager.
Callbacks
- DataUsageCallback renamed to UsageCallback
- DataUsagePolicy removed; passing in params directly to register method
- making it an abstract class
- passing in (networkType, subscriberId) that reached its threshold
- renaming onLimitReached to onThresholdReached to match existing naming
- only monitor single network,subscriberId
- no monitoring of specific uids; using device or user wide instead
Tags
- only owner uid can read its tags
- exposing only TAG_NONE to match service side
BUG: 27530098
Change-Id: I2b2664da71806868a1e937d2bf4d1f234637509b
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index 2e3aca4..4a28117 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -106,7 +106,7 @@
* device. Result is a single Bucket aggregated over time, state, uid, tag and roaming. This
* means the bucket's start and end timestamp are going to be the same as the 'startTime' and
* 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid
- * {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_ALL}
+ * {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE}
* and roaming {@link NetworkStats.Bucket#ROAMING_ALL}.
*
* @param networkType As defined in {@link ConnectivityManager}, e.g.
@@ -122,8 +122,11 @@
*/
public Bucket querySummaryForDevice(int networkType, String subscriberId,
long startTime, long endTime) throws SecurityException, RemoteException {
- NetworkTemplate template = createTemplate(networkType, subscriberId);
- if (template == null) {
+ NetworkTemplate template;
+ try {
+ template = createTemplate(networkType, subscriberId);
+ } catch (IllegalArgumentException e) {
+ if (DBG) Log.e(TAG, "Cannot create template", e);
return null;
}
@@ -136,21 +139,10 @@
}
/**
- * Query network usage statistics summaries aggregated across tags.
- *
- * #see querySummaryForUser(int, String, long, long, boolean)
- */
- public Bucket querySummaryForUser(int networkType, String subscriberId, long startTime,
- long endTime) throws SecurityException, RemoteException {
- return querySummaryForUser(networkType, subscriberId, startTime, endTime,
- false /* includeTags */);
- }
-
- /**
* Query network usage statistics summaries. Result is summarised data usage for all uids
* belonging to calling user. Result is a single Bucket aggregated over time, state and uid.
* This means the bucket's start and end timestamp are going to be the same as the 'startTime'
- * and 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid
+ * and 'endTime' parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid
* {@link NetworkStats.Bucket#UID_ALL}.
*
* @param networkType As defined in {@link ConnectivityManager}, e.g.
@@ -161,42 +153,33 @@
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
- * @param includeTags whether to include network tags. If {@code true}, tags will be returned
- * and history retention may be shorter.
* @return Bucket object or null if permissions are insufficient or error happened during
* statistics collection.
*/
public Bucket querySummaryForUser(int networkType, String subscriberId, long startTime,
- long endTime, boolean includeTags) throws SecurityException, RemoteException {
- NetworkTemplate template = createTemplate(networkType, subscriberId);
- if (template == null) {
+ long endTime) throws SecurityException, RemoteException {
+ NetworkTemplate template;
+ try {
+ template = createTemplate(networkType, subscriberId);
+ } catch (IllegalArgumentException e) {
+ if (DBG) Log.e(TAG, "Cannot create template", e);
return null;
}
NetworkStats stats;
stats = new NetworkStats(mContext, template, startTime, endTime);
- stats.startSummaryEnumeration(includeTags);
+ stats.startSummaryEnumeration();
stats.close();
return stats.getSummaryAggregate();
}
/**
- * Query network usage statistics summaries aggregated across tags.
- *
- * #see querySummary(int, String, long, long, boolean)
- */
- public NetworkStats querySummary(int networkType, String subscriberId, long startTime,
- long endTime) throws SecurityException, RemoteException {
- return querySummary(networkType, subscriberId, startTime, endTime, false /* includeTags */);
- }
-
- /**
* Query network usage statistics summaries. Result filtered to include only uids belonging to
* calling user. Result is aggregated over time, hence all buckets will have the same start and
- * end timestamps. Not aggregated over state or uid or tag. This means buckets' start and end
- * timestamps are going to be the same as the 'startTime' and 'endTime' parameters. State,
- * uid and tag are going to vary.
+ * end timestamps. Not aggregated over state or uid. This means buckets' start and end
+ * timestamps are going to be the same as the 'startTime' and 'endTime' parameters.
+ * State and uid are going to vary, and tag is going to be the same.
*
* @param networkType As defined in {@link ConnectivityManager}, e.g.
* {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
@@ -206,21 +189,22 @@
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
- * @param includeTags whether to include network tags. If {@code true}, tags will be returned
- * and history retention may be shorter.
* @return Statistics object or null if permissions are insufficient or error happened during
* statistics collection.
*/
public NetworkStats querySummary(int networkType, String subscriberId, long startTime,
- long endTime, boolean includeTags) throws SecurityException, RemoteException {
- NetworkTemplate template = createTemplate(networkType, subscriberId);
- if (template == null) {
+ long endTime) throws SecurityException, RemoteException {
+ NetworkTemplate template;
+ try {
+ template = createTemplate(networkType, subscriberId);
+ } catch (IllegalArgumentException e) {
+ if (DBG) Log.e(TAG, "Cannot create template", e);
return null;
}
NetworkStats result;
result = new NetworkStats(mContext, template, startTime, endTime);
- result.startSummaryEnumeration(includeTags);
+ result.startSummaryEnumeration();
return result;
}
@@ -233,7 +217,7 @@
public NetworkStats queryDetailsForUid(int networkType, String subscriberId,
long startTime, long endTime, int uid) throws SecurityException, RemoteException {
return queryDetailsForUidTag(networkType, subscriberId, startTime, endTime, uid,
- NetworkStats.Bucket.TAG_ALL);
+ NetworkStats.Bucket.TAG_NONE);
}
/**
@@ -255,22 +239,28 @@
* @param endTime End of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param uid UID of app
- * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_ANY} for any tags, use
- * {@link NetworkStats.Bucket#TAG_ALL} to aggregate over tags.
+ * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_NONE} for no tags.
* @return Statistics object or null if permissions are insufficient or error happened during
* statistics collection.
*/
public NetworkStats queryDetailsForUidTag(int networkType, String subscriberId,
- long startTime, long endTime, int uid, int tag) throws SecurityException,
- RemoteException {
- NetworkTemplate template = createTemplate(networkType, subscriberId);
- if (template == null) {
+ long startTime, long endTime, int uid, int tag) {
+ NetworkTemplate template;
+ try {
+ template = createTemplate(networkType, subscriberId);
+ } catch (IllegalArgumentException e) {
+ if (DBG) Log.e(TAG, "Cannot create template", e);
return null;
}
NetworkStats result;
- result = new NetworkStats(mContext, template, startTime, endTime);
- result.startHistoryEnumeration(uid, tag);
+ try {
+ result = new NetworkStats(mContext, template, startTime, endTime);
+ result.startHistoryEnumeration(uid, tag);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error while querying stats for uid=" + uid + " tag=" + tag, e);
+ return null;
+ }
return result;
}
@@ -280,7 +270,7 @@
* calling user. Result is aggregated over state but not aggregated over time or uid. This means
* buckets' start and end timestamps are going to be between 'startTime' and 'endTime'
* parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid will vary,
- * tag {@link NetworkStats.Bucket#TAG_ALL} and roaming is going to be
+ * tag {@link NetworkStats.Bucket#TAG_NONE} and roaming is going to be
* {@link NetworkStats.Bucket#ROAMING_ALL}.
* <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
* interpolate across partial buckets. Since bucket length is in the order of hours, this
@@ -299,44 +289,59 @@
*/
public NetworkStats queryDetails(int networkType, String subscriberId, long startTime,
long endTime) throws SecurityException, RemoteException {
- NetworkTemplate template = createTemplate(networkType, subscriberId);
- if (template == null) {
+ NetworkTemplate template;
+ try {
+ template = createTemplate(networkType, subscriberId);
+ } catch (IllegalArgumentException e) {
+ if (DBG) Log.e(TAG, "Cannot create template", e);
return null;
}
+
NetworkStats result;
result = new NetworkStats(mContext, template, startTime, endTime);
result.startUserUidEnumeration();
return result;
}
+ /** @removed */
+ public void registerDataUsageCallback(DataUsagePolicy policy, DataUsageCallback callback,
+ @Nullable Handler handler) {}
+
+ /** @removed */
+ public void registerDataUsageCallback(DataUsagePolicy policy, UsageCallback callback,
+ @Nullable Handler handler) {}
+
+ /** @removed */
+ public void unregisterDataUsageCallback(DataUsageCallback callback) {}
+
/**
- * Registers to receive notifications about data usage on specified networks and uids.
- * The callbacks will continue to be called as long as the process is live or
- * {@link #unregisterDataUsageCallback} is called.
+ * Registers to receive notifications about data usage on specified networks.
*
- * @param policy {@link DataUsagePolicy} describing this request.
- * @param callback The {@link DataUsageCallback} that the system will call when data usage
- * has exceeded the specified threshold.
+ * #see registerUsageCallback(int, String[], long, UsageCallback, Handler)
*/
- public void registerDataUsageCallback(DataUsagePolicy policy, DataUsageCallback callback) {
- registerDataUsageCallback(policy, callback, null /* handler */);
+ public void registerUsageCallback(int networkType, String subscriberId, long thresholdBytes,
+ UsageCallback callback) {
+ registerUsageCallback(networkType, subscriberId, thresholdBytes, null /* handler */);
}
/**
- * Registers to receive notifications about data usage on specified networks and uids.
- * The callbacks will continue to be called as long as the process is live or
- * {@link #unregisterDataUsageCallback} is called.
+ * Registers to receive notifications about data usage on specified networks.
*
- * @param policy {@link DataUsagePolicy} describing this request.
- * @param callback The {@link DataUsageCallback} that the system will call when data usage
+ * <p>The callbacks will continue to be called as long as the process is live or
+ * {@link #unregisterUsageCallback} is called.
+ *
+ * @param networkType Type of network to monitor. Either
+ {@link ConnectivityManager#TYPE_MOBILE} or {@link ConnectivityManager#TYPE_WIFI}.
+ * @param subscriberId If applicable, the subscriber id of the network interface.
+ * @param thresholdBytes Threshold in bytes to be notified on.
+ * @param callback The {@link UsageCallback} that the system will call when data usage
* has exceeded the specified threshold.
* @param handler to dispatch callback events through, otherwise if {@code null} it uses
* the calling thread.
*/
- public void registerDataUsageCallback(DataUsagePolicy policy, DataUsageCallback callback,
- @Nullable Handler handler) {
- checkNotNull(policy, "DataUsagePolicy cannot be null");
- checkNotNull(callback, "DataUsageCallback cannot be null");
+ public void registerUsageCallback(int networkType, String subscriberId, long thresholdBytes,
+ UsageCallback callback, @Nullable Handler handler) {
+ checkNotNull(callback, "UsageCallback cannot be null");
final Looper looper;
if (handler == null) {
@@ -345,62 +350,72 @@
looper = handler.getLooper();
}
- if (DBG) Log.d(TAG, "registerDataUsageCallback called with " + policy);
-
- NetworkTemplate[] templates;
- if (policy.subscriberIds == null || policy.subscriberIds.length == 0) {
- templates = new NetworkTemplate[1];
- templates[0] = createTemplate(policy.networkType, null /* subscriberId */);
- } else {
- templates = new NetworkTemplate[policy.subscriberIds.length];
- for (int i = 0; i < policy.subscriberIds.length; i++) {
- templates[i] = createTemplate(policy.networkType, policy.subscriberIds[i]);
- }
+ if (DBG) {
+ Log.d(TAG, "registerUsageCallback called with: {"
+ + " networkType=" + networkType
+ + " subscriberId=" + subscriberId
+ + " thresholdBytes=" + thresholdBytes
+ + " }");
}
+
+ NetworkTemplate template = createTemplate(networkType, subscriberId);
DataUsageRequest request = new DataUsageRequest(DataUsageRequest.REQUEST_ID_UNSET,
- templates, policy.uids, policy.thresholdInBytes);
+ template, thresholdBytes);
try {
- CallbackHandler callbackHandler = new CallbackHandler(looper, callback);
- callback.request = mService.registerDataUsageCallback(
+ 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, "registerDataUsageCallback returned " + callback.request);
+ 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();
}
}
/**
* Unregisters callbacks on data usage.
*
- * @param callback The {@link DataUsageCallback} used when registering.
+ * @param callback The {@link UsageCallback} used when registering.
*/
- public void unregisterDataUsageCallback(DataUsageCallback callback) {
+ public void unregisterUsageCallback(UsageCallback callback) {
if (callback == null || callback.request == null
|| callback.request.requestId == DataUsageRequest.REQUEST_ID_UNSET) {
- throw new IllegalArgumentException("Invalid DataUsageCallback");
+ throw new IllegalArgumentException("Invalid UsageCallback");
}
try {
- mService.unregisterDataUsageRequest(callback.request);
+ mService.unregisterUsageRequest(callback.request);
} catch (RemoteException e) {
if (DBG) Log.d(TAG, "Remote exception when unregistering callback");
+ throw e.rethrowFromSystemServer();
}
}
- /**
- * Base class for data usage callbacks. Should be extended by applications wanting
- * notifications.
- */
- public static class DataUsageCallback {
- /**
- * Called when data usage has reached the given policy threshold.
- */
+ /** @removed */
+ public static abstract class DataUsageCallback {
+ /** @removed */
+ @Deprecated
public void onLimitReached() {}
+ }
+ /**
+ * Base class for usage callbacks. Should be extended by applications wanting notifications.
+ */
+ public static abstract class UsageCallback {
+
+ /**
+ * Called when data usage has reached the given threshold.
+ */
+ public abstract void onThresholdReached(int networkType, String subscriberId);
+
+ /**
+ * @hide used for internal bookkeeping
+ */
private DataUsageRequest request;
}
@@ -414,18 +429,24 @@
template = NetworkTemplate.buildTemplateWifiWildcard();
} break;
default: {
- Log.w(TAG, "Cannot create template for network type " + networkType
- + ", subscriberId '" + NetworkIdentity.scrubSubscriberId(subscriberId) +
- "'.");
+ throw new IllegalArgumentException("Cannot create template for network type "
+ + networkType + ", subscriberId '"
+ + NetworkIdentity.scrubSubscriberId(subscriberId) + "'.");
}
}
return template;
}
private static class CallbackHandler extends Handler {
- private DataUsageCallback mCallback;
- CallbackHandler(Looper looper, DataUsageCallback callback) {
+ private final int mNetworkType;
+ private final String mSubscriberId;
+ private UsageCallback mCallback;
+
+ CallbackHandler(Looper looper, int networkType, String subscriberId,
+ UsageCallback callback) {
super(looper);
+ mNetworkType = networkType;
+ mSubscriberId = subscriberId;
mCallback = callback;
}
@@ -437,7 +458,7 @@
switch (message.what) {
case CALLBACK_LIMIT_REACHED: {
if (mCallback != null) {
- mCallback.onLimitReached();
+ mCallback.onThresholdReached(mNetworkType, mSubscriberId);
} else {
Log.e(TAG, "limit reached with released callback for " + request);
}