Merge changes I385860db,I52fc5134,Icfcea3d6 into main

* changes:
  Freeze android.hardware.power.stats
  Freeze android.hardware.weaver
  Freeze android.hardware.bluetooth.audio
diff --git a/audio/aidl/default/StreamSwitcher.cpp b/audio/aidl/default/StreamSwitcher.cpp
index 956f413..e00c34b 100644
--- a/audio/aidl/default/StreamSwitcher.cpp
+++ b/audio/aidl/default/StreamSwitcher.cpp
@@ -31,7 +31,9 @@
 namespace aidl::android::hardware::audio::core {
 
 StreamSwitcher::StreamSwitcher(StreamContext* context, const Metadata& metadata)
-    : mMetadata(metadata), mStream(new InnerStreamWrapper<StreamStub>(context, mMetadata)) {}
+    : mContext(context),
+      mMetadata(metadata),
+      mStream(new InnerStreamWrapper<StreamStub>(context, mMetadata)) {}
 
 ndk::ScopedAStatus StreamSwitcher::closeCurrentStream(bool validateStreamState) {
     if (!mStream) return ndk::ScopedAStatus::ok();
@@ -100,6 +102,10 @@
 }
 
 ndk::ScopedAStatus StreamSwitcher::addEffect(const std::shared_ptr<IEffect>& in_effect) {
+    if (in_effect == nullptr) {
+        LOG(DEBUG) << __func__ << ": null effect";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
     if (mStream == nullptr) {
         LOG(ERROR) << __func__ << ": stream was closed";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
@@ -112,6 +118,10 @@
 }
 
 ndk::ScopedAStatus StreamSwitcher::removeEffect(const std::shared_ptr<IEffect>& in_effect) {
+    if (in_effect == nullptr) {
+        LOG(DEBUG) << __func__ << ": null effect";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
     if (mStream == nullptr) {
         LOG(ERROR) << __func__ << ": stream was closed";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
diff --git a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
index b39583e..74854c6 100644
--- a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
@@ -20,16 +20,16 @@
 #include <vector>
 
 #include "core-impl/Stream.h"
+#include "core-impl/StreamSwitcher.h"
 #include "r_submix/SubmixRoute.h"
 
 namespace aidl::android::hardware::audio::core {
 
-using aidl::android::hardware::audio::core::r_submix::AudioConfig;
-using aidl::android::hardware::audio::core::r_submix::SubmixRoute;
-
 class StreamRemoteSubmix : public StreamCommonImpl {
   public:
-    StreamRemoteSubmix(StreamContext* context, const Metadata& metadata);
+    StreamRemoteSubmix(
+            StreamContext* context, const Metadata& metadata,
+            const ::aidl::android::media::audio::common::AudioDeviceAddress& deviceAddress);
 
     ::android::status_t init() override;
     ::android::status_t drain(StreamDescriptor::DrainMode) override;
@@ -51,16 +51,17 @@
     ::android::status_t outWrite(void* buffer, size_t frameCount, size_t* actualFrameCount);
     ::android::status_t inRead(void* buffer, size_t frameCount, size_t* actualFrameCount);
 
-    const int mPortId;
+    const ::aidl::android::media::audio::common::AudioDeviceAddress mDeviceAddress;
     const bool mIsInput;
-    AudioConfig mStreamConfig;
-    std::shared_ptr<SubmixRoute> mCurrentRoute = nullptr;
+    r_submix::AudioConfig mStreamConfig;
+    std::shared_ptr<r_submix::SubmixRoute> mCurrentRoute = nullptr;
 
     // Mutex lock to protect vector of submix routes, each of these submix routes have their mutex
     // locks and none of the mutex locks should be taken together.
     static std::mutex sSubmixRoutesLock;
-    static std::map<int32_t, std::shared_ptr<SubmixRoute>> sSubmixRoutes
-            GUARDED_BY(sSubmixRoutesLock);
+    static std::map<::aidl::android::media::audio::common::AudioDeviceAddress,
+                    std::shared_ptr<r_submix::SubmixRoute>>
+            sSubmixRoutes GUARDED_BY(sSubmixRoutesLock);
 
     // limit for number of read error log entries to avoid spamming the logs
     static constexpr int kMaxReadErrorLogs = 5;
@@ -72,7 +73,7 @@
     static constexpr int kReadAttemptSleepUs = 5000;
 };
 
-class StreamInRemoteSubmix final : public StreamIn, public StreamRemoteSubmix {
+class StreamInRemoteSubmix final : public StreamIn, public StreamSwitcher {
   public:
     friend class ndk::SharedRefBase;
     StreamInRemoteSubmix(
@@ -81,13 +82,19 @@
             const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
 
   private:
+    DeviceSwitchBehavior switchCurrentStream(
+            const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
+            override;
+    std::unique_ptr<StreamCommonInterfaceEx> createNewStream(
+            const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
+            StreamContext* context, const Metadata& metadata) override;
     void onClose(StreamDescriptor::State) override { defaultOnClose(); }
     ndk::ScopedAStatus getActiveMicrophones(
             std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return)
             override;
 };
 
-class StreamOutRemoteSubmix final : public StreamOut, public StreamRemoteSubmix {
+class StreamOutRemoteSubmix final : public StreamOut, public StreamSwitcher {
   public:
     friend class ndk::SharedRefBase;
     StreamOutRemoteSubmix(
@@ -97,6 +104,12 @@
                     offloadInfo);
 
   private:
+    DeviceSwitchBehavior switchCurrentStream(
+            const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
+            override;
+    std::unique_ptr<StreamCommonInterfaceEx> createNewStream(
+            const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
+            StreamContext* context, const Metadata& metadata) override;
     void onClose(StreamDescriptor::State) override { defaultOnClose(); }
 };
 
diff --git a/audio/aidl/default/include/core-impl/StreamSwitcher.h b/audio/aidl/default/include/core-impl/StreamSwitcher.h
index e462481..2cb8470 100644
--- a/audio/aidl/default/include/core-impl/StreamSwitcher.h
+++ b/audio/aidl/default/include/core-impl/StreamSwitcher.h
@@ -86,7 +86,8 @@
 template <typename T>
 class InnerStreamWrapper : public T, public StreamCommonInterfaceEx {
   public:
-    InnerStreamWrapper(StreamContext* context, const Metadata& metadata) : T(context, metadata) {}
+    template <typename... Args>
+    InnerStreamWrapper(Args&&... args) : T(std::forward<Args>(args)...) {}
     StreamDescriptor::State getStatePriorToClosing() const override { return mStatePriorToClosing; }
 
   private:
diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
index 9537ebc..74dea53 100644
--- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
@@ -23,15 +23,18 @@
 
 using aidl::android::hardware::audio::common::SinkMetadata;
 using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::hardware::audio::core::r_submix::SubmixRoute;
+using aidl::android::media::audio::common::AudioDeviceAddress;
 using aidl::android::media::audio::common::AudioOffloadInfo;
 using aidl::android::media::audio::common::MicrophoneDynamicInfo;
 using aidl::android::media::audio::common::MicrophoneInfo;
 
 namespace aidl::android::hardware::audio::core {
 
-StreamRemoteSubmix::StreamRemoteSubmix(StreamContext* context, const Metadata& metadata)
+StreamRemoteSubmix::StreamRemoteSubmix(StreamContext* context, const Metadata& metadata,
+                                       const AudioDeviceAddress& deviceAddress)
     : StreamCommonImpl(context, metadata),
-      mPortId(context->getPortId()),
+      mDeviceAddress(deviceAddress),
       mIsInput(isInput(metadata)) {
     mStreamConfig.frameSize = context->getFrameSize();
     mStreamConfig.format = context->getFormat();
@@ -40,13 +43,14 @@
 }
 
 std::mutex StreamRemoteSubmix::sSubmixRoutesLock;
-std::map<int32_t, std::shared_ptr<SubmixRoute>> StreamRemoteSubmix::sSubmixRoutes;
+std::map<AudioDeviceAddress, std::shared_ptr<SubmixRoute>> StreamRemoteSubmix::sSubmixRoutes;
 
 ::android::status_t StreamRemoteSubmix::init() {
     {
         std::lock_guard guard(sSubmixRoutesLock);
-        if (sSubmixRoutes.find(mPortId) != sSubmixRoutes.end()) {
-            mCurrentRoute = sSubmixRoutes[mPortId];
+        auto routeItr = sSubmixRoutes.find(mDeviceAddress);
+        if (routeItr != sSubmixRoutes.end()) {
+            mCurrentRoute = routeItr->second;
         }
     }
     // If route is not available for this port, add it.
@@ -59,7 +63,7 @@
         }
         {
             std::lock_guard guard(sSubmixRoutesLock);
-            sSubmixRoutes.emplace(mPortId, mCurrentRoute);
+            sSubmixRoutes.emplace(mDeviceAddress, mCurrentRoute);
         }
     } else {
         if (!mCurrentRoute->isStreamConfigValid(mIsInput, mStreamConfig)) {
@@ -116,8 +120,9 @@
         std::shared_ptr<SubmixRoute> route = nullptr;
         {
             std::lock_guard guard(sSubmixRoutesLock);
-            if (sSubmixRoutes.find(mPortId) != sSubmixRoutes.end()) {
-                route = sSubmixRoutes[mPortId];
+            auto routeItr = sSubmixRoutes.find(mDeviceAddress);
+            if (routeItr != sSubmixRoutes.end()) {
+                route = routeItr->second;
             }
         }
         if (route != nullptr) {
@@ -146,7 +151,7 @@
         LOG(DEBUG) << __func__ << ": pipe destroyed";
 
         std::lock_guard guard(sSubmixRoutesLock);
-        sSubmixRoutes.erase(mPortId);
+        sSubmixRoutes.erase(mDeviceAddress);
     }
     mCurrentRoute.reset();
 }
@@ -357,7 +362,7 @@
                                            const SinkMetadata& sinkMetadata,
                                            const std::vector<MicrophoneInfo>& microphones)
     : StreamIn(std::move(context), microphones),
-      StreamRemoteSubmix(&(StreamIn::mContext), sinkMetadata) {}
+      StreamSwitcher(&(StreamIn::mContext), sinkMetadata) {}
 
 ndk::ScopedAStatus StreamInRemoteSubmix::getActiveMicrophones(
         std::vector<MicrophoneDynamicInfo>* _aidl_return) {
@@ -366,10 +371,66 @@
     return ndk::ScopedAStatus::ok();
 }
 
+StreamSwitcher::DeviceSwitchBehavior StreamInRemoteSubmix::switchCurrentStream(
+        const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
+    // This implementation effectively postpones stream creation until
+    // receiving the first call to 'setConnectedDevices' with a non-empty list.
+    if (isStubStream()) {
+        if (devices.size() == 1) {
+            auto deviceDesc = devices.front().type;
+            if (deviceDesc.type ==
+                ::aidl::android::media::audio::common::AudioDeviceType::IN_SUBMIX) {
+                return DeviceSwitchBehavior::CREATE_NEW_STREAM;
+            }
+            LOG(ERROR) << __func__ << ": Device type " << toString(deviceDesc.type)
+                       << " not supported";
+        } else {
+            LOG(ERROR) << __func__ << ": Only single device supported.";
+        }
+        return DeviceSwitchBehavior::UNSUPPORTED_DEVICES;
+    }
+    return DeviceSwitchBehavior::USE_CURRENT_STREAM;
+}
+
+std::unique_ptr<StreamCommonInterfaceEx> StreamInRemoteSubmix::createNewStream(
+        const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
+        StreamContext* context, const Metadata& metadata) {
+    return std::unique_ptr<StreamCommonInterfaceEx>(
+            new InnerStreamWrapper<StreamRemoteSubmix>(context, metadata, devices.front().address));
+}
+
 StreamOutRemoteSubmix::StreamOutRemoteSubmix(StreamContext&& context,
                                              const SourceMetadata& sourceMetadata,
                                              const std::optional<AudioOffloadInfo>& offloadInfo)
     : StreamOut(std::move(context), offloadInfo),
-      StreamRemoteSubmix(&(StreamOut::mContext), sourceMetadata) {}
+      StreamSwitcher(&(StreamOut::mContext), sourceMetadata) {}
+
+StreamSwitcher::DeviceSwitchBehavior StreamOutRemoteSubmix::switchCurrentStream(
+        const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
+    // This implementation effectively postpones stream creation until
+    // receiving the first call to 'setConnectedDevices' with a non-empty list.
+    if (isStubStream()) {
+        if (devices.size() == 1) {
+            auto deviceDesc = devices.front().type;
+            if (deviceDesc.type ==
+                ::aidl::android::media::audio::common::AudioDeviceType::OUT_SUBMIX) {
+                return DeviceSwitchBehavior::CREATE_NEW_STREAM;
+            }
+            LOG(ERROR) << __func__ << ": Device type " << toString(deviceDesc.type)
+                       << " not supported";
+        } else {
+            LOG(ERROR) << __func__ << ": Only single device supported.";
+        }
+        return DeviceSwitchBehavior::UNSUPPORTED_DEVICES;
+    }
+    return DeviceSwitchBehavior::USE_CURRENT_STREAM;
+}
+
+std::unique_ptr<StreamCommonInterfaceEx> StreamOutRemoteSubmix::createNewStream(
+        const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
+        StreamContext* context, const Metadata& metadata) {
+    return std::unique_ptr<StreamCommonInterfaceEx>(
+            new InnerStreamWrapper<StreamRemoteSubmix>(context, metadata, devices.front().address));
+}
 
 }  // namespace aidl::android::hardware::audio::core