Merge "audio: Mitigate double receiving of the "exit" command" into main am: f0ffa20975 am: 6695dae23c am: 9ce8c9dc88

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2748875

Change-Id: I2420105057bb4496d83f1ea29b00f5636b82b061
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index af89f5f..f7298c0 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <pthread.h>
+
 #define LOG_TAG "AHAL_Stream"
 #include <android-base/logging.h>
 #include <android/binder_ibinder_platform.h>
@@ -94,6 +96,14 @@
     mDataMQ.reset();
 }
 
+pid_t StreamWorkerCommonLogic::getTid() const {
+#if defined(__ANDROID__)
+    return pthread_gettid_np(pthread_self());
+#else
+    return 0;
+#endif
+}
+
 std::string StreamWorkerCommonLogic::init() {
     if (mContext->getCommandMQ() == nullptr) return "Command MQ is null";
     if (mContext->getReplyMQ() == nullptr) return "Reply MQ is null";
@@ -164,7 +174,7 @@
     switch (command.getTag()) {
         case Tag::halReservedExit:
             if (const int32_t cookie = command.get<Tag::halReservedExit>();
-                cookie == mContext->getInternalCommandCookie()) {
+                cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
                 mDriver->shutdown();
                 setClosed();
                 // This is an internal command, no need to reply.
@@ -384,7 +394,7 @@
     switch (command.getTag()) {
         case Tag::halReservedExit:
             if (const int32_t cookie = command.get<Tag::halReservedExit>();
-                cookie == mContext->getInternalCommandCookie()) {
+                cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
                 mDriver->shutdown();
                 setClosed();
                 // This is an internal command, no need to reply.
@@ -717,7 +727,7 @@
     if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) {
         LOG(DEBUG) << __func__ << ": asking the worker to exit...";
         auto cmd = StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::halReservedExit>(
-                mContext.getInternalCommandCookie());
+                mContext.getInternalCommandCookie() ^ mWorker->getTid());
         // Note: never call 'pause' and 'resume' methods of StreamWorker
         // in the HAL implementation. These methods are to be used by
         // the client side only. Preventing the worker loop from running
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index a02655f..88fddec 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -223,6 +223,7 @@
         : mContext(context),
           mDriver(driver),
           mTransientStateDelayMs(context->getTransientStateDelayMs()) {}
+    pid_t getTid() const;
     std::string init() override;
     void populateReply(StreamDescriptor::Reply* reply, bool isConnected) const;
     void populateReplyWrongState(StreamDescriptor::Reply* reply,