Check the timestamp by areaId

Instead of check the timestamp by propertyId. In CarRatedFloatListener
we also need to check it by each areaId.

Bug: 140744347
Test: Add Unit tests in CarPropertyManagerTest

Change-Id: I530b31279d137cc87a60e6df2c79152839e5b547
(cherry picked from commit 5e48b4b02697e5d1165936b3392bc7860324637c)
diff --git a/car-lib/src/android/car/hardware/property/CarPropertyManager.java b/car-lib/src/android/car/hardware/property/CarPropertyManager.java
index e3651da..be4766b 100644
--- a/car-lib/src/android/car/hardware/property/CarPropertyManager.java
+++ b/car-lib/src/android/car/hardware/property/CarPropertyManager.java
@@ -538,11 +538,11 @@
         void onPropertyChanged(final CarPropertyEvent event) {
             // throw away old sensor data as oneway binder call can change order.
             long updateTime = event.getCarPropertyValue().getTimestamp();
-            if (updateTime < mLastUpdateTime) {
+            int areaId = event.getCarPropertyValue().getAreaId();
+            if (!needUpdateForAreaId(areaId, updateTime)) {
                 Log.w(TAG, "dropping old property data");
                 return;
             }
-            mLastUpdateTime = updateTime;
             List<CarPropertyEventCallback> listeners;
             synchronized (mActivePropertyListener) {
                 listeners = new ArrayList<>(getListeners());
@@ -550,7 +550,7 @@
             listeners.forEach(new Consumer<CarPropertyEventCallback>() {
                 @Override
                 public void accept(CarPropertyEventCallback listener) {
-                    if (needUpdate(listener, updateTime)) {
+                    if (needUpdateForSelectedListener(listener, updateTime)) {
                         listener.onChangeEvent(event.getCarPropertyValue());
                     }
                 }
diff --git a/car-lib/src/com/android/car/internal/CarRatedFloatListeners.java b/car-lib/src/com/android/car/internal/CarRatedFloatListeners.java
index 93519d6..566eed7 100644
--- a/car-lib/src/com/android/car/internal/CarRatedFloatListeners.java
+++ b/car-lib/src/com/android/car/internal/CarRatedFloatListeners.java
@@ -16,6 +16,8 @@
 
 package com.android.car.internal;
 
+import android.util.SparseArray;
+
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -36,7 +38,8 @@
 
     private float mUpdateRate;
 
-    protected long mLastUpdateTime = -1;
+    // key: areaId, value: lastUpdateTime in nanosecond
+    protected SparseArray<Long> mAreaIdToLastUpdateTime = new SparseArray<>();
 
     protected CarRatedFloatListeners(float rate) {
         mUpdateRate = rate;
@@ -105,7 +108,7 @@
      * @param eventTimeStamp
      * @return true if listener need to be notified.
      */
-    public boolean needUpdate(T listener, long eventTimeStamp) {
+    public boolean needUpdateForSelectedListener(T listener, long eventTimeStamp) {
         Long nextUpdateTime = mListenersUpdateTime.get(listener);
         Float updateRate = mListenersToRate.get(listener);
         /** Update ON_CHANGE property. */
@@ -121,6 +124,21 @@
         return false;
     }
 
+    /**
+     * @param areaId AreaId in CarPropertyValue
+     * @param eventTime TimeStamp in CarPropertyValue
+     * @return true if eventTime is greater than the last event time for the same areaId.
+     */
+    public boolean needUpdateForAreaId(int areaId, long eventTime) {
+        long lastUpdateTime = mAreaIdToLastUpdateTime.get(areaId, 0L);
+        if (eventTime >= lastUpdateTime) {
+            mAreaIdToLastUpdateTime.put(areaId, eventTime);
+            return true;
+        }
+        return false;
+    }
+
+
     public Collection<T> getListeners() {
         return mListenersToRate.keySet();
     }