Merge "Reland CCodecBufferChannel: Process output format when registering buffer" into rvc-dev
diff --git a/media/codec2/hidl/1.0/vts/functional/Android.bp b/media/codec2/hidl/1.0/vts/functional/Android.bp
index cd3be81..5ea4825 100644
--- a/media/codec2/hidl/1.0/vts/functional/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/Android.bp
@@ -91,6 +91,14 @@
         "res/bbb_av1_176_144.info",
         "res/bbb_vp9_704x480_280kbps_24fps_altref_2.vp9",
         "res/bbb_vp9_704x480_280kbps_24fps_altref_2.info",
+        "res/bbb_avc_176x144_300kbps_60fps_chksum.md5",
+        "res/bbb_avc_640x360_768kbps_30fps_chksum.md5",
+        "res/bbb_hevc_176x144_176kbps_60fps_chksum.md5",
+        "res/bbb_hevc_640x360_1600kbps_30fps_chksum.md5",
+        "res/bbb_vp8_640x360_2mbps_30fps_chksm.md5",
+        "res/bbb_vp9_640x360_1600kbps_30fps_chksm.md5",
+        "res/bbb_av1_640_360_chksum.md5",
+        "res/bbb_av1_176_144_chksm.md5",
     ],
 }
 
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_176_144_chksm.md5 b/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_176_144_chksm.md5
new file mode 100644
index 0000000..cb69709
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_176_144_chksm.md5
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_640_360_chksum.md5 b/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_640_360_chksum.md5
new file mode 100644
index 0000000..2693071
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_av1_640_360_chksum.md5
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_176x144_300kbps_60fps_chksum.md5 b/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_176x144_300kbps_60fps_chksum.md5
new file mode 100644
index 0000000..5c802d9
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_176x144_300kbps_60fps_chksum.md5
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_640x360_768kbps_30fps_chksum.md5 b/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_640x360_768kbps_30fps_chksum.md5
new file mode 100644
index 0000000..073f8eb
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_avc_640x360_768kbps_30fps_chksum.md5
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_176x144_176kbps_60fps_chksum.md5 b/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_176x144_176kbps_60fps_chksum.md5
new file mode 100644
index 0000000..83f11c0
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_176x144_176kbps_60fps_chksum.md5
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_640x360_1600kbps_30fps_chksum.md5 b/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_640x360_1600kbps_30fps_chksum.md5
new file mode 100644
index 0000000..3344881
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_hevc_640x360_1600kbps_30fps_chksum.md5
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_640x360_2mbps_30fps_chksm.md5 b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_640x360_2mbps_30fps_chksm.md5
new file mode 100644
index 0000000..738b1da
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp8_640x360_2mbps_30fps_chksm.md5
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_640x360_1600kbps_30fps_chksm.md5 b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_640x360_1600kbps_30fps_chksm.md5
new file mode 100644
index 0000000..a52faf2
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/res/bbb_vp9_640x360_1600kbps_30fps_chksm.md5
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/functional/video/Android.bp b/media/codec2/hidl/1.0/vts/functional/video/Android.bp
index 760f4da..c7b0c12 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/video/Android.bp
@@ -26,6 +26,7 @@
         "libbinder",
         "libgui",
         "libutils",
+        "libcrypto",
     ],
     data: [":media_c2_v1_video_decode_res"],
     test_config: "VtsHalMediaC2V1_0TargetVideoDecTest.xml",
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
index 3362336..6c8c3d2 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
@@ -22,6 +22,8 @@
 #include <hidl/GtestPrinter.h>
 #include <stdio.h>
 
+#include <openssl/md5.h>
+
 #include <C2AllocatorIon.h>
 #include <C2Buffer.h>
 #include <C2BufferPriv.h>
@@ -106,6 +108,9 @@
         mTimestampUs = 0u;
         mWorkResult = C2_OK;
         mTimestampDevTest = false;
+        mMd5Offset = 0;
+        mMd5Enable = false;
+        mRefMd5 = nullptr;
         if (mCompName == unknown_comp) mDisableTest = true;
 
         C2SecureModeTuning secureModeTuning{};
@@ -128,6 +133,77 @@
     // Get the test parameters from GetParam call.
     virtual void getParams() {}
 
+    /* Calculate the CKSUM for the data in inbuf */
+    void calc_md5_cksum(uint8_t* pu1_inbuf, uint32_t u4_stride, uint32_t u4_width,
+                        uint32_t u4_height, uint8_t* pu1_cksum_p) {
+        int32_t row;
+        MD5_CTX s_md5_context;
+        MD5_Init(&s_md5_context);
+        for (row = 0; row < u4_height; row++) {
+            MD5_Update(&s_md5_context, pu1_inbuf, u4_width);
+            pu1_inbuf += u4_stride;
+        }
+        MD5_Final(pu1_cksum_p, &s_md5_context);
+    }
+
+    void compareMd5Chksm(std::unique_ptr<C2Work>& work) {
+        uint8_t chksum[48];
+        uint8_t* au1_y_chksum = chksum;
+        uint8_t* au1_u_chksum = chksum + 16;
+        uint8_t* au1_v_chksum = chksum + 32;
+        const C2GraphicView output = work->worklets.front()
+                                             ->output.buffers[0]
+                                             ->data()
+                                             .graphicBlocks()
+                                             .front()
+                                             .map()
+                                             .get();
+        uint8_t* yPlane = const_cast<uint8_t*>(output.data()[C2PlanarLayout::PLANE_Y]);
+        uint8_t* uPlane = const_cast<uint8_t*>(output.data()[C2PlanarLayout::PLANE_U]);
+        uint8_t* vPlane = const_cast<uint8_t*>(output.data()[C2PlanarLayout::PLANE_V]);
+        C2PlanarLayout layout = output.layout();
+
+        size_t yStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+        size_t uvStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
+        size_t colInc = layout.planes[C2PlanarLayout::PLANE_U].colInc;
+        size_t bitDepth = layout.planes[C2PlanarLayout::PLANE_Y].bitDepth;
+        uint32_t layoutType = layout.type;
+        size_t cropWidth = output.crop().width;
+        size_t cropHeight = output.crop().height;
+
+        if (bitDepth == 8 && layoutType == C2PlanarLayout::TYPE_YUV && colInc == 1) {
+            calc_md5_cksum(yPlane, yStride, cropWidth, cropHeight, au1_y_chksum);
+            calc_md5_cksum(uPlane, uvStride, cropWidth / 2, cropHeight / 2, au1_u_chksum);
+            calc_md5_cksum(vPlane, uvStride, cropWidth / 2, cropHeight / 2, au1_v_chksum);
+        } else if (bitDepth == 8 && layoutType == C2PlanarLayout::TYPE_YUV && colInc == 2) {
+            uint8_t* cbPlane = (uint8_t*)malloc(cropWidth * cropHeight / 4);
+            uint8_t* crPlane = (uint8_t*)malloc(cropWidth * cropHeight / 4);
+            ASSERT_NE(cbPlane, nullptr);
+            ASSERT_NE(crPlane, nullptr);
+            size_t count = 0;
+            for (size_t k = 0; k < (cropHeight / 2); k++) {
+                for (size_t l = 0; l < (cropWidth); l = l + 2) {
+                    cbPlane[count] = uPlane[k * uvStride + l];
+                    crPlane[count] = vPlane[k * uvStride + l];
+                    count++;
+                }
+            }
+            calc_md5_cksum(yPlane, yStride, cropWidth, cropHeight, au1_y_chksum);
+            calc_md5_cksum(cbPlane, cropWidth / 2, cropWidth / 2, cropHeight / 2, au1_u_chksum);
+            calc_md5_cksum(crPlane, cropWidth / 2, cropWidth / 2, cropHeight / 2, au1_v_chksum);
+            free(cbPlane);
+            free(crPlane);
+        } else {
+            mMd5Enable = false;
+            ALOGV("Disabling MD5 chksm flag");
+            return;
+        }
+        if (memcmp(mRefMd5 + mMd5Offset, chksum, 48)) ASSERT_TRUE(false);
+        mMd5Offset += 48;
+        return;
+    }
+    bool configPixelFormat(uint32_t format);
+
     // callback function to process onWorkDone received by Listener
     void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
         for (std::unique_ptr<C2Work>& work : workItems) {
@@ -164,6 +240,9 @@
                             }
                         }
                     }
+                    if (mMd5Enable) {
+                        compareMd5Chksm(work);
+                    }
                 }
                 bool mCsd = false;
                 workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition, mWorkQueue,
@@ -190,8 +269,11 @@
 
     bool mEos;
     bool mDisableTest;
+    bool mMd5Enable;
     bool mTimestampDevTest;
     uint64_t mTimestampUs;
+    uint64_t mMd5Offset;
+    char* mRefMd5;
     std::list<uint64_t> mTimestampUslist;
     std::list<uint64_t> mFlushedIndices;
     standardComp mCompName;
@@ -265,54 +347,73 @@
 
 // number of elementary streams per component
 #define STREAM_COUNT 3
-// LookUpTable of clips and metadata for component testing
-void GetURLForComponent(Codec2VideoDecHidlTest::standardComp comp, char* mURL, char* info,
-                        size_t streamIndex = 1) {
+// LookUpTable of clips, metadata and chksum for component testing
+void GetURLChksmForComponent(Codec2VideoDecHidlTest::standardComp comp, char* mURL, char* info,
+                             char* chksum, size_t streamIndex = 1) {
     struct CompToURL {
         Codec2VideoDecHidlTest::standardComp comp;
         const char mURL[STREAM_COUNT][512];
         const char info[STREAM_COUNT][512];
+        const char chksum[STREAM_COUNT][512];
     };
     ASSERT_TRUE(streamIndex < STREAM_COUNT);
 
     static const CompToURL kCompToURL[] = {
             {Codec2VideoDecHidlTest::standardComp::avc,
              {"bbb_avc_176x144_300kbps_60fps.h264", "bbb_avc_640x360_768kbps_30fps.h264", ""},
-             {"bbb_avc_176x144_300kbps_60fps.info", "bbb_avc_640x360_768kbps_30fps.info", ""}},
+             {"bbb_avc_176x144_300kbps_60fps.info", "bbb_avc_640x360_768kbps_30fps.info", ""},
+             {"bbb_avc_176x144_300kbps_60fps_chksum.md5",
+              "bbb_avc_640x360_768kbps_30fps_chksum.md5", ""}},
             {Codec2VideoDecHidlTest::standardComp::hevc,
              {"bbb_hevc_176x144_176kbps_60fps.hevc", "bbb_hevc_640x360_1600kbps_30fps.hevc", ""},
-             {"bbb_hevc_176x144_176kbps_60fps.info", "bbb_hevc_640x360_1600kbps_30fps.info", ""}},
+             {"bbb_hevc_176x144_176kbps_60fps.info", "bbb_hevc_640x360_1600kbps_30fps.info", ""},
+             {"bbb_hevc_176x144_176kbps_60fps_chksum.md5",
+              "bbb_hevc_640x360_1600kbps_30fps_chksum.md5", ""}},
             {Codec2VideoDecHidlTest::standardComp::mpeg2,
              {"bbb_mpeg2_176x144_105kbps_25fps.m2v", "bbb_mpeg2_352x288_1mbps_60fps.m2v", ""},
-             {"bbb_mpeg2_176x144_105kbps_25fps.info", "bbb_mpeg2_352x288_1mbps_60fps.info", ""}},
+             {"bbb_mpeg2_176x144_105kbps_25fps.info", "bbb_mpeg2_352x288_1mbps_60fps.info", ""},
+             {"", "", ""}},
             {Codec2VideoDecHidlTest::standardComp::h263,
              {"", "bbb_h263_352x288_300kbps_12fps.h263", ""},
-             {"", "bbb_h263_352x288_300kbps_12fps.info", ""}},
+             {"", "bbb_h263_352x288_300kbps_12fps.info", ""},
+             {"", "", ""}},
             {Codec2VideoDecHidlTest::standardComp::mpeg4,
              {"", "bbb_mpeg4_352x288_512kbps_30fps.m4v", ""},
-             {"", "bbb_mpeg4_352x288_512kbps_30fps.info", ""}},
+             {"", "bbb_mpeg4_352x288_512kbps_30fps.info", ""},
+             {"", "", ""}},
             {Codec2VideoDecHidlTest::standardComp::vp8,
              {"bbb_vp8_176x144_240kbps_60fps.vp8", "bbb_vp8_640x360_2mbps_30fps.vp8", ""},
-             {"bbb_vp8_176x144_240kbps_60fps.info", "bbb_vp8_640x360_2mbps_30fps.info", ""}},
+             {"bbb_vp8_176x144_240kbps_60fps.info", "bbb_vp8_640x360_2mbps_30fps.info", ""},
+             {"", "bbb_vp8_640x360_2mbps_30fps_chksm.md5", ""}},
             {Codec2VideoDecHidlTest::standardComp::vp9,
              {"bbb_vp9_176x144_285kbps_60fps.vp9", "bbb_vp9_640x360_1600kbps_30fps.vp9",
               "bbb_vp9_704x480_280kbps_24fps_altref_2.vp9"},
              {"bbb_vp9_176x144_285kbps_60fps.info", "bbb_vp9_640x360_1600kbps_30fps.info",
-              "bbb_vp9_704x480_280kbps_24fps_altref_2.info"}},
+              "bbb_vp9_704x480_280kbps_24fps_altref_2.info"},
+             {"", "bbb_vp9_640x360_1600kbps_30fps_chksm.md5", ""}},
             {Codec2VideoDecHidlTest::standardComp::av1,
              {"bbb_av1_640_360.av1", "bbb_av1_176_144.av1", ""},
-             {"bbb_av1_640_360.info", "bbb_av1_176_144.info", ""}},
+             {"bbb_av1_640_360.info", "bbb_av1_176_144.info", ""},
+             {"bbb_av1_640_360_chksum.md5", "bbb_av1_176_144_chksm.md5", ""}},
     };
 
     for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
         if (kCompToURL[i].comp == comp) {
             strcat(mURL, kCompToURL[i].mURL[streamIndex]);
             strcat(info, kCompToURL[i].info[streamIndex]);
+            strcat(chksum, kCompToURL[i].chksum[streamIndex]);
             return;
         }
     }
 }
 
+void GetURLForComponent(Codec2VideoDecHidlTest::standardComp comp, char* mURL, char* info,
+                        size_t streamIndex = 1) {
+    char chksum[512];
+    strcpy(chksum, sResourceDir.c_str());
+    GetURLChksmForComponent(comp, mURL, info, chksum, streamIndex);
+}
+
 void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
                    std::mutex& queueLock, std::condition_variable& queueCondition,
                    std::list<std::unique_ptr<C2Work>>& workQueue,
@@ -443,6 +544,19 @@
     ASSERT_EQ(producer->setSidebandStream(nativeHandle), NO_ERROR);
 }
 
+// Config output pixel format
+bool Codec2VideoDecHidlTestBase::configPixelFormat(uint32_t format) {
+    std::vector<std::unique_ptr<C2SettingResult>> failures;
+    C2StreamPixelFormatInfo::output pixelformat(0u, format);
+
+    std::vector<C2Param*> configParam{&pixelformat};
+    c2_status_t status = mComponent->config(configParam, C2_DONT_BLOCK, &failures);
+    if (status == C2_OK && failures.size() == 0u) {
+        return true;
+    }
+    return false;
+}
+
 class Codec2VideoDecDecodeTest
     : public Codec2VideoDecHidlTestBase,
       public ::testing::WithParamInterface<
@@ -461,13 +575,27 @@
     uint32_t streamIndex = std::stoi(std::get<2>(GetParam()));
     bool signalEOS = !std::get<2>(GetParam()).compare("true");
     mTimestampDevTest = true;
-    char mURL[512], info[512];
+
+    char mURL[512], info[512], chksum[512];
     android::Vector<FrameInfo> Info;
 
     strcpy(mURL, sResourceDir.c_str());
     strcpy(info, sResourceDir.c_str());
+    strcpy(chksum, sResourceDir.c_str());
 
-    GetURLForComponent(mCompName, mURL, info, streamIndex);
+    GetURLChksmForComponent(mCompName, mURL, info, chksum, streamIndex);
+    if (!(strcmp(mURL, sResourceDir.c_str())) || !(strcmp(info, sResourceDir.c_str()))) {
+        ALOGV("Skipping Test, Stream not available");
+        return;
+    }
+    mMd5Enable = true;
+    if (!strcmp(chksum, sResourceDir.c_str())) mMd5Enable = false;
+
+    uint32_t format = HAL_PIXEL_FORMAT_YCBCR_420_888;
+    if (!configPixelFormat(format)) {
+        std::cout << "[   WARN   ] Test Skipped PixelFormat not configured\n";
+        return;
+    }
 
     mFlushedIndices.clear();
     mTimestampUslist.clear();
@@ -483,6 +611,24 @@
     std::ifstream eleStream;
     eleStream.open(mURL, std::ifstream::binary);
     ASSERT_EQ(eleStream.is_open(), true);
+
+    size_t refChksmSize = 0;
+    std::ifstream refChksum;
+    if (mMd5Enable) {
+        ALOGV("chksum file name: %s", chksum);
+        refChksum.open(chksum, std::ifstream::binary | std::ifstream::ate);
+        ASSERT_EQ(refChksum.is_open(), true);
+        refChksmSize = refChksum.tellg();
+        refChksum.seekg(0, std::ifstream::beg);
+
+        ALOGV("chksum Size %zu ", refChksmSize);
+        mRefMd5 = (char*)malloc(refChksmSize);
+        ASSERT_NE(mRefMd5, nullptr);
+        refChksum.read(mRefMd5, refChksmSize);
+        ASSERT_EQ(refChksum.gcount(), refChksmSize);
+        refChksum.close();
+    }
+
     ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
                                           mFlushedIndices, mLinearPool, eleStream, &Info, 0,
                                           (int)Info.size(), signalEOS));
@@ -509,6 +655,14 @@
         ASSERT_TRUE(false);
     }
 
+    if (mRefMd5 != nullptr) free(mRefMd5);
+    if (mMd5Enable && refChksmSize != mMd5Offset) {
+        ALOGE("refChksum size and generated chksum size mismatch refChksum size %zu generated "
+              "chksum size %" PRId64 "",
+              refChksmSize, mMd5Offset);
+        ASSERT_TRUE(false);
+    }
+
     if (mTimestampDevTest) EXPECT_EQ(mTimestampUslist.empty(), true);
     ASSERT_EQ(mComponent->stop(), C2_OK);
     ASSERT_EQ(mWorkResult, C2_OK);
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.xml b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.xml
index 63e7a69..a1049df 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.xml
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.xml
@@ -51,6 +51,14 @@
         <option name="push-file" key="bbb_av1_176_144.info" value="/data/local/tmp/media/bbb_av1_176_144.info" />
         <option name="push-file" key="bbb_vp9_704x480_280kbps_24fps_altref_2.vp9" value="/data/local/tmp/media/bbb_vp9_704x480_280kbps_24fps_altref_2.vp9" />
         <option name="push-file" key="bbb_vp9_704x480_280kbps_24fps_altref_2.info" value="/data/local/tmp/media/bbb_vp9_704x480_280kbps_24fps_altref_2.info" />
+        <option name="push-file" key="bbb_avc_176x144_300kbps_60fps_chksum.md5" value="/data/local/tmp/media/bbb_avc_176x144_300kbps_60fps_chksum.md5" />
+        <option name="push-file" key="bbb_avc_640x360_768kbps_30fps_chksum.md5" value="/data/local/tmp/media/bbb_avc_640x360_768kbps_30fps_chksum.md5" />
+        <option name="push-file" key="bbb_hevc_176x144_176kbps_60fps_chksum.md5" value="/data/local/tmp/media/bbb_hevc_176x144_176kbps_60fps_chksum.md5" />
+        <option name="push-file" key="bbb_hevc_640x360_1600kbps_30fps_chksum.md5" value="/data/local/tmp/media/bbb_hevc_640x360_1600kbps_30fps_chksum.md5" />
+        <option name="push-file" key="bbb_vp8_640x360_2mbps_30fps_chksm.md5" value="/data/local/tmp/media/bbb_vp8_640x360_2mbps_30fps_chksm.md5" />
+        <option name="push-file" key="bbb_vp9_640x360_1600kbps_30fps_chksm.md5" value="/data/local/tmp/media/bbb_vp9_640x360_1600kbps_30fps_chksm.md5" />
+        <option name="push-file" key="bbb_av1_640_360_chksum.md5" value="/data/local/tmp/media/bbb_av1_640_360_chksum.md5" />
+        <option name="push-file" key="bbb_av1_176_144_chksm.md5" value="/data/local/tmp/media/bbb_av1_176_144_chksm.md5" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index b11051e..8059ff6 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -1307,6 +1307,7 @@
     if (mInputSurface != nullptr) {
         mInputSurface.reset();
     }
+    mPipelineWatcher.lock()->flush();
 }
 
 void CCodecBufferChannel::reset() {
@@ -1314,6 +1315,7 @@
     {
         Mutexed<Input>::Locked input(mInput);
         input->buffers.reset(new DummyInputBuffers(""));
+        input->extraBuffers.flush();
     }
     {
         Mutexed<Output>::Locked output(mOutput);
@@ -1330,6 +1332,8 @@
         blockPools->inputPool.reset();
         blockPools->outputPoolIntf.reset();
     }
+    setCrypto(nullptr);
+    setDescrambler(nullptr);
 }
 
 
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 54f1fa2..d06c8ba 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -20,6 +20,7 @@
 #include <ctype.h>
 #include <inttypes.h>
 #include <algorithm>
+#include <map>
 #include <memory>
 #include <stdint.h>
 #include <stdlib.h>
@@ -204,6 +205,7 @@
         Vector<size_t> encryptedsizes;
     };
     Vector<Sample> mCurrentSamples;
+    std::map<off64_t, uint32_t> mDrmOffsets;
 
     MPEG4Source(const MPEG4Source &);
     MPEG4Source &operator=(const MPEG4Source &);
@@ -5153,6 +5155,9 @@
                     if (chunk_type == FOURCC("moof")) {
                         mNextMoofOffset = *offset;
                         break;
+                    } else if (chunk_type == FOURCC("mdat")) {
+                        parseChunk(offset);
+                        continue;
                     } else if (chunk_size == 0) {
                         break;
                     }
@@ -5214,6 +5219,22 @@
             // parse DRM info if present
             ALOGV("MPEG4Source::parseChunk mdat");
             // if saiz/saoi was previously observed, do something with the sampleinfos
+            status_t err = OK;
+            auto kv = mDrmOffsets.lower_bound(*offset);
+            if (kv != mDrmOffsets.end()) {
+                auto drmoffset = kv->first;
+                auto flags = kv->second;
+                mDrmOffsets.erase(kv);
+                ALOGV("mdat chunk_size %" PRIu64 " drmoffset %" PRId64 " offset %" PRId64,
+                        chunk_size, drmoffset, *offset);
+                if (chunk_size >= drmoffset - *offset) {
+                    err = parseClearEncryptedSizes(drmoffset, false, flags,
+                        chunk_size - (drmoffset - *offset));
+                }
+            }
+            if (err != OK) {
+                return err;
+            }
             *offset += chunk_size;
             break;
         }
@@ -5395,8 +5416,10 @@
     off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof
 
     drmoffset += mCurrentMoofOffset;
+    mDrmOffsets[drmoffset] = flags;
+    ALOGV("saio drmoffset %" PRId64 " flags %u", drmoffset, flags);
 
-    return parseClearEncryptedSizes(drmoffset, false, 0, mCurrentMoofSize);
+    return OK;
 }
 
 status_t MPEG4Source::parseClearEncryptedSizes(
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index a8fea90..3e49bae 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -2,10 +2,21 @@
     name: "libstagefright_headers",
     export_include_dirs: ["include"],
     vendor_available: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media",
+        "com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
 }
 
 cc_library_static {
     name: "libstagefright_esds",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media",
+    ],
+    min_sdk_version: "29",
 
     srcs: ["ESDS.cpp"],
 
@@ -27,6 +38,11 @@
 
 cc_library_static {
     name: "libstagefright_metadatautils",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media",
+    ],
+    min_sdk_version: "29",
 
     srcs: ["MetaDataUtils.cpp"],
 
@@ -94,6 +110,11 @@
 
 cc_library_static {
     name: "libstagefright_mpeg2extractor",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media",
+    ],
+    min_sdk_version: "29",
 
     srcs: [
         "Utils.cpp",
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 7fb5455..b90e6bd 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -3036,20 +3036,21 @@
 
             int32_t async = 0;
             if (msg->findInt32("async", &async) && async) {
-                if ((mState ==  CONFIGURED || mState == STARTED || mState == FLUSHED)
-                       && mSurface != NULL) {
+                if (mSurface != NULL) {
                     if (!mReleaseSurface) {
                         mReleaseSurface.reset(new ReleaseSurface);
                     }
-                    status_t err = connectToSurface(mReleaseSurface->getSurface());
-                    ALOGW_IF(err != OK, "error connecting to release surface: err = %d", err);
-                    if (err == OK && !(mFlags & kFlagUsesSoftwareRenderer)) {
-                        err = mCodec->setSurface(mReleaseSurface->getSurface());
-                        ALOGW_IF(err != OK, "error setting release surface: err = %d", err);
-                    }
-                    if (err == OK) {
-                        (void)disconnectFromSurface();
-                        mSurface = mReleaseSurface->getSurface();
+                    if (mSurface != mReleaseSurface->getSurface()) {
+                        status_t err = connectToSurface(mReleaseSurface->getSurface());
+                        ALOGW_IF(err != OK, "error connecting to release surface: err = %d", err);
+                        if (err == OK && !(mFlags & kFlagUsesSoftwareRenderer)) {
+                            err = mCodec->setSurface(mReleaseSurface->getSurface());
+                            ALOGW_IF(err != OK, "error setting release surface: err = %d", err);
+                        }
+                        if (err == OK) {
+                            (void)disconnectFromSurface();
+                            mSurface = mReleaseSurface->getSurface();
+                        }
                     }
                 }
             }
diff --git a/media/libstagefright/codecs/m4v_h263/dec/Android.bp b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
index c67dc2b..4303565 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
@@ -1,6 +1,11 @@
 cc_library_static {
     name: "libstagefright_m4vh263dec",
     vendor_available: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
     shared_libs: ["liblog"],
 
     srcs: [
diff --git a/media/libstagefright/codecs/m4v_h263/enc/Android.bp b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
index 846f614..b8bc24e 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
@@ -1,6 +1,11 @@
 cc_library_static {
     name: "libstagefright_m4vh263enc",
     vendor_available: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
 
     srcs: [
         "src/bitstream_io.cpp",
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index a04a962..a2f8230 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -35,6 +35,12 @@
 cc_library_headers {
     name: "media_ndk_headers",
     vendor_available: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media",
+        "com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
     export_include_dirs: ["include"]
 }
 
diff --git a/services/mediametrics/Android.bp b/services/mediametrics/Android.bp
index c87fbd9..645d151 100644
--- a/services/mediametrics/Android.bp
+++ b/services/mediametrics/Android.bp
@@ -1,8 +1,94 @@
 // Media Statistics service
 //
 
+tidy_errors = [
+    // https://clang.llvm.org/extra/clang-tidy/checks/list.html
+    // For many categories, the checks are too many to specify individually.
+    // Feel free to disable as needed - as warnings are generally ignored,
+    // we treat warnings as errors.
+    "android-*",
+    "bugprone-*",
+    "cert-*",
+    "clang-analyzer-security*",
+    "google-*",
+    "misc-*",
+    //"modernize-*",  // explicitly list the modernize as they can be subjective.
+    "modernize-avoid-bind",
+    //"modernize-avoid-c-arrays", // std::array<> can be verbose
+    "modernize-concat-nested-namespaces",
+    //"modernize-deprecated-headers", // C headers still ok even if there is C++ equivalent.
+    "modernize-deprecated-ios-base-aliases",
+    "modernize-loop-convert",
+    "modernize-make-shared",
+    "modernize-make-unique",
+    "modernize-pass-by-value",
+    "modernize-raw-string-literal",
+    "modernize-redundant-void-arg",
+    "modernize-replace-auto-ptr",
+    "modernize-replace-random-shuffle",
+    "modernize-return-braced-init-list",
+    "modernize-shrink-to-fit",
+    "modernize-unary-static-assert",
+    "modernize-use-auto",  // debatable - auto can obscure type
+    "modernize-use-bool-literals",
+    "modernize-use-default-member-init",
+    "modernize-use-emplace",
+    "modernize-use-equals-default",
+    "modernize-use-equals-delete",
+    "modernize-use-nodiscard",
+    "modernize-use-noexcept",
+    "modernize-use-nullptr",
+    "modernize-use-override",
+    //"modernize-use-trailing-return-type", // not necessarily more readable
+    "modernize-use-transparent-functors",
+    "modernize-use-uncaught-exceptions",
+    "modernize-use-using",
+    "performance-*",
+
+    // Remove some pedantic stylistic requirements.
+    "-google-readability-casting", // C++ casts not always necessary and may be verbose
+    "-google-readability-todo",    // do not require TODO(info)
+]
+
+cc_defaults {
+    name: "mediametrics_flags_defaults",
+    // https://clang.llvm.org/docs/UsersManual.html#command-line-options
+    // https://clang.llvm.org/docs/DiagnosticsReference.html
+    cflags: [
+        "-Wall",
+        "-Wdeprecated",
+        "-Werror",
+        "-Werror=implicit-fallthrough",
+        "-Werror=sometimes-uninitialized",
+        "-Werror=conditional-uninitialized",
+        "-Wextra",
+        "-Wredundant-decls",
+        "-Wshadow",
+        "-Wstrict-aliasing",
+        "-fstrict-aliasing",
+        "-Wthread-safety",
+        //"-Wthread-safety-negative", // experimental - looks broken in R.
+        "-Wunreachable-code",
+        "-Wunreachable-code-break",
+        "-Wunreachable-code-return",
+        "-Wunused",
+        "-Wused-but-marked-unused",
+    ],
+    // https://clang.llvm.org/extra/clang-tidy/
+    tidy: true,
+    tidy_checks: tidy_errors,
+    tidy_checks_as_errors: tidy_errors,
+    tidy_flags: [
+      "-format-style='file'",
+      "--header-filter='frameworks/av/services/mediametrics/'",
+    ],
+}
+
 cc_binary {
     name: "mediametrics",
+    defaults: [
+        "mediametrics_flags_defaults",
+    ],
 
     srcs: [
         "main_mediametrics.cpp",
@@ -22,17 +108,13 @@
     init_rc: [
         "mediametrics.rc",
     ],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wextra",
-        "-Wthread-safety",
-    ],
 }
 
 cc_library_shared {
     name: "libmediametricsservice",
+    defaults: [
+        "mediametrics_flags_defaults",
+    ],
 
     srcs: [
         "AudioAnalytics.cpp",
@@ -73,11 +155,4 @@
     include_dirs: [
         "system/media/audio_utils/include",
     ],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wextra",
-        "-Wthread-safety",
-    ],
 }
diff --git a/services/mediametrics/AudioAnalytics.cpp b/services/mediametrics/AudioAnalytics.cpp
index 6138d32..31ad234 100644
--- a/services/mediametrics/AudioAnalytics.cpp
+++ b/services/mediametrics/AudioAnalytics.cpp
@@ -594,4 +594,4 @@
 #endif
 }
 
-} // namespace android
+} // namespace android::mediametrics
diff --git a/services/mediametrics/AudioPowerUsage.cpp b/services/mediametrics/AudioPowerUsage.cpp
index b1615bd..b1648d9 100644
--- a/services/mediametrics/AudioPowerUsage.cpp
+++ b/services/mediametrics/AudioPowerUsage.cpp
@@ -160,7 +160,7 @@
         return true; //ignore unknown device
     }
 
-    for (auto item : mItems) {
+    for (const auto& item : mItems) {
         int32_t item_type = 0, item_device = 0;
         double item_volume = 0.;
         int64_t item_duration_ns = 0;
@@ -259,8 +259,8 @@
         const int64_t endCallNs = item->getTimestamp();
         const int64_t durationNs = endCallNs - mDeviceTimeNs;
         if (durationNs > 0) {
-            mDeviceVolume = (mDeviceVolume * (mVolumeTimeNs - mDeviceTimeNs) +
-                    mVoiceVolume * (endCallNs - mVolumeTimeNs)) / durationNs;
+            mDeviceVolume = (mDeviceVolume * double(mVolumeTimeNs - mDeviceTimeNs) +
+                    mVoiceVolume * double(endCallNs - mVolumeTimeNs)) / durationNs;
             saveAsItem_l(mPrimaryDevice, durationNs, VOICE_CALL_TYPE, mDeviceVolume);
         }
     } else if (mode == "AUDIO_MODE_IN_CALL") { // entering call mode
@@ -287,8 +287,8 @@
         const int64_t timeNs = item->getTimestamp();
         const int64_t durationNs = timeNs - mDeviceTimeNs;
         if (durationNs > 0) {
-            mDeviceVolume = (mDeviceVolume * (mVolumeTimeNs - mDeviceTimeNs) +
-                    mVoiceVolume * (timeNs - mVolumeTimeNs)) / durationNs;
+            mDeviceVolume = (mDeviceVolume * double(mVolumeTimeNs - mDeviceTimeNs) +
+                    mVoiceVolume * double(timeNs - mVolumeTimeNs)) / durationNs;
             mVolumeTimeNs = timeNs;
         }
     }
@@ -318,8 +318,8 @@
         const int64_t endDeviceNs = item->getTimestamp();
         const int64_t durationNs = endDeviceNs - mDeviceTimeNs;
         if (durationNs > 0) {
-            mDeviceVolume = (mDeviceVolume * (mVolumeTimeNs - mDeviceTimeNs) +
-                    mVoiceVolume * (endDeviceNs - mVolumeTimeNs)) / durationNs;
+            mDeviceVolume = (mDeviceVolume * double(mVolumeTimeNs - mDeviceTimeNs) +
+                    mVoiceVolume * double(endDeviceNs - mVolumeTimeNs)) / durationNs;
             saveAsItem_l(mPrimaryDevice, durationNs, VOICE_CALL_TYPE, mDeviceVolume);
         }
         // reset statistics
@@ -391,4 +391,4 @@
     return { ss.str(), slot };
 }
 
-} // namespace android
+} // namespace android::mediametrics
diff --git a/services/mediametrics/MediaMetricsService.cpp b/services/mediametrics/MediaMetricsService.cpp
index 3b3dc3e..584bd13 100644
--- a/services/mediametrics/MediaMetricsService.cpp
+++ b/services/mediametrics/MediaMetricsService.cpp
@@ -32,7 +32,8 @@
 
 namespace android {
 
-using namespace mediametrics;
+using mediametrics::Item;
+using mediametrics::startsWith;
 
 // individual records kept in memory: age or count
 // age: <= 28 hours (1 1/6 days)
@@ -63,7 +64,7 @@
 bool MediaMetricsService::useUidForPackage(
         const std::string& package, const std::string& installer)
 {
-    if (strchr(package.c_str(), '.') == NULL) {
+    if (strchr(package.c_str(), '.') == nullptr) {
         return false;  // not of form 'com.whatever...'; assume internal and ok
     } else if (strncmp(package.c_str(), "android.", 8) == 0) {
         return false;  // android.* packages are assumed fine
@@ -203,9 +204,9 @@
 
     // Overwrite package name and version if the caller was untrusted or empty
     if (!isTrusted || item->getPkgName().empty()) {
-        const uid_t uid = item->getUid();
+        const uid_t uidItem = item->getUid();
         const auto [ pkgName, version ] =
-                MediaMetricsService::getSanitizedPackageNameAndVersionCode(uid);
+                MediaMetricsService::getSanitizedPackageNameAndVersionCode(uidItem);
         item->setPkgName(pkgName);
         item->setPkgVersionCode(version);
     }
@@ -320,7 +321,7 @@
                 String8 value(args[i]);
                 char *endp;
                 const char *p = value.string();
-                long long sec = strtoll(p, &endp, 10);
+                const auto sec = (int64_t)strtoll(p, &endp, 10);
                 if (endp == p || *endp != '\0' || sec == 0) {
                     sinceNs = 0;
                 } else if (sec < 0) {
diff --git a/services/mediametrics/TimeMachine.h b/services/mediametrics/TimeMachine.h
index c82778b..00a44a4 100644
--- a/services/mediametrics/TimeMachine.h
+++ b/services/mediametrics/TimeMachine.h
@@ -18,6 +18,7 @@
 
 #include <any>
 #include <map>
+#include <mutex>
 #include <sstream>
 #include <string>
 #include <variant>
@@ -81,6 +82,8 @@
             , mCreationTime(time)
             , mLastModificationTime(time)
         {
+            (void)mCreationTime; // suppress unused warning.
+
             // allowUid allows an untrusted client with a matching uid to set properties
             // in this key.
             // If allowUid == (uid_t)-1, no untrusted client may set properties in the key.
@@ -209,7 +212,7 @@
 
         const std::string mKey;
         const uid_t mAllowUid;
-        const int64_t mCreationTime __unused;
+        const int64_t mCreationTime;
 
         int64_t mLastModificationTime;
         std::map<std::string /* property */, PropertyHistory> mPropertyMap;
@@ -442,7 +445,7 @@
                 ++it) {
             if (ll <= 0) break;
             if (prefix != nullptr && !startsWith(it->first, prefix)) break;
-            std::lock_guard lock(getLockForKey(it->first));
+            std::lock_guard lock2(getLockForKey(it->first));
             auto [s, l] = it->second->dump(ll, sinceNs);
             ss << s;
             ll -= l;
diff --git a/services/mediametrics/iface_statsd.cpp b/services/mediametrics/iface_statsd.cpp
index 3a1eea7..6e51f72 100644
--- a/services/mediametrics/iface_statsd.cpp
+++ b/services/mediametrics/iface_statsd.cpp
@@ -71,7 +71,7 @@
 
 // give me a record, i'll look at the type and upload appropriately
 bool dump2Statsd(const std::shared_ptr<const mediametrics::Item>& item) {
-    if (item == NULL) return false;
+    if (item == nullptr) return false;
 
     // get the key
     std::string key = item->getKey();
diff --git a/services/mediametrics/main_mediametrics.cpp b/services/mediametrics/main_mediametrics.cpp
index 6992c32..3a66538 100644
--- a/services/mediametrics/main_mediametrics.cpp
+++ b/services/mediametrics/main_mediametrics.cpp
@@ -25,9 +25,9 @@
 #include <binder/ProcessState.h>
 #include <mediautils/LimitProcessMemory.h>
 
-int main(int argc __unused, char **argv __unused)
+int main(int argc __unused, char **argv)
 {
-    using namespace android;
+    using namespace android; // NOLINT (clang-tidy)
 
     limitProcessMemory(
         "media.metrics.maxmem", /* property that defines limit */
@@ -39,7 +39,8 @@
     // to match the service name
     // we're replacing "/system/bin/mediametrics" with "media.metrics"
     // we add a ".", but discard the path components: we finish with a shorter string
-    strcpy(argv[0], MediaMetricsService::kServiceName);
+    const size_t origSize = strlen(argv[0]) + 1; // include null termination.
+    strlcpy(argv[0], MediaMetricsService::kServiceName, origSize);
 
     defaultServiceManager()->addService(
             String16(MediaMetricsService::kServiceName), new MediaMetricsService());
diff --git a/services/mediametrics/statsd_audiopolicy.cpp b/services/mediametrics/statsd_audiopolicy.cpp
index 634c801..393c6ae 100644
--- a/services/mediametrics/statsd_audiopolicy.cpp
+++ b/services/mediametrics/statsd_audiopolicy.cpp
@@ -39,7 +39,7 @@
 
 bool statsd_audiopolicy(const mediametrics::Item *item)
 {
-    if (item == NULL) return false;
+    if (item == nullptr) return false;
 
     // these go into the statsd wrapper
     const nsecs_t timestamp = MediaMetricsService::roundTime(item->getTimestamp());
@@ -122,4 +122,4 @@
     return true;
 }
 
-};
+} // namespace android
diff --git a/services/mediametrics/statsd_audiorecord.cpp b/services/mediametrics/statsd_audiorecord.cpp
index 69d1661..43feda1 100644
--- a/services/mediametrics/statsd_audiorecord.cpp
+++ b/services/mediametrics/statsd_audiorecord.cpp
@@ -39,7 +39,7 @@
 
 bool statsd_audiorecord(const mediametrics::Item *item)
 {
-    if (item == NULL) return false;
+    if (item == nullptr) return false;
 
     // these go into the statsd wrapper
     const nsecs_t timestamp = MediaMetricsService::roundTime(item->getTimestamp());
@@ -155,4 +155,4 @@
     return true;
 }
 
-};
+} // namespace android
diff --git a/services/mediametrics/statsd_audiothread.cpp b/services/mediametrics/statsd_audiothread.cpp
index 300151b..e867f5b 100644
--- a/services/mediametrics/statsd_audiothread.cpp
+++ b/services/mediametrics/statsd_audiothread.cpp
@@ -39,7 +39,7 @@
 
 bool statsd_audiothread(const mediametrics::Item *item)
 {
-    if (item == NULL) return false;
+    if (item == nullptr) return false;
 
     // these go into the statsd wrapper
     const nsecs_t timestamp = MediaMetricsService::roundTime(item->getTimestamp());
@@ -204,4 +204,4 @@
     return true;
 }
 
-};
+} // namespace android
diff --git a/services/mediametrics/statsd_audiotrack.cpp b/services/mediametrics/statsd_audiotrack.cpp
index 397cdf3..ee5b9b2 100644
--- a/services/mediametrics/statsd_audiotrack.cpp
+++ b/services/mediametrics/statsd_audiotrack.cpp
@@ -39,7 +39,7 @@
 
 bool statsd_audiotrack(const mediametrics::Item *item)
 {
-    if (item == NULL) return false;
+    if (item == nullptr) return false;
 
     // these go into the statsd wrapper
     const nsecs_t timestamp = MediaMetricsService::roundTime(item->getTimestamp());
@@ -146,4 +146,4 @@
     return true;
 }
 
-};
+} // namespace android
diff --git a/services/mediametrics/statsd_codec.cpp b/services/mediametrics/statsd_codec.cpp
index f5fa57e..7a38c7c 100644
--- a/services/mediametrics/statsd_codec.cpp
+++ b/services/mediametrics/statsd_codec.cpp
@@ -39,7 +39,7 @@
 
 bool statsd_codec(const mediametrics::Item *item)
 {
-    if (item == NULL) return false;
+    if (item == nullptr) return false;
 
     // these go into the statsd wrapper
     const nsecs_t timestamp = MediaMetricsService::roundTime(item->getTimestamp());
@@ -188,4 +188,4 @@
     return true;
 }
 
-};
+} // namespace android
diff --git a/services/mediametrics/statsd_drm.cpp b/services/mediametrics/statsd_drm.cpp
index 4f2e861..89d6f8f 100644
--- a/services/mediametrics/statsd_drm.cpp
+++ b/services/mediametrics/statsd_drm.cpp
@@ -43,22 +43,22 @@
 // mediadrm
 bool statsd_mediadrm(const mediametrics::Item *item)
 {
-    if (item == NULL) return false;
+    if (item == nullptr) return false;
 
     const nsecs_t timestamp = MediaMetricsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;
 
-    char *vendor = NULL;
+    char *vendor = nullptr;
     (void) item->getCString("vendor", &vendor);
-    char *description = NULL;
+    char *description = nullptr;
     (void) item->getCString("description", &description);
-    char *serialized_metrics = NULL;
+    char *serialized_metrics = nullptr;
     (void) item->getCString("serialized_metrics", &serialized_metrics);
 
     if (enabled_statsd) {
-        android::util::BytesField bf_serialized(serialized_metrics ? serialized_metrics : NULL,
+        android::util::BytesField bf_serialized(serialized_metrics ? serialized_metrics : nullptr,
                                                 serialized_metrics ? strlen(serialized_metrics)
                                                                    : 0);
         android::util::stats_write(android::util::MEDIAMETRICS_MEDIADRM_REPORTED,
@@ -80,18 +80,18 @@
 // widevineCDM
 bool statsd_widevineCDM(const mediametrics::Item *item)
 {
-    if (item == NULL) return false;
+    if (item == nullptr) return false;
 
     const nsecs_t timestamp = MediaMetricsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;
 
-    char *serialized_metrics = NULL;
+    char *serialized_metrics = nullptr;
     (void) item->getCString("serialized_metrics", &serialized_metrics);
 
     if (enabled_statsd) {
-        android::util::BytesField bf_serialized(serialized_metrics ? serialized_metrics : NULL,
+        android::util::BytesField bf_serialized(serialized_metrics ? serialized_metrics : nullptr,
                                                 serialized_metrics ? strlen(serialized_metrics)
                                                                    : 0);
         android::util::stats_write(android::util::MEDIAMETRICS_DRM_WIDEVINE_REPORTED,
@@ -111,7 +111,7 @@
 bool statsd_drmmanager(const mediametrics::Item *item)
 {
     using namespace std::string_literals;
-    if (item == NULL) return false;
+    if (item == nullptr) return false;
 
     if (!enabled_statsd) {
         ALOGV("NOT sending: drmmanager data");
@@ -123,13 +123,13 @@
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;
 
-    char *plugin_id = NULL;
+    char *plugin_id = nullptr;
     (void) item->getCString("plugin_id", &plugin_id);
-    char *description = NULL;
+    char *description = nullptr;
     (void) item->getCString("description", &description);
     int32_t method_id = -1;
     (void) item->getInt32("method_id", &method_id);
-    char *mime_types = NULL;
+    char *mime_types = nullptr;
     (void) item->getCString("mime_types", &mime_types);
 
     // Corresponds to the 13 APIs tracked in the MediametricsDrmManagerReported statsd proto
diff --git a/services/mediametrics/statsd_extractor.cpp b/services/mediametrics/statsd_extractor.cpp
index 8574358..3d5739f 100644
--- a/services/mediametrics/statsd_extractor.cpp
+++ b/services/mediametrics/statsd_extractor.cpp
@@ -39,7 +39,7 @@
 
 bool statsd_extractor(const mediametrics::Item *item)
 {
-    if (item == NULL) return false;
+    if (item == nullptr) return false;
 
     // these go into the statsd wrapper
     const nsecs_t timestamp = MediaMetricsService::roundTime(item->getTimestamp());
@@ -91,4 +91,4 @@
     return true;
 }
 
-};
+} // namespace android
diff --git a/services/mediametrics/statsd_nuplayer.cpp b/services/mediametrics/statsd_nuplayer.cpp
index df7e59f..488bdcb 100644
--- a/services/mediametrics/statsd_nuplayer.cpp
+++ b/services/mediametrics/statsd_nuplayer.cpp
@@ -43,7 +43,7 @@
  */
 bool statsd_nuplayer(const mediametrics::Item *item)
 {
-    if (item == NULL) return false;
+    if (item == nullptr) return false;
 
     // these go into the statsd wrapper
     const nsecs_t timestamp = MediaMetricsService::roundTime(item->getTimestamp());
@@ -167,4 +167,4 @@
     return true;
 }
 
-};
+} // namespace android
diff --git a/services/mediametrics/statsd_recorder.cpp b/services/mediametrics/statsd_recorder.cpp
index 4de1746..6d5fca0 100644
--- a/services/mediametrics/statsd_recorder.cpp
+++ b/services/mediametrics/statsd_recorder.cpp
@@ -39,7 +39,7 @@
 
 bool statsd_recorder(const mediametrics::Item *item)
 {
-    if (item == NULL) return false;
+    if (item == nullptr) return false;
 
     // these go into the statsd wrapper
     const nsecs_t timestamp = MediaMetricsService::roundTime(item->getTimestamp());
@@ -186,4 +186,4 @@
     return true;
 }
 
-};
+} // namespace android