Reapply "Add a queue system server-side for NetworkAgent"
Now that faulty Telephony tests have been disabled temporarily
to allow for this bugfix, this can be reverted.
This reverts commit a5ec9b41128ad926475116b184d71b34740fd6f1.
Test: FrameworksTelephonyTests CtsNetTestCases
Change-Id: I71abf9d02bdd34a4de80157a3f42bdfee6f6617e
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 85c4328..a95d95c 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -527,6 +527,7 @@
private final boolean mBackgroundFirewallChainEnabled;
private final boolean mUseDeclaredMethodsForCallbacksEnabled;
+ private final boolean mQueueNetworkAgentEventsInSystemServer;
// Flag to delay callbacks for frozen apps, suppressing duplicate and stale callbacks.
private final boolean mQueueCallbacksForFrozenApps;
@@ -1929,6 +1930,9 @@
mUseDeclaredMethodsForCallbacksEnabled =
mDeps.isFeatureNotChickenedOut(context,
ConnectivityFlags.USE_DECLARED_METHODS_FOR_CALLBACKS);
+ mQueueNetworkAgentEventsInSystemServer =
+ mDeps.isFeatureNotChickenedOut(context,
+ ConnectivityFlags.QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER);
// registerUidFrozenStateChangedCallback is only available on U+
mQueueCallbacksForFrozenApps = mDeps.isAtLeastU()
&& mDeps.isFeatureNotChickenedOut(context, QUEUE_CALLBACKS_FOR_FROZEN_APPS);
@@ -4689,18 +4693,30 @@
private void maybeHandleNetworkAgentMessage(Message msg) {
final Pair<NetworkAgentInfo, Object> arg = (Pair<NetworkAgentInfo, Object>) msg.obj;
final NetworkAgentInfo nai = arg.first;
- if (!mNetworkAgentInfos.contains(nai)) {
- if (VDBG) {
- log(String.format("%s from unknown NetworkAgent", eventName(msg.what)));
- }
- return;
- }
// If the network has been destroyed, the only thing that it can do is disconnect.
if (nai.isDestroyed() && !isDisconnectRequest(msg)) {
return;
}
+ if (mQueueNetworkAgentEventsInSystemServer && nai.maybeEnqueueMessage(msg)) {
+ // If the message is enqueued, the NAI will replay it immediately
+ // when registration is complete. It does this by sending all the
+ // messages in the order received immediately after the
+ // EVENT_AGENT_REGISTERED message.
+ return;
+ }
+
+ // If the nai has been registered (and doesn't enqueue), it should now be
+ // in the list of NAIs.
+ if (!mNetworkAgentInfos.contains(nai)) {
+ // TODO : this is supposed to be impossible
+ if (VDBG) {
+ log(String.format("%s from unknown NetworkAgent", eventName(msg.what)));
+ }
+ return;
+ }
+
switch (msg.what) {
case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
final NetworkCapabilities proposed = (NetworkCapabilities) arg.second;
diff --git a/service/src/com/android/server/connectivity/ConnectivityFlags.java b/service/src/com/android/server/connectivity/ConnectivityFlags.java
index 136ea81..74bd235 100644
--- a/service/src/com/android/server/connectivity/ConnectivityFlags.java
+++ b/service/src/com/android/server/connectivity/ConnectivityFlags.java
@@ -62,6 +62,9 @@
public static final String QUEUE_CALLBACKS_FOR_FROZEN_APPS =
"queue_callbacks_for_frozen_apps";
+ public static final String QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER =
+ "queue_network_agent_events_in_system_server";
+
private boolean mNoRematchAllRequestsOnRegister;
/**
diff --git a/service/src/com/android/server/connectivity/NetworkAgentInfo.java b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
index 6d25d63..4540f02 100644
--- a/service/src/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
@@ -62,6 +62,7 @@
import android.net.TcpKeepalivePacketData;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.os.SystemClock;
@@ -630,6 +631,7 @@
// Used by ConnectivityService to keep track of 464xlat.
public final Nat464Xlat clatd;
+ private final ArrayList<Message> mMessagesPendingRegistration = new ArrayList<>();
// Set after asynchronous creation of the NetworkMonitor.
private volatile NetworkMonitorManager mNetworkMonitor;
@@ -715,6 +717,29 @@
}
mHandler.obtainMessage(EVENT_AGENT_REGISTERED, ARG_AGENT_SUCCESS, 0, this).sendToTarget();
+ for (final Message enqueued : mMessagesPendingRegistration) {
+ mHandler.sendMessage(enqueued);
+ }
+ mMessagesPendingRegistration.clear();
+ }
+
+ /**
+ * Enqueues a message if it needs to be enqueued, and returns whether it was enqueued.
+ *
+ * The message is enqueued iff it can't be sent just yet. If it can be sent
+ * immediately, this method returns false and doesn't enqueue.
+ *
+ * If it enqueues, this method will make a copy of the message for enqueuing since
+ * messages can't be reused or recycled before the end of their processing by the
+ * handler.
+ */
+ public boolean maybeEnqueueMessage(final Message msg) {
+ HandlerUtils.ensureRunningOnHandlerThread(mHandler);
+ if (null != mNetworkMonitor) return false;
+ final Message m = mHandler.obtainMessage();
+ m.copyFrom(msg);
+ mMessagesPendingRegistration.add(m);
+ return true;
}
/**
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index c28a0f8..3eefa0f 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -2200,6 +2200,7 @@
case ConnectivityFlags.DELAY_DESTROY_SOCKETS:
case ConnectivityFlags.USE_DECLARED_METHODS_FOR_CALLBACKS:
case ConnectivityFlags.QUEUE_CALLBACKS_FOR_FROZEN_APPS:
+ case ConnectivityFlags.QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER:
return true;
default:
throw new UnsupportedOperationException("Unknown flag " + name
diff --git a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt
index d7e781e..48333c5 100644
--- a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt
+++ b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt
@@ -169,6 +169,7 @@
it[ConnectivityFlags.DELAY_DESTROY_SOCKETS] = true
it[ConnectivityFlags.USE_DECLARED_METHODS_FOR_CALLBACKS] = true
it[ConnectivityFlags.QUEUE_CALLBACKS_FOR_FROZEN_APPS] = true
+ it[ConnectivityFlags.QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER] = true
}
fun setFeatureEnabled(flag: String, enabled: Boolean) = enabledFeatures.set(flag, enabled)