From bbd573b92f0c67cb76ca1a68d52d77423aeab989 Mon Sep 17 00:00:00 2001 From: Yuyang Huang Date: Mon, 24 Jul 2023 18:30:42 +0900 Subject: [PATCH] Move QueryTaskConfig to a standalone class Bug: 292470176 Test: atest FrameworksNetTests CtsNetTestCases Change-Id: Iff15e7b59277444bbaa92b98318bb4f910eea070 --- .../mdns/MdnsServiceTypeClient.java | 140 -------------- .../connectivity/mdns/QueryTaskConfig.java | 172 ++++++++++++++++++ .../mdns/MdnsServiceTypeClientTests.java | 1 - 3 files changed, 172 insertions(+), 141 deletions(-) create mode 100644 service-t/src/com/android/server/connectivity/mdns/QueryTaskConfig.java diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java index 0752c014a7..b2e6fa516e 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java @@ -39,7 +39,6 @@ import java.net.Inet4Address; import java.net.Inet6Address; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -538,145 +537,6 @@ public class MdnsServiceTypeClient { return new MdnsPacketWriter(DEFAULT_MTU); } - // A configuration for the PeriodicalQueryTask that contains parameters to build a query packet. - // Call to getConfigForNextRun returns a config that can be used to build the next query task. - @VisibleForTesting - static class QueryTaskConfig { - - private static final int INITIAL_TIME_BETWEEN_BURSTS_MS = - (int) MdnsConfigs.initialTimeBetweenBurstsMs(); - private static final int TIME_BETWEEN_BURSTS_MS = (int) MdnsConfigs.timeBetweenBurstsMs(); - private static final int QUERIES_PER_BURST = (int) MdnsConfigs.queriesPerBurst(); - private static final int TIME_BETWEEN_QUERIES_IN_BURST_MS = - (int) MdnsConfigs.timeBetweenQueriesInBurstMs(); - private static final int QUERIES_PER_BURST_PASSIVE_MODE = - (int) MdnsConfigs.queriesPerBurstPassive(); - private static final int UNSIGNED_SHORT_MAX_VALUE = 65536; - // The following fields are used by QueryTask so we need to test them. - @VisibleForTesting - final List subtypes; - private final boolean alwaysAskForUnicastResponse = - MdnsConfigs.alwaysAskForUnicastResponseInEachBurst(); - private final boolean usePassiveMode; - private final boolean onlyUseIpv6OnIpv6OnlyNetworks; - private final int numOfQueriesBeforeBackoff; - @VisibleForTesting - final int transactionId; - @VisibleForTesting - final boolean expectUnicastResponse; - private final int queriesPerBurst; - private final int timeBetweenBurstsInMs; - private final int burstCounter; - private final long delayUntilNextTaskWithoutBackoffMs; - private final boolean isFirstBurst; - private final long queryCount; - @NonNull private final SocketKey socketKey; - - - QueryTaskConfig(@NonNull QueryTaskConfig other, long queryCount, int transactionId, - boolean expectUnicastResponse, boolean isFirstBurst, int burstCounter, - int queriesPerBurst, int timeBetweenBurstsInMs, - long delayUntilNextTaskWithoutBackoffMs) { - this.subtypes = new ArrayList<>(other.subtypes); - this.usePassiveMode = other.usePassiveMode; - this.onlyUseIpv6OnIpv6OnlyNetworks = other.onlyUseIpv6OnIpv6OnlyNetworks; - this.numOfQueriesBeforeBackoff = other.numOfQueriesBeforeBackoff; - this.transactionId = transactionId; - this.expectUnicastResponse = expectUnicastResponse; - this.queriesPerBurst = queriesPerBurst; - this.timeBetweenBurstsInMs = timeBetweenBurstsInMs; - this.burstCounter = burstCounter; - this.delayUntilNextTaskWithoutBackoffMs = delayUntilNextTaskWithoutBackoffMs; - this.isFirstBurst = isFirstBurst; - this.queryCount = queryCount; - this.socketKey = other.socketKey; - } - QueryTaskConfig(@NonNull Collection subtypes, - boolean usePassiveMode, - boolean onlyUseIpv6OnIpv6OnlyNetworks, - int numOfQueriesBeforeBackoff, - @Nullable SocketKey socketKey) { - this.usePassiveMode = usePassiveMode; - this.onlyUseIpv6OnIpv6OnlyNetworks = onlyUseIpv6OnIpv6OnlyNetworks; - this.numOfQueriesBeforeBackoff = numOfQueriesBeforeBackoff; - this.subtypes = new ArrayList<>(subtypes); - this.queriesPerBurst = QUERIES_PER_BURST; - this.burstCounter = 0; - this.transactionId = 1; - this.expectUnicastResponse = true; - this.isFirstBurst = true; - // Config the scan frequency based on the scan mode. - if (this.usePassiveMode) { - // In passive scan mode, sends a single burst of QUERIES_PER_BURST queries, and then - // in each TIME_BETWEEN_BURSTS interval, sends QUERIES_PER_BURST_PASSIVE_MODE - // queries. - this.timeBetweenBurstsInMs = TIME_BETWEEN_BURSTS_MS; - } else { - // In active scan mode, sends a burst of QUERIES_PER_BURST queries, - // TIME_BETWEEN_QUERIES_IN_BURST_MS apart, then waits for the scan interval, and - // then repeats. The scan interval starts as INITIAL_TIME_BETWEEN_BURSTS_MS and - // doubles until it maxes out at TIME_BETWEEN_BURSTS_MS. - this.timeBetweenBurstsInMs = INITIAL_TIME_BETWEEN_BURSTS_MS; - } - this.socketKey = socketKey; - this.queryCount = 0; - this.delayUntilNextTaskWithoutBackoffMs = TIME_BETWEEN_QUERIES_IN_BURST_MS; - } - - QueryTaskConfig getConfigForNextRun() { - long newQueryCount = queryCount + 1; - int newTransactionId = transactionId + 1; - if (newTransactionId > UNSIGNED_SHORT_MAX_VALUE) { - newTransactionId = 1; - } - boolean newExpectUnicastResponse = false; - boolean newIsFirstBurst = isFirstBurst; - int newQueriesPerBurst = queriesPerBurst; - int newBurstCounter = burstCounter + 1; - long newDelayUntilNextTaskWithoutBackoffMs = delayUntilNextTaskWithoutBackoffMs; - int newTimeBetweenBurstsInMs = timeBetweenBurstsInMs; - // Only the first query expects uni-cast response. - if (newBurstCounter == queriesPerBurst) { - newBurstCounter = 0; - - if (alwaysAskForUnicastResponse) { - newExpectUnicastResponse = true; - } - // In passive scan mode, sends a single burst of QUERIES_PER_BURST queries, and - // then in each TIME_BETWEEN_BURSTS interval, sends QUERIES_PER_BURST_PASSIVE_MODE - // queries. - if (isFirstBurst) { - newIsFirstBurst = false; - if (usePassiveMode) { - newQueriesPerBurst = QUERIES_PER_BURST_PASSIVE_MODE; - } - } - // In active scan mode, sends a burst of QUERIES_PER_BURST queries, - // TIME_BETWEEN_QUERIES_IN_BURST_MS apart, then waits for the scan interval, and - // then repeats. The scan interval starts as INITIAL_TIME_BETWEEN_BURSTS_MS and - // doubles until it maxes out at TIME_BETWEEN_BURSTS_MS. - newDelayUntilNextTaskWithoutBackoffMs = timeBetweenBurstsInMs; - if (timeBetweenBurstsInMs < TIME_BETWEEN_BURSTS_MS) { - newTimeBetweenBurstsInMs = Math.min(timeBetweenBurstsInMs * 2, - TIME_BETWEEN_BURSTS_MS); - } - } else { - newDelayUntilNextTaskWithoutBackoffMs = TIME_BETWEEN_QUERIES_IN_BURST_MS; - } - return new QueryTaskConfig(this, newQueryCount, newTransactionId, - newExpectUnicastResponse, newIsFirstBurst, newBurstCounter, newQueriesPerBurst, - newTimeBetweenBurstsInMs, newDelayUntilNextTaskWithoutBackoffMs); - } - - private boolean shouldUseQueryBackoff() { - // Don't enable backoff mode during the burst or in the first burst - if (burstCounter != 0 || isFirstBurst) { - return false; - } - return queryCount > numOfQueriesBeforeBackoff; - } - } - private List makeResponsesForResolve(@NonNull SocketKey socketKey) { final List resolveResponses = new ArrayList<>(); for (int i = 0; i < listeners.size(); i++) { diff --git a/service-t/src/com/android/server/connectivity/mdns/QueryTaskConfig.java b/service-t/src/com/android/server/connectivity/mdns/QueryTaskConfig.java new file mode 100644 index 0000000000..19282b074c --- /dev/null +++ b/service-t/src/com/android/server/connectivity/mdns/QueryTaskConfig.java @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.connectivity.mdns; + +import android.annotation.NonNull; +import android.annotation.Nullable; + +import com.android.internal.annotations.VisibleForTesting; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * A configuration for the PeriodicalQueryTask that contains parameters to build a query packet. + * Call to getConfigForNextRun returns a config that can be used to build the next query task. + */ +public class QueryTaskConfig { + + private static final int INITIAL_TIME_BETWEEN_BURSTS_MS = + (int) MdnsConfigs.initialTimeBetweenBurstsMs(); + private static final int TIME_BETWEEN_BURSTS_MS = (int) MdnsConfigs.timeBetweenBurstsMs(); + private static final int QUERIES_PER_BURST = (int) MdnsConfigs.queriesPerBurst(); + private static final int TIME_BETWEEN_QUERIES_IN_BURST_MS = + (int) MdnsConfigs.timeBetweenQueriesInBurstMs(); + private static final int QUERIES_PER_BURST_PASSIVE_MODE = + (int) MdnsConfigs.queriesPerBurstPassive(); + private static final int UNSIGNED_SHORT_MAX_VALUE = 65536; + // The following fields are used by QueryTask so we need to test them. + @VisibleForTesting + final List subtypes; + private final boolean alwaysAskForUnicastResponse = + MdnsConfigs.alwaysAskForUnicastResponseInEachBurst(); + private final boolean usePassiveMode; + final boolean onlyUseIpv6OnIpv6OnlyNetworks; + private final int numOfQueriesBeforeBackoff; + @VisibleForTesting + final int transactionId; + @VisibleForTesting + final boolean expectUnicastResponse; + private final int queriesPerBurst; + private final int timeBetweenBurstsInMs; + private final int burstCounter; + final long delayUntilNextTaskWithoutBackoffMs; + private final boolean isFirstBurst; + private final long queryCount; + @NonNull + final SocketKey socketKey; + + QueryTaskConfig(@NonNull QueryTaskConfig other, long queryCount, int transactionId, + boolean expectUnicastResponse, boolean isFirstBurst, int burstCounter, + int queriesPerBurst, int timeBetweenBurstsInMs, + long delayUntilNextTaskWithoutBackoffMs) { + this.subtypes = new ArrayList<>(other.subtypes); + this.usePassiveMode = other.usePassiveMode; + this.onlyUseIpv6OnIpv6OnlyNetworks = other.onlyUseIpv6OnIpv6OnlyNetworks; + this.numOfQueriesBeforeBackoff = other.numOfQueriesBeforeBackoff; + this.transactionId = transactionId; + this.expectUnicastResponse = expectUnicastResponse; + this.queriesPerBurst = queriesPerBurst; + this.timeBetweenBurstsInMs = timeBetweenBurstsInMs; + this.burstCounter = burstCounter; + this.delayUntilNextTaskWithoutBackoffMs = delayUntilNextTaskWithoutBackoffMs; + this.isFirstBurst = isFirstBurst; + this.queryCount = queryCount; + this.socketKey = other.socketKey; + } + QueryTaskConfig(@NonNull Collection subtypes, + boolean usePassiveMode, + boolean onlyUseIpv6OnIpv6OnlyNetworks, + int numOfQueriesBeforeBackoff, + @Nullable SocketKey socketKey) { + this.usePassiveMode = usePassiveMode; + this.onlyUseIpv6OnIpv6OnlyNetworks = onlyUseIpv6OnIpv6OnlyNetworks; + this.numOfQueriesBeforeBackoff = numOfQueriesBeforeBackoff; + this.subtypes = new ArrayList<>(subtypes); + this.queriesPerBurst = QUERIES_PER_BURST; + this.burstCounter = 0; + this.transactionId = 1; + this.expectUnicastResponse = true; + this.isFirstBurst = true; + // Config the scan frequency based on the scan mode. + if (this.usePassiveMode) { + // In passive scan mode, sends a single burst of QUERIES_PER_BURST queries, and then + // in each TIME_BETWEEN_BURSTS interval, sends QUERIES_PER_BURST_PASSIVE_MODE + // queries. + this.timeBetweenBurstsInMs = TIME_BETWEEN_BURSTS_MS; + } else { + // In active scan mode, sends a burst of QUERIES_PER_BURST queries, + // TIME_BETWEEN_QUERIES_IN_BURST_MS apart, then waits for the scan interval, and + // then repeats. The scan interval starts as INITIAL_TIME_BETWEEN_BURSTS_MS and + // doubles until it maxes out at TIME_BETWEEN_BURSTS_MS. + this.timeBetweenBurstsInMs = INITIAL_TIME_BETWEEN_BURSTS_MS; + } + this.socketKey = socketKey; + this.queryCount = 0; + this.delayUntilNextTaskWithoutBackoffMs = TIME_BETWEEN_QUERIES_IN_BURST_MS; + } + + /** + * Get new QueryTaskConfig for next run. + */ + public QueryTaskConfig getConfigForNextRun() { + long newQueryCount = queryCount + 1; + int newTransactionId = transactionId + 1; + if (newTransactionId > UNSIGNED_SHORT_MAX_VALUE) { + newTransactionId = 1; + } + boolean newExpectUnicastResponse = false; + boolean newIsFirstBurst = isFirstBurst; + int newQueriesPerBurst = queriesPerBurst; + int newBurstCounter = burstCounter + 1; + long newDelayUntilNextTaskWithoutBackoffMs = delayUntilNextTaskWithoutBackoffMs; + int newTimeBetweenBurstsInMs = timeBetweenBurstsInMs; + // Only the first query expects uni-cast response. + if (newBurstCounter == queriesPerBurst) { + newBurstCounter = 0; + + if (alwaysAskForUnicastResponse) { + newExpectUnicastResponse = true; + } + // In passive scan mode, sends a single burst of QUERIES_PER_BURST queries, and + // then in each TIME_BETWEEN_BURSTS interval, sends QUERIES_PER_BURST_PASSIVE_MODE + // queries. + if (isFirstBurst) { + newIsFirstBurst = false; + if (usePassiveMode) { + newQueriesPerBurst = QUERIES_PER_BURST_PASSIVE_MODE; + } + } + // In active scan mode, sends a burst of QUERIES_PER_BURST queries, + // TIME_BETWEEN_QUERIES_IN_BURST_MS apart, then waits for the scan interval, and + // then repeats. The scan interval starts as INITIAL_TIME_BETWEEN_BURSTS_MS and + // doubles until it maxes out at TIME_BETWEEN_BURSTS_MS. + newDelayUntilNextTaskWithoutBackoffMs = timeBetweenBurstsInMs; + if (timeBetweenBurstsInMs < TIME_BETWEEN_BURSTS_MS) { + newTimeBetweenBurstsInMs = Math.min(timeBetweenBurstsInMs * 2, + TIME_BETWEEN_BURSTS_MS); + } + } else { + newDelayUntilNextTaskWithoutBackoffMs = TIME_BETWEEN_QUERIES_IN_BURST_MS; + } + return new QueryTaskConfig(this, newQueryCount, newTransactionId, + newExpectUnicastResponse, newIsFirstBurst, newBurstCounter, newQueriesPerBurst, + newTimeBetweenBurstsInMs, newDelayUntilNextTaskWithoutBackoffMs); + } + + /** + * Determine if the query backoff should be used. + */ + public boolean shouldUseQueryBackoff() { + // Don't enable backoff mode during the burst or in the first burst + if (burstCounter != 0 || isFirstBurst) { + return false; + } + return queryCount > numOfQueriesBeforeBackoff; + } +} diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java index 92a2115509..1fdfe0916e 100644 --- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java +++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java @@ -52,7 +52,6 @@ import android.text.TextUtils; import com.android.net.module.util.CollectionUtils; import com.android.net.module.util.SharedLog; import com.android.server.connectivity.mdns.MdnsServiceInfo.TextEntry; -import com.android.server.connectivity.mdns.MdnsServiceTypeClient.QueryTaskConfig; import com.android.server.connectivity.mdns.util.MdnsUtils; import com.android.testutils.DevSdkIgnoreRule; import com.android.testutils.DevSdkIgnoreRunner;