Mediametrics: Add max/min volume and duration in AudioPowerUsageData

Bug: 201353537
Test: adb shell dumpsys media.metrics --all | egrep -A10 PowerUsage
Change-Id: I3c603cb03c3b7f84f2572ac43c2da2dc0c798553
diff --git a/services/audioflinger/TrackMetrics.h b/services/audioflinger/TrackMetrics.h
index 7fb69be..30d69ab 100644
--- a/services/audioflinger/TrackMetrics.h
+++ b/services/audioflinger/TrackMetrics.h
@@ -116,6 +116,21 @@
         mDeviceStartupMs.add(startupMs);
     }
 
+    void updateMinMaxVolume(int64_t durationNs, double deviceVolume) {
+        if (deviceVolume > mMaxVolume) {
+            mMaxVolume = deviceVolume;
+            mMaxVolumeDurationNs = durationNs;
+        } else if (deviceVolume == mMaxVolume) {
+            mMaxVolumeDurationNs += durationNs;
+        }
+        if (deviceVolume < mMinVolume) {
+            mMinVolume = deviceVolume;
+            mMinVolumeDurationNs = durationNs;
+        } else if (deviceVolume == mMinVolume) {
+            mMinVolumeDurationNs += durationNs;
+        }
+    }
+
     // may be called multiple times during an interval
     void logVolume(float volume) {
         const int64_t timeNs = systemTime();
@@ -123,10 +138,13 @@
         if (mStartVolumeTimeNs == 0) {
             mDeviceVolume = mVolume = volume;
             mLastVolumeChangeTimeNs = mStartVolumeTimeNs = timeNs;
+            updateMinMaxVolume(0, mVolume);
             return;
         }
+        const int64_t durationNs = timeNs - mLastVolumeChangeTimeNs;
+        updateMinMaxVolume(durationNs, mVolume);
         mDeviceVolume = (mDeviceVolume * (mLastVolumeChangeTimeNs - mStartVolumeTimeNs) +
-            mVolume * (timeNs - mLastVolumeChangeTimeNs)) / (timeNs - mStartVolumeTimeNs);
+            mVolume * durationNs) / (timeNs - mStartVolumeTimeNs);
         mVolume = volume;
         mLastVolumeChangeTimeNs = timeNs;
     }
@@ -157,7 +175,11 @@
                 .set(AMEDIAMETRICS_PROP_EVENT, eventName)
                 .set(AMEDIAMETRICS_PROP_INTERVALCOUNT, (int32_t)mIntervalCount);
             if (mIsOut) {
-                item.set(AMEDIAMETRICS_PROP_DEVICEVOLUME, mDeviceVolume);
+                item.set(AMEDIAMETRICS_PROP_DEVICEVOLUME, mDeviceVolume)
+                    .set(AMEDIAMETRICS_PROP_DEVICEMAXVOLUMEDURATIONNS, mMaxVolumeDurationNs)
+                    .set(AMEDIAMETRICS_PROP_DEVICEMAXVOLUME, mMaxVolume)
+                    .set(AMEDIAMETRICS_PROP_DEVICEMINVOLUMEDURATIONNS, mMinVolumeDurationNs)
+                    .set(AMEDIAMETRICS_PROP_DEVICEMINVOLUME, mMinVolume);
             }
             if (mDeviceLatencyMs.getN() > 0) {
                 item.set(AMEDIAMETRICS_PROP_DEVICELATENCYMS, mDeviceLatencyMs.getMean())
@@ -185,6 +207,10 @@
         mDeviceVolume = 0.f;
         mStartVolumeTimeNs = 0;
         mLastVolumeChangeTimeNs = 0;
+        mMinVolume = AMEDIAMETRICS_INITIAL_MIN_VOLUME;
+        mMaxVolume = AMEDIAMETRICS_INITIAL_MAX_VOLUME;
+        mMinVolumeDurationNs = 0;
+        mMaxVolumeDurationNs = 0;
 
         mDeviceLatencyMs.reset();
         mDeviceStartupMs.reset();
@@ -214,6 +240,12 @@
     int64_t           mStartVolumeTimeNs GUARDED_BY(mLock) = 0;
     int64_t           mLastVolumeChangeTimeNs GUARDED_BY(mLock) = 0;
 
+    // Min/Max volume
+    double            mMinVolume GUARDED_BY(mLock) = AMEDIAMETRICS_INITIAL_MIN_VOLUME;
+    double            mMaxVolume GUARDED_BY(mLock) = AMEDIAMETRICS_INITIAL_MAX_VOLUME;
+    int64_t           mMinVolumeDurationNs GUARDED_BY(mLock) = 0;
+    int64_t           mMaxVolumeDurationNs GUARDED_BY(mLock) = 0;
+
     // latency and startup for each interval.
     audio_utils::Statistics<double> mDeviceLatencyMs GUARDED_BY(mLock);
     audio_utils::Statistics<double> mDeviceStartupMs GUARDED_BY(mLock);