17405867cSopenharmony_ci/*
27405867cSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
37405867cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
47405867cSopenharmony_ci * you may not use this file except in compliance with the License.
57405867cSopenharmony_ci * You may obtain a copy of the License at
67405867cSopenharmony_ci *
77405867cSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
87405867cSopenharmony_ci *
97405867cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
107405867cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
117405867cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127405867cSopenharmony_ci * See the License for the specific language governing permissions and
137405867cSopenharmony_ci * limitations under the License.
147405867cSopenharmony_ci */
157405867cSopenharmony_ci
167405867cSopenharmony_ci#include <mutex>
177405867cSopenharmony_ci#include <string>
187405867cSopenharmony_ci
197405867cSopenharmony_ci#include "appevent_watcher_impl.h"
207405867cSopenharmony_ci#include "app_event_observer_mgr.h"
217405867cSopenharmony_ci#include "cj_ffi/cj_common_ffi.h"
227405867cSopenharmony_ci#include "error.h"
237405867cSopenharmony_ci#include "file_util.h"
247405867cSopenharmony_ci#include "hiappevent_clean.h"
257405867cSopenharmony_ci#include "hiappevent_config.h"
267405867cSopenharmony_ci#include "hiappevent_impl.h"
277405867cSopenharmony_ci#include "hiappevent_userinfo.h"
287405867cSopenharmony_ci#include "hiappevent_verify.h"
297405867cSopenharmony_ci#include "hiappevent_write.h"
307405867cSopenharmony_ci#include "log.h"
317405867cSopenharmony_ci#include "time_util.h"
327405867cSopenharmony_ci
337405867cSopenharmony_ciusing namespace OHOS::HiviewDFX;
347405867cSopenharmony_ciusing namespace OHOS::HiviewDFX::HiAppEvent;
357405867cSopenharmony_ci
367405867cSopenharmony_cinamespace OHOS {
377405867cSopenharmony_cinamespace CJSystemapi {
387405867cSopenharmony_cinamespace HiAppEvent {
397405867cSopenharmony_cistd::mutex g_mutex;
407405867cSopenharmony_ciint HiAppEventImpl::Configure(bool disable, const std::string& maxStorage)
417405867cSopenharmony_ci{
427405867cSopenharmony_ci    std::string disableStr = disable == true ? "true" : "false";
437405867cSopenharmony_ci    bool disableRes = HiAppEventConfig::GetInstance().SetConfigurationItem("disable", disableStr);
447405867cSopenharmony_ci    if (!disableRes) {
457405867cSopenharmony_ci        LOGE("HiAppEvent failed to configure disable HiAppEvent");
467405867cSopenharmony_ci        return ERR_INVALID_MAX_STORAGE;
477405867cSopenharmony_ci    }
487405867cSopenharmony_ci    bool maxStorageRes = HiAppEventConfig::GetInstance().SetConfigurationItem("max_storage", maxStorage);
497405867cSopenharmony_ci    if (!maxStorageRes) {
507405867cSopenharmony_ci        LOGE("HiAppEvent failed to configure maxStorage HiAppEvent");
517405867cSopenharmony_ci        return ERR_INVALID_MAX_STORAGE;
527405867cSopenharmony_ci    }
537405867cSopenharmony_ci    return SUCCESS_CODE;
547405867cSopenharmony_ci}
557405867cSopenharmony_ci
567405867cSopenharmony_cistd::string GetStorageDirPath()
577405867cSopenharmony_ci{
587405867cSopenharmony_ci    return HiAppEventConfig::GetInstance().GetStorageDir();
597405867cSopenharmony_ci}
607405867cSopenharmony_ci
617405867cSopenharmony_ciuint64_t GetMaxStorageSize()
627405867cSopenharmony_ci{
637405867cSopenharmony_ci    return HiAppEventConfig::GetInstance().GetMaxStorageSize();
647405867cSopenharmony_ci}
657405867cSopenharmony_ci
667405867cSopenharmony_cistd::string GetStorageFileName()
677405867cSopenharmony_ci{
687405867cSopenharmony_ci    return "app_event_" + TimeUtil::GetDate() + ".log";
697405867cSopenharmony_ci}
707405867cSopenharmony_ci
717405867cSopenharmony_civoid CheckStorageSpace(const std::string& dir)
727405867cSopenharmony_ci{
737405867cSopenharmony_ci    auto maxSize = GetMaxStorageSize();
747405867cSopenharmony_ci    if (!HiAppEventClean::IsStorageSpaceFull(dir, maxSize)) {
757405867cSopenharmony_ci        return;
767405867cSopenharmony_ci    }
777405867cSopenharmony_ci    LOGI("hiappevent dir space is full, start to clean");
787405867cSopenharmony_ci    HiAppEventClean::ReleaseSomeStorageSpace(dir, maxSize);
797405867cSopenharmony_ci}
807405867cSopenharmony_ci
817405867cSopenharmony_cibool WriteEventToFile(const std::string& filePath, const std::string& event)
827405867cSopenharmony_ci{
837405867cSopenharmony_ci    return FileUtil::SaveStringToFile(filePath, event);
847405867cSopenharmony_ci}
857405867cSopenharmony_ci
867405867cSopenharmony_civoid HiWriteEvent(std::shared_ptr<AppEventPack> appEventPack)
877405867cSopenharmony_ci{
887405867cSopenharmony_ci    if (HiAppEventConfig::GetInstance().GetDisable()) {
897405867cSopenharmony_ci        LOGE("the HiAppEvent function is disabled.");
907405867cSopenharmony_ci        return;
917405867cSopenharmony_ci    }
927405867cSopenharmony_ci    if (appEventPack == nullptr) {
937405867cSopenharmony_ci        LOGE("appEventPack is null.");
947405867cSopenharmony_ci        return;
957405867cSopenharmony_ci    }
967405867cSopenharmony_ci    std::string dirPath = GetStorageDirPath();
977405867cSopenharmony_ci    if (dirPath.empty()) {
987405867cSopenharmony_ci        LOGE("dirPath is null, stop writing the event.");
997405867cSopenharmony_ci        return;
1007405867cSopenharmony_ci    }
1017405867cSopenharmony_ci    std::string event = appEventPack->GetEventStr();
1027405867cSopenharmony_ci    {
1037405867cSopenharmony_ci        std::lock_guard<std::mutex> lockGuard(g_mutex);
1047405867cSopenharmony_ci        if (!FileUtil::IsFileExists(dirPath) && !FileUtil::ForceCreateDirectory(dirPath)) {
1057405867cSopenharmony_ci            LOGE("failed to create hiappevent dir, errno=%{public}d.", errno);
1067405867cSopenharmony_ci            return;
1077405867cSopenharmony_ci        }
1087405867cSopenharmony_ci        CheckStorageSpace(dirPath);
1097405867cSopenharmony_ci        std::string filePath = FileUtil::GetFilePathByDir(dirPath, GetStorageFileName());
1107405867cSopenharmony_ci        if (WriteEventToFile(filePath, event)) {
1117405867cSopenharmony_ci            std::vector<std::shared_ptr<AppEventPack>> events;
1127405867cSopenharmony_ci            events.emplace_back(appEventPack);
1137405867cSopenharmony_ci            AppEventObserverMgr::GetInstance().HandleEvents(events);
1147405867cSopenharmony_ci            return;
1157405867cSopenharmony_ci        }
1167405867cSopenharmony_ci        LOGE("failed to write event to log file, errno=%{public}d.", errno);
1177405867cSopenharmony_ci    }
1187405867cSopenharmony_ci}
1197405867cSopenharmony_ci
1207405867cSopenharmony_ciint HiAppEventImpl::Write(std::shared_ptr<HiviewDFX::AppEventPack> appEventPack)
1217405867cSopenharmony_ci{
1227405867cSopenharmony_ci    if (auto ret = VerifyAppEvent(appEventPack); ret != 0) {
1237405867cSopenharmony_ci        LOGE("HiAppEvent failed to write HiAppEvent %{public}d", ret);
1247405867cSopenharmony_ci        return ret;
1257405867cSopenharmony_ci    }
1267405867cSopenharmony_ci    HiWriteEvent(appEventPack);
1277405867cSopenharmony_ci    return SUCCESS_CODE;
1287405867cSopenharmony_ci}
1297405867cSopenharmony_ci
1307405867cSopenharmony_ciint64_t HiAppEventImpl::AddProcessor(const ReportConfig& conf)
1317405867cSopenharmony_ci{
1327405867cSopenharmony_ci    int64_t processorId = AppEventObserverMgr::GetInstance().RegisterObserver(conf.name, conf);
1337405867cSopenharmony_ci    if (processorId <= 0) {
1347405867cSopenharmony_ci        LOGE("failed to add processor=%{public}s, register processor error", conf.name.c_str());
1357405867cSopenharmony_ci        return processorId;
1367405867cSopenharmony_ci    }
1377405867cSopenharmony_ci    return processorId;
1387405867cSopenharmony_ci}
1397405867cSopenharmony_ci
1407405867cSopenharmony_ciint HiAppEventImpl::RemoveProcessor(int64_t processorId)
1417405867cSopenharmony_ci{
1427405867cSopenharmony_ci    if (processorId <= 0) {
1437405867cSopenharmony_ci        LOGE("failed to remove processor id=%{public}" PRIi64 "", processorId);
1447405867cSopenharmony_ci        return SUCCESS_CODE;
1457405867cSopenharmony_ci    }
1467405867cSopenharmony_ci    if (AppEventObserverMgr::GetInstance().UnregisterObserver(processorId) != 0) {
1477405867cSopenharmony_ci        LOGE("failed to remove processor id=%{public}" PRIi64"", processorId);
1487405867cSopenharmony_ci        return ERR_CODE_PARAM_INVALID;
1497405867cSopenharmony_ci    }
1507405867cSopenharmony_ci    return SUCCESS_CODE;
1517405867cSopenharmony_ci}
1527405867cSopenharmony_ci
1537405867cSopenharmony_ciint HiAppEventImpl::SetUserId(const std::string& name, const std::string& value)
1547405867cSopenharmony_ci{
1557405867cSopenharmony_ci    if (value.empty()) {
1567405867cSopenharmony_ci        if (UserInfo::GetInstance().RemoveUserId(name) != 0) {
1577405867cSopenharmony_ci            LOGE("failed to remove userId");
1587405867cSopenharmony_ci            return ERR_CODE_PARAM_INVALID;
1597405867cSopenharmony_ci        }
1607405867cSopenharmony_ci        return SUCCESS_CODE;
1617405867cSopenharmony_ci    }
1627405867cSopenharmony_ci    if (UserInfo::GetInstance().SetUserId(name, value) != 0) {
1637405867cSopenharmony_ci        LOGE("failed to set userId");
1647405867cSopenharmony_ci        return ERR_CODE_PARAM_INVALID;
1657405867cSopenharmony_ci    }
1667405867cSopenharmony_ci    return SUCCESS_CODE;
1677405867cSopenharmony_ci}
1687405867cSopenharmony_ci
1697405867cSopenharmony_cistd::tuple<int, std::string> HiAppEventImpl::GetUserId(const std::string& name)
1707405867cSopenharmony_ci{
1717405867cSopenharmony_ci    std::string strUserId;
1727405867cSopenharmony_ci    if (UserInfo::GetInstance().GetUserId(name, strUserId) != 0) {
1737405867cSopenharmony_ci        LOGE("failed to get userId");
1747405867cSopenharmony_ci        return {ERR_CODE_PARAM_INVALID, nullptr};
1757405867cSopenharmony_ci    }
1767405867cSopenharmony_ci    return {SUCCESS_CODE, strUserId};
1777405867cSopenharmony_ci}
1787405867cSopenharmony_ci
1797405867cSopenharmony_ciint HiAppEventImpl::SetUserProperty(const std::string& name, const std::string& value)
1807405867cSopenharmony_ci{
1817405867cSopenharmony_ci    if (value.empty()) {
1827405867cSopenharmony_ci        if (UserInfo::GetInstance().RemoveUserProperty(name) != 0) {
1837405867cSopenharmony_ci            LOGE("failed to set user propertyd");
1847405867cSopenharmony_ci            return ERR_CODE_PARAM_INVALID;
1857405867cSopenharmony_ci        }
1867405867cSopenharmony_ci        return SUCCESS_CODE;
1877405867cSopenharmony_ci    }
1887405867cSopenharmony_ci    if (UserInfo::GetInstance().SetUserProperty(name, value) != 0) {
1897405867cSopenharmony_ci        LOGE("failed to set user property");
1907405867cSopenharmony_ci        return ERR_CODE_PARAM_INVALID;
1917405867cSopenharmony_ci    }
1927405867cSopenharmony_ci    return SUCCESS_CODE;
1937405867cSopenharmony_ci}
1947405867cSopenharmony_ci
1957405867cSopenharmony_cistd::tuple<int, std::string> HiAppEventImpl::GetUserProperty(const std::string& name)
1967405867cSopenharmony_ci{
1977405867cSopenharmony_ci    std::string strUserProperty;
1987405867cSopenharmony_ci    if (UserInfo::GetInstance().GetUserProperty(name, strUserProperty) != 0) {
1997405867cSopenharmony_ci        LOGE("failed to get user property");
2007405867cSopenharmony_ci        return {ERR_CODE_PARAM_INVALID, nullptr};
2017405867cSopenharmony_ci    }
2027405867cSopenharmony_ci    return {SUCCESS_CODE, strUserProperty};
2037405867cSopenharmony_ci}
2047405867cSopenharmony_ci
2057405867cSopenharmony_civoid HiAppEventImpl::ClearData()
2067405867cSopenharmony_ci{
2077405867cSopenharmony_ci    std::string dir = HiAppEventConfig::GetInstance().GetStorageDir();
2087405867cSopenharmony_ci    HiAppEventClean::ClearData(dir);
2097405867cSopenharmony_ci}
2107405867cSopenharmony_ci
2117405867cSopenharmony_cistd::tuple<int, int64_t> HiAppEventImpl::addWatcher(const std::string& name,
2127405867cSopenharmony_ci                                                    const std::vector<AppEventFilter>& filters,
2137405867cSopenharmony_ci                                                    const TriggerCondition& cond,
2147405867cSopenharmony_ci                                                    void (*callbackOnTriggerRef)(int, int, int64_t),
2157405867cSopenharmony_ci                                                    void (*callbackOnReceiveRef)(char*, CArrRetAppEventGroup))
2167405867cSopenharmony_ci{
2177405867cSopenharmony_ci    auto watcherPtr = std::make_shared<AppEventWatcherImpl>(name, filters, cond);
2187405867cSopenharmony_ci    if (callbackOnTriggerRef != (void*)-1) {
2197405867cSopenharmony_ci        watcherPtr->InitTrigger(callbackOnTriggerRef);
2207405867cSopenharmony_ci    }
2217405867cSopenharmony_ci    if (callbackOnReceiveRef != (void*)-1) {
2227405867cSopenharmony_ci        watcherPtr->InitReceiver(callbackOnReceiveRef);
2237405867cSopenharmony_ci    }
2247405867cSopenharmony_ci    int64_t observerSeq = AppEventObserverMgr::GetInstance().RegisterObserver(watcherPtr);
2257405867cSopenharmony_ci    if (observerSeq <= 0) {
2267405867cSopenharmony_ci        LOGE("invalid observer sequence");
2277405867cSopenharmony_ci        return {ERR_CODE_PARAM_INVALID, -1};
2287405867cSopenharmony_ci    }
2297405867cSopenharmony_ci    auto holder = OHOS::FFI::FFIData::Create<AppEventPackageHolderImpl>(name, -1);
2307405867cSopenharmony_ci    if (holder == nullptr) {
2317405867cSopenharmony_ci        return {ERR_PARAM, -1};
2327405867cSopenharmony_ci    }
2337405867cSopenharmony_ci    watcherPtr->InitHolder(holder);
2347405867cSopenharmony_ci    return {SUCCESS_CODE, holder->GetID()};
2357405867cSopenharmony_ci}
2367405867cSopenharmony_ci
2377405867cSopenharmony_civoid HiAppEventImpl::removeWatcher(const std::string& name)
2387405867cSopenharmony_ci{
2397405867cSopenharmony_ci    AppEventObserverMgr::GetInstance().UnregisterObserver(name);
2407405867cSopenharmony_ci}
2417405867cSopenharmony_ci
2427405867cSopenharmony_ciint HiAppEventImpl::Load(const std::string& moduleName)
2437405867cSopenharmony_ci{
2447405867cSopenharmony_ci    return AppEventObserverMgr::GetInstance().Load(moduleName);
2457405867cSopenharmony_ci}
2467405867cSopenharmony_ci} // HiAppEvent
2477405867cSopenharmony_ci} // CJSystemapi
2487405867cSopenharmony_ci} // OHOS