* 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 "imf_hisysevent_util.h"
#include <algorithm>
#include <map>
#include "accesstoken_kit.h"
#include "app_mgr_client.h"
#include "hisysevent.h"
#include "ipc_skeleton.h"
#include "running_process_info.h"
#include "singleton.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
const std::map<int32_t, int32_t> ImfHiSysEventUtil::HIDUMPER_ERROR_CODE_MAP = {
{ EXCEPTION_PERMISSION, PERMISSION_CHECK_FAILED },
{ EXCEPTION_SYSTEM_PERMISSION, NOT_SYSTEM_APPLICATION },
{ EXCEPTION_CONFPERSIST, CONFIG_PERSISTENCE_ERROR },
{ EXCEPTION_IMMS, IME_MANAGER_SERVICE_ERROR },
{ EXCEPTION_USER_NOT_EXIST, USER_NOT_EXIST },
{ EXCEPTION_USER_NOT_IN_FOREGROUND, USER_NOT_FOREGROUND },
{ EXCEPTION_CROSS_USER_OPERATION_DENIED, CROSS_USER_OPERATION_DENIED },
};
using namespace OHOS::AppExecFwk;
using HiSysEvent = OHOS::HiviewDFX::HiSysEvent;
using namespace Security::AccessToken;
void ImfHiSysEventUtil::ReportClientAttachFault(
const std::string &selfName, int64_t faultNum, const HiSysOriginalInfo &info)
{
IMSA_HILOGD("run in.");
auto ret = HiSysEventWrite(HiSysEvent::Domain::INPUTMETHOD, "CLIENT_ATTACH_FAILED", HiSysEvent::EventType::FAULT,
"SELF_NAME", selfName, "PEER_NAME", info.peerName, "PEER_PID", info.peerPid, "PEER_USERID", info.peerUserId,
"CLIENT_TYPE", info.clientType, "INPUT_PATTERN", info.inputPattern, "ISSHOWKEYBOARD", info.isShowKeyboard,
"IME_NAME", info.imeName, "ERR_CODE", info.errCode, "FAULT_COUNT", faultNum);
if (ret != HiviewDFX::SUCCESS) {
IMSA_HILOGE("report failed! ret: %{public}d.", ret);
}
}
void ImfHiSysEventUtil::ReportClientShowFault(
const std::string &selfName, int64_t faultNum, const HiSysOriginalInfo &info)
{
IMSA_HILOGD("run in.");
auto ret = HiSysEventWrite(HiSysEvent::Domain::INPUTMETHOD, "CLIENT_SHOW_FAILED", HiSysEvent::EventType::FAULT,
"SELF_NAME", selfName, "PEER_NAME", info.peerName, "PEER_PID", info.peerPid, "PEER_USERID", info.peerUserId,
"CLIENT_TYPE", info.clientType, "INPUT_PATTERN", info.inputPattern, "IME_NAME", info.imeName, "EVENT_CODE",
info.eventCode, "ERR_CODE", info.errCode, "FAULT_COUNT", faultNum);
if (ret != HiviewDFX::SUCCESS) {
IMSA_HILOGE("report failed! ret: %{public}d.", ret);
}
}
void ImfHiSysEventUtil::ReportImeStartInputFault(
const std::string &selfName, int64_t faultNum, const HiSysOriginalInfo &info)
{
IMSA_HILOGD("run in.");
auto ret = HiSysEventWrite(HiSysEvent::Domain::INPUTMETHOD, "IME_START_INPUT_FAILED", HiSysEvent::EventType::FAULT,
"SELF_NAME", selfName, "PEER_NAME", info.peerName, "PEER_PID", info.peerPid, "ISSHOWKEYBOARD",
info.isShowKeyboard, "EVENT_CODE", info.eventCode, "ERR_CODE", info.errCode, "FAULT_COUNT", faultNum);
if (ret != HiviewDFX::SUCCESS) {
IMSA_HILOGE("report failed! ret: %{public}d.", ret);
}
}
void ImfHiSysEventUtil::ReportBaseTextOperationFault(
const std::string &selfName, int64_t faultNum, const HiSysOriginalInfo &info)
{
IMSA_HILOGD("run in.");
auto ret = HiSysEventWrite(HiSysEvent::Domain::INPUTMETHOD, "BASE_TEXT_OPERATION_FAILED",
HiSysEvent::EventType::FAULT, "SELF_NAME", selfName, "PEER_NAME", info.peerName, "PEER_PID", info.peerPid,
"CLIENT_TYPE", info.clientType, "EVENT_CODE", info.eventCode, "ERR_CODE", info.errCode, "FAULT_COUNT",
faultNum);
if (ret != HiviewDFX::SUCCESS) {
IMSA_HILOGE("report failed! ret: %{public}d.", ret);
}
}
void ImfHiSysEventUtil::ReportStatisticsEvent(const std::string &eventName, const std::vector<std::string> &imeNames,
const std::vector<std::string> &appNames, const std::vector<std::string> &statistics)
{
std::string infoStr;
if (!statistics.empty()) {
infoStr = statistics[0];
}
IMSA_HILOGD("run in, [%{public}s, %{public}s].", eventName.c_str(), infoStr.c_str());
auto ret = HiSysEventWrite(HiSysEvent::Domain::INPUTMETHOD, eventName, HiSysEvent::EventType::STATISTIC,
"IME_NAME", imeNames, "APP_NAME", appNames, "INFOS", statistics);
if (ret != HiviewDFX::SUCCESS) {
IMSA_HILOGE("report failed! ret: %{public}d.", ret);
}
}
void ImfHiSysEventUtil::ReportStatisticsEvent(const std::string &eventName, const std::string &imeName,
const std::vector<std::string> &appNames, const std::vector<std::string> &statistics)
{
std::string infoStr;
if (!statistics.empty()) {
infoStr = statistics[0];
}
IMSA_HILOGD("run in, [%{public}s, %{public}s].", eventName.c_str(), infoStr.c_str());
auto ret = HiSysEventWrite(HiSysEvent::Domain::INPUTMETHOD, eventName, HiSysEvent::EventType::STATISTIC,
"SELF_NAME", imeName, "APP_NAME", appNames, "INFOS", statistics);
if (ret != HiviewDFX::SUCCESS) {
IMSA_HILOGE("report failed! ret: %{public}d.", ret);
}
}
std::string ImfHiSysEventUtil::GetAppName(uint64_t fullTokenId)
{
std::string name;
uint32_t tokenId = static_cast<uint32_t>(fullTokenId);
auto tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
switch (tokenType) {
case ATokenTypeEnum::TOKEN_HAP: {
if (fullTokenId == IPCSkeleton::GetSelfTokenID()) {
RunningProcessInfo info;
auto appMgrClient = DelayedSingleton<AppMgrClient>::GetInstance();
if (appMgrClient != nullptr && appMgrClient->GetProcessRunningInformation(info) == 0) {
name = info.processName_;
}
break;
}
HapTokenInfo hapInfo;
if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) == 0) {
name = hapInfo.bundleName;
}
break;
}
case ATokenTypeEnum::TOKEN_NATIVE:
case ATokenTypeEnum::TOKEN_SHELL: {
NativeTokenInfo tokenInfo;
if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) == 0) {
name = tokenInfo.processName;
}
break;
}
default: {
break;
}
}
return name;
}
std::string ImfHiSysEventUtil::AddIfAbsent(const std::string &bundleName, std::vector<std::string> &bundleNames)
{
auto it = std::find_if(bundleNames.begin(), bundleNames.end(),
[&bundleName](const std::string &bundleNameTmp) { return bundleName == bundleNameTmp; });
if (it == bundleNames.end()) {
bundleNames.push_back(bundleName);
return std::to_string(bundleNames.size() - 1);
}
return std::to_string(it - bundleNames.begin());
}
int32_t ImfHiSysEventUtil::HidumperConvertErrorCode(int32_t code)
{
IMSA_HILOGD("HidumperConvert start.");
auto iter = HIDUMPER_ERROR_CODE_MAP.find(code);
if (iter != HIDUMPER_ERROR_CODE_MAP.end()) {
IMSA_HILOGD("ErrorCode: %{public}d", iter->second);
return iter->second;
}
IMSA_HILOGD("HidumperConvert fail.");
return code;
}
int32_t ImfHiSysEventUtil::ConvertErrorCode(int32_t code)
{
IMSA_HILOGD("HidumperConvert start.");
auto iter = ERROR_CODE_MAP.find(code);
if (iter != ERROR_CODE_MAP.end()) {
IMSA_HILOGD("ErrorCode: %{public}d", iter->second);
return HidumperConvertErrorCode(iter->second);
}
IMSA_HILOGD("HidumperConvert fail.");
return code;
}
}
}