Merge "Simplify slicing related structs." into sc-dev
diff --git a/audio/7.0/IDevice.hal b/audio/7.0/IDevice.hal
index e423f29..85c789a 100644
--- a/audio/7.0/IDevice.hal
+++ b/audio/7.0/IDevice.hal
@@ -245,6 +245,7 @@
     /**
      * Gets the HW synchronization source of the device. Calling this method is
      * equivalent to getting AUDIO_PARAMETER_HW_AV_SYNC on the legacy HAL.
+     *
      * Optional method
      *
      * @return retval operation completion status: OK or NOT_SUPPORTED.
@@ -255,6 +256,7 @@
     /**
      * Sets whether the screen is on. Calling this method is equivalent to
      * setting AUDIO_PARAMETER_KEY_SCREEN_STATE on the legacy HAL.
+     *
      * Optional method
      *
      * @param turnedOn whether the screen is turned on.
diff --git a/audio/7.0/IStream.hal b/audio/7.0/IStream.hal
index 393e38f..e4987c2 100644
--- a/audio/7.0/IStream.hal
+++ b/audio/7.0/IStream.hal
@@ -110,6 +110,7 @@
 
     /**
      * Return the set of devices which this stream is connected to.
+     *
      * Optional method
      *
      * @return retval operation completion status: OK or NOT_SUPPORTED.
@@ -133,6 +134,7 @@
     /**
      * Sets the HW synchronization source. Calling this method is equivalent to
      * setting AUDIO_PARAMETER_STREAM_HW_AV_SYNC on the legacy HAL.
+     *
      * Optional method
      *
      * @param hwAvSync HW synchronization source
diff --git a/audio/7.0/IStreamIn.hal b/audio/7.0/IStreamIn.hal
index bf9ae52..be4bda4 100644
--- a/audio/7.0/IStreamIn.hal
+++ b/audio/7.0/IStreamIn.hal
@@ -24,6 +24,7 @@
      * Returns the source descriptor of the input stream. Calling this method is
      * equivalent to getting AUDIO_PARAMETER_STREAM_INPUT_SOURCE on the legacy
      * HAL.
+     *
      * Optional method
      *
      * @return retval operation completion status.
@@ -33,6 +34,7 @@
 
     /**
      * Set the input gain for the audio driver.
+     *
      * Optional method
      *
      * @param gain 1.0f is unity, 0.0f is zero.
@@ -42,6 +44,7 @@
 
     /**
      * Called when the metadata of the stream's sink has been changed.
+     *
      * Optional method
      *
      * @param sinkMetadata Description of the audio that is suggested by the clients.
@@ -148,7 +151,8 @@
 
     /**
      * Return a recent count of the number of audio frames received and the
-     * clock time associated with that frame count.
+     * clock time associated with that frame count. The count must not reset to
+     * zero when a PCM input enters standby.
      *
      * @return retval INVALID_STATE if the device is not ready/available,
      *                NOT_SUPPORTED if the command is not supported,
diff --git a/audio/7.0/IStreamOut.hal b/audio/7.0/IStreamOut.hal
index 78cb51b..6e8498e 100644
--- a/audio/7.0/IStreamOut.hal
+++ b/audio/7.0/IStreamOut.hal
@@ -35,6 +35,7 @@
      * allowing to directly set the volume as apposed to via the framework.
      * This method might produce multiple PCM outputs or hardware accelerated
      * codecs, such as MP3 or AAC.
+     *
      * Optional method
      *
      * @param left left channel attenuation, 1.0f is unity, 0.0f is zero.
@@ -46,6 +47,7 @@
 
     /**
      * Called when the metadata of the stream's source has been changed.
+     *
      * Optional method
      *
      * @param sourceMetadata Description of the audio that is played by the clients.
@@ -130,6 +132,7 @@
     /**
      * Return the number of audio frames written by the audio DSP to DAC since
      * the output has exited standby.
+     *
      * Optional method
      *
      * @return retval operation completion status.
@@ -141,6 +144,7 @@
      * Get the local time at which the next write to the audio driver will be
      * presented. The units are microseconds, where the epoch is decided by the
      * local audio HAL.
+     *
      * Optional method
      *
      * @return retval operation completion status.
@@ -253,8 +257,11 @@
     drain(AudioDrain type) generates (Result retval);
 
     /**
-     * Notifies to the audio driver to flush the queued data. Stream must
-     * already be paused before calling 'flush'.
+     * Notifies to the audio driver to flush (that is, drop) the queued
+     * data. Stream must already be paused before calling 'flush'. For
+     * compressed and offload streams the frame count returned by
+     * 'getPresentationPosition' must reset after flush.
+     *
      * Optional method
      *
      * Implementation of this function is mandatory for offloaded playback.
@@ -266,12 +273,14 @@
     /**
      * Return a recent count of the number of audio frames presented to an
      * external observer. This excludes frames which have been written but are
-     * still in the pipeline. The count is not reset to zero when output enters
-     * standby. Also returns the value of CLOCK_MONOTONIC as of this
+     * still in the pipeline. The count must not reset to zero when a PCM output
+     * enters standby. For compressed and offload streams it is recommended that
+     * HAL resets the frame count.
+     *
+     * This method also returns the value of CLOCK_MONOTONIC as of this
      * presentation count. The returned count is expected to be 'recent', but
      * does not need to be the most recent possible value. However, the
      * associated time must correspond to whatever count is returned.
-     *
      * Example: assume that N+M frames have been presented, where M is a 'small'
      * number. Then it is permissible to return N instead of N+M, and the
      * timestamp must correspond to N rather than N+M. The terms 'recent' and
@@ -287,6 +296,7 @@
     /**
      * Selects a presentation for decoding from a next generation media stream
      * (as defined per ETSI TS 103 190-2) and a program within the presentation.
+     *
      * Optional method
      *
      * @param presentationId selected audio presentation.
diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal
index bea0705..4f920e4 100644
--- a/audio/common/7.0/types.hal
+++ b/audio/common/7.0/types.hal
@@ -344,7 +344,7 @@
         DeviceAddress device;
     } destination;
     AudioChannelMask channelMask;
-    /** Tags from AudioTrack audio atttributes */
+    /** Tags from AudioRecord audio atttributes */
     vec<AudioTag> tags;
 };
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp
index 548285a..9be9ea7 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp
@@ -31,6 +31,14 @@
 GeneratorHub::GeneratorHub(const OnHalEvent& onHalEvent)
     : mOnHalEvent(onHalEvent), mThread(&GeneratorHub::run, this) {}
 
+GeneratorHub::~GeneratorHub() {
+    mShuttingDownFlag.store(true);
+    mCond.notify_all();
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+}
+
 void GeneratorHub::registerGenerator(int32_t cookie, FakeValueGeneratorPtr generator) {
     {
         std::lock_guard<std::mutex> g(mLock);
@@ -58,15 +66,18 @@
 }
 
 void GeneratorHub::run() {
-    while (true) {
+    while (!mShuttingDownFlag.load()) {
         std::unique_lock<std::mutex> g(mLock);
         // Pop events whose generator does not exist (may be already unregistered)
         while (!mEventQueue.empty()
                && mGenerators.find(mEventQueue.top().cookie) == mGenerators.end()) {
              mEventQueue.pop();
         }
-        // Wait until event queue is not empty
-        mCond.wait(g, [this] { return !mEventQueue.empty(); });
+        // Wait until event queue is not empty or shutting down flag is set
+        mCond.wait(g, [this] { return !mEventQueue.empty() || mShuttingDownFlag.load(); });
+        if (mShuttingDownFlag.load()) {
+            break;
+        }
 
         const VhalEvent& curEvent = mEventQueue.top();
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.h
index dcf6a4f..b25dbf1 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.h
@@ -58,7 +58,7 @@
 
 public:
     GeneratorHub(const OnHalEvent& onHalEvent);
-    ~GeneratorHub() = default;
+    ~GeneratorHub();
 
     /**
      * Register a new generator. The generator will be discarded if it could not produce next event.
@@ -84,6 +84,7 @@
     mutable std::mutex mLock;
     std::condition_variable mCond;
     std::thread mThread;
+    std::atomic<bool> mShuttingDownFlag{false};
 };
 
 }  // namespace impl
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
index 0d1ef45..fc4a4d0 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
@@ -36,5 +36,4 @@
 interface IFace {
   android.hardware.biometrics.face.SensorProps[] getSensorProps();
   android.hardware.biometrics.face.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.face.ISessionCallback cb);
-  void reset();
 }
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
index afb7c8d..11cdf77 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
@@ -50,14 +50,4 @@
      * @return A new session.
      */
     ISession createSession(in int sensorId, in int userId, in ISessionCallback cb);
-
-    /**
-     * Resets the HAL into a clean state, forcing it to cancel all of the pending operations, close
-     * its current session, and release all of the acquired resources.
-     *
-     * This should be used as a last resort to recover the HAL if the current session becomes
-     * unresponsive. The implementation might choose to restart the HAL process to get back into a
-     * good state.
-     */
-    void reset();
 }
diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp
index 73e50f3..a4520de 100644
--- a/biometrics/face/aidl/default/Face.cpp
+++ b/biometrics/face/aidl/default/Face.cpp
@@ -63,8 +63,4 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Face::reset() {
-    return ndk::ScopedAStatus::ok();
-}
-
 }  // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/Face.h b/biometrics/face/aidl/default/Face.h
index 809b856..786b4f8 100644
--- a/biometrics/face/aidl/default/Face.h
+++ b/biometrics/face/aidl/default/Face.h
@@ -27,8 +27,6 @@
     ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId,
                                      const std::shared_ptr<ISessionCallback>& cb,
                                      std::shared_ptr<ISession>* _aidl_return) override;
-
-    ndk::ScopedAStatus reset() override;
 };
 
 }  // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 07777c9..5d3df6f 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -36,5 +36,4 @@
 interface IFingerprint {
   android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps();
   android.hardware.biometrics.fingerprint.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.ISessionCallback cb);
-  void reset();
 }
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 37062ba..98a4530 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -65,14 +65,4 @@
      * @return A new session
      */
     ISession createSession(in int sensorId, in int userId, in ISessionCallback cb);
-
-    /**
-     * Resets the HAL into a clean state, forcing it to cancel all of the pending operations, close
-     * its current session, and release all of the acquired resources.
-     *
-     * This should be used as a last resort to recover the HAL if the current session becomes
-     * unresponsive. The implementation might choose to restart the HAL process to get back into a
-     * good state.
-     */
-    void reset();
 }
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
index 206f518..79f48fe 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
@@ -63,10 +63,4 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Fingerprint::reset() {
-    // Crash. The system will start a fresh instance of the HAL.
-    CHECK(false) << "Unable to reset. Crashing.";
-    return ndk::ScopedAStatus::ok();
-}
-
 }  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/Fingerprint.h b/biometrics/fingerprint/aidl/default/include/Fingerprint.h
index 9b43419..7bd3d6d 100644
--- a/biometrics/fingerprint/aidl/default/include/Fingerprint.h
+++ b/biometrics/fingerprint/aidl/default/include/Fingerprint.h
@@ -34,8 +34,6 @@
                                      const std::shared_ptr<ISessionCallback>& cb,
                                      std::shared_ptr<ISession>* out) override;
 
-    ndk::ScopedAStatus reset() override;
-
   private:
     std::unique_ptr<FakeFingerprintEngine> mEngine;
     WorkerThread mWorker;
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index 5ba7a76..362ab41 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -495,7 +495,7 @@
  *    invoked carrying a proper selector;
  *  - program changes exactly to what was requested.
  */
-TEST_F(BroadcastRadioHalTest, DabTune) {
+TEST_P(BroadcastRadioHalTest, DabTune) {
     ASSERT_TRUE(openSession());
 
     ProgramSelector sel = {};
diff --git a/tv/tuner/1.1/default/Android.bp b/tv/tuner/1.1/default/Android.bp
index 86025cf..a612802 100644
--- a/tv/tuner/1.1/default/Android.bp
+++ b/tv/tuner/1.1/default/Android.bp
@@ -31,6 +31,7 @@
         "android.hardware.tv.tuner@1.1",
         "android.hidl.memory@1.0",
         "libcutils",
+        "libdmabufheap",
         "libfmq",
         "libhidlbase",
         "libhidlmemory",
diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp
index 5ddac99..7d609ea 100644
--- a/tv/tuner/1.1/default/Filter.cpp
+++ b/tv/tuner/1.1/default/Filter.cpp
@@ -16,9 +16,11 @@
 
 #define LOG_TAG "android.hardware.tv.tuner@1.1-Filter"
 
-#include "Filter.h"
+#include <BufferAllocator/BufferAllocator.h>
 #include <utils/Log.h>
 
+#include "Filter.h"
+
 namespace android {
 namespace hardware {
 namespace tv {
@@ -829,15 +831,15 @@
 }
 
 int Filter::createAvIonFd(int size) {
-    // Create an ion fd and allocate an av fd mapped to a buffer to it.
-    int ion_fd = ion_open();
-    if (ion_fd == -1) {
-        ALOGE("[Filter] Failed to open ion fd %d", errno);
+    // Create an DMA-BUF fd and allocate an av fd mapped to a buffer to it.
+    auto buffer_allocator = std::make_unique<BufferAllocator>();
+    if (!buffer_allocator) {
+        ALOGE("[Filter] Unable to create BufferAllocator object");
         return -1;
     }
     int av_fd = -1;
-    ion_alloc_fd(dup(ion_fd), size, 0 /*align*/, ION_HEAP_SYSTEM_MASK, 0 /*flags*/, &av_fd);
-    if (av_fd == -1) {
+    av_fd = buffer_allocator->Alloc("system-uncached", size);
+    if (av_fd < 0) {
         ALOGE("[Filter] Failed to create av fd %d", errno);
         return -1;
     }
diff --git a/wifi/1.5/default/service.cpp b/wifi/1.5/default/service.cpp
index 23e2b47..3de49b2 100644
--- a/wifi/1.5/default/service.cpp
+++ b/wifi/1.5/default/service.cpp
@@ -32,7 +32,6 @@
 using android::hardware::LazyServiceRegistrar;
 using android::hardware::wifi::V1_5::implementation::feature_flags::
     WifiFeatureFlags;
-using android::hardware::wifi::V1_5::implementation::iface_util::WifiIfaceUtil;
 using android::hardware::wifi::V1_5::implementation::legacy_hal::WifiLegacyHal;
 using android::hardware::wifi::V1_5::implementation::legacy_hal::
     WifiLegacyHalFactory;
@@ -63,7 +62,6 @@
         new android::hardware::wifi::V1_5::implementation::Wifi(
             iface_tool, legacy_hal_factory,
             std::make_shared<WifiModeController>(),
-            std::make_shared<WifiIfaceUtil>(iface_tool),
             std::make_shared<WifiFeatureFlags>());
     if (kLazyService) {
         auto registrar = LazyServiceRegistrar::getInstance();
diff --git a/wifi/1.5/default/tests/mock_wifi_iface_util.cpp b/wifi/1.5/default/tests/mock_wifi_iface_util.cpp
index fe6e9e2..b101c4a 100644
--- a/wifi/1.5/default/tests/mock_wifi_iface_util.cpp
+++ b/wifi/1.5/default/tests/mock_wifi_iface_util.cpp
@@ -29,8 +29,9 @@
 namespace iface_util {
 
 MockWifiIfaceUtil::MockWifiIfaceUtil(
-    const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
-    : WifiIfaceUtil(iface_tool) {}
+    const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+    : WifiIfaceUtil(iface_tool, legacy_hal) {}
 }  // namespace iface_util
 }  // namespace implementation
 }  // namespace V1_5
diff --git a/wifi/1.5/default/tests/mock_wifi_iface_util.h b/wifi/1.5/default/tests/mock_wifi_iface_util.h
index a719fec..6d5f59c 100644
--- a/wifi/1.5/default/tests/mock_wifi_iface_util.h
+++ b/wifi/1.5/default/tests/mock_wifi_iface_util.h
@@ -31,7 +31,8 @@
 class MockWifiIfaceUtil : public WifiIfaceUtil {
    public:
     MockWifiIfaceUtil(
-        const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
+        const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+        const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
     MOCK_METHOD1(getFactoryMacAddress,
                  std::array<uint8_t, 6>(const std::string&));
     MOCK_METHOD2(setMacAddress,
diff --git a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h b/wifi/1.5/default/tests/mock_wifi_legacy_hal.h
index 9ab2fd5..826b35f 100644
--- a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h
+++ b/wifi/1.5/default/tests/mock_wifi_legacy_hal.h
@@ -62,6 +62,7 @@
                  wifi_error(const std::string& ifname,
                             wifi_interface_type iftype));
     MOCK_METHOD1(deleteVirtualInterface, wifi_error(const std::string& ifname));
+    MOCK_METHOD0(waitForDriverReady, wifi_error());
 };
 }  // namespace legacy_hal
 }  // namespace implementation
diff --git a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp
index d99bfbd..0ad6f3e 100644
--- a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp
@@ -276,7 +276,7 @@
     std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>>
         mode_controller_{new NiceMock<mode_controller::MockWifiModeController>};
     std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
-        new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_)};
+        new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
     std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>>
         feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>};
 
diff --git a/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp
index d70e42f..8b67bb8 100644
--- a/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp
+++ b/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp
@@ -22,6 +22,7 @@
 #include "wifi_iface_util.h"
 
 #include "mock_interface_tool.h"
+#include "mock_wifi_legacy_hal.h"
 
 using testing::NiceMock;
 using testing::Test;
@@ -48,7 +49,11 @@
    protected:
     std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
         new NiceMock<wifi_system::MockInterfaceTool>};
-    WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_);
+    legacy_hal::wifi_hal_fn fake_func_table_;
+    std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
+        new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_,
+                                                    fake_func_table_, true)};
+    WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_, legacy_hal_);
 };
 
 TEST_F(WifiIfaceUtilTest, GetOrCreateRandomMacAddress) {
diff --git a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp
index 52f0c2b..32da55e 100644
--- a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp
+++ b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp
@@ -122,7 +122,7 @@
         new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_,
                                                     fake_func_table_, true)};
     std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
-        new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_)};
+        new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
 };
 
 TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) {
diff --git a/wifi/1.5/default/wifi.cpp b/wifi/1.5/default/wifi.cpp
index 17db51d..da98db8 100644
--- a/wifi/1.5/default/wifi.cpp
+++ b/wifi/1.5/default/wifi.cpp
@@ -37,12 +37,10 @@
     const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
     const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
     const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
-    const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
     const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)
     : iface_tool_(iface_tool),
       legacy_hal_factory_(legacy_hal_factory),
       mode_controller_(mode_controller),
-      iface_util_(iface_util),
       feature_flags_(feature_flags),
       run_state_(RunState::STOPPED) {}
 
@@ -130,7 +128,8 @@
         for (auto& hal : legacy_hals_) {
             chips_.push_back(new WifiChip(
                 chipId, chipId == kPrimaryChipId, hal, mode_controller_,
-                iface_util_, feature_flags_, on_subsystem_restart_callback));
+                std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal),
+                feature_flags_, on_subsystem_restart_callback));
             chipId++;
         }
         run_state_ = RunState::STARTED;
diff --git a/wifi/1.5/default/wifi.h b/wifi/1.5/default/wifi.h
index 9f5a1b0..825c0bc 100644
--- a/wifi/1.5/default/wifi.h
+++ b/wifi/1.5/default/wifi.h
@@ -46,7 +46,6 @@
              legacy_hal_factory,
          const std::shared_ptr<mode_controller::WifiModeController>
              mode_controller,
-         const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
          const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags);
 
     bool isValid();
@@ -85,7 +84,6 @@
     std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory_;
     std::shared_ptr<mode_controller::WifiModeController> mode_controller_;
     std::vector<std::shared_ptr<legacy_hal::WifiLegacyHal>> legacy_hals_;
-    std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_;
     std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags_;
     RunState run_state_;
     std::vector<sp<WifiChip>> chips_;
diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp
index 0450a7b..0499f45 100644
--- a/wifi/1.5/default/wifi_chip.cpp
+++ b/wifi/1.5/default/wifi_chip.cpp
@@ -353,7 +353,7 @@
     ChipId chip_id, bool is_primary,
     const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
     const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
-    const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util,
+    const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
     const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
     const std::function<void(const std::string&)>& handler)
     : chip_id_(chip_id),
@@ -986,14 +986,14 @@
         }
     }
     br_ifaces_ap_instances_[br_ifname] = ap_instances;
-    if (!iface_util_.lock()->createBridge(br_ifname)) {
+    if (!iface_util_->createBridge(br_ifname)) {
         LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
         invalidateAndClearBridgedAp(br_ifname);
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
     for (auto const& instance : ap_instances) {
         // Bind ap instance interface to AP bridge
-        if (!iface_util_.lock()->addIfaceToBridge(br_ifname, instance)) {
+        if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
             LOG(ERROR) << "Failed add if to Bridge - if_name="
                        << instance.c_str();
             invalidateAndClearBridgedAp(br_ifname);
@@ -1054,8 +1054,7 @@
         if (it.first == ifname) {
             for (auto const& iface : it.second) {
                 if (iface == ifInstanceName) {
-                    if (!iface_util_.lock()->removeIfaceFromBridge(it.first,
-                                                                   iface)) {
+                    if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
                         LOG(ERROR)
                             << "Failed to remove interface: " << ifInstanceName
                             << " from " << ifname;
@@ -1086,7 +1085,7 @@
     }
     bool is_dedicated_iface = true;
     std::string ifname = getPredefinedNanIfaceName();
-    if (ifname.empty() || !iface_util_.lock()->ifNameToIndex(ifname)) {
+    if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) {
         // Use the first shared STA iface (wlan0) if a dedicated aware iface is
         // not defined.
         ifname = getFirstActiveWlanIfaceName();
@@ -1968,10 +1967,10 @@
 void WifiChip::invalidateAndClearBridgedApAll() {
     for (auto const& it : br_ifaces_ap_instances_) {
         for (auto const& iface : it.second) {
-            iface_util_.lock()->removeIfaceFromBridge(it.first, iface);
+            iface_util_->removeIfaceFromBridge(it.first, iface);
             legacy_hal_.lock()->deleteVirtualInterface(iface);
         }
-        iface_util_.lock()->deleteBridge(it.first);
+        iface_util_->deleteBridge(it.first);
     }
     br_ifaces_ap_instances_.clear();
 }
@@ -1982,10 +1981,10 @@
     for (auto const& it : br_ifaces_ap_instances_) {
         if (it.first == br_name) {
             for (auto const& iface : it.second) {
-                iface_util_.lock()->removeIfaceFromBridge(br_name, iface);
+                iface_util_->removeIfaceFromBridge(br_name, iface);
                 legacy_hal_.lock()->deleteVirtualInterface(iface);
             }
-            iface_util_.lock()->deleteBridge(br_name);
+            iface_util_->deleteBridge(br_name);
             br_ifaces_ap_instances_.erase(br_name);
             break;
         }
diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h
index b4ed30e..92d639f 100644
--- a/wifi/1.5/default/wifi_chip.h
+++ b/wifi/1.5/default/wifi_chip.h
@@ -54,7 +54,7 @@
              const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
              const std::weak_ptr<mode_controller::WifiModeController>
                  mode_controller,
-             const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util,
+             const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
              const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
              const std::function<void(const std::string&)>&
                  subsystemCallbackHandler);
@@ -307,7 +307,7 @@
     ChipId chip_id_;
     std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
     std::weak_ptr<mode_controller::WifiModeController> mode_controller_;
-    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
+    std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_;
     std::vector<sp<WifiApIface>> ap_ifaces_;
     std::vector<sp<WifiNanIface>> nan_ifaces_;
     std::vector<sp<WifiP2pIface>> p2p_ifaces_;
diff --git a/wifi/1.5/default/wifi_iface_util.cpp b/wifi/1.5/default/wifi_iface_util.cpp
index 2a0aef8..d1434e3 100644
--- a/wifi/1.5/default/wifi_iface_util.cpp
+++ b/wifi/1.5/default/wifi_iface_util.cpp
@@ -41,8 +41,10 @@
 namespace iface_util {
 
 WifiIfaceUtil::WifiIfaceUtil(
-    const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
+    const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
     : iface_tool_(iface_tool),
+      legacy_hal_(legacy_hal),
       random_mac_address_(nullptr),
       event_handlers_map_() {}
 
@@ -59,14 +61,20 @@
         return false;
     }
 #endif
-    if (!iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac)) {
-        LOG(ERROR) << "SetMacAddress failed.";
-        return false;
-    }
+    bool success = iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac);
 #ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
     if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
-        LOG(ERROR) << "SetUpState(true) failed.";
-        return false;
+        LOG(ERROR) << "SetUpState(true) failed. Wait for driver ready.";
+        // Wait for driver ready and try to set iface UP again
+        if (legacy_hal_.lock()->waitForDriverReady() !=
+            legacy_hal::WIFI_SUCCESS) {
+            LOG(ERROR) << "SetUpState(true) wait for driver ready failed.";
+            return false;
+        }
+        if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
+            LOG(ERROR) << "SetUpState(true) failed after retry.";
+            return false;
+        }
     }
 #endif
     IfaceEventHandlers event_handlers = {};
@@ -77,8 +85,12 @@
     if (event_handlers.on_state_toggle_off_on != nullptr) {
         event_handlers.on_state_toggle_off_on(iface_name);
     }
-    LOG(DEBUG) << "Successfully SetMacAddress.";
-    return true;
+    if (!success) {
+        LOG(ERROR) << "SetMacAddress failed.";
+    } else {
+        LOG(DEBUG) << "SetMacAddress succeeded.";
+    }
+    return success;
 }
 
 std::array<uint8_t, 6> WifiIfaceUtil::getOrCreateRandomMacAddress() {
diff --git a/wifi/1.5/default/wifi_iface_util.h b/wifi/1.5/default/wifi_iface_util.h
index 296d182..b449077 100644
--- a/wifi/1.5/default/wifi_iface_util.h
+++ b/wifi/1.5/default/wifi_iface_util.h
@@ -21,6 +21,8 @@
 
 #include <android/hardware/wifi/1.0/IWifi.h>
 
+#include "wifi_legacy_hal.h"
+
 namespace android {
 namespace hardware {
 namespace wifi {
@@ -40,7 +42,8 @@
  */
 class WifiIfaceUtil {
    public:
-    WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
+    WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+                  const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
     virtual ~WifiIfaceUtil() = default;
 
     virtual std::array<uint8_t, 6> getFactoryMacAddress(
@@ -73,6 +76,7 @@
     std::array<uint8_t, 6> createRandomMacAddress();
 
     std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
+    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
     std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_;
     std::map<std::string, IfaceEventHandlers> event_handlers_map_;
 };
diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp
index f5ca753..260f186 100644
--- a/wifi/1.5/default/wifi_legacy_hal.cpp
+++ b/wifi/1.5/default/wifi_legacy_hal.cpp
@@ -476,6 +476,10 @@
 
 bool WifiLegacyHal::isStarted() { return is_started_; }
 
+wifi_error WifiLegacyHal::waitForDriverReady() {
+    return global_func_table_.wifi_wait_for_driver_ready();
+}
+
 std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion(
     const std::string& iface_name) {
     std::array<char, kMaxVersionStringLength> buffer;
diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h
index 03ca841..2372535 100644
--- a/wifi/1.5/default/wifi_legacy_hal.h
+++ b/wifi/1.5/default/wifi_legacy_hal.h
@@ -473,6 +473,7 @@
     // using a predefined timeout.
     virtual wifi_error stop(std::unique_lock<std::recursive_mutex>* lock,
                             const std::function<void()>& on_complete_callback);
+    virtual wifi_error waitForDriverReady();
     // Checks if legacy HAL has successfully started
     bool isStarted();
     // Wrappers for all the functions in the legacy HAL function table.