Merge "Add support for app data accounting for in-kernel dataplanes"
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index fe99f85..8a6c85d 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -48,6 +48,7 @@
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.DataUnit;
import android.util.Log;
@@ -214,6 +215,10 @@
* null} value when querying for the mobile network type to receive usage
* for all mobile networks. For additional details see {@link
* TelephonyManager#getSubscriberId()}.
+ * <p>Starting with API level 31, calling apps can provide a
+ * {@code subscriberId} with wifi network type to receive usage for
+ * wifi networks which is under the given subscription if applicable.
+ * Otherwise, pass {@code null} when querying all wifi networks.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -255,6 +260,10 @@
* null} value when querying for the mobile network type to receive usage
* for all mobile networks. For additional details see {@link
* TelephonyManager#getSubscriberId()}.
+ * <p>Starting with API level 31, calling apps can provide a
+ * {@code subscriberId} with wifi network type to receive usage for
+ * wifi networks which is under the given subscription if applicable.
+ * Otherwise, pass {@code null} when querying all wifi networks.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -300,6 +309,10 @@
* null} value when querying for the mobile network type to receive usage
* for all mobile networks. For additional details see {@link
* TelephonyManager#getSubscriberId()}.
+ * <p>Starting with API level 31, calling apps can provide a
+ * {@code subscriberId} with wifi network type to receive usage for
+ * wifi networks which is under the given subscription if applicable.
+ * Otherwise, pass {@code null} when querying all wifi networks.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -388,6 +401,10 @@
* null} value when querying for the mobile network type to receive usage
* for all mobile networks. For additional details see {@link
* TelephonyManager#getSubscriberId()}.
+ * <p>Starting with API level 31, calling apps can provide a
+ * {@code subscriberId} with wifi network type to receive usage for
+ * wifi networks which is under the given subscription if applicable.
+ * Otherwise, pass {@code null} when querying all wifi networks.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -450,6 +467,10 @@
* null} value when querying for the mobile network type to receive usage
* for all mobile networks. For additional details see {@link
* TelephonyManager#getSubscriberId()}.
+ * <p>Starting with API level 31, calling apps can provide a
+ * {@code subscriberId} with wifi network type to receive usage for
+ * wifi networks which is under the given subscription if applicable.
+ * Otherwise, pass {@code null} when querying all wifi networks.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -531,6 +552,10 @@
* null} value when registering for the mobile network type to receive
* notifications for all mobile networks. For additional details see {@link
* TelephonyManager#getSubscriberId()}.
+ * <p>Starting with API level 31, calling apps can provide a
+ * {@code subscriberId} with wifi network type to receive usage for
+ * wifi networks which is under the given subscription if applicable.
+ * Otherwise, pass {@code null} when querying all wifi networks.
* @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.
@@ -644,7 +669,7 @@
: NetworkTemplate.buildTemplateMobileAll(subscriberId);
break;
case ConnectivityManager.TYPE_WIFI:
- template = subscriberId == null
+ template = TextUtils.isEmpty(subscriberId)
? NetworkTemplate.buildTemplateWifiWildcard()
: NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
subscriberId);
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index 352f2e9..68917a8 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -514,6 +514,10 @@
return mSubscriberIdMatchRule;
}
+ public int getMeteredness() {
+ return mMetered;
+ }
+
/**
* Test if given {@link NetworkIdentity} matches this template.
*/
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index 64f20b8..5a25cfc 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -200,6 +200,9 @@
public static final int RESOLVE_SERVICE_SUCCEEDED = BASE + 20;
/** @hide */
+ public static final int DAEMON_CLEANUP = BASE + 21;
+
+ /** @hide */
public static final int ENABLE = BASE + 24;
/** @hide */
public static final int DISABLE = BASE + 25;
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index d907505..a9f3a1b 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -61,6 +61,7 @@
private static final String MDNS_TAG = "mDnsConnector";
private static final boolean DBG = true;
+ private static final long CLEANUP_DELAY_MS = 10000;
private final Context mContext;
private final NsdSettings mNsdSettings;
@@ -77,6 +78,7 @@
private final SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<>();
private final AsyncChannel mReplyChannel = new AsyncChannel();
+ private final long mCleanupDelayMs;
private static final int INVALID_ID = 0;
private int mUniqueId = 1;
@@ -92,6 +94,28 @@
return NsdManager.nameOf(what);
}
+ private void maybeStartDaemon() {
+ mDaemon.maybeStart();
+ maybeScheduleStop();
+ }
+
+ private boolean isAnyRequestActive() {
+ return mIdToClientInfoMap.size() != 0;
+ }
+
+ private void scheduleStop() {
+ sendMessageDelayed(NsdManager.DAEMON_CLEANUP, mCleanupDelayMs);
+ }
+ private void maybeScheduleStop() {
+ if (!isAnyRequestActive()) {
+ scheduleStop();
+ }
+ }
+
+ private void cancelStop() {
+ this.removeMessages(NsdManager.DAEMON_CLEANUP);
+ }
+
/**
* Observes the NSD on/off setting, and takes action when changed.
*/
@@ -146,6 +170,7 @@
if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
break;
}
+
cInfo = mClients.get(msg.replyTo);
if (cInfo != null) {
cInfo.expungeAllRequests();
@@ -153,7 +178,7 @@
}
//Last client
if (mClients.size() == 0) {
- mDaemon.stop();
+ scheduleStop();
}
break;
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
@@ -180,6 +205,9 @@
replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
NsdManager.FAILURE_INTERNAL_ERROR);
break;
+ case NsdManager.DAEMON_CLEANUP:
+ mDaemon.maybeStop();
+ break;
case NsdManager.NATIVE_DAEMON_EVENT:
default:
Slog.e(TAG, "Unhandled " + msg);
@@ -212,16 +240,13 @@
@Override
public void enter() {
sendNsdStateChangeBroadcast(true);
- if (mClients.size() > 0) {
- mDaemon.start();
- }
}
@Override
public void exit() {
- if (mClients.size() > 0) {
- mDaemon.stop();
- }
+ // TODO: it is incorrect to stop the daemon without expunging all requests
+ // and sending error callbacks to clients.
+ scheduleStop();
}
private boolean requestLimitReached(ClientInfo clientInfo) {
@@ -236,12 +261,15 @@
clientInfo.mClientIds.put(clientId, globalId);
clientInfo.mClientRequests.put(clientId, what);
mIdToClientInfoMap.put(globalId, clientInfo);
+ // Remove the cleanup event because here comes a new request.
+ cancelStop();
}
private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
clientInfo.mClientIds.delete(clientId);
clientInfo.mClientRequests.delete(clientId);
mIdToClientInfoMap.remove(globalId);
+ maybeScheduleStop();
}
@Override
@@ -251,11 +279,6 @@
int id;
switch (msg.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
- //First client
- if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL &&
- mClients.size() == 0) {
- mDaemon.start();
- }
return NOT_HANDLED;
case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
return NOT_HANDLED;
@@ -274,6 +297,7 @@
break;
}
+ maybeStartDaemon();
id = getUniqueId();
if (discoverServices(id, servInfo.getServiceType())) {
if (DBG) {
@@ -316,6 +340,7 @@
break;
}
+ maybeStartDaemon();
id = getUniqueId();
if (registerService(id, (NsdServiceInfo) msg.obj)) {
if (DBG) Slog.d(TAG, "Register " + msg.arg2 + " " + id);
@@ -357,6 +382,7 @@
break;
}
+ maybeStartDaemon();
id = getUniqueId();
if (resolveService(id, servInfo)) {
clientInfo.mResolvedService = new NsdServiceInfo();
@@ -538,7 +564,9 @@
}
@VisibleForTesting
- NsdService(Context ctx, NsdSettings settings, Handler handler, DaemonConnectionSupplier fn) {
+ NsdService(Context ctx, NsdSettings settings, Handler handler,
+ DaemonConnectionSupplier fn, long cleanupDelayMs) {
+ mCleanupDelayMs = cleanupDelayMs;
mContext = ctx;
mNsdSettings = settings;
mNsdStateMachine = new NsdStateMachine(TAG, handler);
@@ -552,7 +580,8 @@
HandlerThread thread = new HandlerThread(TAG);
thread.start();
Handler handler = new Handler(thread.getLooper());
- NsdService service = new NsdService(context, settings, handler, DaemonConnection::new);
+ NsdService service = new NsdService(context, settings, handler,
+ DaemonConnection::new, CLEANUP_DELAY_MS);
service.mDaemonCallback.awaitConnection();
return service;
}
@@ -681,12 +710,16 @@
@VisibleForTesting
public static class DaemonConnection {
final NativeDaemonConnector mNativeConnector;
+ boolean mIsStarted = false;
DaemonConnection(NativeCallbackReceiver callback) {
mNativeConnector = new NativeDaemonConnector(callback, "mdns", 10, MDNS_TAG, 25, null);
new Thread(mNativeConnector, MDNS_TAG).start();
}
+ /**
+ * Executes the specified cmd on the daemon.
+ */
public boolean execute(Object... args) {
if (DBG) {
Slog.d(TAG, "mdnssd " + Arrays.toString(args));
@@ -700,12 +733,26 @@
return true;
}
- public void start() {
+ /**
+ * Starts the daemon if it is not already started.
+ */
+ public void maybeStart() {
+ if (mIsStarted) {
+ return;
+ }
execute("start-service");
+ mIsStarted = true;
}
- public void stop() {
+ /**
+ * Stops the daemon if it is started.
+ */
+ public void maybeStop() {
+ if (!mIsStarted) {
+ return;
+ }
execute("stop-service");
+ mIsStarted = false;
}
}