Merge "[hardware][interfaces][renderscript] fix -Wreorder-init-list"
diff --git a/audio/4.0/config/api/current.txt b/audio/4.0/config/api/current.txt
index d59cade..3462568 100644
--- a/audio/4.0/config/api/current.txt
+++ b/audio/4.0/config/api/current.txt
@@ -114,11 +114,15 @@
     enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_EVRCNW;
     enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_EVRCWB;
     enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_E_AC3;
+    enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_E_AC3_JOC;
     enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_FLAC;
     enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_HE_AAC_V1;
     enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_HE_AAC_V2;
     enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_IEC61937;
     enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_LDAC;
+    enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_MAT_1_0;
+    enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_MAT_2_0;
+    enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_MAT_2_1;
     enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_MP2;
     enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_MP3;
     enum_constant public static final audio.policy.configuration.V4_0.AudioFormat AUDIO_FORMAT_OPUS;
diff --git a/audio/4.0/config/audio_policy_configuration.xsd b/audio/4.0/config/audio_policy_configuration.xsd
index 58bab22..f26e41b 100644
--- a/audio/4.0/config/audio_policy_configuration.xsd
+++ b/audio/4.0/config/audio_policy_configuration.xsd
@@ -357,6 +357,10 @@
             <xs:enumeration value="AUDIO_FORMAT_APTX_HD"/>
             <xs:enumeration value="AUDIO_FORMAT_AC4"/>
             <xs:enumeration value="AUDIO_FORMAT_LDAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT_2_0"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT_2_1"/>
         </xs:restriction>
     </xs:simpleType>
     <xs:simpleType name="extendableAudioFormat">
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index 022f75e..2814c63 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -117,6 +117,10 @@
                 ASSERT_NE(0U, activeMicrophones.size());
             }
             stream->close();
+            // Workaround for b/139329877. Ensures the stream gets closed on the audio hal side.
+            stream.clear();
+            IPCThreadState::self()->flushCommands();
+            usleep(1000);
             if (efGroup) {
                 EventFlag::deleteEventFlag(&efGroup);
             }
diff --git a/authsecret/1.0/vts/functional/Android.bp b/authsecret/1.0/vts/functional/Android.bp
index f2b3a8a..9ce9cda 100644
--- a/authsecret/1.0/vts/functional/Android.bp
+++ b/authsecret/1.0/vts/functional/Android.bp
@@ -19,5 +19,9 @@
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["VtsHalAuthSecretV1_0TargetTest.cpp"],
     static_libs: ["android.hardware.authsecret@1.0"],
-    test_suites: ["general-tests"],
+    test_suites: [
+        "general-tests",
+        "vts-core",
+    ],
+    require_root: true,
 }
diff --git a/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
index 255d4de..0bff9df 100644
--- a/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
+++ b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
@@ -16,36 +16,22 @@
 
 #include <android/hardware/authsecret/1.0/IAuthSecret.h>
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 using ::android::hardware::hidl_vec;
 using ::android::hardware::authsecret::V1_0::IAuthSecret;
 using ::android::sp;
 
-// Test environment for Boot HIDL HAL.
-class AuthSecretHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static AuthSecretHidlEnvironment* Instance() {
-        static AuthSecretHidlEnvironment* instance = new AuthSecretHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IAuthSecret>(); }
-
-   private:
-    AuthSecretHidlEnvironment() {}
-};
-
 /**
  * There is no expected behaviour that can be tested so these tests check the
  * HAL doesn't crash with different execution orders.
  */
-struct AuthSecretHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class AuthSecretHidlTest : public testing::TestWithParam<std::string> {
+  public:
     virtual void SetUp() override {
-        authsecret = ::testing::VtsHalHidlTargetTestBase::getService<IAuthSecret>(
-            AuthSecretHidlEnvironment::Instance()->getServiceName<IAuthSecret>());
+        authsecret = IAuthSecret::getService(GetParam());
         ASSERT_NE(authsecret, nullptr);
 
         // All tests must enroll the correct secret first as this cannot be changed
@@ -59,18 +45,18 @@
 };
 
 /* Provision the primary user with a secret. */
-TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredential) {
+TEST_P(AuthSecretHidlTest, provisionPrimaryUserCredential) {
     // Secret provisioned by SetUp()
 }
 
 /* Provision the primary user with a secret and pass the secret again. */
-TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredentialAndPassAgain) {
+TEST_P(AuthSecretHidlTest, provisionPrimaryUserCredentialAndPassAgain) {
     // Secret provisioned by SetUp()
     authsecret->primaryUserCredential(CORRECT_SECRET);
 }
 
 /* Provision the primary user with a secret and pass the secret again repeatedly. */
-TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredentialAndPassAgainMultipleTimes) {
+TEST_P(AuthSecretHidlTest, provisionPrimaryUserCredentialAndPassAgainMultipleTimes) {
     // Secret provisioned by SetUp()
     constexpr int N = 5;
     for (int i = 0; i < N; ++i) {
@@ -82,16 +68,12 @@
  * should never happen and is an framework bug if it does. As the secret is
  * wrong, the HAL implementation may not be able to function correctly but it
  * should fail gracefully. */
-TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredentialAndWrongSecret) {
+TEST_P(AuthSecretHidlTest, provisionPrimaryUserCredentialAndWrongSecret) {
     // Secret provisioned by SetUp()
     authsecret->primaryUserCredential(WRONG_SECRET);
 }
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(AuthSecretHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    AuthSecretHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    ALOGI("Test result = %d", status);
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, AuthSecretHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IAuthSecret::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/automotive/vehicle/2.0/default/tests/VehicleObjectPool_test.cpp b/automotive/vehicle/2.0/default/tests/VehicleObjectPool_test.cpp
index a291351..4e3ade1 100644
--- a/automotive/vehicle/2.0/default/tests/VehicleObjectPool_test.cpp
+++ b/automotive/vehicle/2.0/default/tests/VehicleObjectPool_test.cpp
@@ -57,11 +57,11 @@
 };
 
 TEST_F(VehicleObjectPoolTest, valuePoolBasicCorrectness) {
-    void* raw = valuePool->obtain(VehiclePropertyType::INT32).get();
+    auto value = valuePool->obtain(VehiclePropertyType::INT32);
     // At this point, v1 should be recycled and the only object in the pool.
-    ASSERT_EQ(raw, valuePool->obtain(VehiclePropertyType::INT32).get());
+    ASSERT_EQ(value.get(), valuePool->obtain(VehiclePropertyType::INT32).get());
     // Obtaining value of another type - should return a new object
-    ASSERT_NE(raw, valuePool->obtain(VehiclePropertyType::FLOAT).get());
+    ASSERT_NE(value.get(), valuePool->obtain(VehiclePropertyType::FLOAT).get());
 
     ASSERT_EQ(3u, stats->Obtained);
     ASSERT_EQ(2u, stats->Created);
diff --git a/bluetooth/audio/2.0/default/session/BluetoothAudioSession.h b/bluetooth/audio/2.0/default/session/BluetoothAudioSession.h
index 85e8742..838d1cc 100644
--- a/bluetooth/audio/2.0/default/session/BluetoothAudioSession.h
+++ b/bluetooth/audio/2.0/default/session/BluetoothAudioSession.h
@@ -156,8 +156,9 @@
 
   static constexpr PcmParameters kInvalidPcmParameters = {
       .sampleRate = SampleRate::RATE_UNKNOWN,
+      .channelMode = ChannelMode::UNKNOWN,
       .bitsPerSample = BitsPerSample::BITS_UNKNOWN,
-      .channelMode = ChannelMode::UNKNOWN};
+  };
   // can't be constexpr because of non-literal type
   static const CodecConfiguration kInvalidCodecConfiguration;
 
diff --git a/bluetooth/audio/2.0/default/session/BluetoothAudioSupportedCodecsDB.cpp b/bluetooth/audio/2.0/default/session/BluetoothAudioSupportedCodecsDB.cpp
index 292e28b..6ea61e1 100644
--- a/bluetooth/audio/2.0/default/session/BluetoothAudioSupportedCodecsDB.cpp
+++ b/bluetooth/audio/2.0/default/session/BluetoothAudioSupportedCodecsDB.cpp
@@ -94,16 +94,18 @@
 static const AptxParameters kDefaultOffloadAptxCapability = {
     .sampleRate = static_cast<SampleRate>(SampleRate::RATE_44100 |
                                           SampleRate::RATE_48000),
+    .channelMode = ChannelMode::STEREO,
     .bitsPerSample = BitsPerSample::BITS_16,
-    .channelMode = ChannelMode::STEREO};
+};
 
 // aptX HD: mSampleRate:(44100|48000), mBitsPerSample:(24),
 //          mChannelMode:(STEREO)
 static const AptxParameters kDefaultOffloadAptxHdCapability = {
     .sampleRate = static_cast<SampleRate>(SampleRate::RATE_44100 |
                                           SampleRate::RATE_48000),
+    .channelMode = ChannelMode::STEREO,
     .bitsPerSample = BitsPerSample::BITS_24,
-    .channelMode = ChannelMode::STEREO};
+};
 
 const std::vector<CodecCapabilities> kDefaultOffloadA2dpCodecCapabilities = {
     {.codecType = CodecType::SBC, .capabilities = {}},
diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp
index 9a2fddf..f518a15 100644
--- a/camera/device/3.4/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -754,11 +754,11 @@
         int fd, double fpsUpperBound, SupportedV4L2Format* format) {
     format->frameRates.clear();
 
-    v4l2_frmivalenum frameInterval {
-        .pixel_format = format->fourcc,
-        .width = format->width,
-        .height = format->height,
-        .index = 0
+    v4l2_frmivalenum frameInterval{
+            .index = 0,
+            .pixel_format = format->fourcc,
+            .width = format->width,
+            .height = format->height,
     };
 
     for (frameInterval.index = 0;
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index dc5579a..9ff0d74 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -2412,9 +2412,7 @@
     mV4L2BufferCount = req_buffers.count;
     for (uint32_t i = 0; i < req_buffers.count; i++) {
         v4l2_buffer buffer = {
-            .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
-            .index = i,
-            .memory = V4L2_MEMORY_MMAP};
+                .index = i, .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, .memory = V4L2_MEMORY_MMAP};
 
         if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QUERYBUF, &buffer)) < 0) {
             ALOGE("%s: QUERYBUF %d failed: %s", __FUNCTION__, i,  strerror(errno));
diff --git a/current.txt b/current.txt
index 972fe16..21db232 100644
--- a/current.txt
+++ b/current.txt
@@ -586,3 +586,6 @@
 # HALs released in Android R
 07d0a252b2d8fa35887908a996ba395cf392968395fc30afab791f46e0c22a52 android.hardware.boot@1.1::IBootControl
 74049a402be913963edfdd80828a53736570e9d8124a1bf18166b6ed46a6b0ab android.hardware.boot@1.1::types
+544049dcda3f943ad67d83d5277f06681a3782982a9af5a78b5d4e8d295d061a android.hardware.vibrator@1.4::IVibrator
+5e1c12efbbba89c9143d10b1b90eceff8bc79aa079f5106215b528e104fef101 android.hardware.vibrator@1.4::IVibratorCallback
+033eae03c09ebc75e82db37bc39995dfaa9086745577b44d9e14e9ccb48bd8cc android.hardware.vibrator@1.4::types
diff --git a/gnss/1.0/default/Gnss.cpp b/gnss/1.0/default/Gnss.cpp
index 32c131c..7d1cacf 100644
--- a/gnss/1.0/default/Gnss.cpp
+++ b/gnss/1.0/default/Gnss.cpp
@@ -128,20 +128,20 @@
     for (size_t i = 0; i < svStatus.numSvs; i++) {
         auto svInfo = status->gnss_sv_list[i];
         IGnssCallback::GnssSvInfo gnssSvInfo = {
-            .svid = svInfo.svid,
-            .constellation = static_cast<
-                android::hardware::gnss::V1_0::GnssConstellationType>(
-                svInfo.constellation),
-            .cN0Dbhz = svInfo.c_n0_dbhz,
-            .elevationDegrees = svInfo.elevation,
-            .azimuthDegrees = svInfo.azimuth,
-            // Older chipsets do not provide carrier frequency, hence
-            // HAS_CARRIER_FREQUENCY flag and the carrierFrequencyHz fields
-            // are not set. So we are resetting both fields here.
-            .svFlag = static_cast<uint8_t>(
-                svInfo.flags &= ~(static_cast<uint8_t>(
-                    IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY))),
-            .carrierFrequencyHz = 0};
+                .svid = svInfo.svid,
+                .constellation = static_cast<android::hardware::gnss::V1_0::GnssConstellationType>(
+                        svInfo.constellation),
+                .cN0Dbhz = svInfo.c_n0_dbhz,
+                .elevationDegrees = svInfo.elevation,
+                .azimuthDegrees = svInfo.azimuth,
+                .carrierFrequencyHz = 0,
+                // Older chipsets do not provide carrier frequency, hence
+                // HAS_CARRIER_FREQUENCY flag and the carrierFrequencyHz fields
+                // are not set. So we are resetting both fields here.
+                .svFlag = static_cast<uint8_t>(
+                        svInfo.flags &=
+                        ~(static_cast<uint8_t>(IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY))),
+        };
         svStatus.gnssSvList[i] = gnssSvInfo;
     }
 
diff --git a/gnss/2.0/default/GnssMeasurement.cpp b/gnss/2.0/default/GnssMeasurement.cpp
index 93de89c..1f95ff9 100644
--- a/gnss/2.0/default/GnssMeasurement.cpp
+++ b/gnss/2.0/default/GnssMeasurement.cpp
@@ -119,12 +119,13 @@
     V2_0::IGnssMeasurementCallback::GnssMeasurement measurement_2_0 = {
             .v1_1 = measurement_1_1,
             .codeType = "C",
-            .constellation = GnssConstellationType::GLONASS,
             .state = GnssMeasurementState::STATE_CODE_LOCK | GnssMeasurementState::STATE_BIT_SYNC |
                      GnssMeasurementState::STATE_SUBFRAME_SYNC |
                      GnssMeasurementState::STATE_TOW_DECODED |
                      GnssMeasurementState::STATE_GLO_STRING_SYNC |
-                     GnssMeasurementState::STATE_GLO_TOD_DECODED};
+                     GnssMeasurementState::STATE_GLO_TOD_DECODED,
+            .constellation = GnssConstellationType::GLONASS,
+    };
 
     hidl_vec<IGnssMeasurementCallback::GnssMeasurement> measurements(1);
     measurements[0] = measurement_2_0;
diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp
index 04382b0..15e8aaf 100644
--- a/tv/tuner/1.0/default/Demux.cpp
+++ b/tv/tuner/1.0/default/Demux.cpp
@@ -106,7 +106,7 @@
     } else {
         filterId = ++mLastUsedFilterId;
 
-        mDemuxCallbacks.resize(filterId + 1);
+        mFilterCallbacks.resize(filterId + 1);
         mFilterMQs.resize(filterId + 1);
         mFilterEvents.resize(filterId + 1);
         mFilterEventFlags.resize(filterId + 1);
@@ -114,6 +114,7 @@
         mFilterThreads.resize(filterId + 1);
         mFilterPids.resize(filterId + 1);
         mFilterOutputs.resize(filterId + 1);
+        mFilterStatus.resize(filterId + 1);
     }
 
     mUsedFilterIds.insert(filterId);
@@ -125,7 +126,7 @@
     }
 
     // Add callback
-    mDemuxCallbacks[filterId] = cb;
+    mFilterCallbacks[filterId] = cb;
 
     // Mapping from the filter ID to the filter event
     DemuxFilterEvent event{
@@ -211,9 +212,16 @@
     return Result::SUCCESS;
 }
 
-Return<Result> Demux::flushFilter(uint32_t /* filterId */) {
+Return<Result> Demux::flushFilter(uint32_t filterId) {
     ALOGV("%s", __FUNCTION__);
 
+    // temp implementation to flush the FMQ
+    int size = mFilterMQs[filterId]->availableToRead();
+    char* buffer = new char[size];
+    mOutputMQ->read((unsigned char*)&buffer[0], size);
+    delete[] buffer;
+    mFilterStatus[filterId] = DemuxFilterStatus::DATA_READY;
+
     return Result::SUCCESS;
 }
 
@@ -254,7 +262,7 @@
     mFilterThreads.clear();
     mUnusedFilterIds.clear();
     mUsedFilterIds.clear();
-    mDemuxCallbacks.clear();
+    mFilterCallbacks.clear();
     mFilterMQs.clear();
     mFilterEvents.clear();
     mFilterEventFlags.clear();
@@ -458,32 +466,54 @@
 
 Result Demux::startPesFilterHandler(uint32_t filterId) {
     std::lock_guard<std::mutex> lock(mFilterEventLock);
-    DemuxFilterPesEvent pesEvent;
     if (mFilterOutputs[filterId].empty()) {
         return Result::SUCCESS;
     }
 
     for (int i = 0; i < mFilterOutputs[filterId].size(); i += 188) {
-        uint8_t pusi = mFilterOutputs[filterId][i + 1] & 0x40;
-        uint8_t adaptFieldControl = (mFilterOutputs[filterId][i + 3] & 0x30) >> 4;
-        ALOGD("[Demux] pusi %d, adaptFieldControl %d", pusi, adaptFieldControl);
-        if (pusi && (adaptFieldControl == 0x01)) {
-            vector<uint8_t>::const_iterator first = mFilterOutputs[filterId].begin() + i + 4;
-            vector<uint8_t>::const_iterator last = mFilterOutputs[filterId].begin() + i + 187;
-            vector<uint8_t> filterOutData(first, last);
-            if (!writeDataToFilterMQ(filterOutData, filterId)) {
-                mFilterOutputs[filterId].clear();
-                return Result::INVALID_STATE;
+        if (mPesSizeLeft == 0) {
+            uint32_t prefix = (mFilterOutputs[filterId][i + 4] << 16) |
+                              (mFilterOutputs[filterId][i + 5] << 8) |
+                              mFilterOutputs[filterId][i + 6];
+            ALOGD("[Demux] prefix %d", prefix);
+            if (prefix == 0x000001) {
+                // TODO handle mulptiple Pes filters
+                mPesSizeLeft =
+                        (mFilterOutputs[filterId][i + 7] << 8) | mFilterOutputs[filterId][i + 8];
+                ALOGD("[Demux] pes data length %d", mPesSizeLeft);
+            } else {
+                continue;
             }
-            pesEvent = {
-                    // temp dump meta data
-                    .streamId = filterOutData[3],
-                    .dataLength = static_cast<uint16_t>(filterOutData.size()),
-            };
-            int size = mFilterEvents[filterId].events.size();
-            mFilterEvents[filterId].events.resize(size + 1);
-            mFilterEvents[filterId].events[size].pes(pesEvent);
         }
+
+        int endPoint = min(184, mPesSizeLeft);
+        // append data and check size
+        vector<uint8_t>::const_iterator first = mFilterOutputs[filterId].begin() + i + 4;
+        vector<uint8_t>::const_iterator last = mFilterOutputs[filterId].begin() + i + 3 + endPoint;
+        mPesOutput.insert(mPesOutput.end(), first, last);
+        // size does not match then continue
+        mPesSizeLeft -= endPoint;
+        if (mPesSizeLeft > 0) {
+            continue;
+        }
+        // size match then create event
+        if (!writeDataToFilterMQ(mPesOutput, filterId)) {
+            mFilterOutputs[filterId].clear();
+            return Result::INVALID_STATE;
+        }
+        maySendFilterStatusCallback(filterId);
+        DemuxFilterPesEvent pesEvent;
+        pesEvent = {
+                // temp dump meta data
+                .streamId = mPesOutput[3],
+                .dataLength = static_cast<uint16_t>(mPesOutput.size()),
+        };
+        ALOGD("[Demux] assembled pes data length %d", pesEvent.dataLength);
+
+        int size = mFilterEvents[filterId].events.size();
+        mFilterEvents[filterId].events.resize(size + 1);
+        mFilterEvents[filterId].events[size].pes(pesEvent);
+        mPesOutput.clear();
     }
 
     mFilterOutputs[filterId].clear();
@@ -672,8 +702,10 @@
             continue;
         }
         // After successfully write, send a callback and wait for the read to be done
-        mDemuxCallbacks[filterId]->onFilterEvent(mFilterEvents[filterId]);
+        mFilterCallbacks[filterId]->onFilterEvent(mFilterEvents[filterId]);
         mFilterEvents[filterId].events.resize(0);
+        mFilterStatus[filterId] = DemuxFilterStatus::DATA_READY;
+        mFilterCallbacks[filterId]->onFilterStatus(filterId, mFilterStatus[filterId]);
         break;
     }
 
@@ -693,18 +725,20 @@
                 break;
             }
 
-            if (mDemuxCallbacks[filterId] == nullptr) {
+            if (mFilterCallbacks[filterId] == nullptr) {
                 ALOGD("[Demux] filter %d does not hava callback. Ending thread", filterId);
                 break;
             }
 
+            maySendFilterStatusCallback(filterId);
+
             while (mFilterThreadRunning[filterId]) {
                 std::lock_guard<std::mutex> lock(mFilterEventLock);
                 if (mFilterEvents[filterId].events.size() == 0) {
                     continue;
                 }
                 // After successfully write, send a callback and wait for the read to be done
-                mDemuxCallbacks[filterId]->onFilterEvent(mFilterEvents[filterId]);
+                mFilterCallbacks[filterId]->onFilterEvent(mFilterEvents[filterId]);
                 mFilterEvents[filterId].events.resize(0);
                 break;
             }
@@ -755,16 +789,31 @@
     int availableToWrite = mInputMQ->availableToWrite();
 
     DemuxInputStatus newStatus =
-            checkStatusChange(availableToWrite, availableToRead, mInputSettings.highThreshold,
-                              mInputSettings.lowThreshold);
+            checkInputStatusChange(availableToWrite, availableToRead, mInputSettings.highThreshold,
+                                   mInputSettings.lowThreshold);
     if (mIntputStatus != newStatus) {
         mInputCallback->onInputStatus(newStatus);
         mIntputStatus = newStatus;
     }
 }
 
-DemuxInputStatus Demux::checkStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
-                                          uint32_t highThreshold, uint32_t lowThreshold) {
+void Demux::maySendFilterStatusCallback(uint32_t filterId) {
+    std::lock_guard<std::mutex> lock(mFilterStatusLock);
+    int availableToRead = mFilterMQs[filterId]->availableToRead();
+    int availableToWrite = mInputMQ->availableToWrite();
+    int fmqSize = mFilterMQs[filterId]->getQuantumCount();
+
+    DemuxFilterStatus newStatus =
+            checkFilterStatusChange(filterId, availableToWrite, availableToRead,
+                                    ceil(fmqSize * 0.75), ceil(fmqSize * 0.25));
+    if (mFilterStatus[filterId] != newStatus) {
+        mFilterCallbacks[filterId]->onFilterStatus(filterId, newStatus);
+        mFilterStatus[filterId] = newStatus;
+    }
+}
+
+DemuxInputStatus Demux::checkInputStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
+                                               uint32_t highThreshold, uint32_t lowThreshold) {
     if (availableToWrite == 0) {
         return DemuxInputStatus::SPACE_FULL;
     } else if (availableToRead > highThreshold) {
@@ -777,6 +826,19 @@
     return mIntputStatus;
 }
 
+DemuxFilterStatus Demux::checkFilterStatusChange(uint32_t filterId, uint32_t availableToWrite,
+                                                 uint32_t availableToRead, uint32_t highThreshold,
+                                                 uint32_t lowThreshold) {
+    if (availableToWrite == 0) {
+        return DemuxFilterStatus::OVERFLOW;
+    } else if (availableToRead > highThreshold) {
+        return DemuxFilterStatus::HIGH_WATER;
+    } else if (availableToRead < lowThreshold) {
+        return DemuxFilterStatus::LOW_WATER;
+    }
+    return mFilterStatus[filterId];
+}
+
 Result Demux::startBroadcastInputLoop() {
     pthread_create(&mBroadcastInputThread, NULL, __threadLoopBroadcast, this);
     pthread_setname_np(mBroadcastInputThread, "broadcast_input_thread");
@@ -818,7 +880,7 @@
                 }
                 // filter and dispatch filter output
                 vector<uint8_t> byteBuffer;
-                byteBuffer.resize(sizeof(buffer));
+                byteBuffer.resize(packetSize);
                 for (int index = 0; index < byteBuffer.size(); index++) {
                     byteBuffer[index] = static_cast<uint8_t>(buffer[index]);
                 }
diff --git a/tv/tuner/1.0/default/Demux.h b/tv/tuner/1.0/default/Demux.h
index e4a4e2b..ba0b9b0 100644
--- a/tv/tuner/1.0/default/Demux.h
+++ b/tv/tuner/1.0/default/Demux.h
@@ -19,6 +19,7 @@
 
 #include <android/hardware/tv/tuner/1.0/IDemux.h>
 #include <fmq/MessageQueue.h>
+#include <math.h>
 #include <set>
 #include "Frontend.h"
 #include "Tuner.h"
@@ -153,8 +154,12 @@
     bool readDataFromMQ();
     bool writeSectionsAndCreateEvent(uint32_t filterId, vector<uint8_t> data);
     void maySendInputStatusCallback();
-    DemuxInputStatus checkStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
-                                       uint32_t highThreshold, uint32_t lowThreshold);
+    void maySendFilterStatusCallback(uint32_t filterId);
+    DemuxInputStatus checkInputStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
+                                            uint32_t highThreshold, uint32_t lowThreshold);
+    DemuxFilterStatus checkFilterStatusChange(uint32_t filterId, uint32_t availableToWrite,
+                                              uint32_t availableToRead, uint32_t highThreshold,
+                                              uint32_t lowThreshold);
     /**
      * A dispatcher to read and dispatch input data to all the started filters.
      * Each filter handler handles the data filtering/output writing/filterEvent updating.
@@ -203,7 +208,7 @@
     /**
      * Demux callbacks used on filter events or IO buffer status
      */
-    vector<sp<IDemuxCallback>> mDemuxCallbacks;
+    vector<sp<IDemuxCallback>> mFilterCallbacks;
     sp<IDemuxCallback> mInputCallback;
     sp<IDemuxCallback> mOutputCallback;
     bool mInputConfigured = false;
@@ -219,6 +224,7 @@
 
     // FMQ status local records
     DemuxInputStatus mIntputStatus;
+    vector<DemuxFilterStatus> mFilterStatus;
     /**
      * If a specific filter's writing loop is still running
      */
@@ -239,6 +245,7 @@
      * Lock to protect writes to the input status
      */
     std::mutex mInputStatusLock;
+    std::mutex mFilterStatusLock;
     std::mutex mBroadcastInputThreadLock;
     std::mutex mFilterThreadLock;
     std::mutex mInputThreadLock;
@@ -247,6 +254,11 @@
      * TODO make this dynamic/random/can take as a parameter
      */
     const uint16_t SECTION_WRITE_COUNT = 10;
+
+    // temp handle single PES filter
+    // TODO handle mulptiple Pes filters
+    int mPesSizeLeft = 0;
+    vector<uint8_t> mPesOutput;
 };
 
 }  // namespace implementation
diff --git a/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp
index dbf7bd6..4e9ebde 100644
--- a/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp
+++ b/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp
@@ -170,12 +170,14 @@
 
         legacy_hal::wifi_channel_stat channel_stat1 = {
             .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0},
+            .on_time = 0x1111,
             .cca_busy_time = 0x55,
-            .on_time = 0x1111};
+        };
         legacy_hal::wifi_channel_stat channel_stat2 = {
             .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0},
+            .on_time = 0x2222,
             .cca_busy_time = 0x66,
-            .on_time = 0x2222};
+        };
         radio.channel_stats.push_back(channel_stat1);
         radio.channel_stats.push_back(channel_stat2);
     }