Merge changes from topic "evs_next"

* changes:
  Explictly cast size_t into a long data type
  Revert "Revert "Revert "Revert "Extend EVS interfaces and data types""""
diff --git a/current.txt b/current.txt
index 87498a1..4e0d0e0 100644
--- a/current.txt
+++ b/current.txt
@@ -595,3 +595,6 @@
 619fc9839ec6e369cfa9b28e3e9412e6885720ff8f9b5750c1b6ffb905120391 android.hardware.wifi.supplicant@1.3::ISupplicantStaIfaceCallback
 6fe09b18e913608579638594788198ec45bb2369e567d7df661db46c4f0e5f08 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork
 91931b05bd70ea6bdffbe075086183f803379571788564e28854207620eb75cf android.hardware.wifi.supplicant@1.3::types
+033eae03c09ebc75e82db37bc39995dfaa9086745577b44d9e14e9ccb48bd8cc android.hardware.vibrator@1.4::types
+544049dcda3f943ad67d83d5277f06681a3782982a9af5a78b5d4e8d295d061a android.hardware.vibrator@1.4::IVibrator
+5e1c12efbbba89c9143d10b1b90eceff8bc79aa079f5106215b528e104fef101 android.hardware.vibrator@1.4::IVibratorCallback
diff --git a/light/2.0/vts/functional/Android.bp b/light/2.0/vts/functional/Android.bp
index 9f03d27..2c0a08f 100644
--- a/light/2.0/vts/functional/Android.bp
+++ b/light/2.0/vts/functional/Android.bp
@@ -19,6 +19,6 @@
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["VtsHalLightV2_0TargetTest.cpp"],
     static_libs: ["android.hardware.light@2.0"],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
 
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index 3e9d5f7..ba9fb45 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -71,5 +71,5 @@
     header_libs: [
         "libneuralnetworks_headers",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp
index 4e85355..69e1761 100644
--- a/neuralnetworks/1.1/vts/functional/Android.bp
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -47,5 +47,5 @@
     header_libs: [
         "libneuralnetworks_headers",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index fc727b7..bdca0e9 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -71,5 +71,5 @@
     header_libs: [
         "libneuralnetworks_headers",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/sensors/2.0/multihal/HalProxy.cpp b/sensors/2.0/multihal/HalProxy.cpp
index 1fbc787..5aa3b3d 100644
--- a/sensors/2.0/multihal/HalProxy.cpp
+++ b/sensors/2.0/multihal/HalProxy.cpp
@@ -38,6 +38,18 @@
 
 typedef ISensorsSubHal*(SensorsHalGetSubHalFunc)(uint32_t*);
 
+/**
+ * Set the subhal index as first byte of sensor handle and return this modified version.
+ *
+ * @param sensorHandle The sensor handle to modify.
+ * @param subHalIndex The index in the hal proxy of the sub hal this sensor belongs to.
+ *
+ * @return The modified sensor handle.
+ */
+uint32_t setSubHalIndex(uint32_t sensorHandle, size_t subHalIndex) {
+    return sensorHandle | (subHalIndex << 24);
+}
+
 HalProxy::HalProxy() {
     const char* kMultiHalConfigFile = "/vendor/etc/sensors/hals.conf";
     initializeSubHalListFromConfigFile(kMultiHalConfigFile);
@@ -206,15 +218,45 @@
     return Return<void>();
 }
 
-Return<void> HalProxy::onDynamicSensorsConnected(
-        const hidl_vec<SensorInfo>& /* dynamicSensorsAdded */, int32_t /* subHalIndex */) {
-    // TODO: Map the SensorInfo to the global list and then invoke the framework's callback.
+Return<void> HalProxy::onDynamicSensorsConnected(const hidl_vec<SensorInfo>& dynamicSensorsAdded,
+                                                 int32_t subHalIndex) {
+    std::vector<SensorInfo> sensors;
+    {
+        std::lock_guard<std::mutex> lock(mDynamicSensorsMutex);
+        for (SensorInfo sensor : dynamicSensorsAdded) {
+            if (!subHalIndexIsClear(sensor.sensorHandle)) {
+                ALOGE("Dynamic sensor added %s had sensorHandle with first byte not 0.",
+                      sensor.name.c_str());
+            } else {
+                sensor.sensorHandle = setSubHalIndex(sensor.sensorHandle, subHalIndex);
+                mDynamicSensors[sensor.sensorHandle] = sensor;
+                sensors.push_back(sensor);
+            }
+        }
+    }
+    mDynamicSensorsCallback->onDynamicSensorsConnected(sensors);
     return Return<void>();
 }
 
 Return<void> HalProxy::onDynamicSensorsDisconnected(
-        const hidl_vec<int32_t>& /* dynamicSensorHandlesRemoved */, int32_t /* subHalIndex */) {
-    // TODO: Unmap the SensorInfo from the global list and then invoke the framework's callback.
+        const hidl_vec<int32_t>& dynamicSensorHandlesRemoved, int32_t subHalIndex) {
+    // TODO: Block this call until all pending events are flushed from queue
+    std::vector<int32_t> sensorHandles;
+    {
+        std::lock_guard<std::mutex> lock(mDynamicSensorsMutex);
+        for (int32_t sensorHandle : dynamicSensorHandlesRemoved) {
+            if (!subHalIndexIsClear(sensorHandle)) {
+                ALOGE("Dynamic sensorHandle removed had first byte not 0.");
+            } else {
+                sensorHandle = setSubHalIndex(sensorHandle, subHalIndex);
+                if (mDynamicSensors.find(sensorHandle) != mDynamicSensors.end()) {
+                    mDynamicSensors.erase(sensorHandle);
+                    sensorHandles.push_back(sensorHandle);
+                }
+            }
+        }
+    }
+    mDynamicSensorsCallback->onDynamicSensorsDisconnected(sensorHandles);
     return Return<void>();
 }
 
@@ -264,7 +306,7 @@
         ISensorsSubHal* subHal = mSubHalList[subHalIndex];
         auto result = subHal->getSensorsList([&](const auto& list) {
             for (SensorInfo sensor : list) {
-                if ((sensor.sensorHandle & kSensorHandleSubHalIndexMask) != 0) {
+                if (!subHalIndexIsClear(sensor.sensorHandle)) {
                     ALOGE("SubHal sensorHandle's first byte was not 0");
                 } else {
                     ALOGV("Loaded sensor: %s", sensor.name.c_str());
@@ -389,6 +431,10 @@
     return sensorHandle & (~kSensorHandleSubHalIndexMask);
 }
 
+bool HalProxy::subHalIndexIsClear(uint32_t sensorHandle) {
+    return (sensorHandle & kSensorHandleSubHalIndexMask) == 0;
+}
+
 void HalProxyCallback::postEvents(const std::vector<Event>& events, ScopedWakelock wakelock) {
     (void)wakelock;
     size_t numWakeupEvents;
@@ -418,7 +464,7 @@
     std::vector<Event> eventsOut;
     *numWakeupEvents = 0;
     for (Event event : events) {
-        event.sensorHandle = setSubHalIndex(event.sensorHandle);
+        event.sensorHandle = setSubHalIndex(event.sensorHandle, mSubHalIndex);
         eventsOut.push_back(event);
         if ((mHalProxy->getSensorInfo(event.sensorHandle).flags & V1_0::SensorFlagBits::WAKE_UP) !=
             0) {
@@ -428,10 +474,6 @@
     return eventsOut;
 }
 
-uint32_t HalProxyCallback::setSubHalIndex(uint32_t sensorHandle) const {
-    return sensorHandle | mSubHalIndex << 24;
-}
-
 }  // namespace implementation
 }  // namespace V2_0
 }  // namespace sensors
diff --git a/sensors/2.0/multihal/include/HalProxy.h b/sensors/2.0/multihal/include/HalProxy.h
index ae4b2c5..47571a6 100644
--- a/sensors/2.0/multihal/include/HalProxy.h
+++ b/sensors/2.0/multihal/include/HalProxy.h
@@ -176,6 +176,9 @@
      */
     std::map<uint32_t, SensorInfo> mSensors;
 
+    //! Map of the dynamic sensors that have been added to halproxy.
+    std::map<uint32_t, SensorInfo> mDynamicSensors;
+
     //! The current operation mode for all subhals.
     OperationMode mCurrentOperationMode = OperationMode::NORMAL;
 
@@ -212,6 +215,9 @@
     //! The bool indicating whether to end the pending writes background thread or not
     bool mPendingWritesRun = true;
 
+    //! The mutex protecting access to the dynamic sensors added and removed methods.
+    std::mutex mDynamicSensorsMutex;
+
     /**
      * Initialize the list of SubHal objects in mSubHalList by reading from dynamic libraries
      * listed in a config file.
@@ -271,6 +277,13 @@
      * @return The modified version of the sensor handle.
      */
     static uint32_t clearSubHalIndex(uint32_t sensorHandle);
+
+    /**
+     * @param sensorHandle The sensor handle to modify.
+     *
+     * @return true if subHalIndex byte of sensorHandle is zeroed.
+     */
+    static bool subHalIndexIsClear(uint32_t sensorHandle);
 };
 
 /**
@@ -303,8 +316,6 @@
 
     std::vector<Event> processEvents(const std::vector<Event>& events,
                                      size_t* numWakeupEvents) const;
-
-    uint32_t setSubHalIndex(uint32_t sensorHandle) const;
 };
 
 }  // namespace implementation
diff --git a/sensors/2.0/multihal/tests/HalProxy_test.cpp b/sensors/2.0/multihal/tests/HalProxy_test.cpp
index 61fb14c..c8fbb73 100644
--- a/sensors/2.0/multihal/tests/HalProxy_test.cpp
+++ b/sensors/2.0/multihal/tests/HalProxy_test.cpp
@@ -23,6 +23,7 @@
 #include "SensorsSubHal.h"
 
 #include <chrono>
+#include <set>
 #include <thread>
 #include <vector>
 
@@ -38,6 +39,7 @@
 using ::android::hardware::sensors::V2_0::ISensorsCallback;
 using ::android::hardware::sensors::V2_0::implementation::HalProxy;
 using ::android::hardware::sensors::V2_0::implementation::HalProxyCallback;
+using ::android::hardware::sensors::V2_0::subhal::implementation::AddAndRemoveDynamicSensorsSubHal;
 using ::android::hardware::sensors::V2_0::subhal::implementation::AllSensorsSubHal;
 using ::android::hardware::sensors::V2_0::subhal::implementation::
         AllSupportDirectChannelSensorsSubHal;
@@ -68,6 +70,34 @@
     }
 };
 
+// The sensors callback that expects a variable list of sensors to be added
+class TestSensorsCallback : public ISensorsCallback {
+  public:
+    Return<void> onDynamicSensorsConnected(
+            const hidl_vec<SensorInfo>& dynamicSensorsAdded) override {
+        mSensorsConnected.insert(mSensorsConnected.end(), dynamicSensorsAdded.begin(),
+                                 dynamicSensorsAdded.end());
+        return Return<void>();
+    }
+
+    Return<void> onDynamicSensorsDisconnected(
+            const hidl_vec<int32_t>& dynamicSensorHandlesRemoved) override {
+        mSensorHandlesDisconnected.insert(mSensorHandlesDisconnected.end(),
+                                          dynamicSensorHandlesRemoved.begin(),
+                                          dynamicSensorHandlesRemoved.end());
+        return Return<void>();
+    }
+
+    const std::vector<SensorInfo>& getSensorsConnected() const { return mSensorsConnected; }
+    const std::vector<int32_t>& getSensorHandlesDisconnected() const {
+        return mSensorHandlesDisconnected;
+    }
+
+  private:
+    std::vector<SensorInfo> mSensorsConnected;
+    std::vector<int32_t> mSensorHandlesDisconnected;
+};
+
 // Helper declarations follow
 
 /**
@@ -129,6 +159,20 @@
  */
 std::vector<Event> makeMultipleAccelerometerEvents(size_t numEvents);
 
+/**
+ * Given a SensorInfo vector and a sensor handles vector populate 'sensors' with SensorInfo
+ * objects that have the sensorHandle property set to int32_ts from start to start + size
+ * (exclusive) and push those sensorHandles also onto 'sensorHandles'.
+ *
+ * @param start The starting sensorHandle value.
+ * @param size The ending (not included) sensorHandle value.
+ * @param sensors The SensorInfo object vector reference to push_back to.
+ * @param sensorHandles The sensor handles int32_t vector reference to push_back to.
+ */
+void makeSensorsAndSensorHandlesStartingAndOfSize(int32_t start, size_t size,
+                                                  std::vector<SensorInfo>& sensors,
+                                                  std::vector<int32_t>& sensorHandles);
+
 // Tests follow
 TEST(HalProxyTest, GetSensorsListOneSubHalTest) {
     AllSensorsSubHal subHal;
@@ -396,6 +440,83 @@
     // If this TEST completes then it was a success, if it hangs we will see a crash
 }
 
+TEST(HalProxyTest, DynamicSensorsConnectedTest) {
+    constexpr size_t kNumSensors = 3;
+    AddAndRemoveDynamicSensorsSubHal subHal;
+    std::vector<ISensorsSubHal*> subHals{&subHal};
+    HalProxy proxy(subHals);
+    std::unique_ptr<EventMessageQueue> eventQueue = std::make_unique<EventMessageQueue>(0, true);
+    std::unique_ptr<WakeupMessageQueue> wakeLockQueue =
+            std::make_unique<WakeupMessageQueue>(0, true);
+
+    std::vector<SensorInfo> sensorsToConnect;
+    std::vector<int32_t> sensorHandlesToExpect;
+    makeSensorsAndSensorHandlesStartingAndOfSize(1, kNumSensors, sensorsToConnect,
+                                                 sensorHandlesToExpect);
+
+    TestSensorsCallback* callback = new TestSensorsCallback();
+    ::android::sp<ISensorsCallback> callbackPtr = callback;
+    proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callbackPtr);
+    subHal.addDynamicSensors(sensorsToConnect);
+
+    std::vector<SensorInfo> sensorsSeen = callback->getSensorsConnected();
+    EXPECT_EQ(kNumSensors, sensorsSeen.size());
+    for (size_t i = 0; i < kNumSensors; i++) {
+        auto sensorHandleSeen = sensorsSeen[i].sensorHandle;
+        // Note since only one subhal we do not need to change first byte for expected
+        auto sensorHandleExpected = sensorHandlesToExpect[i];
+        EXPECT_EQ(sensorHandleSeen, sensorHandleExpected);
+    }
+}
+
+TEST(HalProxyTest, DynamicSensorsDisconnectedTest) {
+    constexpr size_t kNumSensors = 3;
+    AddAndRemoveDynamicSensorsSubHal subHal;
+    std::vector<ISensorsSubHal*> subHals{&subHal};
+    HalProxy proxy(subHals);
+    std::unique_ptr<EventMessageQueue> eventQueue = std::make_unique<EventMessageQueue>(0, true);
+    std::unique_ptr<WakeupMessageQueue> wakeLockQueue =
+            std::make_unique<WakeupMessageQueue>(0, true);
+
+    std::vector<SensorInfo> sensorsToConnect;
+    std::vector<int32_t> sensorHandlesToExpect;
+    makeSensorsAndSensorHandlesStartingAndOfSize(20, kNumSensors, sensorsToConnect,
+                                                 sensorHandlesToExpect);
+
+    std::vector<int32_t> nonDynamicSensorHandles;
+    for (int32_t sensorHandle = 1; sensorHandle < 10; sensorHandle++) {
+        nonDynamicSensorHandles.push_back(sensorHandle);
+    }
+
+    std::set<int32_t> nonDynamicSensorHandlesSet(nonDynamicSensorHandles.begin(),
+                                                 nonDynamicSensorHandles.end());
+
+    std::vector<int32_t> sensorHandlesToAttemptToRemove;
+    sensorHandlesToAttemptToRemove.insert(sensorHandlesToAttemptToRemove.end(),
+                                          sensorHandlesToExpect.begin(),
+                                          sensorHandlesToExpect.end());
+    sensorHandlesToAttemptToRemove.insert(sensorHandlesToAttemptToRemove.end(),
+                                          nonDynamicSensorHandles.begin(),
+                                          nonDynamicSensorHandles.end());
+
+    TestSensorsCallback* callback = new TestSensorsCallback();
+    ::android::sp<ISensorsCallback> callbackPtr = callback;
+    proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callbackPtr);
+    subHal.addDynamicSensors(sensorsToConnect);
+    subHal.removeDynamicSensors(sensorHandlesToAttemptToRemove);
+
+    std::vector<int32_t> sensorHandlesSeen = callback->getSensorHandlesDisconnected();
+    EXPECT_EQ(kNumSensors, sensorHandlesSeen.size());
+    for (size_t i = 0; i < kNumSensors; i++) {
+        auto sensorHandleSeen = sensorHandlesSeen[i];
+        // Note since only one subhal we do not need to change first byte for expected
+        auto sensorHandleExpected = sensorHandlesToExpect[i];
+        EXPECT_EQ(sensorHandleSeen, sensorHandleExpected);
+        EXPECT_TRUE(nonDynamicSensorHandlesSet.find(sensorHandleSeen) ==
+                    nonDynamicSensorHandlesSet.end());
+    }
+}
+
 // Helper implementations follow
 void testSensorsListFromProxyAndSubHal(const std::vector<SensorInfo>& proxySensorsList,
                                        const std::vector<SensorInfo>& subHalSensorsList) {
@@ -463,4 +584,18 @@
     return events;
 }
 
+void makeSensorsAndSensorHandlesStartingAndOfSize(int32_t start, size_t size,
+                                                  std::vector<SensorInfo>& sensors,
+                                                  std::vector<int32_t>& sensorHandles) {
+    for (int32_t sensorHandle = start; sensorHandle < start + static_cast<int32_t>(size);
+         sensorHandle++) {
+        SensorInfo sensor;
+        // Just set the sensorHandle field to the correct value so as to not have
+        // to compare every field
+        sensor.sensorHandle = sensorHandle;
+        sensors.push_back(sensor);
+        sensorHandles.push_back(sensorHandle);
+    }
+}
+
 }  // namespace
diff --git a/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.cpp b/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.cpp
index d581c49..cf3ae75 100644
--- a/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.cpp
+++ b/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.cpp
@@ -221,6 +221,16 @@
     return Void();
 }
 
+void AddAndRemoveDynamicSensorsSubHal::addDynamicSensors(
+        const std::vector<SensorInfo>& sensorsAdded) {
+    mCallback->onDynamicSensorsConnected(sensorsAdded);
+}
+
+void AddAndRemoveDynamicSensorsSubHal::removeDynamicSensors(
+        const std::vector<int32_t>& sensorHandlesRemoved) {
+    mCallback->onDynamicSensorsDisconnected(sensorHandlesRemoved);
+}
+
 }  // namespace implementation
 }  // namespace subhal
 }  // namespace V2_0
diff --git a/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.h b/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.h
index 61caa2c..c1e3647 100644
--- a/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.h
+++ b/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.h
@@ -98,13 +98,6 @@
      */
     std::map<int32_t, std::shared_ptr<Sensor>> mSensors;
 
-  private:
-    /**
-     * The current operation mode of the multihal framework. Ensures that all subhals are set to
-     * the same operation mode.
-     */
-    OperationMode mCurrentOperationMode = OperationMode::NORMAL;
-
     /**
      * Callback used to communicate to the HalProxy when dynamic sensors are connected /
      * disconnected, sensor events need to be sent to the framework, and when a wakelock should be
@@ -112,6 +105,13 @@
      */
     sp<IHalProxyCallback> mCallback;
 
+  private:
+    /**
+     * The current operation mode of the multihal framework. Ensures that all subhals are set to
+     * the same operation mode.
+     */
+    OperationMode mCurrentOperationMode = OperationMode::NORMAL;
+
     /**
      * The next available sensor handle
      */
@@ -151,6 +151,12 @@
     Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
 };
 
+class AddAndRemoveDynamicSensorsSubHal : public AllSensorsSubHal {
+  public:
+    void addDynamicSensors(const std::vector<SensorInfo>& sensorsAdded);
+    void removeDynamicSensors(const std::vector<int32_t>& sensorHandlesAdded);
+};
+
 }  // namespace implementation
 }  // namespace subhal
 }  // namespace V2_0
diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp
index d65df59..b18d4df 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