Merge "Revert "audiopolicy: HW Bridge Sink matching rule""
diff --git a/OWNERS b/OWNERS
index 9989bf0..7f523a2 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,5 +1,7 @@
+chz@google.com
 elaurent@google.com
 etalvala@google.com
+hkuang@google.com
 lajos@google.com
 marcone@google.com
 
diff --git a/media/codec2/components/aac/Android.bp b/media/codec2/components/aac/Android.bp
index 9eca585..50495a9 100644
--- a/media/codec2/components/aac/Android.bp
+++ b/media/codec2/components/aac/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_aacdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -15,7 +15,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_aacenc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/amr_nb_wb/Android.bp b/media/codec2/components/amr_nb_wb/Android.bp
index ce25bc9..b09a505 100644
--- a/media/codec2/components/amr_nb_wb/Android.bp
+++ b/media/codec2/components/amr_nb_wb/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_amrnbdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -21,7 +21,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_amrwbdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -40,7 +40,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_amrnbenc",
     defaults: [
         "libcodec2_soft-defaults",
@@ -58,7 +58,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_amrwbenc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/aom/Android.bp b/media/codec2/components/aom/Android.bp
index 61dbd4c..fcc4552 100644
--- a/media/codec2/components/aom/Android.bp
+++ b/media/codec2/components/aom/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_av1dec_aom",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/avc/Android.bp b/media/codec2/components/avc/Android.bp
index 4021444..6b0e363 100644
--- a/media/codec2/components/avc/Android.bp
+++ b/media/codec2/components/avc/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_avcdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -15,7 +15,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_avcenc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/base/Android.bp b/media/codec2/components/base/Android.bp
index f10835f..3712564 100644
--- a/media/codec2/components/base/Android.bp
+++ b/media/codec2/components/base/Android.bp
@@ -1,6 +1,6 @@
 // DO NOT DEPEND ON THIS DIRECTLY
 // use libcodec2_soft-defaults instead
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_common",
     defaults: ["libcodec2-impl-defaults"],
     vendor_available: true,
@@ -96,7 +96,7 @@
 }
 
 // TEMP: used by cheets2 project - remove when no longer used
-cc_library_shared {
+cc_library {
     name: "libcodec2_simple_component",
     vendor_available: true,
 
diff --git a/media/codec2/components/flac/Android.bp b/media/codec2/components/flac/Android.bp
index 48cc51b..603c412 100644
--- a/media/codec2/components/flac/Android.bp
+++ b/media/codec2/components/flac/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_flacdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -14,7 +14,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_flacenc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/g711/Android.bp b/media/codec2/components/g711/Android.bp
index 0101b1a..c39df7b 100644
--- a/media/codec2/components/g711/Android.bp
+++ b/media/codec2/components/g711/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_g711alawdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -14,7 +14,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_g711mlawdec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/gav1/Android.bp b/media/codec2/components/gav1/Android.bp
index f374089..32aa98d 100644
--- a/media/codec2/components/gav1/Android.bp
+++ b/media/codec2/components/gav1/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_av1dec_gav1",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/gsm/Android.bp b/media/codec2/components/gsm/Android.bp
index 9330c01..7f54af8 100644
--- a/media/codec2/components/gsm/Android.bp
+++ b/media/codec2/components/gsm/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_gsmdec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/hevc/Android.bp b/media/codec2/components/hevc/Android.bp
index 369bd78..2858212 100644
--- a/media/codec2/components/hevc/Android.bp
+++ b/media/codec2/components/hevc/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_hevcdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -11,7 +11,7 @@
 
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_hevcenc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/mp3/Android.bp b/media/codec2/components/mp3/Android.bp
index 66665ed..b4fb1b0 100644
--- a/media/codec2/components/mp3/Android.bp
+++ b/media/codec2/components/mp3/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_mp3dec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/mpeg2/Android.bp b/media/codec2/components/mpeg2/Android.bp
index 841f0a9..666e697 100644
--- a/media/codec2/components/mpeg2/Android.bp
+++ b/media/codec2/components/mpeg2/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_mpeg2dec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/mpeg4_h263/Android.bp b/media/codec2/components/mpeg4_h263/Android.bp
index 41e4f44..0673709 100644
--- a/media/codec2/components/mpeg4_h263/Android.bp
+++ b/media/codec2/components/mpeg4_h263/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_mpeg4dec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -15,7 +15,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_h263dec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -31,7 +31,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_mpeg4enc",
     defaults: [
         "libcodec2_soft-defaults",
@@ -49,7 +49,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_h263enc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/opus/Android.bp b/media/codec2/components/opus/Android.bp
index 0ed141b..32e2bf8 100644
--- a/media/codec2/components/opus/Android.bp
+++ b/media/codec2/components/opus/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_opusdec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -9,7 +9,7 @@
 
     shared_libs: ["libopus"],
 }
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_opusenc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/raw/Android.bp b/media/codec2/components/raw/Android.bp
index dc944da..d4fb8f8 100644
--- a/media/codec2/components/raw/Android.bp
+++ b/media/codec2/components/raw/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_rawdec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/vorbis/Android.bp b/media/codec2/components/vorbis/Android.bp
index bc1c380..ff1183f 100644
--- a/media/codec2/components/vorbis/Android.bp
+++ b/media/codec2/components/vorbis/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_vorbisdec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/vpx/Android.bp b/media/codec2/components/vpx/Android.bp
index 34f5753..72178aa 100644
--- a/media/codec2/components/vpx/Android.bp
+++ b/media/codec2/components/vpx/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_vp9dec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -14,7 +14,7 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_vp8dec",
     defaults: [
         "libcodec2_soft-defaults",
@@ -26,7 +26,7 @@
     shared_libs: ["libvpx"],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_vp9enc",
     defaults: [
         "libcodec2_soft-defaults",
@@ -43,7 +43,7 @@
     cflags: ["-DVP9"],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_vp8enc",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/components/xaac/Android.bp b/media/codec2/components/xaac/Android.bp
index 7795cc1..4889d78 100644
--- a/media/codec2/components/xaac/Android.bp
+++ b/media/codec2/components/xaac/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libcodec2_soft_xaacdec",
     defaults: [
         "libcodec2_soft-defaults",
diff --git a/media/codec2/core/Android.bp b/media/codec2/core/Android.bp
index 33fafa7..beeadb8 100644
--- a/media/codec2/core/Android.bp
+++ b/media/codec2/core/Android.bp
@@ -5,7 +5,7 @@
     export_include_dirs: ["include"],
 }
 
-cc_library_shared {
+cc_library {
     name: "libcodec2",
     vendor_available: true,
     min_sdk_version: "29",
diff --git a/media/codec2/sfplugin/utils/Android.bp b/media/codec2/sfplugin/utils/Android.bp
index 6287221..e7dc92a 100644
--- a/media/codec2/sfplugin/utils/Android.bp
+++ b/media/codec2/sfplugin/utils/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libsfplugin_ccodec_utils",
     vendor_available: true,
     min_sdk_version: "29",
diff --git a/media/codec2/vndk/Android.bp b/media/codec2/vndk/Android.bp
index 60f4736..19afccf 100644
--- a/media/codec2/vndk/Android.bp
+++ b/media/codec2/vndk/Android.bp
@@ -13,7 +13,7 @@
 
 // !!!DO NOT DEPEND ON THIS SHARED LIBRARY DIRECTLY!!!
 // use libcodec2-impl-defaults instead
-cc_library_shared {
+cc_library {
     name: "libcodec2_vndk",
     vendor_available: true,
     min_sdk_version: "29",
diff --git a/media/codecs/m4v_h263/dec/src/vop.cpp b/media/codecs/m4v_h263/dec/src/vop.cpp
index 335846c..7b32498 100644
--- a/media/codecs/m4v_h263/dec/src/vop.cpp
+++ b/media/codecs/m4v_h263/dec/src/vop.cpp
@@ -497,6 +497,13 @@
                 }
                 while ((qmat[*(zigzag_inv+i)] != 0) && (++i < 64));
 
+                /* qmatrix must have at least one non-zero value, which means
+                   i would be non-zero in valid cases */
+                if (i == 0)
+                {
+                    return PV_FAIL;
+                }
+
                 for (j = i; j < 64; j++)
                     qmat[*(zigzag_inv+j)] = qmat[*(zigzag_inv+i-1)];
             }
@@ -520,6 +527,13 @@
                 }
                 while ((qmat[*(zigzag_inv+i)] != 0) && (++i < 64));
 
+                /* qmatrix must have at least one non-zero value, which means
+                   i would be non-zero in valid cases */
+                if (i == 0)
+                {
+                    return PV_FAIL;
+                }
+
                 for (j = i; j < 64; j++)
                     qmat[*(zigzag_inv+j)] = qmat[*(zigzag_inv+i-1)];
             }
diff --git a/media/libstagefright/FrameDecoder.cpp b/media/libstagefright/FrameDecoder.cpp
index e783578..d11408d 100644
--- a/media/libstagefright/FrameDecoder.cpp
+++ b/media/libstagefright/FrameDecoder.cpp
@@ -44,7 +44,7 @@
 namespace android {
 
 static const int64_t kBufferTimeOutUs = 10000LL; // 10 msec
-static const size_t kRetryCount = 50; // must be >0
+static const size_t kRetryCount = 100; // must be >0
 static const int64_t kDefaultSampleDurationUs = 33333LL; // 33ms
 
 sp<IMemory> allocVideoFrame(const sp<MetaData>& trackMeta,
diff --git a/services/mediametrics/fuzzer/Android.bp b/services/mediametrics/fuzzer/Android.bp
new file mode 100644
index 0000000..df4c867
--- /dev/null
+++ b/services/mediametrics/fuzzer/Android.bp
@@ -0,0 +1,59 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_fuzz {
+    name: "mediametrics_service_fuzzer",
+
+    srcs: [
+        "mediametrics_service_fuzzer.cpp",
+    ],
+
+    static_libs: [
+        "libmediametrics",
+        "libmediametricsservice",
+        "libplatformprotos",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "libcutils",
+        "liblog",
+        "libmedia_helper",
+        "libmediautils",
+        "libmemunreachable",
+        "libprotobuf-cpp-lite",
+        "libstagefright",
+        "libstatslog",
+        "libutils",
+    ],
+
+    include_dirs: [
+        "frameworks/av/services/mediametrics",
+        "system/media/audio_utils/include",
+    ],
+
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
diff --git a/services/mediametrics/fuzzer/README.md b/services/mediametrics/fuzzer/README.md
new file mode 100644
index 0000000..a13830e
--- /dev/null
+++ b/services/mediametrics/fuzzer/README.md
@@ -0,0 +1,54 @@
+# Fuzzer for libmediametricsservice
+
+## Plugin Design Considerations
+The fuzzer plugin for libmediametricsservice is designed based on the
+understanding of the service and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+Media Metrics Service contains the following modules:
+1. Media Metrics Item Manipulation (module name: `Item`)
+2. Media Metrics Time Machine Storage (module name: `TimeMachineStorage`)
+3. Media Metrics Transaction Log (module name: `TransactionLog`)
+4. Media Metrics Analytics Action (module name: `AnalyticsAction`)
+5. Media Metrics Audio Analytics (module name: `AudioAnalytics`)
+6. Media Metrics Timed Action (module name: `TimedAction`)
+
+| Module| Valid Input Values| Configured Value|
+|------------- |-------------| ----- |
+| `Item` | Key: `std::string`. Values: `INT32_MIN` to `INT32_MAX`, `INT64_MIN` to `INT64_MAX`, `std::string`, `double`, `pair<INT32_MIN to INT32_MAX, INT32_MIN to INT32_MAX>` | Value obtained from FuzzedDataProvider |
+| `TimeMachineStorage`   | Key: `std::string`. Values: `INT32_MIN` to `INT32_MAX`, `INT64_MIN` to `INT64_MAX`, `std::string`, `double`, `pair<INT32_MIN to INT32_MAX, INT32_MIN to INT32_MAX>` | Value obtained from FuzzedDataProvider |
+| `TranscationLog`   | `mediametrics::Item` | `mediametrics::Item` created by obtaining values from FuzzedDataProvider|
+| `AnalyticsAction`   | URL: `std::string` ending with .event, Value: `std::string`, action: A function | URL and Values obtained from FuzzedDataProvider, a placeholder function was passed as action|
+| `AudioAnalytics`   | `mediametrics::Item` | `mediametrics::Item` created by obtaining values from FuzzedDataProvider|
+| `TimedAction`   | time: `std::chrono::seconds`, function: `std::function` | `std::chrono::seconds` : value obtained from FuzzedDataProvider, `std::function`: a placeholder function was used. |
+
+This also ensures that the plugin is always deterministic for any given input.
+
+## Build
+
+This describes steps to build mediametrics_service_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) mediametrics_service_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/mediametrics_service_fuzzer/mediametrics_service_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp b/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp
new file mode 100644
index 0000000..0cb2594
--- /dev/null
+++ b/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp
@@ -0,0 +1,372 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#include <fuzzer/FuzzedDataProvider.h>
+#include <media/MediaMetricsItem.h>
+#include <stdio.h>
+#include <string.h>
+#include <utils/Log.h>
+#include <algorithm>
+
+#include "AudioTypes.h"
+#include "MediaMetricsService.h"
+#include "StringUtils.h"
+
+using namespace android;
+
+// low water mark
+constexpr size_t kLogItemsLowWater = 1;
+// high water mark
+constexpr size_t kLogItemsHighWater = 2;
+
+class MediaMetricsServiceFuzzer {
+   public:
+    void invokeStartsWith(const uint8_t *data, size_t size);
+    void invokeInstantiate(const uint8_t *data, size_t size);
+    void invokePackageInstallerCheck(const uint8_t *data, size_t size);
+    void invokeItemManipulation(const uint8_t *data, size_t size);
+    void invokeItemExpansion(const uint8_t *data, size_t size);
+    void invokeTimeMachineStorage(const uint8_t *data, size_t size);
+    void invokeTransactionLog(const uint8_t *data, size_t size);
+    void invokeAnalyticsAction(const uint8_t *data, size_t size);
+    void invokeAudioAnalytics(const uint8_t *data, size_t size);
+    void invokeTimedAction(const uint8_t *data, size_t size);
+    void process(const uint8_t *data, size_t size);
+};
+
+void MediaMetricsServiceFuzzer::invokeStartsWith(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+    while (fdp.remaining_bytes()) {
+        android::mediametrics::startsWith(fdp.ConsumeRandomLengthString(),
+                                          fdp.ConsumeRandomLengthString());
+    }
+}
+
+void MediaMetricsServiceFuzzer::invokeInstantiate(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+    sp mediaMetricsService = new MediaMetricsService();
+
+    while (fdp.remaining_bytes()) {
+        std::unique_ptr<mediametrics::Item> random_key(
+            mediametrics::Item::create(fdp.ConsumeRandomLengthString()));
+        mediaMetricsService->submit(random_key.get());
+        random_key->setInt32(fdp.ConsumeRandomLengthString().c_str(),
+                             fdp.ConsumeIntegral<int32_t>());
+        mediaMetricsService->submit(random_key.get());
+
+        std::unique_ptr<mediametrics::Item> audiotrack_key(
+            mediametrics::Item::create("audiotrack"));
+        mediaMetricsService->submit(audiotrack_key.get());
+        audiotrack_key->addInt32(fdp.ConsumeRandomLengthString().c_str(),
+                                 fdp.ConsumeIntegral<int32_t>());
+        mediaMetricsService->submit(audiotrack_key.get());
+    }
+}
+
+void MediaMetricsServiceFuzzer::invokePackageInstallerCheck(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+    while (fdp.remaining_bytes()) {
+        MediaMetricsService::useUidForPackage(fdp.ConsumeRandomLengthString().c_str(),
+                                              fdp.ConsumeRandomLengthString().c_str());
+    }
+}
+
+void MediaMetricsServiceFuzzer::invokeItemManipulation(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+
+    mediametrics::Item item(fdp.ConsumeRandomLengthString().c_str());
+    while (fdp.remaining_bytes()) {
+        const uint8_t action = fdp.ConsumeIntegralInRange<uint8_t>(0, 16);
+        const std::string key = fdp.ConsumeRandomLengthString();
+        if (fdp.remaining_bytes() < 1 || key.length() < 1) {
+            break;
+        }
+        switch (action) {
+            case 0: {
+                item.setInt32(key.c_str(), fdp.ConsumeIntegral<int32_t>());
+                break;
+            }
+            case 1: {
+                item.addInt32(key.c_str(), fdp.ConsumeIntegral<int32_t>());
+                break;
+            }
+            case 2: {
+                int32_t i32 = 0;
+                item.getInt32(key.c_str(), &i32);
+                break;
+            }
+            case 3: {
+                item.setInt64(key.c_str(), fdp.ConsumeIntegral<int64_t>());
+                break;
+            }
+            case 4: {
+                item.addInt64(key.c_str(), fdp.ConsumeIntegral<int64_t>());
+                break;
+            }
+            case 5: {
+                int64_t i64 = 0;
+                item.getInt64(key.c_str(), &i64);
+                break;
+            }
+            case 6: {
+                item.setDouble(key.c_str(), fdp.ConsumeFloatingPoint<double>());
+                break;
+            }
+            case 7: {
+                item.addDouble(key.c_str(), fdp.ConsumeFloatingPoint<double>());
+                break;
+            }
+            case 8: {
+                double d = 0;
+                item.getDouble(key.c_str(), &d);
+                break;
+            }
+            case 9: {
+                item.setCString(key.c_str(), fdp.ConsumeRandomLengthString().c_str());
+                break;
+            }
+            case 10: {
+                char *s = nullptr;
+                item.getCString(key.c_str(), &s);
+                if (s) free(s);
+                break;
+            }
+            case 11: {
+                std::string s;
+                item.getString(key.c_str(), &s);
+                break;
+            }
+            case 12: {
+                item.setRate(key.c_str(), fdp.ConsumeIntegral<int64_t>(),
+                             fdp.ConsumeIntegral<int64_t>());
+                break;
+            }
+            case 13: {
+                int64_t b = 0, h = 0;
+                double d = 0;
+                item.getRate(key.c_str(), &b, &h, &d);
+                break;
+            }
+            case 14: {
+                (void)item.filter(key.c_str());
+                break;
+            }
+            case 15: {
+                const char *arr[1] = {""};
+                arr[0] = const_cast<char *>(key.c_str());
+                (void)item.filterNot(1, arr);
+                break;
+            }
+            case 16: {
+                (void)item.toString().c_str();
+                break;
+            }
+        }
+    }
+
+    Parcel p;
+    mediametrics::Item item2;
+
+    (void)item.writeToParcel(&p);
+    p.setDataPosition(0);  // rewind for reading
+    (void)item2.readFromParcel(p);
+
+    char *byteData = nullptr;
+    size_t length = 0;
+    (void)item.writeToByteString(&byteData, &length);
+    (void)item2.readFromByteString(byteData, length);
+    if (byteData) {
+        free(byteData);
+    }
+
+    sp mediaMetricsService = new MediaMetricsService();
+    mediaMetricsService->submit(&item2);
+}
+
+void MediaMetricsServiceFuzzer::invokeItemExpansion(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+
+    mediametrics::LogItem<1> item("FuzzItem");
+    item.setPid(fdp.ConsumeIntegral<int16_t>()).setUid(fdp.ConsumeIntegral<int16_t>());
+
+    while (fdp.remaining_bytes()) {
+        int32_t i = fdp.ConsumeIntegral<int32_t>();
+        item.set(std::to_string(i).c_str(), (int32_t)i);
+    }
+    item.updateHeader();
+
+    mediametrics::Item item2;
+    (void)item2.readFromByteString(item.getBuffer(), item.getLength());
+
+    sp mediaMetricsService = new MediaMetricsService();
+    mediaMetricsService->submit(&item2);
+}
+
+void MediaMetricsServiceFuzzer::invokeTimeMachineStorage(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+
+    auto item = std::make_shared<mediametrics::Item>("FuzzKey");
+    int32_t i32 = fdp.ConsumeIntegral<int32_t>();
+    int64_t i64 = fdp.ConsumeIntegral<int64_t>();
+    double d = fdp.ConsumeFloatingPoint<double>();
+    std::string str = fdp.ConsumeRandomLengthString();
+    std::pair<int64_t, int64_t> pair(fdp.ConsumeIntegral<int64_t>(),
+                                     fdp.ConsumeIntegral<int64_t>());
+    (*item).set("i32", i32).set("i64", i64).set("double", d).set("string", str).set("rate", pair);
+
+    android::mediametrics::TimeMachine timeMachine;
+    timeMachine.put(item, true);
+
+    timeMachine.get("Key", "i32", &i32, -1);
+
+    timeMachine.get("Key", "i64", &i64, -1);
+
+    timeMachine.get("Key", "double", &d, -1);
+
+    timeMachine.get("Key", "string", &str, -1);
+
+    timeMachine.get("Key.i32", &i32, -1);
+
+    timeMachine.get("Key.i64", &i64, -1);
+
+    timeMachine.get("Key.double", &d, -1);
+
+    str.clear();
+    timeMachine.get("Key.string", &str, -1);
+}
+
+void MediaMetricsServiceFuzzer::invokeTransactionLog(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+
+    auto item = std::make_shared<mediametrics::Item>("Key1");
+    (*item)
+        .set("one", fdp.ConsumeIntegral<int32_t>())
+        .set("two", fdp.ConsumeIntegral<int32_t>())
+        .setTimestamp(fdp.ConsumeIntegral<int32_t>());
+
+    android::mediametrics::TransactionLog transactionLog(
+        kLogItemsLowWater, kLogItemsHighWater);  // keep at most 2 items
+    transactionLog.size();
+
+    transactionLog.put(item);
+    transactionLog.size();
+
+    auto item2 = std::make_shared<mediametrics::Item>("Key2");
+    (*item2)
+        .set("three", fdp.ConsumeIntegral<int32_t>())
+        .set("[Key1]three", fdp.ConsumeIntegral<int32_t>())
+        .setTimestamp(fdp.ConsumeIntegral<int32_t>());
+
+    transactionLog.put(item2);
+    transactionLog.size();
+
+    auto item3 = std::make_shared<mediametrics::Item>("Key3");
+    (*item3)
+        .set("six", fdp.ConsumeIntegral<int32_t>())
+        .set("[Key1]four", fdp.ConsumeIntegral<int32_t>())  // affects Key1
+        .set("[Key1]five", fdp.ConsumeIntegral<int32_t>())  // affects key1
+        .setTimestamp(fdp.ConsumeIntegral<int32_t>());
+
+    transactionLog.put(item3);
+    transactionLog.size();
+}
+
+void MediaMetricsServiceFuzzer::invokeAnalyticsAction(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+
+    mediametrics::AnalyticsActions analyticsActions;
+    bool action = false;
+
+    while (fdp.remaining_bytes()) {
+        analyticsActions.addAction(
+            (fdp.ConsumeRandomLengthString() + std::string(".event")).c_str(),
+            fdp.ConsumeRandomLengthString(),
+            std::make_shared<mediametrics::AnalyticsActions::Function>(
+                [&](const std::shared_ptr<const android::mediametrics::Item> &) {
+                    action = true;
+                }));
+    }
+
+    FuzzedDataProvider fdp2 = FuzzedDataProvider(data, size);
+
+    while (fdp2.remaining_bytes()) {
+        // make a test item
+        auto item = std::make_shared<mediametrics::Item>(fdp2.ConsumeRandomLengthString().c_str());
+        (*item).set("event", fdp2.ConsumeRandomLengthString().c_str());
+
+        // get the actions and execute them
+        auto actions = analyticsActions.getActionsForItem(item);
+        for (const auto &action : actions) {
+            action->operator()(item);
+        }
+    }
+}
+
+void MediaMetricsServiceFuzzer::invokeAudioAnalytics(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+    android::mediametrics::AudioAnalytics audioAnalytics;
+
+    while (fdp.remaining_bytes()) {
+        auto item = std::make_shared<mediametrics::Item>(fdp.ConsumeRandomLengthString().c_str());
+        int32_t transactionUid = fdp.ConsumeIntegral<int32_t>();  // arbitrary
+        (*item)
+            .set(fdp.ConsumeRandomLengthString().c_str(), fdp.ConsumeIntegral<int32_t>())
+            .set(fdp.ConsumeRandomLengthString().c_str(), fdp.ConsumeIntegral<int32_t>())
+            .set(AMEDIAMETRICS_PROP_ALLOWUID, transactionUid)
+            .setUid(transactionUid)
+            .setTimestamp(fdp.ConsumeIntegral<int32_t>());
+        audioAnalytics.submit(item, fdp.ConsumeBool());
+    }
+
+    audioAnalytics.dump(1000);
+}
+
+void MediaMetricsServiceFuzzer::invokeTimedAction(const uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+    android::mediametrics::TimedAction timedAction;
+    std::atomic_int value = 0;
+
+    while (fdp.remaining_bytes()) {
+        timedAction.postIn(std::chrono::seconds(fdp.ConsumeIntegral<int32_t>()),
+                           [&value] { ++value; });
+        timedAction.size();
+    }
+}
+
+void MediaMetricsServiceFuzzer::process(const uint8_t *data, size_t size) {
+    invokeStartsWith(data, size);
+    invokeInstantiate(data, size);
+    invokePackageInstallerCheck(data, size);
+    invokeItemManipulation(data, size);
+    invokeItemExpansion(data, size);
+    invokeTimeMachineStorage(data, size);
+    invokeTransactionLog(data, size);
+    invokeAnalyticsAction(data, size);
+    invokeAudioAnalytics(data, size);
+    invokeTimedAction(data, size);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+    if (size < 1) {
+        return 0;
+    }
+    MediaMetricsServiceFuzzer mediaMetricsServiceFuzzer;
+    mediaMetricsServiceFuzzer.process(data, size);
+    return 0;
+}