Merge "Handle non IPv6 packet in getRaPios" into main
diff --git a/staticlibs/device/com/android/net/module/util/TimerFileDescriptor.java b/staticlibs/device/com/android/net/module/util/TimerFileDescriptor.java
index 5a16de6..dbbccc5 100644
--- a/staticlibs/device/com/android/net/module/util/TimerFileDescriptor.java
+++ b/staticlibs/device/com/android/net/module/util/TimerFileDescriptor.java
@@ -21,6 +21,7 @@
import android.os.Handler;
import android.os.Looper;
+import android.os.Message;
import android.os.MessageQueue;
import android.os.ParcelFileDescriptor;
import android.util.CloseGuard;
@@ -69,7 +70,61 @@
private final ParcelFileDescriptor mParcelFileDescriptor;
private final int mFdInt;
@Nullable
- private Runnable mTask;
+ private ITask mTask;
+
+ /**
+ * An interface for defining tasks that can be executed using a {@link Handler}.
+ */
+ public interface ITask {
+ /**
+ * Executes the task using the provided {@link Handler}.
+ *
+ * @param handler The {@link Handler} to use for executing the task.
+ */
+ void post(Handler handler);
+ }
+
+ /**
+ * A task that sends a {@link Message} using a {@link Handler}.
+ */
+ public static class MessageTask implements ITask {
+ private final Message mMessage;
+
+ public MessageTask(Message message) {
+ mMessage = message;
+ }
+
+ /**
+ * Sends the {@link Message} using the provided {@link Handler}.
+ *
+ * @param handler The {@link Handler} to use for sending the message.
+ */
+ @Override
+ public void post(Handler handler) {
+ handler.sendMessage(mMessage);
+ }
+ }
+
+ /**
+ * A task that posts a {@link Runnable} to a {@link Handler}.
+ */
+ public static class RunnableTask implements ITask {
+ private final Runnable mRunnable;
+
+ public RunnableTask(Runnable runnable) {
+ mRunnable = runnable;
+ }
+
+ /**
+ * Posts the {@link Runnable} to the provided {@link Handler}.
+ *
+ * @param handler The {@link Handler} to use for posting the runnable.
+ */
+ @Override
+ public void post(Handler handler) {
+ handler.post(mRunnable);
+ }
+ }
/**
* TimerFileDescriptor constructor
@@ -98,13 +153,13 @@
* @throws IllegalArgumentException if try to replace the current scheduled task
* @throws IllegalArgumentException if the delay time is less than 0
*/
- public void setDelayedTask(@NonNull Runnable task, long delayMs) {
+ public void setDelayedTask(@NonNull ITask task, long delayMs) {
ensureRunningOnCorrectThread();
if (mTask != null) {
throw new IllegalArgumentException("task is already scheduled");
}
if (delayMs <= 0L) {
- mHandler.post(task);
+ task.post(mHandler);
return;
}
@@ -163,7 +218,7 @@
private void handleExpiration() {
// Execute the task
if (mTask != null) {
- mTask.run();
+ mTask.post(mHandler);
mTask = null;
}
}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/TimerFileDescriptorTest.kt b/staticlibs/tests/unit/src/com/android/net/module/util/TimerFileDescriptorTest.kt
index 2018902..f5e47c9 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/TimerFileDescriptorTest.kt
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/TimerFileDescriptorTest.kt
@@ -20,7 +20,12 @@
import android.os.ConditionVariable
import android.os.Handler
import android.os.HandlerThread
+import android.os.Looper
+import android.os.Message
import androidx.test.filters.SmallTest
+import com.android.net.module.util.TimerFileDescriptor.ITask
+import com.android.net.module.util.TimerFileDescriptor.MessageTask
+import com.android.net.module.util.TimerFileDescriptor.RunnableTask
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import com.android.testutils.tryTest
@@ -33,13 +38,21 @@
import kotlin.test.assertFalse
import kotlin.test.assertTrue
+private const val MSG_TEST = 1
+
@DevSdkIgnoreRunner.MonitorThreadLeak
@RunWith(DevSdkIgnoreRunner::class)
@SmallTest
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
class TimerFileDescriptorTest {
+ private class TestHandler(looper: Looper) : Handler(looper) {
+ override fun handleMessage(msg: Message) {
+ val cv = msg.obj as ConditionVariable
+ cv.open()
+ }
+ }
private val thread = HandlerThread(TimerFileDescriptorTest::class.simpleName).apply { start() }
- private val handler by lazy { Handler(thread.looper) }
+ private val handler by lazy { TestHandler(thread.looper) }
@After
fun tearDown() {
@@ -47,18 +60,33 @@
thread.join()
}
+ private fun assertDelayedTaskPost(
+ timerFd: TimerFileDescriptor,
+ task: ITask,
+ cv: ConditionVariable
+ ) {
+ val delayTime = 10L
+ val startTime1 = Instant.now()
+ handler.post { timerFd.setDelayedTask(task, delayTime) }
+ assertTrue(cv.block(100L /* timeoutMs*/))
+ assertTrue(Duration.between(startTime1, Instant.now()).toMillis() >= delayTime)
+ }
+
@Test
fun testSetDelayedTask() {
- val delayTime = 10L
val timerFd = TimerFileDescriptor(handler)
- val cv = ConditionVariable()
- val startTime = Instant.now()
tryTest {
- handler.post { timerFd.setDelayedTask({ cv.open() }, delayTime) }
- assertTrue(cv.block(100L /* timeoutMs*/))
- // Verify that the delay time has actually passed.
- val duration = Duration.between(startTime, Instant.now())
- assertTrue(duration.toMillis() >= delayTime)
+ // Verify the delayed task is executed with the self-implemented ITask
+ val cv1 = ConditionVariable()
+ assertDelayedTaskPost(timerFd, { cv1.open() }, cv1)
+
+ // Verify the delayed task is executed with the RunnableTask
+ val cv2 = ConditionVariable()
+ assertDelayedTaskPost(timerFd, RunnableTask{ cv2.open() }, cv2)
+
+ // Verify the delayed task is executed with the MessageTask
+ val cv3 = ConditionVariable()
+ assertDelayedTaskPost(timerFd, MessageTask(handler.obtainMessage(MSG_TEST, cv3)), cv3)
} cleanup {
visibleOnHandlerThread(handler) { timerFd.close() }
}
diff --git a/staticlibs/testutils/host/python/tether_utils.py b/staticlibs/testutils/host/python/tether_utils.py
index 702b596..c63de1f 100644
--- a/staticlibs/testutils/host/python/tether_utils.py
+++ b/staticlibs/testutils/host/python/tether_utils.py
@@ -108,3 +108,6 @@
server.unregisterAll()
# Teardown the hotspot.
server.stopAllTethering()
+ # Some test cases would disable wifi, e.g. cellular upstream tests.
+ # Reconnect to it if feasible.
+ server.reconnectWifiIfSupported()
diff --git a/tests/cts/multidevices/snippet/ConnectivityMultiDevicesSnippet.kt b/tests/cts/multidevices/snippet/ConnectivityMultiDevicesSnippet.kt
index 49688cc..6da7e9a 100644
--- a/tests/cts/multidevices/snippet/ConnectivityMultiDevicesSnippet.kt
+++ b/tests/cts/multidevices/snippet/ConnectivityMultiDevicesSnippet.kt
@@ -89,6 +89,11 @@
ctsNetUtils.expectNetworkIsSystemDefault(network)
}
+ @Rpc(description = "Reconnect to wifi if supported.")
+ fun reconnectWifiIfSupported() {
+ ctsNetUtils.reconnectWifiIfSupported()
+ }
+
@Rpc(description = "Unregister all connections.")
fun unregisterAll() {
cbHelper.unregisterAll()
diff --git a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
index 30d5a02..c55096b 100644
--- a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
+++ b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
@@ -351,14 +351,14 @@
}
otDaemon.initialize(
- mTunIfController.getTunFd(),
shouldEnableThread(),
newOtDaemonConfig(mPersistentSettings.getConfiguration()),
+ mTunIfController.getTunFd(),
mNsdPublisher,
getMeshcopTxtAttributes(mResources.get()),
- mOtDaemonCallbackProxy,
mCountryCodeSupplier.get(),
- FeatureFlags.isTrelEnabled());
+ FeatureFlags.isTrelEnabled(),
+ mOtDaemonCallbackProxy);
otDaemon.asBinder().linkToDeath(() -> mHandler.post(this::onOtDaemonDied), 0);
mOtDaemon = otDaemon;
mHandler.post(mNat64CidrController::maybeUpdateNat64Cidr);
diff --git a/thread/tests/integration/src/android/net/thread/BorderRoutingTest.java b/thread/tests/integration/src/android/net/thread/BorderRoutingTest.java
index aeeed65..875a4ad 100644
--- a/thread/tests/integration/src/android/net/thread/BorderRoutingTest.java
+++ b/thread/tests/integration/src/android/net/thread/BorderRoutingTest.java
@@ -16,7 +16,6 @@
package android.net.thread;
-import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
import static android.net.InetAddresses.parseNumericAddress;
import static android.net.thread.utils.IntegrationTestUtils.DEFAULT_DATASET;
import static android.net.thread.utils.IntegrationTestUtils.buildIcmpv4EchoReply;
@@ -38,7 +37,6 @@
import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ECHO_REPLY_TYPE;
import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE;
-import static com.android.testutils.TestPermissionUtil.runAsShell;
import static com.google.common.truth.Truth.assertThat;
@@ -56,7 +54,6 @@
import android.net.RouteInfo;
import android.net.thread.utils.FullThreadDevice;
import android.net.thread.utils.InfraNetworkDevice;
-import android.net.thread.utils.IntegrationTestUtils;
import android.net.thread.utils.OtDaemonController;
import android.net.thread.utils.TestTunNetworkUtils;
import android.net.thread.utils.ThreadFeatureCheckerRule;