diff --git a/services/ans/include/notification_subscriber_manager.h b/services/ans/include/notification_subscriber_manager.h index 61156a03d5279130e7d4ad1e8f802d213fda1011..d43ecdd64b56decb641bb63eab3b8e2b74b01fcc 100644 --- a/services/ans/include/notification_subscriber_manager.h +++ b/services/ans/include/notification_subscriber_manager.h @@ -151,6 +151,8 @@ public: #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED bool GetIsEnableEffectedRemind(); bool IsDeviceTypeSubscriberd(const std::string deviceType); + ErrCode IsDeviceTypeAffordConsume(const std::string deviceType, + const sptr &request, bool &result); #endif void NotifyApplicationInfoNeedChanged(const std::string& bundleName); diff --git a/services/ans/include/smart_reminder_center.h b/services/ans/include/smart_reminder_center.h index 4aa1d550c424f7eafcc0f98ae9d3eed23e99c40f..47f1bd2f9af32da8b5f6ede2dd4989f7be07c3b6 100644 --- a/services/ans/include/smart_reminder_center.h +++ b/services/ans/include/smart_reminder_center.h @@ -66,12 +66,16 @@ private: const string &deviceType, const map>> &reminderFilterDevice, const sptr &request, - set &validDevices, + set &syncDevices, + set &smartDevices, + shared_ptr defaultFlag, + map> &statusMap, shared_ptr>> notificationFlagsOfDevices) const; bool HandleAffectedReminder( const string &deviceType, const shared_ptr &reminderAffected, - const set &validDevices, + const set &smartDevices, + map> &statusMap, shared_ptr>> notificationFlagsOfDevices) const; void GetReminderAffecteds( const map>> &reminderFilterDevice, @@ -80,7 +84,11 @@ private: void GetDeviceStatusByType(const string &deviceType, bitset &bitStatus) const; bool IsNeedSynergy(const NotificationConstant::SlotType &slotType, const string &deviceType, const string &ownerBundleName, int32_t ownerUid) const; - void InitValidDevices(set &validDevices, const sptr &request) const; + bool GetAppSwitch(const string &deviceType, const string &ownerBundleName, int32_t ownerUid) const; + bool GetSmartSwitch(const string &deviceType) const; + void InitValidDevices(set &syncDevices, set &smartDevices, + map> &statusMap, + const sptr &request) const; bool IsCollaborationAllowed(const sptr &request) const; map> currentReminderMethods_; map>>> reminderMethods_; diff --git a/services/ans/src/notification_smart_reminder/smart_reminder_center.cpp b/services/ans/src/notification_smart_reminder/smart_reminder_center.cpp index e0f23ab95833a5529f1154621056d2ebb94a66b3..047cee1a2d0fc1c5424318c1097967f357a946f9 100644 --- a/services/ans/src/notification_smart_reminder/smart_reminder_center.cpp +++ b/services/ans/src/notification_smart_reminder/smart_reminder_center.cpp @@ -253,60 +253,114 @@ void SmartReminderCenter::ReminderDecisionProcess(const sptr>> notificationFlagsOfDevices = make_shared>>(); + shared_ptr defaultFlag = make_shared(); NotificationConstant::SlotType slotType = request->GetSlotType(); auto iter = currentReminderMethods_.find(slotType); if (iter != currentReminderMethods_.end()) { // Only config file can set reminder open now. Otherwise, change iter->second to 11111 (*notificationFlagsOfDevices)[NotificationConstant::CURRENT_DEVICE_TYPE] = iter->second; + defaultFlag = iter->second; } if (!IsCollaborationAllowed(request)) { request->SetDeviceFlags(notificationFlagsOfDevices); return; } - set validDevices; - InitValidDevices(validDevices, request); + set syncDevices; + set smartDevices; + map> statusMap; + InitValidDevices(syncDevices, smartDevices, statusMap, request); + if (syncDevices.size() <= 1) { + return; + } + for (auto &reminderMethod : reminderMethods_) { - if (validDevices.size() <= 1 && reminderMethod.first.compare(NotificationConstant::CURRENT_DEVICE_TYPE) == 0) { - continue; - } HandleReminderMethods( - reminderMethod.first, reminderMethod.second, request, validDevices, notificationFlagsOfDevices); + reminderMethod.first, reminderMethod.second, request, + syncDevices, smartDevices, defaultFlag, statusMap, + notificationFlagsOfDevices); } request->SetDeviceFlags(notificationFlagsOfDevices); } void SmartReminderCenter::InitValidDevices( - set &validDevices, + set &syncDevices, set &smartDevices, + map> &statusMap, const sptr &request) const { auto notificationControlFlags = request->GetNotificationControlFlags(); - validDevices.insert(NotificationConstant::CURRENT_DEVICE_TYPE); + syncDevices.insert(NotificationConstant::CURRENT_DEVICE_TYPE); + smartDevices.insert(NotificationConstant::CURRENT_DEVICE_TYPE); + bitset status; + GetDeviceStatusByType(NotificationConstant::CURRENT_DEVICE_TYPE, status); + statusMap.insert( + pair>(NotificationConstant::CURRENT_DEVICE_TYPE, status)); + for (std::string deviceType : NotificationConstant::DEVICESTYPES) { - if (!NotificationSubscriberManager::GetInstance()->IsDeviceTypeSubscriberd(deviceType)) { + GetDeviceStatusByType(deviceType, status); + statusMap.insert(pair>(deviceType, status)); + request->AdddeviceStatu(deviceType, status.bitset::to_string()); + + bool affordConsume = false; + NotificationSubscriberManager::GetInstance()->IsDeviceTypeAffordConsume(deviceType, request, affordConsume); + if (!affordConsume) { + ANS_LOGI("not afford consume, deviceType = %{public}s", deviceType.c_str()); continue; } if (NotificationConstant::SlotType::LIVE_VIEW == request->GetSlotType()) { bool isEnable = false; + std::string queryDeviceType = deviceType; + if (deviceType.compare(NotificationConstant::WEARABLE_DEVICE_TYPE) == 0) { + queryDeviceType = NotificationConstant::LITEWEARABLE_DEVICE_TYPE; + } NotificationPreferences::GetInstance()->IsDistributedEnabledBySlot( - request->GetSlotType(), deviceType, isEnable); + request->GetSlotType(), queryDeviceType, isEnable); if (!isEnable) { - ANS_LOGI("switch-status, slot switch closed. device = %{public}s", deviceType.c_str()); + ANS_LOGI("liveView smart switch is closed, deviceType = %{public}s", deviceType.c_str()); continue; - } else { - validDevices.insert(deviceType); - request->SetNotificationControlFlags(notificationControlFlags | CONTROL_BY_SMART_REMINDER); - ANS_LOGI("InitValidDevices- %{public}s", deviceType.c_str()); } + syncDevices.insert(deviceType); + smartDevices.insert(deviceType); + request->SetNotificationControlFlags(notificationControlFlags | CONTROL_BY_SMART_REMINDER); } else { - if (IsNeedSynergy(request->GetSlotType(), deviceType, - request->GetOwnerBundleName(), request->GetOwnerUid())) { - validDevices.insert(deviceType); + bool appSwitch = GetAppSwitch(deviceType, request->GetOwnerBundleName(), request->GetOwnerUid()); + // app-close + if (!appSwitch) { + ANS_LOGI("app switch is closed, deveiceType = %{public}s", deviceType.c_str()); + continue; + } + + bool smartSwitch = GetSmartSwitch(deviceType); + ANS_LOGI("smart switch deviceType = %{public}s status = %{public}d", deviceType.c_str(), smartSwitch); + // app-open ,smart-open + if (smartSwitch) { + syncDevices.insert(deviceType); + smartDevices.insert(deviceType); request->SetNotificationControlFlags(notificationControlFlags | CONTROL_BY_SMART_REMINDER); - ANS_LOGI("InitValidDevices- %{public}s", deviceType.c_str()); + continue; + } + // app-open, smart-close not watch + if (deviceType.compare(NotificationConstant::WEARABLE_DEVICE_TYPE) != 0 && + deviceType.compare(NotificationConstant::LITEWEARABLE_DEVICE_TYPE) != 0) { + syncDevices.insert(deviceType); + continue; + } + // app-open, smart-close watch + if (!CompareStatus(STATUS_UNUSED, status)) { + syncDevices.insert(deviceType); } } } + string syncDevicesStr; + string smartDevicesStr; + for (auto it = syncDevices.begin(); it != syncDevices.end(); ++it) { + syncDevicesStr = syncDevicesStr + *it + StringUtils::SPLIT_CHAR; + } + for (auto it = smartDevices.begin(); it != smartDevices.end(); ++it) { + smartDevicesStr = smartDevicesStr + *it + StringUtils::SPLIT_CHAR; + } + ANS_LOGI("sync device list: %{public}s", syncDevicesStr.c_str()); + ANS_LOGI("smart device list: %{public}s", smartDevicesStr.c_str()); return; } @@ -314,7 +368,10 @@ void SmartReminderCenter::HandleReminderMethods( const string &deviceType, const map>> &reminderFilterDevice, const sptr &request, - set &validDevices, + set &syncDevices, + set &smartDevices, + shared_ptr defaultFlag, + map> &statusMap, shared_ptr>> notificationFlagsOfDevices) const { std::string classfication = request->GetClassification(); @@ -323,27 +380,39 @@ void SmartReminderCenter::HandleReminderMethods( ANS_LOGI("VOIP or CALL is not affected with SmartReminder"); return; } - vector> reminderAffecteds; - GetReminderAffecteds(reminderFilterDevice, request, reminderAffecteds); - if (reminderAffecteds.size() <= 0) { + + if (syncDevices.find(deviceType) == syncDevices.end()) { return; } - bitset bitStatus; - GetDeviceStatusByType(deviceType, bitStatus); - request->AdddeviceStatu(deviceType, bitStatus.bitset::to_string()); - if (NotificationConstant::SlotType::LIVE_VIEW == request->GetSlotType() && - validDevices.find(deviceType) == validDevices.end() - ) { - ANS_LOGI("live view slot switch is close, not notify"); + if (smartDevices.find(deviceType) == smartDevices.end()) { + (*notificationFlagsOfDevices)[deviceType] = defaultFlag; + ANS_LOGI("default remindFlags, deviceType = %{public}s , remindFlags = %{public}d", + deviceType.c_str(), defaultFlag->GetReminderFlags()); return; } - bool enabledAffectedBy = true; + if (deviceType.compare(NotificationConstant::CURRENT_DEVICE_TYPE) == 0 && + smartDevices.size() <= 1) { + (*notificationFlagsOfDevices)[deviceType] = defaultFlag; + ANS_LOGI("default remindFlags, deviceType = %{public}s , remindFlags = %{public}d", + deviceType.c_str(), defaultFlag->GetReminderFlags()); + return; + } + + vector> reminderAffecteds; + GetReminderAffecteds(reminderFilterDevice, request, reminderAffecteds); + if (reminderAffecteds.size() <= 0) { + ANS_LOGI("not set any rule for deviceType %{public}s", deviceType.c_str()); + return; + } - if (validDevices.find(deviceType) == validDevices.end()) { - enabledAffectedBy = false; + auto iter = statusMap.find(deviceType); + if (iter == statusMap.end()) { + ANS_LOGE("get device status failed. deviceType = %{public}s", deviceType.c_str()); + return; } + bitset bitStatus = iter->second; for (auto &reminderAffected : reminderAffecteds) { if (!CompareStatus(reminderAffected->status_, bitStatus)) { @@ -351,15 +420,20 @@ void SmartReminderCenter::HandleReminderMethods( } if (reminderAffected->affectedBy_.size() <= 0) { (*notificationFlagsOfDevices)[deviceType] = reminderAffected->reminderFlags_; - ANS_LOGI("unaffect match deviceType = %{public}s , remindFlags = %{public}d", + ANS_LOGI("smart rule matched, deviceType = %{public}s , remindFlags = %{public}d", deviceType.c_str(), reminderAffected->reminderFlags_->GetReminderFlags()); - continue; - } - if (enabledAffectedBy && - HandleAffectedReminder(deviceType, reminderAffected, validDevices, notificationFlagsOfDevices)) { - break; + return; + } else { + bool matched = + HandleAffectedReminder(deviceType, reminderAffected, smartDevices, statusMap, notificationFlagsOfDevices); + if (matched) { + ANS_LOGI("smart rule matched, deviceType = %{public}s , remindFlags = %{public}d", + deviceType.c_str(), reminderAffected->reminderFlags_->GetReminderFlags()); + return; + } } } + ANS_LOGI("not match any rule. deviceType = %{public}s", deviceType.c_str()); } bool SmartReminderCenter::IsNeedSynergy(const NotificationConstant::SlotType &slotType, @@ -386,20 +460,61 @@ bool SmartReminderCenter::IsNeedSynergy(const NotificationConstant::SlotType &sl return true; } +bool SmartReminderCenter::GetAppSwitch(const string &deviceType, + const string &ownerBundleName, int32_t ownerUid) const +{ + std::string device = deviceType; + if (deviceType.compare(NotificationConstant::WEARABLE_DEVICE_TYPE) == 0) { + device = NotificationConstant::LITEWEARABLE_DEVICE_TYPE; + } + + bool isEnable = true; + + sptr bundleOption = + new (std::nothrow) NotificationBundleOption(ownerBundleName, ownerUid); + if (NotificationPreferences::GetInstance()->IsDistributedEnabledByBundle( + bundleOption, device, isEnable) != ERR_OK || !isEnable) { + return false; + } + return true; +} + +bool SmartReminderCenter::GetSmartSwitch(const string &deviceType) const +{ + std::string device = deviceType; + if (deviceType.compare(NotificationConstant::WEARABLE_DEVICE_TYPE) == 0) { + device = NotificationConstant::LITEWEARABLE_DEVICE_TYPE; + } + + bool isEnable = true; + if (NotificationPreferences::GetInstance()->IsSmartReminderEnabled(device, isEnable) != ERR_OK || !isEnable) { + return false; + } + return true; +} + bool SmartReminderCenter::HandleAffectedReminder( const string &deviceType, const shared_ptr &reminderAffected, - const set &validDevices, + const set &smartDevices, + map> &statusMap, shared_ptr>> notificationFlagsOfDevices) const { bool ret = true; for (auto &affectedBy : reminderAffected->affectedBy_) { - if (validDevices.find(affectedBy.first) == validDevices.end()) { + if (smartDevices.find(affectedBy.first) == smartDevices.end()) { ret = false; break; } - bitset bitStatus; - GetDeviceStatusByType(affectedBy.first, bitStatus); + + auto iter = statusMap.find(affectedBy.first); + if (iter == statusMap.end()) { + ANS_LOGE("get device status failed. deviceType = %{public}s", deviceType.c_str()); + ret = false; + break; + } + bitset bitStatus = iter->second; + if (!CompareStatus(affectedBy.second, bitStatus)) { ret = false; break; @@ -407,8 +522,6 @@ bool SmartReminderCenter::HandleAffectedReminder( } if (ret) { (*notificationFlagsOfDevices)[deviceType] = reminderAffected->reminderFlags_; - ANS_LOGI("affect match deviceType = %{public}s , remindFlags = %{public}d", - deviceType.c_str(), reminderAffected->reminderFlags_->GetReminderFlags()); } return ret; } diff --git a/services/ans/src/notification_subscriber_manager.cpp b/services/ans/src/notification_subscriber_manager.cpp index fdf171dc90aa04e8235a394302ef9693db904d91..a33041a38f8a640266441c368ac7d4564c9320ed 100644 --- a/services/ans/src/notification_subscriber_manager.cpp +++ b/services/ans/src/notification_subscriber_manager.cpp @@ -554,6 +554,29 @@ bool NotificationSubscriberManager::IsDeviceTypeSubscriberd(const std::string de ANS_LOGE("device not subscribe, device = %{public}s", deviceType.c_str()); return false; } + +ErrCode NotificationSubscriberManager::IsDeviceTypeAffordConsume( + const std::string deviceType, + const sptr &request, + bool &result) +{ + for (auto record : subscriberRecordList_) { + if (record->deviceType.compare(deviceType) != 0) { + continue; + } + sptr notification = new (std::nothrow) Notification(request); + if (notification == nullptr) { + ANS_LOGE("Failed to create notification"); + return ERR_ANS_NO_MEMORY; + } + if (IsSubscribedBysubscriber(record, notification) && ConsumeRecordFilter(record, notification)) { + result = true; + return ERR_OK; + } + } + result = false; + return ERR_OK; +} #endif void NotificationSubscriberManager::BatchNotifyConsumedInner(const std::vector> ¬ifications, diff --git a/services/ans/test/unittest/smart_reminder_center_test.cpp b/services/ans/test/unittest/smart_reminder_center_test.cpp index 8de0acbc7e19cab33d1b73cb97541a54199f7485..565a8dcfe629e2fed2c0e3dff3f0a02540f49e8c 100644 --- a/services/ans/test/unittest/smart_reminder_center_test.cpp +++ b/services/ans/test/unittest/smart_reminder_center_test.cpp @@ -98,16 +98,22 @@ HWTEST_F(SmartReminderCenterTest, HandleAffectedReminder_00001, Function | Small shared_ptr>> notificationFlagsOfDevices = make_shared>>(); + + map> statusMap; + statusMap.insert(pair>("test", bitset(0))); auto res = smartReminderCenter_->HandleAffectedReminder( - deviceType, reminderAffected, validDevices, notificationFlagsOfDevices); + deviceType, reminderAffected, validDevices, + statusMap, notificationFlagsOfDevices); ASSERT_TRUE(res); auto affectedByTwo = std::make_pair("test111", "1111"); affectedBy.push_back(affectedByTwo); reminderAffected->affectedBy_ = affectedBy; res = smartReminderCenter_->HandleAffectedReminder( - deviceType, reminderAffected, validDevices, notificationFlagsOfDevices); + deviceType, reminderAffected, validDevices, + statusMap, notificationFlagsOfDevices); ASSERT_FALSE(res); } @@ -167,9 +173,11 @@ HWTEST_F(SmartReminderCenterTest, InitValidDevices_00001, Function | SmallTest | request->SetSlotType(NotificationConstant::SlotType::LIVE_VIEW); set validDevices; + set smartDevices; + map> statusMap; NotificationPreferences::GetInstance()->SetDistributedEnabledBySlot( request->GetSlotType(), "headset", true); - smartReminderCenter_->InitValidDevices(validDevices, request); + smartReminderCenter_->InitValidDevices(validDevices, smartDevices, statusMap, request); ASSERT_EQ(request->GetNotificationControlFlags(), 0); } @@ -199,7 +207,9 @@ HWTEST_F(SmartReminderCenterTest, InitValidDevices_00002, Function | SmallTest | ASSERT_EQ(res, 0); set validDevices; - smartReminderCenter_->InitValidDevices(validDevices, request); + set smartDevices; + map> statusMap; + smartReminderCenter_->InitValidDevices(validDevices, smartDevices, statusMap, request); ASSERT_EQ(request->GetNotificationControlFlags(), 0); } } //namespace Notification