* Copyright (C) 2025 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 <string>
#include "location_hiappevent.h"
#include "location_log.h"
#include "common_utils.h"
#ifdef LOCATION_HIAPPEVENT_ENABLE
#include "app_event.h"
#include "app_event_processor_mgr.h"
#endif
namespace OHOS {
namespace Location {
LocationHiAppEvent::LocationHiAppEvent()
{
LBSLOGI(LOCATION_HIAPPEVENT, "ability constructed.");
}
LocationHiAppEvent::~LocationHiAppEvent()
{
LBSLOGI(LOCATION_HIAPPEVENT, "ability destructed.");
}
LocationHiAppEvent* LocationHiAppEvent::GetInstance()
{
static LocationHiAppEvent data;
return &data;
}
void LocationHiAppEvent::AddProcessor()
{
#ifdef LOCATION_HIAPPEVENT_ENABLE
std::unique_lock<std::mutex> lock(processorIdMutex_);
if (processorId_ != -1) {
return;
}
HiviewDFX::HiAppEvent::ReportConfig config;
config.name = "ha_app_event";
std::string appId = "";
if (!CommonUtils::GetConfigFromJson(KEY_KIT_REPORT_APPID, appId)) {
LBSLOGI(LOCATION_HIAPPEVENT, "GetConfigFromJson error appId:%{public}s.", appId.c_str());
return;
}
config.appId = appId;
config.routeInfo = "AUTO";
config.triggerCond.timeout = HA_CONFIG_TIMEOUT;
config.triggerCond.row = HA_CONFIG_ROW;
config.eventConfigs.clear();
{
OHOS::HiviewDFX::HiAppEvent::EventConfig event1;
event1.domain = "api_diagnostic";
event1.name = "api_exec_end";
event1.isRealTime = false;
config.eventConfigs.push_back(event1);
}
{
OHOS::HiviewDFX::HiAppEvent::EventConfig event2;
event2.domain = "api_diagnostic";
event2.name = "api_called_stat";
event2.isRealTime = true;
config.eventConfigs.push_back(event2);
}
{
OHOS::HiviewDFX::HiAppEvent::EventConfig event3;
event3.domain = "api_diagnostic";
event3.name = "api_called_stat_cnt";
event3.isRealTime = true;
config.eventConfigs.push_back(event3);
}
processorId_ = HiviewDFX::HiAppEvent::AppEventProcessorMgr::AddProcessor(config);
#endif
}
void LocationHiAppEvent::WriteEndEvent(const int64_t beginTime, const int result, const int errCode,
const std::string& apiName)
{
#ifdef LOCATION_HIAPPEVENT_ENABLE
AddProcessor();
if (processorId_ == HA_NOT_SUPPORT_PROCESS_ID) {
LBSLOGI(LOCATION_HIAPPEVENT, "not support");
return;
}
HiviewDFX::HiAppEvent::Event event("api_diagnostic", "api_exec_end", OHOS::HiviewDFX::HiAppEvent::BEHAVIOR);
event.AddParam("trans_id", CommonUtils::GenerateUuid());
event.AddParam("api_name", apiName);
event.AddParam("sdk_name", std::string("LocationKit"));
event.AddParam("begin_time", beginTime);
event.AddParam("end_time", CommonUtils::GetCurrentTimeMilSec());
event.AddParam("result", result);
event.AddParam("error_code", errCode);
OHOS::HiviewDFX::HiAppEvent::Write(event);
LBSLOGD(LOCATION_HIAPPEVENT, "WriteEndEvent end, apiName:%{public}s", apiName.c_str());
#endif
}
void LocationHiAppEvent::CountEventTimeAndNum(const std::string apiName, const int64_t startTime, const int errCode)
{
#ifdef LOCATION_HIAPPEVENT_ENABLE
int64_t currentTimeMilSec = CommonUtils::GetCurrentTimeMilSec();
if (currentTimeMilSec - startTime < 0) {
return;
}
HaEventInfo eventInfo;
std::unique_lock<std::mutex> lock(haEventInfoMapMutex_);
auto it = haEventInfoMap_.find(apiName);
if (it != haEventInfoMap_.end()) {
eventInfo = it->second;
}
eventInfo.runTime.push_back(currentTimeMilSec - startTime);
eventInfo.sumTime += currentTimeMilSec - startTime;
if (eventInfo.beginTime == 0) {
eventInfo.beginTime = startTime;
}
if (errCode == 0) {
eventInfo.succCount++;
} else {
eventInfo.errCodes[errCode] = !eventInfo.errCodes[errCode] ? 1 : eventInfo.errCodes[errCode] + 1;
}
haEventInfoMap_[apiName] = eventInfo;
if (eventInfo.lastReportTime == 0 || currentTimeMilSec - eventInfo.lastReportTime >= HA_REPORT_INTERVAL) {
WriteCallStatusEvent(apiName, eventInfo);
eventInfo.lastReportTime = currentTimeMilSec;
std::vector<int64_t>().swap(eventInfo.runTime);
eventInfo.sumTime = 0;
eventInfo.succCount = 0;
std::vector<std::string>().swap(eventInfo.errCodeType);
std::vector<int64_t>().swap(eventInfo.errCodeNum);
std::map<int, int64_t>().swap(eventInfo.errCodes);
eventInfo.beginTime = 0;
haEventInfoMap_[apiName] = eventInfo;
}
#endif
}
void LocationHiAppEvent::WriteCallStatusEvent(const std::string apiName, HaEventInfo eventInfo)
{
#ifdef LOCATION_HIAPPEVENT_ENABLE
AddProcessor();
if (processorId_ == HA_NOT_SUPPORT_PROCESS_ID) {
LBSLOGI(LOCATION_HIAPPEVENT, "not support");
return;
}
for (auto it = eventInfo.errCodes.begin(); it != eventInfo.errCodes.end(); it++) {
eventInfo.errCodeType.push_back(std::to_string(it->first));
eventInfo.errCodeNum.push_back(it->second);
}
HiviewDFX::HiAppEvent::Event event("api_diagnostic", "api_called_stat", OHOS::HiviewDFX::HiAppEvent::BEHAVIOR);
event.AddParam("api_name", apiName);
event.AddParam("sdk_name", std::string("LocationKit"));
event.AddParam("begin_time", eventInfo.beginTime);
event.AddParam("call_times", static_cast<int32_t>(eventInfo.runTime.size()));
event.AddParam("success_times", eventInfo.succCount);
event.AddParam("max_cost_time", *max_element(eventInfo.runTime.begin(), eventInfo.runTime.end()));
event.AddParam("min_cost_time", *min_element(eventInfo.runTime.begin(), eventInfo.runTime.end()));
event.AddParam("total_cost_time", eventInfo.sumTime);
event.AddParam("error_code_types", eventInfo.errCodeType);
event.AddParam("error_code_num", eventInfo.errCodeNum);
OHOS::HiviewDFX::HiAppEvent::Write(event);
LBSLOGD(LOCATION_HIAPPEVENT, "WriteCallStatusEvent end, apiName:%{public}s, callTimes:%{public}zu",
apiName.c_str(), eventInfo.runTime.size());
#endif
}
}
}