Merge "Move QueryTaskConfig to a standalone class" into main
This commit is contained in:
@@ -39,7 +39,6 @@ import java.net.Inet4Address;
|
|||||||
import java.net.Inet6Address;
|
import java.net.Inet6Address;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -545,145 +544,6 @@ public class MdnsServiceTypeClient {
|
|||||||
return new MdnsPacketWriter(DEFAULT_MTU);
|
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<String> 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<String> 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<MdnsResponse> makeResponsesForResolve(@NonNull SocketKey socketKey) {
|
private List<MdnsResponse> makeResponsesForResolve(@NonNull SocketKey socketKey) {
|
||||||
final List<MdnsResponse> resolveResponses = new ArrayList<>();
|
final List<MdnsResponse> resolveResponses = new ArrayList<>();
|
||||||
for (int i = 0; i < listeners.size(); i++) {
|
for (int i = 0; i < listeners.size(); i++) {
|
||||||
|
|||||||
@@ -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<String> 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<String> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,7 +52,6 @@ import android.text.TextUtils;
|
|||||||
import com.android.net.module.util.CollectionUtils;
|
import com.android.net.module.util.CollectionUtils;
|
||||||
import com.android.net.module.util.SharedLog;
|
import com.android.net.module.util.SharedLog;
|
||||||
import com.android.server.connectivity.mdns.MdnsServiceInfo.TextEntry;
|
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.server.connectivity.mdns.util.MdnsUtils;
|
||||||
import com.android.testutils.DevSdkIgnoreRule;
|
import com.android.testutils.DevSdkIgnoreRule;
|
||||||
import com.android.testutils.DevSdkIgnoreRunner;
|
import com.android.testutils.DevSdkIgnoreRunner;
|
||||||
|
|||||||
Reference in New Issue
Block a user