Add large persistableBundle flag.

- publishers push to subscribers with a flag indicating large bundle so
that piping may be used if true
- statsPublisher now calculates the bundle size.

Bug: 203613819
Test: atest CarServiceUnitTest:DataBrokerTest
Test: atest CarServiceUnitTest:StatsPublisherTest
Test: atest CarServiceUnitTest:VehiclePropertyPublisherTest
Test: atest CarServiceUnitTest:ActivityForegroundStateChangedConverterTest
Test: atest CarServiceUnitTest:AppStartMemoryStateCapturedConverterTest
Test: atest CarServiceUnitTest:AtomListConverterTest
Test: atest CarServiceUnitTest:EventMetricDataConverterTest
Test: atest CarServiceUnitTest:GaugeMetricDataConverterTest
Test: atest CarServiceUnitTest:ProcessMemoryStateConverterTest
Change-Id: Ia429e06beaa02e75a8e1b312cbf13959bb8780ae
diff --git a/service/src/com/android/car/telemetry/databroker/DataSubscriber.java b/service/src/com/android/car/telemetry/databroker/DataSubscriber.java
index 9ab7604..d61d89c 100644
--- a/service/src/com/android/car/telemetry/databroker/DataSubscriber.java
+++ b/service/src/com/android/car/telemetry/databroker/DataSubscriber.java
@@ -57,12 +57,20 @@
 
     /**
      * Creates a {@link ScriptExecutionTask} and pushes it to the priority queue where the task
-     * will be pending execution.
+     * will be pending execution. Flag isLargeData indicates whether data is large.
+     */
+    public void push(PersistableBundle data, boolean isLargeData) {
+        ScriptExecutionTask task = new ScriptExecutionTask(
+                this, data, SystemClock.elapsedRealtime(), isLargeData);
+        mDataBroker.addTaskToQueue(task);
+    }
+
+    /**
+     * Creates a {@link ScriptExecutionTask} and pushes it to the priority queue where the task
+     * will be pending execution. Defaults isLargeData flag to false.
      */
     public void push(PersistableBundle data) {
-        ScriptExecutionTask task = new ScriptExecutionTask(
-                this, data, SystemClock.elapsedRealtime());
-        mDataBroker.addTaskToQueue(task);
+        push(data, false);
     }
 
     /** Returns the {@link TelemetryProto.MetricsConfig}. */
diff --git a/service/src/com/android/car/telemetry/databroker/ScriptExecutionTask.java b/service/src/com/android/car/telemetry/databroker/ScriptExecutionTask.java
index 18d0512..5a995d2 100644
--- a/service/src/com/android/car/telemetry/databroker/ScriptExecutionTask.java
+++ b/service/src/com/android/car/telemetry/databroker/ScriptExecutionTask.java
@@ -17,7 +17,6 @@
 package com.android.car.telemetry.databroker;
 
 import android.car.telemetry.MetricsConfigKey;
-import android.os.Parcel;
 import android.os.PersistableBundle;
 
 import com.android.car.telemetry.TelemetryProto;
@@ -30,37 +29,17 @@
  * The object can be accessed from any thread. See {@link DataSubscriber} for thread-safety.
  */
 public class ScriptExecutionTask implements Comparable<ScriptExecutionTask> {
-    // Key to the calculated bundle size, which doesn't contain implementation-dependent overhead
-    // and other allocations. It's approximately 10% smaller than the actual size of binder parcel.
-    public static final String APPROX_BUNDLE_SIZE_BYTES_KEY = "approx_bundle_size_bytes";
-
-    /**
-     * Binder transaction size limit is 1MB for all binders per process, so for large script input
-     * file pipe will be used to transfer the data to script executor instead of binder call. This
-     * is the input size threshold above which piping is used.
-     */
-    private static final int LARGE_SCRIPT_INPUT_SIZE_BYTES = 20 * 1024; // 20 kb
-
     private final long mTimestampMillis;
     private final DataSubscriber mSubscriber;
     private final PersistableBundle mData;
     private final boolean mIsLargeData;
 
     ScriptExecutionTask(DataSubscriber subscriber, PersistableBundle data,
-            long elapsedRealtimeMillis) {
+            long elapsedRealtimeMillis, boolean isLargeData) {
         mTimestampMillis = elapsedRealtimeMillis;
         mSubscriber = subscriber;
         mData = data;
-        if (mData.containsKey(APPROX_BUNDLE_SIZE_BYTES_KEY)) {
-            mIsLargeData =
-                    mData.getInt(APPROX_BUNDLE_SIZE_BYTES_KEY) > LARGE_SCRIPT_INPUT_SIZE_BYTES;
-            mData.remove(APPROX_BUNDLE_SIZE_BYTES_KEY);
-        } else {
-            Parcel parcel = Parcel.obtain();
-            parcel.writePersistableBundle(mData);
-            mIsLargeData = parcel.dataSize() > LARGE_SCRIPT_INPUT_SIZE_BYTES;
-            parcel.recycle();
-        }
+        mIsLargeData = isLargeData;
     }
 
     /** Returns the priority of the task. */
diff --git a/service/src/com/android/car/telemetry/publisher/StatsPublisher.java b/service/src/com/android/car/telemetry/publisher/StatsPublisher.java
index fc590d4..3376aa3 100644
--- a/service/src/com/android/car/telemetry/publisher/StatsPublisher.java
+++ b/service/src/com/android/car/telemetry/publisher/StatsPublisher.java
@@ -21,6 +21,8 @@
 import static com.android.car.telemetry.AtomsProto.Atom.PROCESS_CPU_TIME_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.Atom.PROCESS_MEMORY_STATE_FIELD_NUMBER;
 
+import static java.nio.charset.StandardCharsets.UTF_16;
+
 import android.app.StatsManager.StatsUnavailableException;
 import android.car.builtin.util.Slogf;
 import android.os.Handler;
@@ -91,6 +93,12 @@
 
     private static final String BUNDLE_CONFIG_KEY_PREFIX = "statsd-publisher-config-id-";
     private static final String BUNDLE_CONFIG_VERSION_PREFIX = "statsd-publisher-config-version-";
+    /**
+     * Binder transaction size limit is 1MB for all binders per process, so for large script input
+     * file pipe will be used to transfer the data to script executor instead of binder call. This
+     * is the input size threshold above which piping is used.
+     */
+    private static final int SCRIPT_INPUT_SIZE_THRESHOLD_BYTES = 20 * 1024; // 20 kb
 
     @VisibleForTesting
     static final StatsdConfigProto.FieldMatcher PROCESS_MEMORY_STATE_FIELDS_MATCHER =
@@ -240,7 +248,39 @@
                     "No reports for metric id " + metricId + " for config " + configKey);
             return;
         }
-        subscriber.push(metricBundles.get(metricId));
+        PersistableBundle bundle = metricBundles.get(metricId);
+        subscriber.push(bundle, isBundleLargeData(bundle));
+    }
+
+    @VisibleForTesting
+    boolean isBundleLargeData(PersistableBundle bundle) {
+        String[] keys = bundle.keySet().toArray(new String[0]);
+        int bytes = 0;
+        for (int i = 0; i < keys.length; ++i) {
+            Object array = bundle.get(keys[i]);
+            if (array instanceof boolean[]) {
+                boolean[] boolArray = (boolean[]) array;
+                bytes += boolArray.length;  // Java boolean is 1 byte
+            } else if (array instanceof long[]) {
+                long[] longArray = (long[]) array;
+                bytes += longArray.length * Long.BYTES;
+            } else if (array instanceof int[]) {
+                int[] intArray = (int[]) array;
+                bytes += intArray.length * Integer.BYTES;
+            } else if (array instanceof double[]) {
+                double[] doubleArray = (double[]) array;
+                bytes += doubleArray.length * Double.BYTES;
+            } else if (array instanceof String[]) {
+                String[] stringArray = (String[]) array;
+                for (String str : stringArray) {
+                    bytes += str.getBytes(UTF_16).length;
+                }
+            }
+        }
+        if (bytes < SCRIPT_INPUT_SIZE_THRESHOLD_BYTES) {
+            return false;
+        }
+        return true;
     }
 
     private void processStatsMetadata(StatsLogProto.StatsdStatsReport statsReport) {
diff --git a/service/src/com/android/car/telemetry/publisher/statsconverters/AbstractAtomConverter.java b/service/src/com/android/car/telemetry/publisher/statsconverters/AbstractAtomConverter.java
index e201f1d..8e20eb4 100644
--- a/service/src/com/android/car/telemetry/publisher/statsconverters/AbstractAtomConverter.java
+++ b/service/src/com/android/car/telemetry/publisher/statsconverters/AbstractAtomConverter.java
@@ -16,10 +16,6 @@
 
 package com.android.car.telemetry.publisher.statsconverters;
 
-import static com.android.car.telemetry.databroker.ScriptExecutionTask.APPROX_BUNDLE_SIZE_BYTES_KEY;
-
-import static java.nio.charset.StandardCharsets.UTF_16;
-
 import android.os.PersistableBundle;
 import android.util.SparseArray;
 
@@ -102,7 +98,6 @@
             Map<Long, String> hashToStringMap) throws StatsConversionException {
         PersistableBundle bundle = new PersistableBundle();
         SparseArray<AtomFieldAccessor<T>> parserConfig = getAtomFieldAccessorMap();
-        int bundleByteSize = 0;
         // For each field, if set, add the values from all atoms to list and convert
         for (int i = 0; i < parserConfig.size(); ++i) {
             AtomFieldAccessor<T> atomFieldAccessor = parserConfig.valueAt(i);
@@ -120,13 +115,12 @@
                     }
                     valueList.add(atomFieldAccessor.getField(atomData));
                 }
-                bundleByteSize += setPersistableBundleArrayField(
+                setPersistableBundleArrayField(
                         atomFieldAccessor.getFieldName(), valueList, bundle);
             }
         }
         // Check if there are dimension fields needing conversion
         if (dimensionsFieldsIds == null || dimensionsValuesList == null) {
-            bundle.putInt(APPROX_BUNDLE_SIZE_BYTES_KEY, bundleByteSize);
             return bundle;
         }
         // Create conversions for fields encoded in dimension fields
@@ -137,12 +131,11 @@
             for (List<DimensionsValue> dvList : dimensionsValuesList) {
                 valueList.add(extractDimensionsValue(dvList.get(i), hashToStringMap));
             }
-            bundleByteSize += setPersistableBundleArrayField(
+            setPersistableBundleArrayField(
                     getAtomFieldAccessorMap().get(fieldId).getFieldName(),
                     valueList,
                     bundle);
         }
-        bundle.putInt(APPROX_BUNDLE_SIZE_BYTES_KEY, bundleByteSize);
         return bundle;
     }
 
@@ -186,58 +179,44 @@
      * @param name key value for the bundle, corresponds to atom field name.
      * @param objList the list to be converted to {@link PersistableBundle} compatible array.
      * @param bundle the {@link PersistableBundle} to put the arrays to.
-     * @return bytes written to PersistableBundle.
      */
-    private static int setPersistableBundleArrayField(
+    private static void setPersistableBundleArrayField(
             String name,
             List<Object> objList,
             PersistableBundle bundle) {
         Object e = objList.get(0);  // All elements of the list are the same type.
-        int len = objList.size();
         if (e instanceof Integer) {
             int[] intArray = new int[objList.size()];
             for (int i = 0; i < objList.size(); ++i) {
                 intArray[i] = (Integer) objList.get(i);
             }
             bundle.putIntArray(name, intArray);
-            return len * Integer.BYTES;
         } else if (e instanceof Long) {
             long[] longArray = new long[objList.size()];
             for (int i = 0; i < objList.size(); ++i) {
                 longArray[i] = (Long) objList.get(i);
             }
             bundle.putLongArray(name, longArray);
-            return len * Long.BYTES;
         } else if (e instanceof String) {
-            String[] strArray = objList.toArray(new String[0]);
-            bundle.putStringArray(name, strArray);
-            int bytes = 0;
-            for (String str : strArray) {
-                bytes += str.getBytes(UTF_16).length;
-            }
-            return bytes;
+            bundle.putStringArray(name, objList.toArray(new String[0]));
         } else if (e instanceof Boolean) {
             boolean[] boolArray = new boolean[objList.size()];
             for (int i = 0; i < objList.size(); ++i) {
                 boolArray[i] = (Boolean) objList.get(i);
             }
             bundle.putBooleanArray(name, boolArray);
-            return len;  // Java boolean is 1 byte
         } else if (e instanceof Double) {
             double[] doubleArray = new double[objList.size()];
             for (int i = 0; i < objList.size(); ++i) {
                 doubleArray[i] = (Double) objList.get(i);
             }
             bundle.putDoubleArray(name, doubleArray);
-            return len * Double.BYTES;
         } else if (e instanceof Float) {
             double[] doubleArray = new double[objList.size()];
             for (int i = 0; i < objList.size(); ++i) {
                 doubleArray[i] = ((Float) objList.get(i)).doubleValue();
             }
             bundle.putDoubleArray(name, doubleArray);
-            return len * Double.BYTES;
         }
-        return 0;
     }
 }
diff --git a/service/src/com/android/car/telemetry/publisher/statsconverters/EventMetricDataConverter.java b/service/src/com/android/car/telemetry/publisher/statsconverters/EventMetricDataConverter.java
index f0803d6..52f9713 100644
--- a/service/src/com/android/car/telemetry/publisher/statsconverters/EventMetricDataConverter.java
+++ b/service/src/com/android/car/telemetry/publisher/statsconverters/EventMetricDataConverter.java
@@ -16,8 +16,6 @@
 
 package com.android.car.telemetry.publisher.statsconverters;
 
-import static com.android.car.telemetry.databroker.ScriptExecutionTask.APPROX_BUNDLE_SIZE_BYTES_KEY;
-
 import android.os.PersistableBundle;
 
 import com.android.car.telemetry.AtomsProto;
@@ -58,9 +56,6 @@
         }
         PersistableBundle bundle = AtomListConverter.convert(atoms, null, null, null);
         bundle.putLongArray(ELAPSED_TIME_NANOS, elapsedTimes);
-        int bundleSize = bundle.getInt(APPROX_BUNDLE_SIZE_BYTES_KEY)
-                + elapsedTimes.length * Long.BYTES;
-        bundle.putInt(APPROX_BUNDLE_SIZE_BYTES_KEY, bundleSize);
         return bundle;
     }
 }
diff --git a/service/src/com/android/car/telemetry/publisher/statsconverters/GaugeMetricDataConverter.java b/service/src/com/android/car/telemetry/publisher/statsconverters/GaugeMetricDataConverter.java
index e82a6ce..32a139c 100644
--- a/service/src/com/android/car/telemetry/publisher/statsconverters/GaugeMetricDataConverter.java
+++ b/service/src/com/android/car/telemetry/publisher/statsconverters/GaugeMetricDataConverter.java
@@ -16,8 +16,6 @@
 
 package com.android.car.telemetry.publisher.statsconverters;
 
-import static com.android.car.telemetry.databroker.ScriptExecutionTask.APPROX_BUNDLE_SIZE_BYTES_KEY;
-
 import android.os.PersistableBundle;
 
 import com.android.car.telemetry.AtomsProto;
@@ -84,9 +82,6 @@
             elapsedTimesArray[i] = elapsedTimes.get(i);
         }
         bundle.putLongArray(ELAPSED_TIME_NANOS, elapsedTimesArray);
-        int bundleSize = bundle.getInt(APPROX_BUNDLE_SIZE_BYTES_KEY)
-                + elapsedTimesArray.length * Long.BYTES;
-        bundle.putInt(APPROX_BUNDLE_SIZE_BYTES_KEY, bundleSize);
         return bundle;
     }
 }
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/databroker/DataBrokerTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/databroker/DataBrokerTest.java
index c5f30c2..d639820 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/databroker/DataBrokerTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/databroker/DataBrokerTest.java
@@ -16,8 +16,6 @@
 
 package com.android.car.telemetry.databroker;
 
-import static com.android.car.telemetry.databroker.ScriptExecutionTask.APPROX_BUNDLE_SIZE_BYTES_KEY;
-
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
@@ -156,11 +154,13 @@
         mHighPriorityTask = new ScriptExecutionTask(
                 new DataSubscriber(mDataBroker, METRICS_CONFIG_FOO, SUBSCRIBER_FOO),
                 mData,
-                SystemClock.elapsedRealtime());
+                SystemClock.elapsedRealtime(),
+                false);
         mLowPriorityTask = new ScriptExecutionTask(
                 new DataSubscriber(mDataBroker, METRICS_CONFIG_BAR, SUBSCRIBER_BAR),
                 mData,
-                SystemClock.elapsedRealtime());
+                SystemClock.elapsedRealtime(),
+                false);
     }
 
     @Override
@@ -319,13 +319,13 @@
     }
 
     @Test
-    public void testScheduleNextTask_largeInput_shouldPipeData() throws Exception {
+    public void testScheduleNextTask_withLargeDataFlag_shouldPipeData() throws Exception {
         PersistableBundle data = new PersistableBundle();
-        data.putBooleanArray("1 MB Array", new boolean [1024 * 1024]);
         ScriptExecutionTask highPriorityTask = new ScriptExecutionTask(
                 new DataSubscriber(mDataBroker, METRICS_CONFIG_FOO, SUBSCRIBER_FOO),
                 data,
-                SystemClock.elapsedRealtime());
+                SystemClock.elapsedRealtime(),
+                true);
         mDataBroker.getTaskQueue().add(highPriorityTask);
 
         mDataBroker.scheduleNextTask();
@@ -335,29 +335,13 @@
     }
 
     @Test
-    public void testScheduleNextTask_largeReportWithApproxSize_shouldPipeData() throws Exception {
+    public void testScheduleNextTask_withoutLargeDataFlag_doesNotPipeData() throws Exception {
         PersistableBundle data = new PersistableBundle();
-        data.putInt(APPROX_BUNDLE_SIZE_BYTES_KEY, 21000);
         ScriptExecutionTask highPriorityTask = new ScriptExecutionTask(
                 new DataSubscriber(mDataBroker, METRICS_CONFIG_FOO, SUBSCRIBER_FOO),
                 data,
-                SystemClock.elapsedRealtime());
-        mDataBroker.getTaskQueue().add(highPriorityTask);
-
-        mDataBroker.scheduleNextTask();
-
-        waitForTelemetryThreadToFinish();
-        assertThat(mFakeScriptExecutor.getInvokeScriptForLargeInputCount()).isEqualTo(1);
-    }
-
-    @Test
-    public void testScheduleNextTask_smallReportWithApproxSize_doesNotPipeData() throws Exception {
-        PersistableBundle data = new PersistableBundle();
-        data.putInt(APPROX_BUNDLE_SIZE_BYTES_KEY, 1000);
-        ScriptExecutionTask highPriorityTask = new ScriptExecutionTask(
-                new DataSubscriber(mDataBroker, METRICS_CONFIG_FOO, SUBSCRIBER_FOO),
-                data,
-                SystemClock.elapsedRealtime());
+                SystemClock.elapsedRealtime(),
+                false);
         mDataBroker.getTaskQueue().add(highPriorityTask);
 
         mDataBroker.scheduleNextTask();
@@ -369,18 +353,18 @@
     @Test
     public void testScheduleNextTask_largeInputPipeIOException_shouldIgnoreCurrentTask()
             throws Exception {
-        PersistableBundle data = new PersistableBundle();
-        data.putBooleanArray("1 MB Array", new boolean [1024 * 1024]);
         PriorityBlockingQueue<ScriptExecutionTask> taskQueue = mDataBroker.getTaskQueue();
         ScriptExecutionTask highPriorityTask = new ScriptExecutionTask(
                 new DataSubscriber(mDataBroker, METRICS_CONFIG_FOO, SUBSCRIBER_FOO),
-                data,
-                SystemClock.elapsedRealtime());
+                new PersistableBundle(),
+                SystemClock.elapsedRealtime(),
+                true);
         taskQueue.add(highPriorityTask); // invokeScriptForLargeInput() path
         taskQueue.add(new ScriptExecutionTask(
                 new DataSubscriber(mDataBroker, METRICS_CONFIG_FOO, SUBSCRIBER_FOO),
                 new PersistableBundle(),
-                SystemClock.elapsedRealtime())); // invokeScript() path
+                SystemClock.elapsedRealtime(),
+                false)); // invokeScript() path
         ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
         when(ParcelFileDescriptor.createPipe()).thenReturn(fds);
         fds[1].close(); // cause IO Exception in invokeScriptForLargeInput() path
@@ -496,7 +480,8 @@
         ScriptExecutionTask taskWithMetricsConfigFoo = new ScriptExecutionTask(
                 new DataSubscriber(mDataBroker, METRICS_CONFIG_FOO, SUBSCRIBER_FOO),
                 mData,
-                SystemClock.elapsedRealtime());
+                SystemClock.elapsedRealtime(),
+                false);
         PriorityBlockingQueue<ScriptExecutionTask> taskQueue = mDataBroker.getTaskQueue();
         taskQueue.add(mHighPriorityTask); // associated with METRICS_CONFIG_FOO
         taskQueue.add(mLowPriorityTask); // associated with METRICS_CONFIG_BAR
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/StatsPublisherTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/StatsPublisherTest.java
index 25076a1..35173aa 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/StatsPublisherTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/StatsPublisherTest.java
@@ -33,6 +33,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.reset;
@@ -449,7 +450,7 @@
 
         mFakeHandlerWrapper.dispatchQueuedMessages();
 
-        verify(subscriber1).push(mBundleCaptor.capture());
+        verify(subscriber1).push(mBundleCaptor.capture(), anyBoolean());
         PersistableBundle bundle1 = mBundleCaptor.getValue();
         assertThat(bundle1.getLongArray("elapsed_timestamp_nanos"))
             .asList().containsExactly(99999999L);
@@ -457,7 +458,7 @@
         assertThat(Arrays.asList(bundle1.getStringArray("activity_name")))
             .containsExactly("activityName");
         assertThat(bundle1.getLongArray("rss_in_bytes")).asList().containsExactly(1234L);
-        verify(subscriber2).push(mBundleCaptor.capture());
+        verify(subscriber2).push(mBundleCaptor.capture(), anyBoolean());
         PersistableBundle bundle2 = mBundleCaptor.getValue();
         assertThat(bundle2.getIntArray("uid")).asList().containsExactly(234);
         assertThat(bundle2.getLongArray("rss_in_bytes")).asList().containsExactly(4567L);
@@ -466,6 +467,38 @@
     }
 
     @Test
+    public void testBundleWithLargeSize_isLargeData() throws Exception {
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putBooleanArray("bool", new boolean[1000]);
+        bundle.putLongArray("long", new long[1000]);
+        bundle.putIntArray("int", new int[1000]);
+        bundle.putDoubleArray("double", new double[1000]);
+        String[] strArray = new String[1000];
+        for (int i = 0; i < strArray.length; ++i) {
+            strArray[i] = "test";
+        }
+        bundle.putStringArray("string", strArray);
+
+        assertThat(mPublisher.isBundleLargeData(bundle)).isTrue();
+    }
+
+    @Test
+    public void testBundleWithSmallSize_isNotLargeData() throws Exception {
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putBooleanArray("bool", new boolean[100]);
+        bundle.putLongArray("long", new long[100]);
+        bundle.putIntArray("int", new int[100]);
+        bundle.putDoubleArray("double", new double[100]);
+        String[] strArray = new String[100];
+        for (int i = 0; i < strArray.length; ++i) {
+            strArray[i] = "test";
+        }
+        bundle.putStringArray("string", strArray);
+
+        assertThat(mPublisher.isBundleLargeData(bundle)).isFalse();
+    }
+
+    @Test
     public void testOnInvalidConfig_notifiesPublisherFailureListener() throws Exception {
         DataSubscriber subscriber = spy(new DataSubscriber(null, METRICS_CONFIG, SUBSCRIBER_1));
         mPublisher.addDataSubscriber(subscriber);
@@ -483,7 +516,7 @@
         mFakeHandlerWrapper.dispatchQueuedMessages();
 
         // subscriber shouldn't get data, because of EMPTY_METRICS_REPORT.
-        verify(subscriber, times(0)).push(any());
+        verify(subscriber, times(0)).push(any(), anyBoolean());
         assertThat(mFailedConfigs).containsExactly(METRICS_CONFIG);
         assertThat(mPublisherFailure).hasMessageThat().contains("Found invalid configs");
     }
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ActivityForegroundStateChangedConverterTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ActivityForegroundStateChangedConverterTest.java
index 221c716..98a0925 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ActivityForegroundStateChangedConverterTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ActivityForegroundStateChangedConverterTest.java
@@ -20,7 +20,6 @@
 import static com.android.car.telemetry.AtomsProto.ActivityForegroundStateChanged.PKG_NAME_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.ActivityForegroundStateChanged.STATE_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.ActivityForegroundStateChanged.UID_FIELD_NUMBER;
-import static com.android.car.telemetry.databroker.ScriptExecutionTask.APPROX_BUNDLE_SIZE_BYTES_KEY;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -105,8 +104,7 @@
         PersistableBundle bundle = mConverter.convert(atomsList, DIM_FIELDS_IDS,
                 dimensionsValuesList, HASH_STR_MAP);
 
-        assertThat(bundle.size()).isEqualTo(5);
-        assertThat(bundle.getInt(APPROX_BUNDLE_SIZE_BYTES_KEY)).isEqualTo(120);
+        assertThat(bundle.size()).isEqualTo(4);
         assertThat(bundle.getIntArray(accessorMap.get(UID_FIELD_NUMBER).getFieldName()))
             .asList().containsExactly(1000, 2000).inOrder();
         assertThat(Arrays.asList(
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/AppStartMemoryStateCapturedConverterTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/AppStartMemoryStateCapturedConverterTest.java
index b309069..1579e00 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/AppStartMemoryStateCapturedConverterTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/AppStartMemoryStateCapturedConverterTest.java
@@ -24,7 +24,6 @@
 import static com.android.car.telemetry.AtomsProto.AppStartMemoryStateCaptured.RSS_IN_BYTES_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.AppStartMemoryStateCaptured.SWAP_IN_BYTES_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.AppStartMemoryStateCaptured.UID_FIELD_NUMBER;
-import static com.android.car.telemetry.databroker.ScriptExecutionTask.APPROX_BUNDLE_SIZE_BYTES_KEY;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -119,8 +118,7 @@
         PersistableBundle bundle = mConverter.convert(atomsList, DIM_FIELDS_IDS,
                 dimensionsValuesList, HASH_STR_MAP);
 
-        assertThat(bundle.size()).isEqualTo(9);
-        assertThat(bundle.getInt(APPROX_BUNDLE_SIZE_BYTES_KEY)).isEqualTo(204);
+        assertThat(bundle.size()).isEqualTo(8);
         assertThat(bundle.getIntArray(accessorMap.get(UID_FIELD_NUMBER).getFieldName()))
             .asList().containsExactly(1000, 2000).inOrder();
         assertThat(Arrays.asList(
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/AtomListConverterTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/AtomListConverterTest.java
index 4704966..a8cc426 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/AtomListConverterTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/AtomListConverterTest.java
@@ -16,8 +16,6 @@
 
 package com.android.car.telemetry.publisher.statsconverters;
 
-import static com.android.car.telemetry.databroker.ScriptExecutionTask.APPROX_BUNDLE_SIZE_BYTES_KEY;
-
 import static com.google.common.truth.Truth.assertThat;
 
 import android.os.PersistableBundle;
@@ -60,8 +58,7 @@
 
         PersistableBundle bundle = AtomListConverter.convert(pushedAtomsList, null, null, null);
 
-        assertThat(bundle.size()).isEqualTo(4);
-        assertThat(bundle.getInt(APPROX_BUNDLE_SIZE_BYTES_KEY)).isEqualTo(80);
+        assertThat(bundle.size()).isEqualTo(3);
         assertThat(bundle.getIntArray(
                 accessorMap.get(AppStartMemoryStateCaptured.UID_FIELD_NUMBER).getFieldName()))
             .asList().containsExactly(1000, 1100).inOrder();
@@ -97,8 +94,7 @@
 
         PersistableBundle bundle = AtomListConverter.convert(pulledAtomsList, null, null, null);
 
-        assertThat(bundle.size()).isEqualTo(4);
-        assertThat(bundle.getInt(APPROX_BUNDLE_SIZE_BYTES_KEY)).isEqualTo(76);
+        assertThat(bundle.size()).isEqualTo(3);
         assertThat(bundle.getIntArray(
                 accessorMap.get(ProcessMemoryState.UID_FIELD_NUMBER).getFieldName()))
             .asList().containsExactly(1000, 1100).inOrder();
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/EventMetricDataConverterTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/EventMetricDataConverterTest.java
index 0bac4cd..dac3310 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/EventMetricDataConverterTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/EventMetricDataConverterTest.java
@@ -19,7 +19,6 @@
 import static com.android.car.telemetry.AtomsProto.AppStartMemoryStateCaptured.ACTIVITY_NAME_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.AppStartMemoryStateCaptured.RSS_IN_BYTES_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.AppStartMemoryStateCaptured.UID_FIELD_NUMBER;
-import static com.android.car.telemetry.databroker.ScriptExecutionTask.APPROX_BUNDLE_SIZE_BYTES_KEY;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -67,8 +66,7 @@
 
         PersistableBundle bundle = EventMetricDataConverter.convertEventDataList(eventDataList);
 
-        assertThat(bundle.size()).isEqualTo(5);
-        assertThat(bundle.getInt(APPROX_BUNDLE_SIZE_BYTES_KEY)).isEqualTo(96);
+        assertThat(bundle.size()).isEqualTo(4);
         assertThat(bundle.getLongArray(EventMetricDataConverter.ELAPSED_TIME_NANOS))
             .asList().containsExactly(12345678L, 23456789L).inOrder();
         assertThat(bundle.getIntArray(accessorMap.get(UID_FIELD_NUMBER).getFieldName()))
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/GaugeMetricDataConverterTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/GaugeMetricDataConverterTest.java
index 808a6a1..8e747ae 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/GaugeMetricDataConverterTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/GaugeMetricDataConverterTest.java
@@ -21,7 +21,6 @@
 import static com.android.car.telemetry.AtomsProto.ProcessMemoryState.RSS_IN_BYTES_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.ProcessMemoryState.SWAP_IN_BYTES_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.ProcessMemoryState.UID_FIELD_NUMBER;
-import static com.android.car.telemetry.databroker.ScriptExecutionTask.APPROX_BUNDLE_SIZE_BYTES_KEY;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -104,8 +103,7 @@
 
         // For each atom 2 fields were set, additionally 3 fields were encoded in dimension values,
         // and 1 elapsed time array, so 6 arrays are expected in the bundle.
-        assertThat(bundle.size()).isEqualTo(7);
-        assertThat(bundle.getInt(APPROX_BUNDLE_SIZE_BYTES_KEY)).isEqualTo(264);
+        assertThat(bundle.size()).isEqualTo(6);
         assertThat(bundle.getIntArray(accessorMap.get(UID_FIELD_NUMBER).getFieldName()))
             .asList().containsExactly(123, 123, 123, 234).inOrder();
         assertThat(Arrays.asList(bundle.getStringArray(
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ProcessCpuTimeConverterTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ProcessCpuTimeConverterTest.java
index 24d898a..0075391 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ProcessCpuTimeConverterTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ProcessCpuTimeConverterTest.java
@@ -101,7 +101,7 @@
         PersistableBundle bundle = mConverter.convert(atomsList, DIM_FIELDS_IDS,
                 dimensionsValuesList, HASH_STR_MAP);
 
-        assertThat(bundle.size()).isEqualTo(5);
+        assertThat(bundle.size()).isEqualTo(4);
         assertThat(bundle.getIntArray(accessorMap.get(UID_FIELD_NUMBER).getFieldName()))
             .asList().containsExactly(1000, 2000).inOrder();
         assertThat(Arrays.asList(
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ProcessMemoryStateConverterTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ProcessMemoryStateConverterTest.java
index 050cb4c..f922d17 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ProcessMemoryStateConverterTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/publisher/statsconverters/ProcessMemoryStateConverterTest.java
@@ -24,7 +24,6 @@
 import static com.android.car.telemetry.AtomsProto.ProcessMemoryState.RSS_IN_BYTES_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.ProcessMemoryState.SWAP_IN_BYTES_FIELD_NUMBER;
 import static com.android.car.telemetry.AtomsProto.ProcessMemoryState.UID_FIELD_NUMBER;
-import static com.android.car.telemetry.databroker.ScriptExecutionTask.APPROX_BUNDLE_SIZE_BYTES_KEY;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -117,8 +116,7 @@
         PersistableBundle bundle = mConverter.convert(atomsList, DIM_FIELDS_IDS,
                 dimensionsValuesList, HASH_STR_MAP);
 
-        assertThat(bundle.size()).isEqualTo(9);
-        assertThat(bundle.getInt(APPROX_BUNDLE_SIZE_BYTES_KEY)).isEqualTo(156);
+        assertThat(bundle.size()).isEqualTo(8);
         assertThat(bundle.getIntArray(accessorMap.get(UID_FIELD_NUMBER).getFieldName()))
             .asList().containsExactly(1000, 2000).inOrder();
         assertThat(Arrays.asList(