Merge "ContextHubTestModeManager: Improve reliable message testing" into main
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java
index f2714db..2bb3be6 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java
@@ -17,10 +17,12 @@
package com.android.server.location.contexthub;
import android.chre.flags.Flags;
+import android.hardware.location.ContextHubTransaction;
import android.hardware.location.NanoAppMessage;
import android.util.Log;
-import java.util.Random;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.Callable;
/**
* A class to manage behaviors during test mode. This is used for testing.
@@ -29,32 +31,31 @@
public class ContextHubTestModeManager {
private static final String TAG = "ContextHubTestModeManager";
- /** Probability of duplicating a message. */
- private static final double MESSAGE_DROP_PROBABILITY = 0.05;
-
- /** Probability of duplicating a message. */
- private static final double MESSAGE_DUPLICATION_PROBABILITY = 0.05;
+ private static final int DROP_MESSAGE_TO_HOST_EVENT = 0;
+ private static final int DROP_MESSAGE_TO_CONTEXT_HUB_EVENT = 1;
+ private static final int DUPLICATE_MESSAGE_TO_HOST_EVENT = 2;
+ private static final int DUPLICATE_MESSAGE_TO_CONTEXT_HUB_EVENT = 3;
+ private static final int NUMBER_OF_EVENTS = 4;
/** The number of total messages to send when the duplication event happens. */
private static final int NUM_MESSAGES_TO_DUPLICATE = 3;
- /**
- * The seed for the random number generator. This is used to make the
- * test more deterministic.
- */
- private static final long SEED = 0xDEADBEEF;
-
- private final Random mRandom = new Random(SEED);
+ /** The counter to track the number of interactions with the test mode manager. */
+ private final AtomicLong mCounter = new AtomicLong(0);
/**
* @return whether the message was handled
* @see ContextHubServiceCallback#handleNanoappMessage
*/
public boolean handleNanoappMessage(Runnable handleMessage, NanoAppMessage message) {
+ if (!message.isReliable()) {
+ return false;
+ }
+
+ long counterValue = mCounter.getAndIncrement();
if (Flags.reliableMessageDuplicateDetectionService()
- && message.isReliable()
- && mRandom.nextDouble() < MESSAGE_DUPLICATION_PROBABILITY) {
- Log.i(TAG, "[TEST MODE] Duplicating message ("
+ && counterValue % NUMBER_OF_EVENTS == DUPLICATE_MESSAGE_TO_HOST_EVENT) {
+ Log.i(TAG, "[TEST MODE] Duplicating message to host ("
+ NUM_MESSAGES_TO_DUPLICATE
+ " sends) with message sequence number: "
+ message.getMessageSequenceNumber());
@@ -63,6 +64,14 @@
}
return true;
}
+
+ if (counterValue % NUMBER_OF_EVENTS == DROP_MESSAGE_TO_HOST_EVENT) {
+ Log.i(TAG, "[TEST MODE] Dropping message to host with "
+ + "message sequence number: "
+ + message.getMessageSequenceNumber());
+ return true;
+ }
+
return false;
}
@@ -70,14 +79,39 @@
* @return whether the message was handled
* @see IContextHubWrapper#sendMessageToContextHub
*/
- public boolean sendMessageToContextHub(NanoAppMessage message) {
+ public boolean sendMessageToContextHub(Callable<Integer> sendMessage, NanoAppMessage message) {
+ if (!message.isReliable()) {
+ return false;
+ }
+
+ long counterValue = mCounter.getAndIncrement();
+ if (counterValue % NUMBER_OF_EVENTS == DUPLICATE_MESSAGE_TO_CONTEXT_HUB_EVENT) {
+ Log.i(TAG, "[TEST MODE] Duplicating message to the Context Hub ("
+ + NUM_MESSAGES_TO_DUPLICATE
+ + " sends) with message sequence number: "
+ + message.getMessageSequenceNumber());
+ for (int i = 0; i < NUM_MESSAGES_TO_DUPLICATE; ++i) {
+ try {
+ int result = sendMessage.call();
+ if (result != ContextHubTransaction.RESULT_SUCCESS) {
+ Log.e(TAG, "sendMessage returned an error: " + result);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in sendMessageToContextHub: "
+ + e.getMessage());
+ }
+ }
+ return true;
+ }
+
if (Flags.reliableMessageRetrySupportService()
- && message.isReliable()
- && mRandom.nextDouble() < MESSAGE_DROP_PROBABILITY) {
- Log.i(TAG, "[TEST MODE] Dropping message with message sequence number: "
+ && counterValue % NUMBER_OF_EVENTS == DROP_MESSAGE_TO_CONTEXT_HUB_EVENT) {
+ Log.i(TAG, "[TEST MODE] Dropping message to the Context Hub with "
+ + "message sequence number: "
+ message.getMessageSequenceNumber());
return true;
}
+
return false;
}
}
diff --git a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
index 4fc3d87..a8ad418 100644
--- a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
+++ b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
@@ -53,6 +53,7 @@
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.Callable;
/**
* @hide
@@ -659,32 +660,40 @@
@ContextHubTransaction.Result
public int sendMessageToContextHub(short hostEndpointId, int contextHubId,
- NanoAppMessage message) throws RemoteException {
+ NanoAppMessage message) {
android.hardware.contexthub.IContextHub hub = getHub();
if (hub == null) {
return ContextHubTransaction.RESULT_FAILED_BAD_PARAMS;
}
- try {
- var msg = ContextHubServiceUtil.createAidlContextHubMessage(
- hostEndpointId, message);
-
- // Only process the message normally if not using test mode manager or if
- // the test mode manager call returned false as this indicates it did not
- // process the message.
- boolean useTestModeManager = Flags.reliableMessageImplementation()
- && Flags.reliableMessageTestModeBehavior()
- && mIsTestModeEnabled.get();
- if (!useTestModeManager || !mTestModeManager.sendMessageToContextHub(message)) {
+ Callable<Integer> sendMessage = () -> {
+ try {
+ var msg = ContextHubServiceUtil.createAidlContextHubMessage(
+ hostEndpointId, message);
hub.sendMessageToHub(contextHubId, msg);
+ return ContextHubTransaction.RESULT_SUCCESS;
+ } catch (RemoteException | ServiceSpecificException e) {
+ return ContextHubTransaction.RESULT_FAILED_UNKNOWN;
+ } catch (IllegalArgumentException e) {
+ return ContextHubTransaction.RESULT_FAILED_BAD_PARAMS;
}
+ };
- return ContextHubTransaction.RESULT_SUCCESS;
- } catch (RemoteException | ServiceSpecificException e) {
- return ContextHubTransaction.RESULT_FAILED_UNKNOWN;
- } catch (IllegalArgumentException e) {
- return ContextHubTransaction.RESULT_FAILED_BAD_PARAMS;
+ // Only process the message normally if not using test mode manager or if
+ // the test mode manager call returned false as this indicates it did not
+ // process the message.
+ boolean useTestModeManager = Flags.reliableMessageImplementation()
+ && Flags.reliableMessageTestModeBehavior()
+ && mIsTestModeEnabled.get();
+ if (!useTestModeManager || !mTestModeManager.sendMessageToContextHub(
+ sendMessage, message)) {
+ try {
+ return sendMessage.call();
+ } catch (Exception e) {
+ return ContextHubTransaction.RESULT_FAILED_UNKNOWN;
+ }
}
+ return ContextHubTransaction.RESULT_SUCCESS;
}
@ContextHubTransaction.Result