Merge "Audio: Document channel order convention" into qt-dev
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index 2093c25..696c746 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -119,6 +119,10 @@
network_type_bitmap |= ::android::hardware::radio::V1_4::RadioAccessFamily::LTE;
+ // TODO(b/131634656): LTE_CA will be sent to modem as a RAF in Q, but LTE_CA is not a RAF,
+ // we will not send it to modem as a RAF in R.
+ network_type_bitmap |= ::android::hardware::radio::V1_4::RadioAccessFamily::LTE_CA;
+
Return<void> res = radio_v1_4->setPreferredNetworkTypeBitmap(serial, network_type_bitmap);
ASSERT_OK(res);
diff --git a/wifi/1.3/default/Android.mk b/wifi/1.3/default/Android.mk
index 199ea3b..1f91861 100644
--- a/wifi/1.3/default/Android.mk
+++ b/wifi/1.3/default/Android.mk
@@ -142,12 +142,14 @@
LOCAL_SRC_FILES := \
tests/hidl_struct_util_unit_tests.cpp \
tests/main.cpp \
+ tests/mock_interface_tool.cpp \
tests/mock_wifi_feature_flags.cpp \
tests/mock_wifi_iface_util.cpp \
tests/mock_wifi_legacy_hal.cpp \
tests/mock_wifi_mode_controller.cpp \
tests/ringbuffer_unit_tests.cpp \
tests/wifi_ap_iface_unit_tests.cpp \
+ tests/wifi_nan_iface_unit_tests.cpp \
tests/wifi_chip_unit_tests.cpp \
tests/wifi_iface_util_unit_tests.cpp
LOCAL_STATIC_LIBRARIES := \
diff --git a/wifi/1.3/default/service.cpp b/wifi/1.3/default/service.cpp
index 73015cf..fcbc37c 100644
--- a/wifi/1.3/default/service.cpp
+++ b/wifi/1.3/default/service.cpp
@@ -48,12 +48,14 @@
configureRpcThreadpool(1, true /* callerWillJoin */);
+ const auto iface_tool =
+ std::make_shared<android::wifi_system::InterfaceTool>();
// Setup hwbinder service
android::sp<android::hardware::wifi::V1_3::IWifi> service =
new android::hardware::wifi::V1_3::implementation::Wifi(
- std::make_shared<WifiLegacyHal>(),
+ iface_tool, std::make_shared<WifiLegacyHal>(iface_tool),
std::make_shared<WifiModeController>(),
- std::make_shared<WifiIfaceUtil>(),
+ std::make_shared<WifiIfaceUtil>(iface_tool),
std::make_shared<WifiFeatureFlags>());
if (kLazyService) {
LazyServiceRegistrar registrar;
diff --git a/wifi/1.3/default/tests/mock_interface_tool.cpp b/wifi/1.3/default/tests/mock_interface_tool.cpp
new file mode 100644
index 0000000..b99a164
--- /dev/null
+++ b/wifi/1.3/default/tests/mock_interface_tool.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38
+#include "mock_interface_tool.h"
+
+namespace android {
+namespace wifi_system {
+
+MockInterfaceTool::MockInterfaceTool() {}
+
+} // namespace wifi_system
+} // namespace android
diff --git a/wifi/1.3/default/tests/mock_interface_tool.h b/wifi/1.3/default/tests/mock_interface_tool.h
new file mode 100644
index 0000000..0f17551
--- /dev/null
+++ b/wifi/1.3/default/tests/mock_interface_tool.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_INTERFACE_TOOL_H
+#define MOCK_INTERFACE_TOOL_H
+
+#include <gmock/gmock.h>
+#include <wifi_system/interface_tool.h>
+
+namespace android {
+namespace wifi_system {
+
+class MockInterfaceTool : public InterfaceTool {
+ public:
+ MockInterfaceTool();
+
+ MOCK_METHOD1(GetUpState, bool(const char* if_name));
+ MOCK_METHOD2(SetUpState, bool(const char* if_name, bool request_up));
+ MOCK_METHOD1(SetWifiUpState, bool(bool request_up));
+ MOCK_METHOD2(SetMacAddress,
+ bool(const char* if_name,
+ const std::array<uint8_t, ETH_ALEN>& address));
+ MOCK_METHOD1(GetFactoryMacAddress,
+ std::array<uint8_t, ETH_ALEN>(const char* if_name));
+
+}; // class MockInterfaceTool
+
+} // namespace wifi_system
+} // namespace android
+
+#endif // MOCK_INTERFACE_TOOL_H
diff --git a/wifi/1.3/default/tests/mock_wifi_iface_util.cpp b/wifi/1.3/default/tests/mock_wifi_iface_util.cpp
index 706cb6a..3d877c0 100644
--- a/wifi/1.3/default/tests/mock_wifi_iface_util.cpp
+++ b/wifi/1.3/default/tests/mock_wifi_iface_util.cpp
@@ -28,7 +28,9 @@
namespace implementation {
namespace iface_util {
-MockWifiIfaceUtil::MockWifiIfaceUtil() : WifiIfaceUtil() {}
+MockWifiIfaceUtil::MockWifiIfaceUtil(
+ const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
+ : WifiIfaceUtil(iface_tool) {}
} // namespace iface_util
} // namespace implementation
} // namespace V1_3
diff --git a/wifi/1.3/default/tests/mock_wifi_iface_util.h b/wifi/1.3/default/tests/mock_wifi_iface_util.h
index 87ab5db..8ec93eb 100644
--- a/wifi/1.3/default/tests/mock_wifi_iface_util.h
+++ b/wifi/1.3/default/tests/mock_wifi_iface_util.h
@@ -30,12 +30,16 @@
class MockWifiIfaceUtil : public WifiIfaceUtil {
public:
- MockWifiIfaceUtil();
+ MockWifiIfaceUtil(
+ const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
MOCK_METHOD1(getFactoryMacAddress,
std::array<uint8_t, 6>(const std::string&));
MOCK_METHOD2(setMacAddress,
bool(const std::string&, const std::array<uint8_t, 6>&));
MOCK_METHOD0(getOrCreateRandomMacAddress, std::array<uint8_t, 6>());
+ MOCK_METHOD2(registerIfaceEventHandlers,
+ void(const std::string&, IfaceEventHandlers));
+ MOCK_METHOD1(unregisterIfaceEventHandlers, void(const std::string&));
};
} // namespace iface_util
} // namespace implementation
diff --git a/wifi/1.3/default/tests/mock_wifi_legacy_hal.cpp b/wifi/1.3/default/tests/mock_wifi_legacy_hal.cpp
index 4cd279d..0a202c4 100644
--- a/wifi/1.3/default/tests/mock_wifi_legacy_hal.cpp
+++ b/wifi/1.3/default/tests/mock_wifi_legacy_hal.cpp
@@ -28,7 +28,9 @@
namespace implementation {
namespace legacy_hal {
-MockWifiLegacyHal::MockWifiLegacyHal() : WifiLegacyHal() {}
+MockWifiLegacyHal::MockWifiLegacyHal(
+ const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
+ : WifiLegacyHal(iface_tool) {}
} // namespace legacy_hal
} // namespace implementation
} // namespace V1_3
diff --git a/wifi/1.3/default/tests/mock_wifi_legacy_hal.h b/wifi/1.3/default/tests/mock_wifi_legacy_hal.h
index 53fa8d6..81cb1de 100644
--- a/wifi/1.3/default/tests/mock_wifi_legacy_hal.h
+++ b/wifi/1.3/default/tests/mock_wifi_legacy_hal.h
@@ -30,7 +30,8 @@
class MockWifiLegacyHal : public WifiLegacyHal {
public:
- MockWifiLegacyHal();
+ MockWifiLegacyHal(
+ const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
MOCK_METHOD0(initialize, wifi_error());
MOCK_METHOD0(start, wifi_error());
MOCK_METHOD2(stop, wifi_error(std::unique_lock<std::recursive_mutex>*,
diff --git a/wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp b/wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp
index 28e028b..680f534 100644
--- a/wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp
+++ b/wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp
@@ -22,6 +22,7 @@
#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38
#include "wifi_ap_iface.h"
+#include "mock_interface_tool.h"
#include "mock_wifi_feature_flags.h"
#include "mock_wifi_iface_util.h"
#include "mock_wifi_legacy_hal.h"
@@ -42,10 +43,12 @@
class WifiApIfaceTest : public Test {
protected:
+ std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
+ new NiceMock<wifi_system::MockInterfaceTool>};
std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
- new NiceMock<legacy_hal::MockWifiLegacyHal>};
+ new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_)};
std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
- new NiceMock<iface_util::MockWifiIfaceUtil>};
+ new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_)};
std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>>
feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>};
};
diff --git a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
index 7928328..d8ce278 100644
--- a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
@@ -22,6 +22,7 @@
#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38
#include "wifi_chip.h"
+#include "mock_interface_tool.h"
#include "mock_wifi_feature_flags.h"
#include "mock_wifi_iface_util.h"
#include "mock_wifi_legacy_hal.h"
@@ -263,12 +264,14 @@
sp<WifiChip> chip_;
ChipId chip_id_ = kFakeChipId;
+ std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
+ new NiceMock<wifi_system::MockInterfaceTool>};
std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
- new NiceMock<legacy_hal::MockWifiLegacyHal>};
+ new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_)};
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>};
+ new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_)};
std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>>
feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>};
@@ -700,6 +703,72 @@
});
}
+TEST_F(WifiChipV2_AwareIfaceCombinationTest,
+ InvalidateAndRemoveNanOnStaRemove) {
+ findModeAndConfigureForIfaceType(IfaceType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+
+ // Create NAN iface
+ ASSERT_EQ(createIface(IfaceType::NAN), "wlan0");
+
+ // We should have 1 nan iface.
+ chip_->getNanIfaceNames(
+ [](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) {
+ ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+ ASSERT_EQ(iface_names.size(), 1u);
+ ASSERT_EQ(iface_names[0], "wlan0");
+ });
+ // Retrieve the exact iface object.
+ sp<IWifiNanIface> nan_iface;
+ chip_->getNanIface("wlan0", [&nan_iface](const WifiStatus& status,
+ const sp<IWifiNanIface>& iface) {
+ ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+ ASSERT_NE(iface.get(), nullptr);
+ nan_iface = iface;
+ });
+
+ // Remove the STA iface.
+ removeIface(IfaceType::STA, "wlan0");
+ // We should have 0 nan iface now.
+ chip_->getNanIfaceNames(
+ [](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) {
+ ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+ ASSERT_EQ(iface_names.size(), 0u);
+ });
+ // Any operation on the nan iface object should return error now.
+ nan_iface->getName(
+ [](const WifiStatus& status, const std::string& /* iface_name */) {
+ ASSERT_EQ(WifiStatusCode::ERROR_WIFI_IFACE_INVALID, status.code);
+ });
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest,
+ InvalidateAndRemoveRttControllerOnStaRemove) {
+ findModeAndConfigureForIfaceType(IfaceType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+
+ // Create RTT controller
+ sp<IWifiRttController> rtt_controller;
+ chip_->createRttController(
+ NULL, [&rtt_controller](const WifiStatus& status,
+ const sp<IWifiRttController>& rtt) {
+ if (WifiStatusCode::SUCCESS == status.code) {
+ ASSERT_NE(rtt.get(), nullptr);
+ rtt_controller = rtt;
+ }
+ });
+
+ // Remove the STA iface.
+ removeIface(IfaceType::STA, "wlan0");
+
+ // Any operation on the rtt controller object should return error now.
+ rtt_controller->getBoundIface(
+ [](const WifiStatus& status, const sp<IWifiIface>& /* iface */) {
+ ASSERT_EQ(WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ status.code);
+ });
+}
+
////////// V1 Iface Combinations when AP creation is disabled //////////
class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
public:
@@ -732,6 +801,7 @@
ASSERT_TRUE(createIface(IfaceType::AP).empty());
}
+////////// Hypothetical Iface Combination with multiple ifaces //////////
class WifiChip_MultiIfaceTest : public WifiChipTest {
public:
void SetUp() override {
diff --git a/wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp
index e5758fa..28d23ff 100644
--- a/wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp
+++ b/wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp
@@ -21,10 +21,15 @@
#undef NAN
#include "wifi_iface_util.h"
+#include "mock_interface_tool.h"
+
+using testing::NiceMock;
using testing::Test;
namespace {
constexpr uint8_t kValidUnicastLocallyAssignedMacAddressMask = 0x02;
+constexpr uint8_t kMacAddress[] = {0x02, 0x12, 0x45, 0x56, 0xab, 0xcc};
+constexpr char kIfaceName[] = "test-wlan0";
bool isValidUnicastLocallyAssignedMacAddress(
const std::array<uint8_t, 6>& mac_address) {
@@ -38,19 +43,52 @@
namespace wifi {
namespace V1_3 {
namespace implementation {
+namespace iface_util {
class WifiIfaceUtilTest : public Test {
protected:
- iface_util::WifiIfaceUtil iface_util_;
+ std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
+ new NiceMock<wifi_system::MockInterfaceTool>};
+ WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_);
};
TEST_F(WifiIfaceUtilTest, GetOrCreateRandomMacAddress) {
- auto mac_address = iface_util_.getOrCreateRandomMacAddress();
+ auto mac_address = iface_util_->getOrCreateRandomMacAddress();
ASSERT_TRUE(isValidUnicastLocallyAssignedMacAddress(mac_address));
// All further calls should return the same MAC address.
- ASSERT_EQ(mac_address, iface_util_.getOrCreateRandomMacAddress());
- ASSERT_EQ(mac_address, iface_util_.getOrCreateRandomMacAddress());
+ ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress());
+ ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress());
}
+
+TEST_F(WifiIfaceUtilTest, IfaceEventHandlers_SetMacAddress) {
+ std::array<uint8_t, 6> mac_address = {};
+ std::copy(std::begin(kMacAddress), std::end(kMacAddress),
+ std::begin(mac_address));
+ EXPECT_CALL(*iface_tool_, SetMacAddress(testing::_, testing::_))
+ .WillRepeatedly(testing::Return(true));
+ EXPECT_CALL(*iface_tool_, SetUpState(testing::_, testing::_))
+ .WillRepeatedly(testing::Return(true));
+
+ // Register for iface state toggle events.
+ bool callback_invoked = false;
+ iface_util::IfaceEventHandlers event_handlers = {};
+ event_handlers.on_state_toggle_off_on =
+ [&callback_invoked](const std::string& /* iface_name */) {
+ callback_invoked = true;
+ };
+ iface_util_->registerIfaceEventHandlers(kIfaceName, event_handlers);
+ // Invoke setMacAddress and ensure that the cb is invoked.
+ ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address));
+ ASSERT_TRUE(callback_invoked);
+
+ // Unregister for iface state toggle events.
+ callback_invoked = false;
+ iface_util_->unregisterIfaceEventHandlers(kIfaceName);
+ // Invoke setMacAddress and ensure that the cb is not invoked.
+ ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address));
+ ASSERT_FALSE(callback_invoked);
+}
+} // namespace iface_util
} // namespace implementation
} // namespace V1_3
} // namespace wifi
diff --git a/wifi/1.3/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.3/default/tests/wifi_nan_iface_unit_tests.cpp
new file mode 100644
index 0000000..eb6c610
--- /dev/null
+++ b/wifi/1.3/default/tests/wifi_nan_iface_unit_tests.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <cutils/properties.h>
+#include <gmock/gmock.h>
+
+#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38
+#include "wifi_nan_iface.h"
+
+#include "mock_interface_tool.h"
+#include "mock_wifi_feature_flags.h"
+#include "mock_wifi_iface_util.h"
+#include "mock_wifi_legacy_hal.h"
+
+using testing::NiceMock;
+using testing::Return;
+using testing::Test;
+
+namespace {
+constexpr char kIfaceName[] = "mockWlan0";
+} // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_3 {
+namespace implementation {
+
+bool CaptureIfaceEventHandlers(
+ const std::string& /* iface_name*/,
+ iface_util::IfaceEventHandlers in_iface_event_handlers,
+ iface_util::IfaceEventHandlers* out_iface_event_handlers) {
+ *out_iface_event_handlers = in_iface_event_handlers;
+ return true;
+}
+
+class MockNanIfaceEventCallback : public IWifiNanIfaceEventCallback {
+ public:
+ MockNanIfaceEventCallback() = default;
+
+ MOCK_METHOD3(notifyCapabilitiesResponse,
+ Return<void>(uint16_t, const WifiNanStatus&,
+ const NanCapabilities&));
+ MOCK_METHOD2(notifyEnableResponse,
+ Return<void>(uint16_t, const WifiNanStatus&));
+ MOCK_METHOD2(notifyConfigResponse,
+ Return<void>(uint16_t, const WifiNanStatus&));
+ MOCK_METHOD2(notifyDisableResponse,
+ Return<void>(uint16_t, const WifiNanStatus&));
+ MOCK_METHOD3(notifyStartPublishResponse,
+ Return<void>(uint16_t, const WifiNanStatus&, uint8_t));
+ MOCK_METHOD2(notifyStopPublishResponse,
+ Return<void>(uint16_t, const WifiNanStatus&));
+ MOCK_METHOD3(notifyStartSubscribeResponse,
+ Return<void>(uint16_t, const WifiNanStatus&, uint8_t));
+ MOCK_METHOD2(notifyStopSubscribeResponse,
+ Return<void>(uint16_t, const WifiNanStatus&));
+ MOCK_METHOD2(notifyTransmitFollowupResponse,
+ Return<void>(uint16_t, const WifiNanStatus&));
+ MOCK_METHOD2(notifyCreateDataInterfaceResponse,
+ Return<void>(uint16_t, const WifiNanStatus&));
+ MOCK_METHOD2(notifyDeleteDataInterfaceResponse,
+ Return<void>(uint16_t, const WifiNanStatus&));
+ MOCK_METHOD3(notifyInitiateDataPathResponse,
+ Return<void>(uint16_t, const WifiNanStatus&, uint32_t));
+ MOCK_METHOD2(notifyRespondToDataPathIndicationResponse,
+ Return<void>(uint16_t, const WifiNanStatus&));
+ MOCK_METHOD2(notifyTerminateDataPathResponse,
+ Return<void>(uint16_t, const WifiNanStatus&));
+ MOCK_METHOD1(eventClusterEvent, Return<void>(const NanClusterEventInd&));
+ MOCK_METHOD1(eventDisabled, Return<void>(const WifiNanStatus&));
+ MOCK_METHOD2(eventPublishTerminated,
+ Return<void>(uint8_t, const WifiNanStatus&));
+ MOCK_METHOD2(eventSubscribeTerminated,
+ Return<void>(uint8_t, const WifiNanStatus&));
+ MOCK_METHOD1(eventMatch, Return<void>(const NanMatchInd&));
+ MOCK_METHOD2(eventMatchExpired, Return<void>(uint8_t, uint32_t));
+ MOCK_METHOD1(eventFollowupReceived,
+ Return<void>(const NanFollowupReceivedInd&));
+ MOCK_METHOD2(eventTransmitFollowup,
+ Return<void>(uint16_t, const WifiNanStatus&));
+ MOCK_METHOD1(eventDataPathRequest,
+ Return<void>(const NanDataPathRequestInd&));
+ MOCK_METHOD1(eventDataPathConfirm,
+ Return<void>(const NanDataPathConfirmInd&));
+ MOCK_METHOD1(eventDataPathTerminated, Return<void>(uint32_t));
+};
+
+class WifiNanIfaceTest : public Test {
+ protected:
+ std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
+ new NiceMock<wifi_system::MockInterfaceTool>};
+ std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
+ new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_)};
+ std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
+ new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_)};
+};
+
+TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) {
+ iface_util::IfaceEventHandlers captured_iface_event_handlers = {};
+ EXPECT_CALL(*legacy_hal_,
+ nanRegisterCallbackHandlers(testing::_, testing::_))
+ .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+ EXPECT_CALL(*iface_util_,
+ registerIfaceEventHandlers(testing::_, testing::_))
+ .WillOnce(testing::Invoke(
+ bind(CaptureIfaceEventHandlers, std::placeholders::_1,
+ std::placeholders::_2, &captured_iface_event_handlers)));
+ sp<WifiNanIface> nan_iface =
+ new WifiNanIface(kIfaceName, legacy_hal_, iface_util_);
+
+ // Register a mock nan event callback.
+ sp<NiceMock<MockNanIfaceEventCallback>> mock_event_callback{
+ new NiceMock<MockNanIfaceEventCallback>};
+ nan_iface->registerEventCallback(
+ mock_event_callback, [](const WifiStatus& status) {
+ ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+ });
+ // Ensure that the eventDisabled() function in mock callback will be
+ // invoked.
+ WifiNanStatus expected_nan_status = {
+ NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
+ EXPECT_CALL(*mock_event_callback, eventDisabled(expected_nan_status))
+ .Times(1);
+
+ // Trigger the iface state toggle callback.
+ captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName);
+}
+} // namespace implementation
+} // namespace V1_3
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/1.3/default/wifi.cpp b/wifi/1.3/default/wifi.cpp
index 1f64085..2f21819 100644
--- a/wifi/1.3/default/wifi.cpp
+++ b/wifi/1.3/default/wifi.cpp
@@ -34,11 +34,13 @@
using hidl_return_util::validateAndCallWithLock;
Wifi::Wifi(
+ const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
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)
- : legacy_hal_(legacy_hal),
+ : iface_tool_(iface_tool),
+ legacy_hal_(legacy_hal),
mode_controller_(mode_controller),
iface_util_(iface_util),
feature_flags_(feature_flags),
diff --git a/wifi/1.3/default/wifi.h b/wifi/1.3/default/wifi.h
index c4ab773..1c2a154 100644
--- a/wifi/1.3/default/wifi.h
+++ b/wifi/1.3/default/wifi.h
@@ -40,7 +40,8 @@
*/
class Wifi : public V1_3::IWifi {
public:
- Wifi(const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ Wifi(const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
+ const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
const std::shared_ptr<mode_controller::WifiModeController>
mode_controller,
const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
@@ -77,6 +78,7 @@
// Instance is created in this root level |IWifi| HIDL interface object
// and shared with all the child HIDL interface objects.
+ std::shared_ptr<wifi_system::InterfaceTool> iface_tool_;
std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
std::shared_ptr<mode_controller::WifiModeController> mode_controller_;
std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_;
diff --git a/wifi/1.3/default/wifi_chip.cpp b/wifi/1.3/default/wifi_chip.cpp
index b768959..e9991dc 100644
--- a/wifi/1.3/default/wifi_chip.cpp
+++ b/wifi/1.3/default/wifi_chip.cpp
@@ -634,6 +634,27 @@
rtt_controllers_.clear();
}
+void WifiChip::invalidateAndRemoveDependencies(
+ const std::string& removed_iface_name) {
+ for (const auto& nan_iface : nan_ifaces_) {
+ if (nan_iface->getName() == removed_iface_name) {
+ invalidateAndClear(nan_ifaces_, nan_iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback
+ ->onIfaceRemoved(IfaceType::NAN, removed_iface_name)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+ }
+ }
+ }
+ }
+ for (const auto& rtt : rtt_controllers_) {
+ if (rtt->getIfaceName() == removed_iface_name) {
+ invalidateAndClear(rtt_controllers_, rtt);
+ }
+ }
+}
+
std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
}
@@ -819,6 +840,11 @@
if (!iface.get()) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
+ // Invalidate & remove any dependent objects first.
+ // Note: This is probably not required because we never create
+ // nan/rtt objects over AP iface. But, there is no harm to do it
+ // here and not make that assumption all over the place.
+ invalidateAndRemoveDependencies(ifname);
invalidateAndClear(ap_ifaces_, iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
@@ -835,7 +861,7 @@
}
// These are still assumed to be based on wlan0.
std::string ifname = getFirstActiveWlanIfaceName();
- sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_);
+ sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_, iface_util_);
nan_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
@@ -960,6 +986,8 @@
if (!iface.get()) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
+ // Invalidate & remove any dependent objects first.
+ invalidateAndRemoveDependencies(ifname);
invalidateAndClear(sta_ifaces_, iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
@@ -1435,6 +1463,13 @@
return canCurrentModeSupportIfaceCombo(req_iface_combo);
}
+bool WifiChip::isDualApAllowedInCurrentMode() {
+ // Check if we can support atleast 1 STA & 1 AP concurrently.
+ std::map<IfaceType, size_t> req_iface_combo;
+ req_iface_combo[IfaceType::AP] = 2;
+ return canCurrentModeSupportIfaceCombo(req_iface_combo);
+}
+
std::string WifiChip::getFirstActiveWlanIfaceName() {
if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName();
if (ap_ifaces_.size() > 0) return ap_ifaces_[0]->getName();
@@ -1460,10 +1495,12 @@
}
// AP iface names start with idx 1 for modes supporting
-// concurrent STA, else start with idx 0.
+// concurrent STA and not dual AP, else start with idx 0.
std::string WifiChip::allocateApIfaceName() {
- return allocateApOrStaIfaceName(
- isStaApConcurrencyAllowedInCurrentMode() ? 1 : 0);
+ return allocateApOrStaIfaceName((isStaApConcurrencyAllowedInCurrentMode() &&
+ !isDualApAllowedInCurrentMode())
+ ? 1
+ : 0);
}
// STA iface names start with idx 0.
diff --git a/wifi/1.3/default/wifi_chip.h b/wifi/1.3/default/wifi_chip.h
index 3d12f4c..153ca6a 100644
--- a/wifi/1.3/default/wifi_chip.h
+++ b/wifi/1.3/default/wifi_chip.h
@@ -155,6 +155,9 @@
private:
void invalidateAndRemoveAllIfaces();
+ // When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are
+ // invalidated & removed.
+ void invalidateAndRemoveDependencies(const std::string& removed_iface_name);
// Corresponding worker functions for the HIDL methods.
std::pair<WifiStatus, ChipId> getIdInternal();
@@ -237,6 +240,7 @@
bool canCurrentModeSupportIfaceOfType(IfaceType requested_type);
bool isValidModeId(ChipModeId mode_id);
bool isStaApConcurrencyAllowedInCurrentMode();
+ bool isDualApAllowedInCurrentMode();
std::string getFirstActiveWlanIfaceName();
std::string allocateApOrStaIfaceName(uint32_t start_idx);
std::string allocateApIfaceName();
diff --git a/wifi/1.3/default/wifi_iface_util.cpp b/wifi/1.3/default/wifi_iface_util.cpp
index 5d61271..34bc02d 100644
--- a/wifi/1.3/default/wifi_iface_util.cpp
+++ b/wifi/1.3/default/wifi_iface_util.cpp
@@ -39,27 +39,39 @@
namespace implementation {
namespace iface_util {
-WifiIfaceUtil::WifiIfaceUtil() : random_mac_address_(nullptr) {}
+WifiIfaceUtil::WifiIfaceUtil(
+ const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
+ : iface_tool_(iface_tool),
+ random_mac_address_(nullptr),
+ event_handlers_map_() {}
std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(
const std::string& iface_name) {
- return iface_tool_.GetFactoryMacAddress(iface_name.c_str());
+ return iface_tool_.lock()->GetFactoryMacAddress(iface_name.c_str());
}
bool WifiIfaceUtil::setMacAddress(const std::string& iface_name,
const std::array<uint8_t, 6>& mac) {
- if (!iface_tool_.SetUpState(iface_name.c_str(), false)) {
+ if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), false)) {
LOG(ERROR) << "SetUpState(false) failed.";
return false;
}
- if (!iface_tool_.SetMacAddress(iface_name.c_str(), mac)) {
+ if (!iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac)) {
LOG(ERROR) << "SetMacAddress failed.";
return false;
}
- if (!iface_tool_.SetUpState(iface_name.c_str(), true)) {
+ if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
LOG(ERROR) << "SetUpState(true) failed.";
return false;
}
+ IfaceEventHandlers event_handlers = {};
+ const auto it = event_handlers_map_.find(iface_name);
+ if (it != event_handlers_map_.end()) {
+ event_handlers = it->second;
+ }
+ if (event_handlers.on_state_toggle_off_on != nullptr) {
+ event_handlers.on_state_toggle_off_on(iface_name);
+ }
LOG(DEBUG) << "Successfully SetMacAddress.";
return true;
}
@@ -73,6 +85,16 @@
return *random_mac_address_.get();
}
+void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name,
+ IfaceEventHandlers handlers) {
+ event_handlers_map_[iface_name] = handlers;
+}
+
+void WifiIfaceUtil::unregisterIfaceEventHandlers(
+ const std::string& iface_name) {
+ event_handlers_map_.erase(iface_name);
+}
+
std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() {
std::array<uint8_t, 6> address = {};
std::random_device rd;
diff --git a/wifi/1.3/default/wifi_iface_util.h b/wifi/1.3/default/wifi_iface_util.h
index b238234..98073e0 100644
--- a/wifi/1.3/default/wifi_iface_util.h
+++ b/wifi/1.3/default/wifi_iface_util.h
@@ -28,12 +28,19 @@
namespace implementation {
namespace iface_util {
+// Iface event handlers.
+struct IfaceEventHandlers {
+ // Callback to be invoked when the iface is set down & up for MAC address
+ // change.
+ std::function<void(const std::string& iface_name)> on_state_toggle_off_on;
+};
+
/**
* Util class for common iface operations.
*/
class WifiIfaceUtil {
public:
- WifiIfaceUtil();
+ WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
virtual ~WifiIfaceUtil() = default;
virtual std::array<uint8_t, 6> getFactoryMacAddress(
@@ -45,11 +52,17 @@
// daemon. (So, changes on every reboot)
virtual std::array<uint8_t, 6> getOrCreateRandomMacAddress();
+ // Register for any iface event callbacks for the provided interface.
+ virtual void registerIfaceEventHandlers(const std::string& iface_name,
+ IfaceEventHandlers handlers);
+ virtual void unregisterIfaceEventHandlers(const std::string& iface_name);
+
private:
std::array<uint8_t, 6> createRandomMacAddress();
- wifi_system::InterfaceTool iface_tool_;
+ std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_;
+ std::map<std::string, IfaceEventHandlers> event_handlers_map_;
};
} // namespace iface_util
diff --git a/wifi/1.3/default/wifi_legacy_hal.cpp b/wifi/1.3/default/wifi_legacy_hal.cpp
index 7f9b635..485bd16 100644
--- a/wifi/1.3/default/wifi_legacy_hal.cpp
+++ b/wifi/1.3/default/wifi_legacy_hal.cpp
@@ -333,10 +333,12 @@
}
// End of the free-standing "C" style callbacks.
-WifiLegacyHal::WifiLegacyHal()
+WifiLegacyHal::WifiLegacyHal(
+ const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
: global_handle_(nullptr),
awaiting_event_loop_termination_(false),
- is_started_(false) {}
+ is_started_(false),
+ iface_tool_(iface_tool) {}
wifi_error WifiLegacyHal::initialize() {
LOG(DEBUG) << "Initialize legacy HAL";
@@ -371,7 +373,7 @@
property_set(kDriverPropName, "ok");
LOG(DEBUG) << "Starting legacy HAL";
- if (!iface_tool_.SetWifiUpState(true)) {
+ if (!iface_tool_.lock()->SetWifiUpState(true)) {
LOG(ERROR) << "Failed to set WiFi interface up";
return WIFI_ERROR_UNKNOWN;
}
@@ -407,7 +409,7 @@
// Invalidate all the internal pointers now that the HAL is
// stopped.
invalidate();
- iface_tool_.SetWifiUpState(false);
+ iface_tool_.lock()->SetWifiUpState(false);
on_stop_complete_user_callback();
is_started_ = false;
};
diff --git a/wifi/1.3/default/wifi_legacy_hal.h b/wifi/1.3/default/wifi_legacy_hal.h
index a3ed460..9cfa172 100644
--- a/wifi/1.3/default/wifi_legacy_hal.h
+++ b/wifi/1.3/default/wifi_legacy_hal.h
@@ -170,7 +170,7 @@
*/
class WifiLegacyHal {
public:
- WifiLegacyHal();
+ WifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
virtual ~WifiLegacyHal() = default;
// Initialize the legacy HAL function table.
@@ -391,7 +391,7 @@
std::condition_variable_any stop_wait_cv_;
// Flag to indicate if the legacy HAL has been started.
bool is_started_;
- wifi_system::InterfaceTool iface_tool_;
+ std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
};
} // namespace legacy_hal
diff --git a/wifi/1.3/default/wifi_nan_iface.cpp b/wifi/1.3/default/wifi_nan_iface.cpp
index 4325f44..ff9f422 100644
--- a/wifi/1.3/default/wifi_nan_iface.cpp
+++ b/wifi/1.3/default/wifi_nan_iface.cpp
@@ -30,8 +30,12 @@
WifiNanIface::WifiNanIface(
const std::string& ifname,
- const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
- : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+ : ifname_(ifname),
+ legacy_hal_(legacy_hal),
+ iface_util_(iface_util),
+ is_valid_(true) {
// Register all the callbacks here. these should be valid for the lifetime
// of the object. Whenever the mode changes legacy HAL will remove
// all of these callbacks.
@@ -498,6 +502,26 @@
LOG(ERROR) << "Failed to register nan callbacks. Invalidating object";
invalidate();
}
+
+ // Register for iface state toggle events.
+ iface_util::IfaceEventHandlers event_handlers = {};
+ event_handlers.on_state_toggle_off_on =
+ [weak_ptr_this](const std::string& /* iface_name */) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ // Tell framework that NAN has been disabled.
+ WifiNanStatus status = {
+ NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventDisabled(status).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+ iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers);
}
void WifiNanIface::invalidate() {
@@ -505,7 +529,7 @@
legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF);
legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0");
legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1");
-
+ iface_util_.lock()->unregisterIfaceEventHandlers(ifname_);
legacy_hal_.reset();
event_cb_handler_.invalidate();
event_cb_handler_1_2_.invalidate();
diff --git a/wifi/1.3/default/wifi_nan_iface.h b/wifi/1.3/default/wifi_nan_iface.h
index f735d61..737be93 100644
--- a/wifi/1.3/default/wifi_nan_iface.h
+++ b/wifi/1.3/default/wifi_nan_iface.h
@@ -22,6 +22,7 @@
#include <android/hardware/wifi/1.2/IWifiNanIface.h>
#include "hidl_callback_util.h"
+#include "wifi_iface_util.h"
#include "wifi_legacy_hal.h"
namespace android {
@@ -37,7 +38,8 @@
class WifiNanIface : public V1_2::IWifiNanIface {
public:
WifiNanIface(const std::string& ifname,
- const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
// Refer to |WifiChip::invalidate()|.
void invalidate();
bool isValid();
@@ -147,6 +149,7 @@
std::string ifname_;
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
bool is_valid_;
hidl_callback_util::HidlCallbackHandler<V1_0::IWifiNanIfaceEventCallback>
event_cb_handler_;
diff --git a/wifi/1.3/default/wifi_rtt_controller.cpp b/wifi/1.3/default/wifi_rtt_controller.cpp
index fa317e3..3dcbee6 100644
--- a/wifi/1.3/default/wifi_rtt_controller.cpp
+++ b/wifi/1.3/default/wifi_rtt_controller.cpp
@@ -49,6 +49,8 @@
return event_callbacks_;
}
+std::string WifiRttController::getIfaceName() { return ifname_; }
+
Return<void> WifiRttController::getBoundIface(getBoundIface_cb hidl_status_cb) {
return validateAndCall(
this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
diff --git a/wifi/1.3/default/wifi_rtt_controller.h b/wifi/1.3/default/wifi_rtt_controller.h
index 9798b79..eedd22a 100644
--- a/wifi/1.3/default/wifi_rtt_controller.h
+++ b/wifi/1.3/default/wifi_rtt_controller.h
@@ -42,6 +42,7 @@
void invalidate();
bool isValid();
std::vector<sp<IWifiRttControllerEventCallback>> getEventCallbacks();
+ std::string getIfaceName();
// HIDL methods exposed.
Return<void> getBoundIface(getBoundIface_cb hidl_status_cb) override;