diff --git a/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_sub_manage/wifi_p2p_manager.cpp b/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_sub_manage/wifi_p2p_manager.cpp index 369472849dd8e5d85dd78ce11707d44f7188b6d0..1745408a1d50a521b01db4925eb0bad156314ea2 100644 --- a/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_sub_manage/wifi_p2p_manager.cpp +++ b/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_sub_manage/wifi_p2p_manager.cpp @@ -23,6 +23,7 @@ #include "wifi_system_timer.h" #include "wifi_hisysevent.h" #include "p2p_define.h" +#include "wifi_global_func.h" #ifdef OHOS_ARCH_LITE #include "wifi_internal_event_dispatcher_lite.h" #else @@ -38,6 +39,7 @@ DEFINE_WIFILOG_LABEL("WifiP2pManager"); namespace OHOS { namespace Wifi { constexpr int32_t P2P_ENABLE_WAIT_MS = 500; +constexpr int64_t TIMEOUT_REMOVE_GROUP = 15 * 60 * 1000; WifiP2pManager::WifiP2pManager() { WIFI_LOGI("create WifiP2pManager"); @@ -214,6 +216,48 @@ void WifiP2pManager::StartUnloadP2PSaTimer(void) } #endif +static void RemoveGroupTimerCallback(void) +{ + IP2pService *pService = WifiServiceManager::GetInstance().GetP2pServiceInst(); + if (pService != nullptr) { + WIFI_LOGI("p2p group has 0 client in 15min, remove it for powersave"); + pService->RemoveGroup(); + } + WifiManager::GetInstance().GetWifiP2pManager()->StopRemoveGroupTimer(); +} + +void WifiP2pManager::StopRemoveGroupTimer(void) +{ + WIFI_LOGD("StopRemoveGroupTimer! removeGroupTimerId:%{public}u", removeGroupTimerId); + std::unique_lock lock(removeGroupTimerMutex); + if (removeGroupTimerId == 0) { + return; + } + MiscServices::TimeServiceClient::GetInstance()->StopTimer(removeGroupTimerId); + MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(removeGroupTimerId); + removeGroupTimerId = 0; + return; +} + +void WifiP2pManager::StartRemoveGroupTimer(void) +{ + if (GetDeviceType() != ProductDeviceType::PHONE) { + return; + } + WIFI_LOGD("StartRemoveGroupTimer! removeGroupTimerId:%{public}u", removeGroupTimerId); + std::unique_lock lock(removeGroupTimerMutex); + if (removeGroupTimerId == 0) { + std::shared_ptr removeTimer = std::make_shared(false, 0, true, false); + removeTimer->SetCallbackInfo(RemoveGroupTimerCallback); + removeGroupTimerId = MiscServices::TimeServiceClient::GetInstance()->CreateTimer(removeTimer); + int64_t currentTime = MiscServices::TimeServiceClient::GetInstance()->GetBootTimeMs(); + MiscServices::TimeServiceClient::GetInstance()->StartTimer(removeGroupTimerId, + currentTime + TIMEOUT_REMOVE_GROUP); + WIFI_LOGI("StartRemoveGroupTimer success! removeGroupTimerId:%{public}u", removeGroupTimerId); + } + return; +} + void WifiP2pManager::CloseP2pService(void) { WIFI_LOGD("close p2p service"); @@ -371,6 +415,7 @@ void WifiP2pManager::DealP2pConnectionChanged(const WifiP2pLinkedInfo &info) ErrCode errCode = pService->GetCurrentGroup(group); if (errCode != WIFI_OPT_SUCCESS) { WIFI_LOGE("Get current group info failed!"); + StopRemoveGroupTimer(); return; } WriteWifiP2pStateHiSysEvent(group.GetInterface(), (int32_t)info.IsGroupOwner(), (int32_t)info.GetConnectState()); @@ -387,6 +432,19 @@ void WifiP2pManager::DealP2pConnectionChanged(const WifiP2pLinkedInfo &info) if (rptManager != nullptr) { rptManager->OnP2pConnectionChanged(info.GetConnectState()); } + if (!group.IsGroupOwner()) { + return; + } + std::vector devices = group.GetClientDevices(); + if (info.GetConnectState() == P2pConnectedState::P2P_CONNECTED) { + if (devices.empty()) { + StartRemoveGroupTimer(); + } else { + StopRemoveGroupTimer(); + } + } else { + StopRemoveGroupTimer(); + } return; } diff --git a/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_sub_manage/wifi_p2p_manager.h b/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_sub_manage/wifi_p2p_manager.h index 531c52d380d445e81b656fcbee6c5be16e24d669..5cdf68cfab2652812e23753fe28036dc633c3e48 100644 --- a/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_sub_manage/wifi_p2p_manager.h +++ b/wifi/services/wifi_standard/wifi_framework/wifi_manage/wifi_sub_manage/wifi_p2p_manager.h @@ -36,6 +36,7 @@ public: ErrCode AutoStopP2pService(); void StopUnloadP2PSaTimer(void); void StartUnloadP2PSaTimer(void); + void StopRemoveGroupTimer(void); bool HasP2pActivatedBefore(void); private: @@ -56,10 +57,14 @@ private: void DealP2pPrivatePeersChanged(const std::string &privateInfo); // do not call this function directly, use AutoStartP2pService instead void CloseP2pService(void); + void StartRemoveGroupTimer(void); + private: IP2pServiceCallbacks mP2pCallback; uint32_t unloadP2PSaTimerId{0}; + uint32_t removeGroupTimerId{0}; std::mutex unloadP2PSaTimerMutex; + std::mutex removeGroupTimerMutex; std::string ifaceName{""}; // mutex to avoid EnableP2p and DisableP2p at the same time std::mutex p2pEnableMutex; diff --git a/wifi/test/wifi_standard/wifi_framework/wifi_manage/unittest/wifi_manager_test.cpp b/wifi/test/wifi_standard/wifi_framework/wifi_manage/unittest/wifi_manager_test.cpp index 11fe6d1f6a7d60a147c68a26492bd0cf7a515eba..c38efe704a1d236d0b7f31e18af146e67a69c790 100644 --- a/wifi/test/wifi_standard/wifi_framework/wifi_manage/unittest/wifi_manager_test.cpp +++ b/wifi/test/wifi_standard/wifi_framework/wifi_manage/unittest/wifi_manager_test.cpp @@ -283,6 +283,8 @@ HWTEST_F(WifiManagerTest, StartUnloadP2PSaTimerTest, TestSize.Level1) HWTEST_F(WifiManagerTest, CloseP2pServiceTest, TestSize.Level1) { WIFI_LOGI("CloseP2pServiceTest enter!"); + wifiManager.wifiP2pManager->StartRemoveGroupTimer(); + wifiManager.wifiP2pManager->StopRemoveGroupTimer(); wifiManager.wifiP2pManager->CloseP2pService(); EXPECT_FALSE(g_errLog.find("service is null") != std::string::npos); }