/* * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * 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 "common_event_control_manager.h" #include #include "access_token_helper.h" #include "bundle_manager_helper.h" #include "common_event_constant.h" #include "event_log_wrapper.h" #include "event_report.h" #include "hitrace_meter_adapter.h" #include "ievent_receive.h" #include "system_time.h" #include "xcollie/watchdog.h" namespace OHOS { namespace EventFwk { constexpr int32_t LENGTH = 80; constexpr int32_t DOUBLE = 2; const std::string CONNECTOR = " or "; static const int32_t TIME_UNIT_SIZE = 1000; CommonEventControlManager::CommonEventControlManager() : handler_(nullptr), handlerOrdered_(nullptr), pendingTimeoutMessage_(false), scheduled_(false) { EVENT_LOGD("enter"); } CommonEventControlManager::~CommonEventControlManager() { EVENT_LOGD("enter"); } bool CommonEventControlManager::PublishCommonEvent( const CommonEventRecord &eventRecord, const sptr &commonEventListener) { HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); EVENT_LOGD("enter"); bool ret = false; if (!eventRecord.publishInfo->IsOrdered()) { ret = ProcessUnorderedEvent(eventRecord); } else { ret = ProcessOrderedEvent(eventRecord, commonEventListener); } return ret; } bool CommonEventControlManager::PublishStickyCommonEvent( const CommonEventRecord &eventRecord, const std::shared_ptr &subscriberRecord) { HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); EVENT_LOGD("enter"); if (!subscriberRecord) { EVENT_LOGE("subscriberRecord is null"); return false; } return ProcessUnorderedEvent(eventRecord, subscriberRecord); } bool CommonEventControlManager::PublishFreezeCommonEvent(const uid_t &uid) { HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); EVENT_LOGD("enter"); if (!GetUnorderedEventHandler()) { EVENT_LOGE("failed to get eventhandler"); return false; } PublishFrozenEventsInner(DelayedSingleton::GetInstance()->GetFrozenEvents(uid)); return true; } bool CommonEventControlManager::PublishFreezeCommonEvent(std::set pidList) { HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); EVENT_LOGD("enter"); if (!GetUnorderedEventHandler()) { EVENT_LOGE("failed to get eventhandler"); return false; } for (auto it = pidList.begin(); it != pidList.end(); it++) { PublishFrozenEventsInner( DelayedSingleton::GetInstance()->GetFrozenEventsMapByPid(*it)); } return true; } bool CommonEventControlManager::PublishAllFreezeCommonEvents() { HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); EVENT_LOGD("enter"); if (!GetUnorderedEventHandler()) { EVENT_LOGE("failed to get eventhandler"); return false; } std::map frozenEventRecords = DelayedSingleton::GetInstance()->GetAllFrozenEvents(); for (auto record : frozenEventRecords) { PublishFrozenEventsInner(record.second); } std::map frozenEventRecordsMap = DelayedSingleton::GetInstance()->GetAllFrozenEventsMap(); for (auto record : frozenEventRecordsMap) { PublishFrozenEventsInner(record.second); } return true; } void CommonEventControlManager::PublishFrozenEventsInner(const FrozenRecords &frozenRecords) { for (auto record : frozenRecords) { for (auto vec : record.second) { if (!vec) { EVENT_LOGW("failed to find record"); continue; } EventSubscriberRecord subscriberRecord = record.first; CommonEventRecord eventRecord = *vec; std::weak_ptr weak = shared_from_this(); auto innerCallback = [weak, subscriberRecord, eventRecord]() { auto control = weak.lock(); if (control == nullptr) { EVENT_LOGE("CommonEventControlManager is null"); return; } control->NotifyFreezeEvents(subscriberRecord, eventRecord); }; unorderedImmediateQueue_->submit(innerCallback); } } } bool CommonEventControlManager::NotifyFreezeEvents( const EventSubscriberRecord &subscriberRecord, const CommonEventRecord &eventRecord) { EVENT_LOGD("enter"); sptr commonEventListenerProxy = iface_cast(subscriberRecord.commonEventListener); if (!commonEventListenerProxy) { EVENT_LOGE("Fail to get IEventReceive proxy"); return false; } int8_t ret = CheckPermission(subscriberRecord, eventRecord); if (ret != OrderedEventRecord::DELIVERED) { EVENT_LOGE("check permission is failed"); return false; } if (eventRecord.commonEventData == nullptr) { EVENT_LOGE("commonEventData == nullptr"); return false; } EVENT_LOGI("Send common event %{public}s to subscriber %{public}s (pid = %{public}d, uid = %{public}d) " "when unfreezed", eventRecord.commonEventData->GetWant().GetAction().c_str(), subscriberRecord.eventRecordInfo.bundleName.c_str(), subscriberRecord.eventRecordInfo.pid, subscriberRecord.eventRecordInfo.uid); commonEventListenerProxy->NotifyEvent(*(eventRecord.commonEventData), false, eventRecord.publishInfo->IsSticky()); AccessTokenHelper::RecordSensitivePermissionUsage(subscriberRecord.eventRecordInfo.callerToken, eventRecord.commonEventData->GetWant().GetAction()); return true; } bool CommonEventControlManager::GetUnorderedEventHandler() { if (!unorderedQueue_) { unorderedQueue_ = std::make_shared("unordered_common_event"); } if (!unorderedImmediateQueue_) { unorderedImmediateQueue_ = std::make_shared("unordered_immediate_common_event", ffrt::queue_attr().qos(ffrt::qos_utility)); } return true; } void CommonEventControlManager::NotifyUnorderedEventLocked(std::shared_ptr &eventRecord) { int32_t succCnt = 0; int32_t failCnt = 0; int32_t freezeCnt = 0; for (auto vec : eventRecord->receivers) { if (vec == nullptr) { EVENT_LOGE("invalid vec"); failCnt++; continue; } size_t index = eventRecord->nextReceiver++; if (vec->isFreeze) { eventRecord->deliveryState[index] = OrderedEventRecord::SKIPPED; DelayedSingleton::GetInstance()->InsertFrozenEvents(vec, *eventRecord); DelayedSingleton::GetInstance()->InsertFrozenEventsMap( vec, *eventRecord); EVENT_LOGE("NotifyUnorderedEvent = %{public}s freeze, suscriberID = %{public}s", eventRecord->commonEventData->GetWant().GetAction().c_str(), vec->eventRecordInfo.subId.c_str()); freezeCnt++; } else { sptr commonEventListenerProxy = iface_cast(vec->commonEventListener); if (!commonEventListenerProxy) { eventRecord->deliveryState[index] = OrderedEventRecord::SKIPPED; EVENT_LOGE("Failed to get IEventReceive proxy, suscriberID = %{public}s", vec->eventRecordInfo.subId.c_str()); failCnt++; continue; } int8_t ret = CheckPermission(*vec, *eventRecord); eventRecord->deliveryState[index] = ret; if (ret == OrderedEventRecord::DELIVERED) { eventRecord->state = OrderedEventRecord::RECEIVING; commonEventListenerProxy->NotifyEvent( *(eventRecord->commonEventData), false, eventRecord->publishInfo->IsSticky()); eventRecord->state = OrderedEventRecord::RECEIVED; succCnt++; AccessTokenHelper::RecordSensitivePermissionUsage(vec->eventRecordInfo.callerToken, eventRecord->commonEventData->GetWant().GetAction()); } else { failCnt++; EVENT_LOGE("NotifyUnorderedEvent = %{public}s fail, suscriberID = %{public}s", eventRecord->commonEventData->GetWant().GetAction().c_str(), vec->eventRecordInfo.subId.c_str()); } } } EVENT_LOGI("NotifyUnorderedEvent = %{public}s end, subscriberCnt = %{public}zu, succCnt = %{public}d," "failCnt = %{public}d, freezeCnt = %{public}d", eventRecord->commonEventData->GetWant().GetAction().c_str(), eventRecord->receivers.size(), succCnt, failCnt, freezeCnt); } bool CommonEventControlManager::NotifyUnorderedEvent(std::shared_ptr &eventRecord) { HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); if (!eventRecord) { EVENT_LOGD("Invalid event record."); return false; } std::lock_guard lock(unorderedMutex_); NotifyUnorderedEventLocked(eventRecord); EnqueueHistoryEventRecord(eventRecord, false); auto it = std::find(unorderedEventQueue_.begin(), unorderedEventQueue_.end(), eventRecord); if (it != unorderedEventQueue_.end()) { unorderedEventQueue_.erase(it); } return true; } bool CommonEventControlManager::ProcessUnorderedEvent( const CommonEventRecord &eventRecord, const std::shared_ptr &subscriberRecord) { HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); EVENT_LOGD("enter"); bool ret = false; if (!GetUnorderedEventHandler()) { EVENT_LOGE("failed to get eventhandler"); return ret; } std::shared_ptr eventRecordPtr = std::make_shared(); if (eventRecordPtr == nullptr) { EVENT_LOGE("eventRecordPtr is null"); return ret; } std::shared_ptr spinstance = DelayedSingleton::GetInstance(); eventRecordPtr->FillCommonEventRecord(eventRecord); if (subscriberRecord) { eventRecordPtr->receivers.emplace_back(subscriberRecord); } else { eventRecordPtr->receivers = spinstance->GetSubscriberRecords(eventRecord); } for (auto vec : eventRecordPtr->receivers) { eventRecordPtr->deliveryState.emplace_back(OrderedEventRecord::PENDING); } EnqueueUnorderedRecord(eventRecordPtr); std::weak_ptr weak = shared_from_this(); auto innerCallback = [weak, eventRecordPtr]() { auto manager = weak.lock(); if (manager == nullptr) { EVENT_LOGE("CommonEventControlManager is null"); return; } std::shared_ptr ordered = eventRecordPtr; manager->NotifyUnorderedEvent(ordered); }; if (eventRecord.isSystemEvent) { unorderedImmediateQueue_->submit(innerCallback); } else { unorderedQueue_->submit(innerCallback); } return ret; } std::shared_ptr CommonEventControlManager::GetMatchingOrderedReceiver( const sptr &proxy) { EVENT_LOGD("enter"); std::lock_guard lock(orderedMutex_); if (!orderedEventQueue_.empty()) { std::shared_ptr firstRecord = orderedEventQueue_.front(); if ((firstRecord != nullptr) && (firstRecord->curReceiver == proxy)) { return firstRecord; } } return nullptr; } bool CommonEventControlManager::GetOrderedEventHandler() { if (!orderedQueue_) { orderedQueue_ = std::make_shared("ordered_common_event"); } return true; } bool CommonEventControlManager::ProcessOrderedEvent( const CommonEventRecord &eventRecord, const sptr &commonEventListener) { HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); EVENT_LOGD("enter"); bool ret = false; if (!GetOrderedEventHandler()) { EVENT_LOGE("failed to get eventhandler"); return ret; } std::shared_ptr eventRecordPtr = std::make_shared(); if (eventRecordPtr == nullptr) { EVENT_LOGE("eventRecordPtr is null"); return ret; } std::shared_ptr spinstance = DelayedSingleton::GetInstance(); auto subscribers = spinstance->GetSubscriberRecords(eventRecord); auto OrderedSubscriberCompareFunc = [] ( std::shared_ptr fist, std::shared_ptr second) { return fist->eventSubscribeInfo->GetPriority() > second->eventSubscribeInfo->GetPriority(); }; std::sort(subscribers.begin(), subscribers.end(), OrderedSubscriberCompareFunc); eventRecordPtr->FillCommonEventRecord(eventRecord); eventRecordPtr->resultTo = commonEventListener; eventRecordPtr->state = OrderedEventRecord::IDLE; eventRecordPtr->nextReceiver = 0; eventRecordPtr->receivers = subscribers; for (auto vec : eventRecordPtr->receivers) { eventRecordPtr->deliveryState.emplace_back(OrderedEventRecord::PENDING); } EnqueueOrderedRecord(eventRecordPtr); ret = ScheduleOrderedCommonEvent(); return ret; } bool CommonEventControlManager::EnqueueUnorderedRecord(const std::shared_ptr &eventRecordPtr) { if (eventRecordPtr == nullptr) { EVENT_LOGE("eventRecordPtr is null"); return false; } std::lock_guard lock(unorderedMutex_); unorderedEventQueue_.emplace_back(eventRecordPtr); return true; } bool CommonEventControlManager::EnqueueOrderedRecord(const std::shared_ptr &eventRecordPtr) { if (eventRecordPtr == nullptr) { EVENT_LOGE("eventRecordPtr is null"); return false; } std::lock_guard lock(orderedMutex_); orderedEventQueue_.emplace_back(eventRecordPtr); return true; } void CommonEventControlManager::EnqueueHistoryEventRecord( const std::shared_ptr &eventRecordPtr, bool hasLastSubscribe) { #ifdef BUILD_VARIANT_USER EVENT_LOGD("User version don't record history"); return; #endif if (eventRecordPtr == nullptr) { EVENT_LOGE("eventRecordPtr is nullptr"); return; } HistoryEventRecord record; record.want = eventRecordPtr->commonEventData->GetWant(); record.code = eventRecordPtr->commonEventData->GetCode(); record.data = eventRecordPtr->commonEventData->GetData(); record.sticky = eventRecordPtr->publishInfo->IsSticky(); record.ordered = eventRecordPtr->publishInfo->IsOrdered(); record.subscriberPermissions = eventRecordPtr->publishInfo->GetSubscriberPermissions(); record.recordTime = eventRecordPtr->recordTime; record.pid = eventRecordPtr->eventRecordInfo.pid; record.uid = eventRecordPtr->eventRecordInfo.uid; record.userId = eventRecordPtr->userId; record.bundleName = eventRecordPtr->eventRecordInfo.bundleName; record.isSystemApp = eventRecordPtr->eventRecordInfo.isSystemApp; record.isSystemEvent = eventRecordPtr->isSystemEvent; for (auto vec : eventRecordPtr->receivers) { if (vec == nullptr) { continue; } HistorySubscriberRecord receiver; receiver.recordTime = vec->recordTime; receiver.bundleName = vec->eventRecordInfo.bundleName; receiver.priority = vec->eventSubscribeInfo->GetPriority(); receiver.userId = vec->eventSubscribeInfo->GetUserId(); receiver.permission = vec->eventSubscribeInfo->GetPermission(); receiver.deviceId = vec->eventSubscribeInfo->GetDeviceId(); receiver.isFreeze = vec->isFreeze; receiver.freezeTime = vec->freezeTime; record.receivers.emplace_back(receiver); } record.hasLastSubscribe = hasLastSubscribe; record.deliveryState = eventRecordPtr->deliveryState; record.dispatchTime = eventRecordPtr->dispatchTime; record.receiverTime = eventRecordPtr->receiverTime; record.state = eventRecordPtr->state; record.resultAbort = eventRecordPtr->resultAbort; std::lock_guard lock(historyMutex_); if (historyEventRecords_.size() == HISTORY_MAX_SIZE) { historyEventRecords_.pop_front(); } historyEventRecords_.emplace_back(record); } bool CommonEventControlManager::ScheduleOrderedCommonEvent() { EVENT_LOGD("enter"); if (scheduled_) { return true; } scheduled_ = true; std::weak_ptr weak = shared_from_this(); orderedQueue_->submit([weak]() { auto manager = weak.lock(); if (manager == nullptr) { EVENT_LOGE("CommonEventControlManager is null"); return; } manager->ProcessNextOrderedEvent(true); }); return true; } bool CommonEventControlManager::NotifyOrderedEvent(std::shared_ptr &eventRecordPtr, size_t index) { HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); EVENT_LOGD("enter with index %{public}zu", index); if (eventRecordPtr == nullptr) { EVENT_LOGE("eventRecordPtr = nullptr"); return false; } size_t receiverNum = eventRecordPtr->receivers.size(); if ((index < 0) || (index >= receiverNum)) { EVENT_LOGE("Invalid index (= %{public}zu)", index); return false; } int8_t ret = CheckPermission(*(eventRecordPtr->receivers[index]), *eventRecordPtr); if (ret == OrderedEventRecord::SKIPPED) { eventRecordPtr->deliveryState[index] = ret; return true; } if (ret == OrderedEventRecord::DELIVERED) { if (eventRecordPtr->receivers[index]->isFreeze) { EVENT_LOGD("vec isFreeze: %{public}d", eventRecordPtr->receivers[index]->isFreeze); DelayedSingleton::GetInstance()->InsertFrozenEvents( eventRecordPtr->receivers[index], *eventRecordPtr); DelayedSingleton::GetInstance()->InsertFrozenEventsMap( eventRecordPtr->receivers[index], *eventRecordPtr); eventRecordPtr->deliveryState[index] = OrderedEventRecord::SKIPPED; eventRecordPtr->curReceiver = nullptr; return true; } eventRecordPtr->deliveryState[index] = ret; eventRecordPtr->curReceiver = eventRecordPtr->receivers[index]->commonEventListener; eventRecordPtr->state = OrderedEventRecord::RECEIVING; sptr receiver = iface_cast(eventRecordPtr->curReceiver); if (!receiver) { EVENT_LOGE("Failed to get IEventReceive proxy"); eventRecordPtr->curReceiver = nullptr; return false; } eventRecordPtr->state = OrderedEventRecord::RECEIVED; receiver->NotifyEvent(*(eventRecordPtr->commonEventData), true, eventRecordPtr->publishInfo->IsSticky()); EVENT_LOGD("NotifyOrderedEvent index = %{public}zu event = %{public}s success, subId = %{public}s", index, eventRecordPtr->commonEventData->GetWant().GetAction().c_str(), eventRecordPtr->receivers[index]->eventRecordInfo.subId.c_str()); AccessTokenHelper::RecordSensitivePermissionUsage( eventRecordPtr->receivers[index]->eventRecordInfo.callerToken, eventRecordPtr->commonEventData->GetWant().GetAction()); } return true; } void CommonEventControlManager::ProcessNextOrderedEvent(bool isSendMsg) { HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); EVENT_LOGD("enter"); if (isSendMsg) { scheduled_ = false; } std::shared_ptr sp = nullptr; std::lock_guard lock(orderedMutex_); do { if (orderedEventQueue_.empty()) { EVENT_LOGD("orderedEventQueue_ is empty"); return; } sp = orderedEventQueue_.front(); bool forceReceive = false; size_t numReceivers = sp->receivers.size(); uint64_t nowSysTime = static_cast(SystemTime::GetNowSysTime()); if (sp->dispatchTime > 0) { if ((numReceivers > 0) && (nowSysTime > static_cast(sp->dispatchTime) + (DOUBLE * TIMEOUT * numReceivers))) { CurrentOrderedEventTimeout(false); forceReceive = true; sp->state = OrderedEventRecord::IDLE; } } if (sp->state != OrderedEventRecord::IDLE) { return; } if ((sp->receivers.empty()) || (sp->nextReceiver >= numReceivers) || sp->resultAbort || forceReceive) { // No more receivers for this ordered common event, then process the final result receiver bool hasLastSubscribe = (sp->resultTo != nullptr) ? true : false; if (sp->resultTo != nullptr) { EVENT_LOGD("Process the final subscriber"); sptr receiver = iface_cast(sp->resultTo); if (!receiver) { EVENT_LOGE("Failed to get IEventReceive proxy"); return; } receiver->NotifyEvent(*(sp->commonEventData), true, sp->publishInfo->IsSticky()); sp->resultTo = nullptr; } EVENT_LOGI("NotifyOrderedEvent = %{public}s end, success: %{public}zu, total: %{public}zu", sp->commonEventData->GetWant().GetAction().c_str(), sp->nextReceiver, numReceivers); CancelTimeout(); EnqueueHistoryEventRecord(sp, hasLastSubscribe); orderedEventQueue_.erase(orderedEventQueue_.begin()); sp = nullptr; } } while (sp == nullptr); size_t recIdx = sp->nextReceiver++; SetTime(recIdx, sp, pendingTimeoutMessage_); NotifyOrderedEvent(sp, recIdx); if (sp->curReceiver == nullptr) { sp->state = OrderedEventRecord::IDLE; ScheduleOrderedCommonEvent(); } } void CommonEventControlManager::SetTime(size_t recIdx, std::shared_ptr &sp, bool timeoutMessage) { EVENT_LOGD("enter"); sp->receiverTime = SystemTime::GetNowSysTime(); if (recIdx == 0) { sp->dispatchTime = sp->receiverTime; } if (!timeoutMessage) { SetTimeout(); } } bool CommonEventControlManager::SetTimeout() { EVENT_LOGD("enter"); bool ret = true; if (!pendingTimeoutMessage_) { pendingTimeoutMessage_ = true; std::weak_ptr weak = shared_from_this(); orderedHandler = orderedQueue_->submit_h([weak]() { auto manager = weak.lock(); if (manager == nullptr) { EVENT_LOGE("CommonEventControlManager is null"); return; } manager->CurrentOrderedEventTimeout(true); }, ffrt::task_attr().delay(TIMEOUT * TIME_UNIT_SIZE)); } return ret; } bool CommonEventControlManager::CancelTimeout() { EVENT_LOGD("enter"); if (pendingTimeoutMessage_) { pendingTimeoutMessage_ = false; orderedQueue_->cancel(orderedHandler); } return true; } void CommonEventControlManager::CurrentOrderedEventTimeout(bool isFromMsg) { EVENT_LOGD("enter"); if (isFromMsg) { pendingTimeoutMessage_ = false; } if (orderedEventQueue_.empty()) { EVENT_LOGE("empty orderedEventQueue_"); return; } int64_t nowSysTime = SystemTime::GetNowSysTime(); std::shared_ptr sp = orderedEventQueue_.front(); if (isFromMsg) { int64_t timeoutTime = sp->receiverTime + TIMEOUT; if (timeoutTime > nowSysTime) { SetTimeout(); return; } } // The processing of current receiver has timeout sp->receiverTime = nowSysTime; if (sp->nextReceiver > 0) { std::shared_ptr subscriberRecord = sp->receivers[sp->nextReceiver - 1]; EVENT_LOGW("Timeout: When %{public}s (pid = %{public}d, uid = %{public}d) process common event %{public}s", subscriberRecord->eventRecordInfo.bundleName.c_str(), subscriberRecord->eventRecordInfo.pid, subscriberRecord->eventRecordInfo.uid, sp->commonEventData->GetWant().GetAction().c_str()); SendOrderedEventProcTimeoutHiSysEvent(subscriberRecord, sp->commonEventData->GetWant().GetAction()); sp->deliveryState[sp->nextReceiver - 1] = OrderedEventRecord::TIMEOUT; } // Forced to finish the current receiver to process the next receiver int32_t code = sp->commonEventData->GetCode(); const std::string &strRef = sp->commonEventData->GetData(); bool abort = sp->resultAbort; FinishReceiver(sp, code, strRef, abort); ScheduleOrderedCommonEvent(); return; } bool CommonEventControlManager::FinishReceiver(std::shared_ptr recordPtr, const int32_t &code, const std::string &receiverData, const bool &abortEvent) { EVENT_LOGD("enter"); if (recordPtr == nullptr) { EVENT_LOGE("recordPtr is null"); return false; } EVENT_LOGD("enter recordPtr->state=%{public}d", recordPtr->state); int8_t state = recordPtr->state; recordPtr->state = OrderedEventRecord::IDLE; recordPtr->curReceiver = nullptr; recordPtr->commonEventData->SetCode(code); recordPtr->commonEventData->SetData(receiverData); recordPtr->resultAbort = abortEvent; return state == OrderedEventRecord::RECEIVED; } bool CommonEventControlManager::FinishReceiverAction(std::shared_ptr recordPtr, const int32_t &code, const std::string &receiverData, const bool &abortEvent) { EVENT_LOGD("enter"); if (recordPtr == nullptr) { EVENT_LOGE("recordPtr is nullptr"); return false; } bool doNext = false; doNext = FinishReceiver(recordPtr, code, receiverData, abortEvent); if (doNext) { ProcessNextOrderedEvent(false); } return true; } int8_t CommonEventControlManager::CheckPermission( const EventSubscriberRecord &subscriberRecord, const CommonEventRecord &eventRecord) { EVENT_LOGD("enter"); if (subscriberRecord.eventRecordInfo.uid == eventRecord.eventRecordInfo.uid) { EVENT_LOGD("CheckPermission subscribe uid = %{public}d, publish uid = %{public}d", subscriberRecord.eventRecordInfo.uid, eventRecord.eventRecordInfo.uid); return OrderedEventRecord::DELIVERED; } bool ret = false; ret = CheckSubscriberPermission(subscriberRecord, eventRecord); if (!ret) { return OrderedEventRecord::SKIPPED; } std::string subscriberRequiredPermission = subscriberRecord.eventSubscribeInfo->GetPermission(); ret = CheckSubscriberRequiredPermission(subscriberRequiredPermission, eventRecord, subscriberRecord); if (!ret) { return OrderedEventRecord::SKIPPED; } std::vector publisherRequiredPermissions = eventRecord.publishInfo->GetSubscriberPermissions(); ret = CheckPublisherRequiredPermissions(publisherRequiredPermissions, subscriberRecord, eventRecord); if (!ret) { return OrderedEventRecord::SKIPPED; } return OrderedEventRecord::DELIVERED; } bool CommonEventControlManager::CheckSubscriberPermission( const EventSubscriberRecord &subscriberRecord, const CommonEventRecord &eventRecord) { EVENT_LOGD("enter"); bool ret = false; std::string lackPermission {}; std::string event = eventRecord.commonEventData->GetWant().GetAction(); bool isSystemAPIEvent = DelayedSingleton::GetInstance()->IsSystemAPIEvent(event); if (isSystemAPIEvent && !(subscriberRecord.eventRecordInfo.isSubsystem || subscriberRecord.eventRecordInfo.isSystemApp)) { EVENT_LOGW("Invalid permission for system api event."); return false; } Permission permission = DelayedSingleton::GetInstance()->GetEventPermission(event); if (permission.names.empty()) { return true; } if (permission.names.size() == 1) { ret = AccessTokenHelper::VerifyAccessToken(subscriberRecord.eventRecordInfo.callerToken, permission.names[0]); lackPermission = permission.names[0]; } else if (permission.state == PermissionState::AND) { for (auto vec : permission.names) { ret = AccessTokenHelper::VerifyAccessToken(subscriberRecord.eventRecordInfo.callerToken, vec); if (!ret) { lackPermission = vec; break; } } } else if (permission.state == PermissionState::OR) { for (auto vec : permission.names) { ret = AccessTokenHelper::VerifyAccessToken(subscriberRecord.eventRecordInfo.callerToken, vec); lackPermission += vec + CONNECTOR; if (ret) { break; } } lackPermission = lackPermission.substr(0, lackPermission.length() - CONNECTOR.length()); } else { EVENT_LOGW("Invalid Permission."); return false; } if (!ret) { EVENT_LOGW("No permission to receive common event %{public}s, " "due to subscriber %{public}s (pid = %{public}d, uid = %{public}d) lacks " "the %{public}s permission.", event.c_str(), subscriberRecord.eventRecordInfo.bundleName.c_str(), subscriberRecord.eventRecordInfo.pid, subscriberRecord.eventRecordInfo.uid, lackPermission.c_str()); } return ret; } bool CommonEventControlManager::CheckSubscriberRequiredPermission(const std::string &subscriberRequiredPermission, const CommonEventRecord &eventRecord, const EventSubscriberRecord &subscriberRecord) { bool ret = false; if (subscriberRequiredPermission.empty()) { return true; } ret = AccessTokenHelper::VerifyAccessToken(eventRecord.eventRecordInfo.callerToken, subscriberRequiredPermission); if (!ret) { EVENT_LOGW("No permission to send common event %{public}s " "from %{public}s (pid = %{public}d, uid = %{public}d), userId = %{public}d " "to %{public}s (pid = %{public}d, uid = %{public}d), userId = %{public}d " "due to registered subscriber requires the %{public}s permission.", eventRecord.commonEventData->GetWant().GetAction().c_str(), eventRecord.eventRecordInfo.bundleName.c_str(), eventRecord.eventRecordInfo.pid, eventRecord.eventRecordInfo.uid, eventRecord.userId, subscriberRecord.eventRecordInfo.bundleName.c_str(), subscriberRecord.eventRecordInfo.pid, subscriberRecord.eventRecordInfo.uid, subscriberRecord.eventSubscribeInfo->GetUserId(), subscriberRequiredPermission.c_str()); } return ret; } bool CommonEventControlManager::CheckPublisherRequiredPermissions( const std::vector &publisherRequiredPermissions, const EventSubscriberRecord &subscriberRecord, const CommonEventRecord &eventRecord) { bool ret = false; if (publisherRequiredPermissions.empty()) { return true; } for (auto publisherRequiredPermission : publisherRequiredPermissions) { ret = AccessTokenHelper::VerifyAccessToken( subscriberRecord.eventRecordInfo.callerToken, publisherRequiredPermission); if (!ret) { EVENT_LOGW("No permission to receive common event %{public}s " "to %{public}s (pid = %{public}d, uid = %{public}d), userId = %{public}d " "due to publisher %{public}s (pid = %{public}d, uid = %{public}d)," " userId = %{public}d requires the %{public}s permission.", eventRecord.commonEventData->GetWant().GetAction().c_str(), subscriberRecord.eventRecordInfo.bundleName.c_str(), subscriberRecord.eventRecordInfo.pid, subscriberRecord.eventRecordInfo.uid, subscriberRecord.eventSubscribeInfo->GetUserId(), eventRecord.eventRecordInfo.bundleName.c_str(), eventRecord.eventRecordInfo.pid, eventRecord.eventRecordInfo.uid, eventRecord.userId, publisherRequiredPermission.c_str()); break; } } return ret; } void CommonEventControlManager::GetUnorderedEventRecords( const std::string &event, const int32_t &userId, std::vector> &records) { EVENT_LOGD("enter"); if (event.empty() && userId == ALL_USER) { records = unorderedEventQueue_; } else if (event.empty()) { for (auto vec : unorderedEventQueue_) { if (vec->userId == userId) { records.emplace_back(vec); } } } else if (userId == ALL_USER) { for (auto vec : unorderedEventQueue_) { if (vec->commonEventData->GetWant().GetAction() == event) { records.emplace_back(vec); } } } else { for (auto vec : unorderedEventQueue_) { if (vec->commonEventData->GetWant().GetAction() == event && vec->userId == userId) { records.emplace_back(vec); } } } } void CommonEventControlManager::GetOrderedEventRecords( const std::string &event, const int32_t &userId, std::vector> &records) { EVENT_LOGD("enter"); if (event.empty() && userId == ALL_USER) { records = orderedEventQueue_; } else if (event.empty()) { for (auto vec : orderedEventQueue_) { if (vec->userId == userId) { records.emplace_back(vec); } } } else if (userId == ALL_USER) { for (auto vec : orderedEventQueue_) { if (vec->commonEventData->GetWant().GetAction() == event) { records.emplace_back(vec); } } } else { for (auto vec : orderedEventQueue_) { if (vec->commonEventData->GetWant().GetAction() == event && vec->userId == userId) { records.emplace_back(vec); } } } } void CommonEventControlManager::GetHistoryEventRecords( const std::string &event, const int32_t &userId, std::list &records) { EVENT_LOGD("enter"); if (event.empty() && userId == ALL_USER) { records = historyEventRecords_; } else if (event.empty()) { for (auto vec : historyEventRecords_) { if (vec.userId == userId) { records.push_back(vec); } } } else if (userId == ALL_USER) { for (auto vec : historyEventRecords_) { if (vec.want.GetAction() == event) { records.push_back(vec); } } } else { for (auto vec : historyEventRecords_) { if (vec.want.GetAction() == event && vec.userId == userId) { records.push_back(vec); } } } } void CommonEventControlManager::DumpStateByCommonEventRecord( const std::shared_ptr &record, std::string &dumpInfo) { EVENT_LOGD("enter"); char systime[LENGTH]; strftime(systime, sizeof(char) * LENGTH, "%Y%m%d %I:%M %p", &record->recordTime); std::string recordTime = "\tTime: " + std::string(systime) + "\n"; std::string pid = "\tPID: " + std::to_string(record->eventRecordInfo.pid) + "\n"; std::string uid = "\tUID: " + std::to_string(record->eventRecordInfo.uid) + "\n"; std::string userId; switch (record->userId) { case UNDEFINED_USER: userId = "UNDEFINED_USER"; break; case ALL_USER: userId = "ALL_USER"; break; default: userId = std::to_string(record->userId); break; } userId = "\tUSERID: " + userId + "\n"; std::string bundleName = "\tBundleName: " + record->eventRecordInfo.bundleName + "\n"; std::string permission = "\tRequiredPermission: "; std::string separator; size_t permissionNum = 0; for (auto permissionVec : record->publishInfo->GetSubscriberPermissions()) { if (permissionNum == 0) { separator = ""; } else { separator = ", "; } permission = permission + separator + permissionVec; permissionNum++; } permission = permission + "\n"; std::string isSticky; if (record->publishInfo->IsSticky()) { isSticky = "\tIsSticky: true\n"; } else { isSticky = "\tIsSticky: false\n"; } std::string isOrdered; if (record->publishInfo->IsOrdered()) { isOrdered = "\tIsOrdered: true\n"; } else { isOrdered = "\tIsOrdered: false\n"; } std::string isSystemApp = record->eventRecordInfo.isSystemApp ? "true" : "false"; isSystemApp = "\tIsSystemApp: " + isSystemApp + "\n"; std::string isSystemEvent = record->isSystemEvent ? "true" : "false"; isSystemEvent = "\tIsSystemEvent: " + isSystemEvent + "\n"; std::string action = "\t\tAction: " + record->commonEventData->GetWant().GetAction() + "\n"; std::string entities = "\t\tEntity: "; size_t entityNum = 0; for (auto entitiesVec : record->commonEventData->GetWant().GetEntities()) { if (entityNum == 0) { separator = ""; } else { separator = ", "; } entities = entities + separator + entitiesVec; entityNum++; } entities = entities + "\n"; std::string scheme = "\t\tScheme: " + record->commonEventData->GetWant().GetScheme() + "\n"; std::string uri = "\t\tUri: " + record->commonEventData->GetWant().GetUriString() + "\n"; std::string flags = "\t\tFlags: " + std::to_string(record->commonEventData->GetWant().GetFlags()) + "\n"; std::string type = "\t\tType: " + record->commonEventData->GetWant().GetType() + "\n"; std::string bundle = "\t\tBundleName: " + record->commonEventData->GetWant().GetBundle() + "\n"; std::string ability = "\t\tAbilityName: " + record->commonEventData->GetWant().GetElement().GetAbilityName() + "\n"; std::string deviced = "\t\tDevicedID: " + record->commonEventData->GetWant().GetElement().GetDeviceID() + "\n"; std::string want = "\tWant:\n" + action + entities + scheme + uri + flags + type + bundle + ability + deviced; std::string code = "\tCode: " + std::to_string(record->commonEventData->GetCode()) + "\n"; std::string data = "\tData: " + record->commonEventData->GetData() + "\n"; std::string lastSubscriber; if (record->resultTo) { lastSubscriber = "\tHasLastSubscriber: true\n"; } else { lastSubscriber = "\tHasLastSubscriber: false\n"; } std::string state; switch (record->state) { case OrderedEventRecord::IDLE: state = "\tEventState: IDLE\n"; break; case OrderedEventRecord::RECEIVING: state = "\tEventState: RECEIVING\n"; break; case OrderedEventRecord::RECEIVED: state = "\tEventState: RECEIVED\n"; break; } std::string dispatchTime = "\tDispatchTime: " + std::to_string(record->dispatchTime) + "\n"; std::string receiverTime = "\tReceiverTime: " + std::to_string(record->receiverTime) + "\n"; std::string resultAbort = record->resultAbort ? "true" : "false"; resultAbort = "\tResultAbort: " + resultAbort + "\n"; dumpInfo = recordTime + pid + uid + userId + bundleName + permission + isSticky + isOrdered + isSystemApp + isSystemEvent + want + code + data + lastSubscriber + state + receiverTime + dispatchTime + resultAbort; } void CommonEventControlManager::DumpHistoryStateByCommonEventRecord( const HistoryEventRecord &record, std::string &dumpInfo) { EVENT_LOGD("enter"); char systime[LENGTH]; strftime(systime, sizeof(char) * LENGTH, "%Y%m%d %I:%M %p", &record.recordTime); std::string recordTime = "\tTime: " + std::string(systime) + "\n"; std::string pid = "\tPID: " + std::to_string(record.pid) + "\n"; std::string uid = "\tUID: " + std::to_string(record.uid) + "\n"; std::string userId; switch (record.userId) { case UNDEFINED_USER: userId = "UNDEFINED_USER"; break; case ALL_USER: userId = "ALL_USER"; break; default: userId = std::to_string(record.userId); break; } userId = "\tUSERID: " + userId + "\n"; std::string bundleName = "\tBundleName: " + record.bundleName + "\n"; std::string permission = "\tRequiredPermission: "; std::string separator; size_t permissionNum = 0; for (auto permissionVec : record.subscriberPermissions) { if (permissionNum == 0) { separator = ""; } else { separator = ", "; } permission = permission + separator + permissionVec; permissionNum++; } permission = permission + "\n"; std::string isSticky; if (record.sticky) { isSticky = "\tIsSticky: true\n"; } else { isSticky = "\tIsSticky: false\n"; } std::string isOrdered; if (record.ordered) { isOrdered = "\tIsOrdered: true\n"; } else { isOrdered = "\tIsOrdered: false\n"; } std::string isSystemApp = record.isSystemApp ? "true" : "false"; isSystemApp = "\tIsSystemApp: " + isSystemApp + "\n"; std::string isSystemEvent = record.isSystemEvent ? "true" : "false"; isSystemEvent = "\tIsSystemEvent: " + isSystemEvent + "\n"; std::string action = "\t\tAction: " + record.want.GetAction() + "\n"; std::string entities = "\t\tEntity: "; size_t entityNum = 0; for (auto entitiesVec : record.want.GetEntities()) { if (entityNum == 0) { separator = ""; } else { separator = ", "; } entities = entities + separator + entitiesVec; entityNum++; } entities = entities + "\n"; std::string scheme = "\t\tScheme: " + record.want.GetScheme() + "\n"; std::string uri = "\t\tUri: " + record.want.GetUriString() + "\n"; std::string flags = "\t\tFlags: " + std::to_string(record.want.GetFlags()) + "\n"; std::string type = "\t\tType: " + record.want.GetType() + "\n"; std::string bundle = "\t\tBundleName: " + record.want.GetBundle() + "\n"; std::string ability = "\t\tAbilityName: " + record.want.GetElement().GetAbilityName() + "\n"; std::string deviced = "\t\tDevicedID: " + record.want.GetElement().GetDeviceID() + "\n"; std::string want = "\tWant:\n" + action + entities + scheme + uri + flags + type + bundle + ability + deviced; std::string code = "\tCode: " + std::to_string(record.code) + "\n"; std::string data = "\tData: " + record.data + "\n"; std::string lastSubscriber; if (record.hasLastSubscribe) { lastSubscriber = "\tHasLastSubscriber: true\n"; } else { lastSubscriber = "\tHasLastSubscriber: false\n"; } std::string state; switch (record.state) { case OrderedEventRecord::IDLE: state = "\tEventState: IDLE\n"; break; case OrderedEventRecord::RECEIVING: state = "\tEventState: RECEIVING\n"; break; case OrderedEventRecord::RECEIVED: state = "\tEventState: RECEIVED\n"; break; } std::string dispatchTime = "\tDispatchTime: " + std::to_string(record.dispatchTime) + "\n"; std::string receiverTime = "\tReceiverTime: " + std::to_string(record.receiverTime) + "\n"; std::string resultAbort = record.resultAbort ? "true" : "false"; resultAbort = "\tResultAbort: " + resultAbort + "\n"; dumpInfo = recordTime + pid + uid + userId + bundleName + permission + isSticky + isOrdered + isSystemApp + isSystemEvent + want + code + data + lastSubscriber + state + receiverTime + dispatchTime + resultAbort; } void CommonEventControlManager::DumpStateBySubscriberRecord( const std::shared_ptr &record, std::string &dumpInfo) { EVENT_LOGD("enter"); if (record->receivers.empty()) { dumpInfo = "\tSubscribers:\tNo information"; return; } size_t num = 0; for (auto receiver : record->receivers) { num++; std::string title = std::to_string(num); if (num == 1) { title = "\tSubscribers:\tTotal " + std::to_string(record->receivers.size()) + " subscribers\n\tNO " + title + "\n"; } else { title = "\tNO " + title + "\n"; } std::string dumpInfoBySubscriber; DelayedSingleton::GetInstance()->DumpDetailed( title, receiver, "\t\t", dumpInfoBySubscriber); std::string deliveryState; switch (record->deliveryState[num - 1]) { case OrderedEventRecord::PENDING: deliveryState = "\t\tEventState: PENDING\n"; break; case OrderedEventRecord::DELIVERED: deliveryState = "\t\tEventState: DELIVERED\n"; break; case OrderedEventRecord::SKIPPED: deliveryState = "\t\tEventState: SKIPPED\n"; break; case OrderedEventRecord::TIMEOUT: deliveryState = "\t\tEventState: TIMEOUT\n"; break; } dumpInfo = dumpInfo + dumpInfoBySubscriber + deliveryState; } } void CommonEventControlManager::DumpHistoryStateBySubscriberRecord( const HistoryEventRecord &record, std::string &dumpInfo) { EVENT_LOGD("enter"); if (record.receivers.empty()) { dumpInfo = "\tSubscribers:\tNo information"; return; } size_t num = 0; for (auto receiver : record.receivers) { num++; std::string title = std::to_string(num); if (num == 1) { title = "\tSubscribers:\tTotal " + std::to_string(record.receivers.size()) + " subscribers\n\tNO " + title + "\n"; } else { title = "\tNO " + title + "\n"; } char systime[LENGTH]; strftime(systime, sizeof(char) * LENGTH, "%Y%m%d %I:%M %p", &receiver.recordTime); std::string format = "\t\t"; std::string recordTime = format + "Time: " + std::string(systime) + "\n"; std::string bundleName = format + "BundleName: " + receiver.bundleName + "\n"; std::string priority = format + "Priority: " + std::to_string(receiver.priority) + "\n"; std::string userId; switch (receiver.userId) { case UNDEFINED_USER: userId = "UNDEFINED_USER"; break; case ALL_USER: userId = "ALL_USER"; break; default: userId = std::to_string(receiver.userId); break; } userId = format + "USERID: " + userId + "\n"; std::string permission = format + "Permission: " + receiver.permission + "\n"; std::string deviceId = format + "DevicedID: " + receiver.deviceId + "\n"; std::string isFreeze = receiver.isFreeze ? "true" : "false"; isFreeze = format + "IsFreeze: " + isFreeze + "\n"; std::string freezeTime; if (receiver.freezeTime == 0) { freezeTime = format + "FreezeTime: -\n"; } else { freezeTime = format + "FreezeTime: " + std::to_string(receiver.freezeTime) + "\n"; } std::string deliveryState; switch (record.deliveryState[num - 1]) { case OrderedEventRecord::PENDING: deliveryState = "\t\tEventState: PENDING\n"; break; case OrderedEventRecord::DELIVERED: deliveryState = "\t\tEventState: DELIVERED\n"; break; case OrderedEventRecord::SKIPPED: deliveryState = "\t\tEventState: SKIPPED\n"; break; case OrderedEventRecord::TIMEOUT: deliveryState = "\t\tEventState: TIMEOUT\n"; break; } dumpInfo = dumpInfo + title + recordTime + bundleName + priority + userId + permission + deviceId + isFreeze + freezeTime + deliveryState; } } void CommonEventControlManager::DumpState( const std::string &event, const int32_t &userId, std::vector &state) { EVENT_LOGD("enter"); std::vector> records; std::vector> unorderedRecords; std::vector> orderedRecords; std::lock_guard orderedLock(orderedMutex_); std::lock_guard unorderedLock(unorderedMutex_); GetUnorderedEventRecords(event, userId, unorderedRecords); GetOrderedEventRecords(event, userId, orderedRecords); records.insert(records.end(), unorderedRecords.begin(), unorderedRecords.end()); records.insert(records.end(), orderedRecords.begin(), orderedRecords.end()); if (records.empty()) { state.emplace_back("Pending Events:\tNo information"); return; } size_t num = 0; for (auto record : records) { num++; std::string no = std::to_string(num); if (num == 1) { no = "Pending Events:\tTotal " + std::to_string(records.size()) + " information\nNO " + no + "\n"; } else { no = "NO " + no + "\n"; } std::string commonEventRecord; DumpStateByCommonEventRecord(record, commonEventRecord); std::string subscriberRecord; DumpStateBySubscriberRecord(record, subscriberRecord); std::string stateInfo = no + commonEventRecord + subscriberRecord; state.emplace_back(stateInfo); } } void CommonEventControlManager::DumpHistoryState( const std::string &event, const int32_t &userId, std::vector &state) { EVENT_LOGD("enter"); std::list records; std::lock_guard lock(historyMutex_); GetHistoryEventRecords(event, userId, records); if (records.empty()) { state.emplace_back("History Events:\tNo information"); return; } size_t num = 0; for (auto record : records) { num++; std::string no = std::to_string(num); if (num == 1) { no = "History Events:\tTotal " + std::to_string(records.size()) + " information\nNO " + no + "\n"; } else { no = "NO " + no + "\n"; } std::string commonEventRecord; DumpHistoryStateByCommonEventRecord(record, commonEventRecord); std::string subscriberRecord; DumpHistoryStateBySubscriberRecord(record, subscriberRecord); std::string stateInfo = no + commonEventRecord + subscriberRecord; state.emplace_back(stateInfo); } } void CommonEventControlManager::SendOrderedEventProcTimeoutHiSysEvent( const std::shared_ptr &subscriberRecord, const std::string &eventName) { if (subscriberRecord == nullptr) { return; } EventInfo eventInfo; if (subscriberRecord->eventSubscribeInfo != nullptr) { eventInfo.userId = subscriberRecord->eventSubscribeInfo->GetUserId(); } eventInfo.subscriberName = subscriberRecord->eventRecordInfo.bundleName; eventInfo.pid = subscriberRecord->eventRecordInfo.pid; eventInfo.uid = static_cast(subscriberRecord->eventRecordInfo.uid); eventInfo.eventName = eventName; EventReport::SendHiSysEvent(ORDERED_EVENT_PROC_TIMEOUT, eventInfo); } } // namespace EventFwk } // namespace OHOS