Fix an issue where CarStorageMonitoringTest would fail due to timing of intent delivery

This fix is twofold:
a) it makes the actual intent delivery more predictable in real-life;
b) it mocks the intent delivery for testing purposes such that:
  - we can still tell if the right recipient would receive the intent;
  - we can immediately call into the recipient and forward them the intent;

This removes the inherent race, but still validates the configuration mechanism.

Bug: 73659209
Test: runtest -x tests/carservice_test/src/com/android/car/CarStorageMonitoringTest.java
Change-Id: Idbee4025c899c18883a5541c4cffa3e3da9f0a76
diff --git a/tests/carservice_test/src/com/android/car/CarStorageMonitoringTest.java b/tests/carservice_test/src/com/android/car/CarStorageMonitoringTest.java
index 4dc97bb..83cc06d 100644
--- a/tests/carservice_test/src/com/android/car/CarStorageMonitoringTest.java
+++ b/tests/carservice_test/src/com/android/car/CarStorageMonitoringTest.java
@@ -34,6 +34,8 @@
 import android.car.storagemonitoring.WearEstimate;
 import android.car.storagemonitoring.WearEstimateChange;
 import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
 import android.os.SystemClock;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -54,7 +56,10 @@
 import com.android.car.systeminterface.TimeInterface;
 
 import com.android.car.test.utils.TemporaryFile;
+import java.util.ArrayDeque;
 import java.util.Collection;
+import java.util.Objects;
+import java.util.Queue;
 import org.json.JSONArray;
 import org.json.JSONObject;
 import org.junit.Rule;
@@ -85,6 +90,35 @@
     private static final WearInformation DEFAULT_WEAR_INFORMATION =
         new WearInformation(30, 0, WearInformation.PRE_EOL_INFO_NORMAL);
 
+    final class TestContext extends MockContext {
+        TestContext(MockContext context) {
+            super(context.getBaseContext());
+        }
+
+        @Override
+        public void sendBroadcast(Intent intent, String receiverPermission) {
+            Log.d(TAG, "test context broadcasting " + intent);
+            if (CarStorageMonitoringManager.INTENT_EXCESSIVE_IO.equals(intent.getAction())) {
+                assertEquals(Car.PERMISSION_STORAGE_MONITORING, receiverPermission);
+
+                List<ResolveInfo> resolveInfoList = mContext.getPackageManager().
+                        queryBroadcastReceivers(intent, 0);
+
+                assertEquals(1,
+                        resolveInfoList.stream().map(ri -> ri.activityInfo)
+                            .filter(Objects::nonNull)
+                            .map(ai -> ai.name)
+                            .filter(CarStorageMonitoringBroadcastReceiver.class
+                                    .getCanonicalName()::equals)
+                            .count());
+
+                CarStorageMonitoringBroadcastReceiver.deliver(intent);
+            } else {
+                super.sendBroadcast(intent, receiverPermission);
+            }
+        }
+    }
+
     static class ResourceOverrides {
         private final HashMap<Integer, Integer> mIntegerOverrides = new HashMap<>();
         private final HashMap<Integer, String> mStringOverrides = new HashMap<>();
@@ -148,7 +182,6 @@
         @NonNull
         final LifetimeWriteInfo[] currentLifetimeWriteInfo;
 
-
         TestData(long uptime,
             @Nullable WearInformation wearInformation,
             @Nullable WearHistory wearHistory,
@@ -300,10 +333,19 @@
             new MockStorageMonitoringInterface();
     private final MockTimeInterface mMockTimeInterface =
             new MockTimeInterface();
+    private TestContext mContext;
 
     private CarStorageMonitoringManager mCarStorageMonitoringManager;
 
     @Override
+    protected MockContext getCarServiceContext() throws NameNotFoundException {
+        if (mContext == null) {
+            mContext = new TestContext(super.getCarServiceContext());
+        }
+        return mContext;
+    }
+
+    @Override
     protected synchronized SystemInterface.Builder getSystemInterfaceBuilder() {
         SystemInterface.Builder builder = super.getSystemInterfaceBuilder();
         return builder.withSystemStateInterface(mMockSystemStateInterface)