Merge changes I48279bba,I3baf29a5 into tm-qpr-dev

* changes:
  Populate data sizes in audio egress metrics
  Hotword: Use new Audio Egress metrics instead of older one
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamCopier.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamCopier.java
index b9d2ae6..3a8b8cc 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamCopier.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamCopier.java
@@ -19,13 +19,13 @@
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.service.voice.HotwordAudioStream.KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES;
 
-import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_CLOSE_ERROR_FROM_SYSTEM;
-import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_EMPTY_AUDIO_STREAM_LIST;
-import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_END;
-import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_ILLEGAL_COPY_BUFFER_SIZE;
-import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_INTERRUPTED_EXCEPTION;
-import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_NO_PERMISSION;
-import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_START;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__CLOSE_ERROR_FROM_SYSTEM;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__EMPTY_AUDIO_STREAM_LIST;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__ENDED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__ILLEGAL_COPY_BUFFER_SIZE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__INTERRUPTED_EXCEPTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__NO_PERMISSION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__STARTED;
 import static com.android.server.voiceinteraction.HotwordDetectionConnection.DEBUG;
 
 import android.annotation.NonNull;
@@ -98,14 +98,17 @@
             throws IOException {
         List<HotwordAudioStream> audioStreams = result.getAudioStreams();
         if (audioStreams.isEmpty()) {
-            HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
-                    HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_EMPTY_AUDIO_STREAM_LIST,
-                    mVoiceInteractorUid);
+            HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+                    HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__EMPTY_AUDIO_STREAM_LIST,
+                    mVoiceInteractorUid, /* streamSizeBytes= */ 0, /* bundleSizeBytes= */ 0,
+                    /* streamCount= */ 0);
             return result;
         }
 
+        final int audioStreamCount = audioStreams.size();
         List<HotwordAudioStream> newAudioStreams = new ArrayList<>(audioStreams.size());
         List<CopyTaskInfo> copyTaskInfos = new ArrayList<>(audioStreams.size());
+        int totalMetadataBundleSizeBytes = 0;
         for (HotwordAudioStream audioStream : audioStreams) {
             ParcelFileDescriptor[] clientPipe = ParcelFileDescriptor.createReliablePipe();
             ParcelFileDescriptor clientAudioSource = clientPipe[0];
@@ -117,12 +120,14 @@
 
             int copyBufferLength = DEFAULT_COPY_BUFFER_LENGTH_BYTES;
             PersistableBundle metadata = audioStream.getMetadata();
+            totalMetadataBundleSizeBytes += HotwordDetectedResult.getParcelableSize(metadata);
             if (metadata.containsKey(KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES)) {
                 copyBufferLength = metadata.getInt(KEY_AUDIO_STREAM_COPY_BUFFER_LENGTH_BYTES, -1);
                 if (copyBufferLength < 1 || copyBufferLength > MAX_COPY_BUFFER_LENGTH_BYTES) {
-                    HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
-                            HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_ILLEGAL_COPY_BUFFER_SIZE,
-                            mVoiceInteractorUid);
+                    HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+                            HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__ILLEGAL_COPY_BUFFER_SIZE,
+                            mVoiceInteractorUid, /* streamSizeBytes= */ 0, /* bundleSizeBytes= */ 0,
+                            audioStreamCount);
                     Slog.w(TAG, "Attempted to set an invalid copy buffer length ("
                             + copyBufferLength + ") for: " + audioStream);
                     copyBufferLength = DEFAULT_COPY_BUFFER_LENGTH_BYTES;
@@ -139,7 +144,9 @@
         }
 
         String resultTaskId = TASK_ID_PREFIX + System.identityHashCode(result);
-        mExecutorService.execute(new HotwordDetectedResultCopyTask(resultTaskId, copyTaskInfos));
+        mExecutorService.execute(
+                new HotwordDetectedResultCopyTask(resultTaskId, copyTaskInfos,
+                        totalMetadataBundleSizeBytes));
 
         return result.buildUpon().setAudioStreams(newAudioStreams).build();
     }
@@ -159,11 +166,14 @@
     private class HotwordDetectedResultCopyTask implements Runnable {
         private final String mResultTaskId;
         private final List<CopyTaskInfo> mCopyTaskInfos;
+        private final int mTotalMetadataSizeBytes;
         private final ExecutorService mExecutorService = Executors.newCachedThreadPool();
 
-        HotwordDetectedResultCopyTask(String resultTaskId, List<CopyTaskInfo> copyTaskInfos) {
+        HotwordDetectedResultCopyTask(String resultTaskId, List<CopyTaskInfo> copyTaskInfos,
+                int totalMetadataSizeBytes) {
             mResultTaskId = resultTaskId;
             mCopyTaskInfos = copyTaskInfos;
+            mTotalMetadataSizeBytes = totalMetadataSizeBytes;
         }
 
         @Override
@@ -183,19 +193,38 @@
                     mVoiceInteractorUid, mVoiceInteractorPackageName,
                     mVoiceInteractorAttributionTag, OP_MESSAGE) == MODE_ALLOWED) {
                 try {
-                    HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
-                            HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_START,
-                            mVoiceInteractorUid);
+                    HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+                            HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__STARTED,
+                            mVoiceInteractorUid, /* streamSizeBytes= */ 0, mTotalMetadataSizeBytes,
+                            size);
                     // TODO(b/244599891): Set timeout, close after inactivity
                     mExecutorService.invokeAll(tasks);
-                    HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
-                            HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_END,
-                            mVoiceInteractorUid);
+
+                    int totalStreamSizeBytes = 0;
+                    for (SingleAudioStreamCopyTask task : tasks) {
+                        totalStreamSizeBytes += task.mTotalCopiedBytes;
+                    }
+
+                    Slog.i(TAG, mResultTaskId + ": Task was completed. Total bytes streamed: "
+                            + totalStreamSizeBytes + ", total metadata bundle size bytes: "
+                            + mTotalMetadataSizeBytes);
+                    HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+                            HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__ENDED,
+                            mVoiceInteractorUid, totalStreamSizeBytes, mTotalMetadataSizeBytes,
+                            size);
                 } catch (InterruptedException e) {
-                    HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
-                            HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_INTERRUPTED_EXCEPTION,
-                            mVoiceInteractorUid);
-                    Slog.e(TAG, mResultTaskId + ": Task was interrupted", e);
+                    int totalStreamSizeBytes = 0;
+                    for (SingleAudioStreamCopyTask task : tasks) {
+                        totalStreamSizeBytes += task.mTotalCopiedBytes;
+                    }
+
+                    HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+                            HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__INTERRUPTED_EXCEPTION,
+                            mVoiceInteractorUid, totalStreamSizeBytes, mTotalMetadataSizeBytes,
+                            size);
+                    Slog.e(TAG, mResultTaskId + ": Task was interrupted. Total bytes streamed: "
+                            + totalStreamSizeBytes + ", total metadata bundle size bytes: "
+                            + mTotalMetadataSizeBytes);
                     bestEffortPropagateError(e.getMessage());
                 } finally {
                     mAppOpsManager.finishOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD,
@@ -203,9 +232,10 @@
                             mVoiceInteractorAttributionTag);
                 }
             } else {
-                HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
-                        HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_NO_PERMISSION,
-                        mVoiceInteractorUid);
+                HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+                        HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__NO_PERMISSION,
+                        mVoiceInteractorUid, /* streamSizeBytes= */ 0, /* bundleSizeBytes= */ 0,
+                        size);
                 bestEffortPropagateError(
                         "Failed to obtain RECORD_AUDIO_HOTWORD permission for voice interactor with"
                                 + " uid=" + mVoiceInteractorUid
@@ -220,9 +250,10 @@
                     copyTaskInfo.mSource.closeWithError(errorMessage);
                     copyTaskInfo.mSink.closeWithError(errorMessage);
                 }
-                HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
-                        HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_CLOSE_ERROR_FROM_SYSTEM,
-                        mVoiceInteractorUid);
+                HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+                        HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__CLOSE_ERROR_FROM_SYSTEM,
+                        mVoiceInteractorUid, /* streamSizeBytes= */ 0, /* bundleSizeBytes= */ 0,
+                        mCopyTaskInfos.size());
             } catch (IOException e) {
                 Slog.e(TAG, mResultTaskId + ": Failed to propagate error", e);
             }
@@ -237,6 +268,8 @@
         private final int mDetectorType;
         private final int mUid;
 
+        private volatile int mTotalCopiedBytes = 0;
+
         SingleAudioStreamCopyTask(String streamTaskId, ParcelFileDescriptor audioSource,
                 ParcelFileDescriptor audioSink, int copyBufferLength, int detectorType, int uid) {
             mStreamTaskId = streamTaskId;
@@ -281,6 +314,7 @@
                                     Arrays.copyOfRange(buffer, 0, 20)));
                         }
                         fos.write(buffer, 0, bytesRead);
+                        mTotalCopiedBytes += bytesRead;
                     }
                     // TODO(b/244599891): Close PFDs after inactivity
                 }
@@ -288,8 +322,10 @@
                 mAudioSource.closeWithError(e.getMessage());
                 mAudioSink.closeWithError(e.getMessage());
                 Slog.e(TAG, mStreamTaskId + ": Failed to copy audio stream", e);
-                HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
-                        HOTWORD_DETECTOR_EVENTS__EVENT__AUDIO_EGRESS_CLOSE_ERROR_FROM_SYSTEM, mUid);
+                HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
+                        HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__CLOSE_ERROR_FROM_SYSTEM,
+                        mUid, /* streamSizeBytes= */ 0, /* bundleSizeBytes= */ 0,
+                        /* streamCount= */ 0);
             } finally {
                 if (fis != null) {
                     fis.close();
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
index 61c18be..c35d90f 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
@@ -16,6 +16,9 @@
 
 package com.android.server.voiceinteraction;
 
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
@@ -47,6 +50,12 @@
             HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
     private static final int METRICS_INIT_NORMAL_DETECTOR =
             HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
+    private static final int AUDIO_EGRESS_DSP_DETECTOR =
+            HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
+    private static final int AUDIO_EGRESS_SOFTWARE_DETECTOR =
+            HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
+    private static final int AUDIO_EGRESS_NORMAL_DETECTOR =
+            HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
 
     private HotwordMetricsLogger() {
         // Class only contains static utility functions, and should not be instantiated
@@ -97,6 +106,16 @@
                 metricsDetectorType, event, uid);
     }
 
+    /**
+     * Logs information related to hotword audio egress events.
+     */
+    public static void writeAudioEgressEvent(int detectorType, int event, int uid,
+            int streamSizeBytes, int bundleSizeBytes, int streamCount) {
+        int metricsDetectorType = getAudioEgressDetectorType(detectorType);
+        FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED,
+                metricsDetectorType, event, uid, streamSizeBytes, bundleSizeBytes, streamCount);
+    }
+
     private static int getCreateMetricsDetectorType(int detectorType) {
         switch (detectorType) {
             case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
@@ -151,4 +170,15 @@
                 return HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__NORMAL_DETECTOR;
         }
     }
+
+    private static int getAudioEgressDetectorType(int detectorType) {
+        switch (detectorType) {
+            case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
+                return AUDIO_EGRESS_SOFTWARE_DETECTOR;
+            case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
+                return AUDIO_EGRESS_DSP_DETECTOR;
+            default:
+                return AUDIO_EGRESS_NORMAL_DETECTOR;
+        }
+    }
 }