12dc7c57fSopenharmony_ci/*
22dc7c57fSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
32dc7c57fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
42dc7c57fSopenharmony_ci * you may not use this file except in compliance with the License.
52dc7c57fSopenharmony_ci * You may obtain a copy of the License at
62dc7c57fSopenharmony_ci *
72dc7c57fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
82dc7c57fSopenharmony_ci *
92dc7c57fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
102dc7c57fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
112dc7c57fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122dc7c57fSopenharmony_ci * See the License for the specific language governing permissions and
132dc7c57fSopenharmony_ci * limitations under the License.
142dc7c57fSopenharmony_ci */
152dc7c57fSopenharmony_ci
162dc7c57fSopenharmony_ci#include "common_event.h"
172dc7c57fSopenharmony_ci#include "native_log.h"
182dc7c57fSopenharmony_ci#include "parameter_parse.h"
192dc7c57fSopenharmony_ci
202dc7c57fSopenharmony_cinamespace OHOS::CommonEventManager {
212dc7c57fSopenharmony_ci    const int8_t STR_PTR_TYPE = 5;
222dc7c57fSopenharmony_ci    std::atomic_ullong SubscriberImpl::subscriberID_ = 0;
232dc7c57fSopenharmony_ci
242dc7c57fSopenharmony_ci    SubscriberImpl::SubscriberImpl(std::shared_ptr<CommonEventSubscribeInfo> sp, int64_t infoId)
252dc7c57fSopenharmony_ci        : CommonEventSubscriber(*sp)
262dc7c57fSopenharmony_ci    {
272dc7c57fSopenharmony_ci        id_ = ++subscriberID_;
282dc7c57fSopenharmony_ci        LOGI("constructor SubscriberImpl");
292dc7c57fSopenharmony_ci        valid_ = std::make_shared<bool>(false);
302dc7c57fSopenharmony_ci        infoId_ = infoId;
312dc7c57fSopenharmony_ci    }
322dc7c57fSopenharmony_ci
332dc7c57fSopenharmony_ci    SubscriberImpl::~SubscriberImpl()
342dc7c57fSopenharmony_ci    {
352dc7c57fSopenharmony_ci        LOGI("destructor SubscriberImpl[%{public}llu]", id_.load());
362dc7c57fSopenharmony_ci        *valid_ = false;
372dc7c57fSopenharmony_ci    }
382dc7c57fSopenharmony_ci
392dc7c57fSopenharmony_ci    static void FreeCCommonEventData(CCommonEventData &cData)
402dc7c57fSopenharmony_ci    {
412dc7c57fSopenharmony_ci        FreeCCommonEventDataCharPtr(cData);
422dc7c57fSopenharmony_ci        for (int i = 0; i < cData.parameters.size; i++) {
432dc7c57fSopenharmony_ci            auto ptr = cData.parameters.head[i];
442dc7c57fSopenharmony_ci            free(ptr.key);
452dc7c57fSopenharmony_ci            ptr.key = nullptr;
462dc7c57fSopenharmony_ci            if (ptr.valueType == STR_PTR_TYPE) {
472dc7c57fSopenharmony_ci                char **value = reinterpret_cast<char **>(ptr.value);
482dc7c57fSopenharmony_ci                for (int j = 0; j < ptr.size; j++) {
492dc7c57fSopenharmony_ci                    free(value[j]);
502dc7c57fSopenharmony_ci                    value[j] = nullptr;
512dc7c57fSopenharmony_ci                }
522dc7c57fSopenharmony_ci            }
532dc7c57fSopenharmony_ci            free(ptr.value);
542dc7c57fSopenharmony_ci            ptr.value = nullptr;
552dc7c57fSopenharmony_ci        }
562dc7c57fSopenharmony_ci        free(cData.parameters.head);
572dc7c57fSopenharmony_ci        cData.parameters.head = nullptr;
582dc7c57fSopenharmony_ci    }
592dc7c57fSopenharmony_ci
602dc7c57fSopenharmony_ci    void SubscriberImpl::OnReceiveEvent(const CommonEventData &data)
612dc7c57fSopenharmony_ci    {
622dc7c57fSopenharmony_ci        LOGI("Receive event.")
632dc7c57fSopenharmony_ci        if (valid_ == nullptr || *(valid_) == false) {
642dc7c57fSopenharmony_ci            LOGE("OnReceiveEvent commonEventDataWorkerData or ref is invalid which may be freed before");
652dc7c57fSopenharmony_ci            return;
662dc7c57fSopenharmony_ci        }
672dc7c57fSopenharmony_ci        if (this->IsOrderedCommonEvent()) {
682dc7c57fSopenharmony_ci            LOGI("IsOrderedCommonEvent is true");
692dc7c57fSopenharmony_ci            SetPublishResult(this);
702dc7c57fSopenharmony_ci        }
712dc7c57fSopenharmony_ci        LOGI("Subscribe callback start to run.")
722dc7c57fSopenharmony_ci        CCommonEventData cData;
732dc7c57fSopenharmony_ci        int32_t code = GetCommonEventData(data, cData);
742dc7c57fSopenharmony_ci        if (code == ERR_NO_MEMORY || code == ERR_CES_FAILED) {
752dc7c57fSopenharmony_ci            LOGE("Failed to excute callback: out of memory.");
762dc7c57fSopenharmony_ci            return;
772dc7c57fSopenharmony_ci        }
782dc7c57fSopenharmony_ci        callback_(cData);
792dc7c57fSopenharmony_ci        FreeCCommonEventData(cData);
802dc7c57fSopenharmony_ci    }
812dc7c57fSopenharmony_ci
822dc7c57fSopenharmony_ci    unsigned long long SubscriberImpl::GetID()
832dc7c57fSopenharmony_ci    {
842dc7c57fSopenharmony_ci        return id_.load();
852dc7c57fSopenharmony_ci    }
862dc7c57fSopenharmony_ci
872dc7c57fSopenharmony_ci    int64_t SubscriberImpl::GetSubscribeInfoId()
882dc7c57fSopenharmony_ci    {
892dc7c57fSopenharmony_ci        return infoId_;
902dc7c57fSopenharmony_ci    }
912dc7c57fSopenharmony_ci
922dc7c57fSopenharmony_ci    void SubscriberImpl::SetSubscriberManagerId(int64_t id)
932dc7c57fSopenharmony_ci    {
942dc7c57fSopenharmony_ci        managerId_ = id;
952dc7c57fSopenharmony_ci    }
962dc7c57fSopenharmony_ci
972dc7c57fSopenharmony_ci    int64_t SubscriberImpl::GetSubscriberManagerId()
982dc7c57fSopenharmony_ci    {
992dc7c57fSopenharmony_ci        return managerId_;
1002dc7c57fSopenharmony_ci    }
1012dc7c57fSopenharmony_ci
1022dc7c57fSopenharmony_ci    void SubscriberImpl::SetCallback(const std::function<void(CCommonEventData)> &callback)
1032dc7c57fSopenharmony_ci    {
1042dc7c57fSopenharmony_ci        callback_ = callback;
1052dc7c57fSopenharmony_ci        *valid_ = true;
1062dc7c57fSopenharmony_ci    }
1072dc7c57fSopenharmony_ci
1082dc7c57fSopenharmony_ci    SubscriberManager::SubscriberManager(std::shared_ptr<CommonEventSubscribeInfo> info, int64_t infoId)
1092dc7c57fSopenharmony_ci    {
1102dc7c57fSopenharmony_ci        auto objectInfo = new (std::nothrow) SubscriberImpl(info, infoId);
1112dc7c57fSopenharmony_ci        subscriber = std::shared_ptr<SubscriberImpl>(objectInfo);
1122dc7c57fSopenharmony_ci    }
1132dc7c57fSopenharmony_ci
1142dc7c57fSopenharmony_ci    SubscriberManager::~SubscriberManager()
1152dc7c57fSopenharmony_ci    {
1162dc7c57fSopenharmony_ci    }
1172dc7c57fSopenharmony_ci
1182dc7c57fSopenharmony_ci    std::shared_ptr<SubscriberImpl> SubscriberManager::GetSubscriber()
1192dc7c57fSopenharmony_ci    {
1202dc7c57fSopenharmony_ci        return subscriber;
1212dc7c57fSopenharmony_ci    }
1222dc7c57fSopenharmony_ci
1232dc7c57fSopenharmony_ci    int64_t SubscriberManager::GetSubscribeInfoId()
1242dc7c57fSopenharmony_ci    {
1252dc7c57fSopenharmony_ci        return subscriber->GetSubscribeInfoId();
1262dc7c57fSopenharmony_ci    }
1272dc7c57fSopenharmony_ci} // namespace OHOS::CommonEventManager