Merge "avoid duplicate of mediaswcodec seccomp policy files"
diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp
index dc7f88a..09a333b 100644
--- a/camera/cameraserver/Android.bp
+++ b/camera/cameraserver/Android.bp
@@ -37,7 +37,7 @@
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.device@3.4",
     ],
-    compile_multilib: "32",
+    compile_multilib: "prefer32",
     cflags: [
         "-Wall",
         "-Wextra",
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
index 3ecf6d5..1495703 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -148,14 +148,17 @@
     // Calculate the output buffer size and determine if any subsamples are
     // encrypted.
     size_t destSize = 0;
+    size_t srcSize = 0;
     bool haveEncryptedSubsamples = false;
     for (size_t i = 0; i < subSamples.size(); i++) {
         const SubSample &subSample = subSamples[i];
-        if (__builtin_add_overflow(destSize, subSample.numBytesOfClearData, &destSize)) {
+        if (__builtin_add_overflow(destSize, subSample.numBytesOfClearData, &destSize) ||
+            __builtin_add_overflow(srcSize, subSample.numBytesOfClearData, &srcSize)) {
             _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "subsample clear size overflow");
             return Void();
         }
-        if (__builtin_add_overflow(destSize, subSample.numBytesOfEncryptedData, &destSize)) {
+        if (__builtin_add_overflow(destSize, subSample.numBytesOfEncryptedData, &destSize) ||
+            __builtin_add_overflow(srcSize, subSample.numBytesOfEncryptedData, &srcSize)) {
             _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "subsample encrypted size overflow");
             return Void();
         }
@@ -164,7 +167,7 @@
         }
     }
 
-    if (destSize > destBuffer.size) {
+    if (destSize > destBuffer.size || srcSize > source.size) {
         _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "subsample sum too large");
         return Void();
     }
diff --git a/media/codec2/components/aac/C2SoftAacDec.cpp b/media/codec2/components/aac/C2SoftAacDec.cpp
index 9884733..677f316 100644
--- a/media/codec2/components/aac/C2SoftAacDec.cpp
+++ b/media/codec2/components/aac/C2SoftAacDec.cpp
@@ -791,7 +791,6 @@
 
                 // After an error, replace bufferSize with the sum of the
                 // decodedSizes to resynchronize the in/out lists.
-                inInfo.decodedSizes.pop_back();
                 inInfo.bufferSize = std::accumulate(
                         inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0);
 
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index 2699dfe..983887b 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -141,6 +141,7 @@
         case AAUDIO_STREAM_STATE_PAUSED:
         case AAUDIO_STREAM_STATE_STOPPING:
         case AAUDIO_STREAM_STATE_STOPPED:
+        case AAUDIO_STREAM_STATE_FLUSHING:
         case AAUDIO_STREAM_STATE_FLUSHED:
             break; // Proceed with starting.
 
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index d50a74b..3bfa2b7 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -342,13 +342,17 @@
     // Enable callback before starting AudioRecord to avoid shutting
     // down because of a race condition.
     mCallbackEnabled.store(true);
+    aaudio_stream_state_t originalState = getState();
+    // Set before starting the callback so that we are in the correct state
+    // before updateStateMachine() can be called by the callback.
+    setState(AAUDIO_STREAM_STATE_STARTING);
     mFramesWritten.reset32(); // service writes frames
     mTimestampPosition.reset32();
     status_t err = mAudioRecord->start(); // resets position to zero
     if (err != OK) {
+        mCallbackEnabled.store(false);
+        setState(originalState);
         return AAudioConvert_androidToAAudioResult(err);
-    } else {
-        setState(AAUDIO_STREAM_STATE_STARTING);
     }
     return AAUDIO_OK;
 }
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 74292dd..0427220 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -304,11 +304,15 @@
     // Enable callback before starting AudioTrack to avoid shutting
     // down because of a race condition.
     mCallbackEnabled.store(true);
+    aaudio_stream_state_t originalState = getState();
+    // Set before starting the callback so that we are in the correct state
+    // before updateStateMachine() can be called by the callback.
+    setState(AAUDIO_STREAM_STATE_STARTING);
     err = mAudioTrack->start();
     if (err != OK) {
+        mCallbackEnabled.store(false);
+        setState(originalState);
         return AAudioConvert_androidToAAudioResult(err);
-    } else {
-        setState(AAUDIO_STREAM_STATE_STARTING);
     }
     return AAUDIO_OK;
 }
diff --git a/media/libaaudio/tests/test_various.cpp b/media/libaaudio/tests/test_various.cpp
index 1c26615..a20c799 100644
--- a/media/libaaudio/tests/test_various.cpp
+++ b/media/libaaudio/tests/test_various.cpp
@@ -124,7 +124,7 @@
 }
 
 enum FunctionToCall {
-    CALL_START, CALL_STOP, CALL_PAUSE, CALL_FLUSH
+    CALL_START, CALL_STOP, CALL_PAUSE, CALL_FLUSH, CALL_RELEASE
 };
 
 void checkStateTransition(aaudio_performance_mode_t perfMode,
@@ -177,11 +177,27 @@
             } else if (originalState == AAUDIO_STREAM_STATE_PAUSED) {
                 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
                 inputState = AAUDIO_STREAM_STATE_PAUSING;
+            } else if (originalState == AAUDIO_STREAM_STATE_FLUSHING) {
+                ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
+                // We can only flush() after pause is complete.
+                ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
+                                                                 AAUDIO_STREAM_STATE_PAUSING,
+                                                                 &state,
+                                                                 1000 * NANOS_PER_MILLISECOND));
+                ASSERT_EQ(AAUDIO_STREAM_STATE_PAUSED, state);
+                ASSERT_EQ(AAUDIO_OK, AAudioStream_requestFlush(aaudioStream));
+                // That will put the stream into the FLUSHING state.
+                // The FLUSHING state will persist until we process functionToCall.
+                // That is because the transition to FLUSHED is caused by the callback,
+                // or by calling write() or waitForStateChange(). But those will not
+                // occur.
+            } else if (originalState == AAUDIO_STREAM_STATE_CLOSING) {
+                ASSERT_EQ(AAUDIO_OK, AAudioStream_release(aaudioStream));
             }
         }
     }
 
-    // Wait until past transitional state.
+    // Wait until we get past the transitional state if requested.
     if (inputState != AAUDIO_STREAM_STATE_UNINITIALIZED) {
         ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
                                                              inputState,
@@ -208,12 +224,20 @@
             EXPECT_EQ(expectedResult, AAudioStream_requestFlush(aaudioStream));
             transitionalState = AAUDIO_STREAM_STATE_FLUSHING;
             break;
+        case FunctionToCall::CALL_RELEASE:
+            EXPECT_EQ(expectedResult, AAudioStream_release(aaudioStream));
+            // Set to UNINITIALIZED so the waitForStateChange() below will
+            // will return immediately with the current state.
+            transitionalState = AAUDIO_STREAM_STATE_UNINITIALIZED;
+            break;
     }
 
-    EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
-                                                         transitionalState,
-                                                         &state,
-                                                         1000 * NANOS_PER_MILLISECOND));
+    EXPECT_EQ(AAUDIO_OK,
+            AAudioStream_waitForStateChange(aaudioStream,
+                    transitionalState,
+                    &state,
+                    1000 * NANOS_PER_MILLISECOND));
+
     // We should not change state when a function fails.
     if (expectedResult != AAUDIO_OK) {
         ASSERT_EQ(originalState, expectedState);
@@ -493,6 +517,88 @@
         AAUDIO_STREAM_STATE_FLUSHED);
 }
 
+// FLUSHING ================================================================
+TEST(test_various, aaudio_state_lowlat_flushing_start) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+        AAUDIO_STREAM_STATE_FLUSHING,
+        FunctionToCall::CALL_START,
+        AAUDIO_OK,
+        AAUDIO_STREAM_STATE_STARTED);
+}
+
+TEST(test_various, aaudio_state_none_flushing_start) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+        AAUDIO_STREAM_STATE_FLUSHING,
+        FunctionToCall::CALL_START,
+        AAUDIO_OK,
+        AAUDIO_STREAM_STATE_STARTED);
+}
+
+TEST(test_various, aaudio_state_lowlat_flushing_release) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+        AAUDIO_STREAM_STATE_FLUSHING,
+        FunctionToCall::CALL_RELEASE,
+        AAUDIO_OK,
+        AAUDIO_STREAM_STATE_CLOSING);
+}
+
+TEST(test_various, aaudio_state_none_flushing_release) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+        AAUDIO_STREAM_STATE_FLUSHING,
+        FunctionToCall::CALL_RELEASE,
+        AAUDIO_OK,
+        AAUDIO_STREAM_STATE_CLOSING);
+}
+
+TEST(test_various, aaudio_state_lowlat_starting_release) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+        AAUDIO_STREAM_STATE_STARTING,
+        FunctionToCall::CALL_RELEASE,
+        AAUDIO_OK,
+        AAUDIO_STREAM_STATE_CLOSING);
+}
+
+TEST(test_various, aaudio_state_none_starting_release) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+        AAUDIO_STREAM_STATE_STARTING,
+        FunctionToCall::CALL_RELEASE,
+        AAUDIO_OK,
+        AAUDIO_STREAM_STATE_CLOSING);
+}
+
+// CLOSING ================================================================
+TEST(test_various, aaudio_state_lowlat_closing_start) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+        AAUDIO_STREAM_STATE_CLOSING,
+        FunctionToCall::CALL_START,
+        AAUDIO_ERROR_INVALID_STATE,
+        AAUDIO_STREAM_STATE_CLOSING);
+}
+
+TEST(test_various, aaudio_state_none_closing_start) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+        AAUDIO_STREAM_STATE_CLOSING,
+        FunctionToCall::CALL_START,
+        AAUDIO_ERROR_INVALID_STATE,
+        AAUDIO_STREAM_STATE_CLOSING);
+}
+
+TEST(test_various, aaudio_state_lowlat_closing_stop) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+        AAUDIO_STREAM_STATE_CLOSING,
+        FunctionToCall::CALL_STOP,
+        AAUDIO_ERROR_INVALID_STATE,
+        AAUDIO_STREAM_STATE_CLOSING);
+}
+
+TEST(test_various, aaudio_state_none_closing_stop) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+        AAUDIO_STREAM_STATE_CLOSING,
+        FunctionToCall::CALL_STOP,
+        AAUDIO_ERROR_INVALID_STATE,
+        AAUDIO_STREAM_STATE_CLOSING);
+}
+
 // ==========================================================================
 TEST(test_various, aaudio_set_buffer_size) {
 
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 16d2232..6d79aba 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -1001,7 +1001,7 @@
             break;
     }
 
-    // Whitelist of relevant events to trigger log merging.
+    // List of relevant events that trigger log merging.
     // Log merging should activate during audio activity of any kind. This are considered the
     // most relevant events.
     // TODO should select more wisely the items from the list