/* * Copyright (c) 2022-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 "inputmethod_sysevent.h" #include #include "common_timer_errors.h" #include "hisysevent.h" namespace OHOS { namespace MiscServices { namespace { using HiSysEventNameSpace = OHOS::HiviewDFX::HiSysEvent; } // namespace const std::unordered_map InputMethodSysEvent::operateInfo_ = { { static_cast(OperateIMEInfoCode::IME_SHOW_ATTACH), "Attach: attach, bind and show soft keyboard." }, { static_cast(OperateIMEInfoCode::IME_SHOW_ENEDITABLE), "ShowTextInput: enter editable state, show soft " "keyboard." }, { static_cast(OperateIMEInfoCode::IME_SHOW_NORMAL), "ShowSoftKeyboard: show soft keyboard." }, { static_cast(OperateIMEInfoCode::IME_UNBIND), "Close: unbind." }, { static_cast(OperateIMEInfoCode::IME_HIDE_UNBIND), "Close: hide soft keyboard, and unbind." }, { static_cast(OperateIMEInfoCode::IME_HIDE_UNEDITABLE), "HideTextInput: hide soft keyboard, quit " "editable state." }, { static_cast(OperateIMEInfoCode::IME_HIDE_NORMAL), "HideSoftKeyboard, hide soft keyboard." }, { static_cast(OperateIMEInfoCode::IME_HIDE_UNFOCUSED), "OnUnfocused: unfocused, hide soft keyboard." }, { static_cast(OperateIMEInfoCode::IME_HIDE_SELF), "HideKeyboardSelf: hide soft keyboard self." } }; std::map InputMethodSysEvent::inputmethodBehaviour_ = { {static_cast(IMEBehaviour::START_IME), 0}, {static_cast(IMEBehaviour::CHANGE_IME), 0} }; InputMethodSysEvent::~InputMethodSysEvent() { StopTimer(); } InputMethodSysEvent &InputMethodSysEvent::GetInstance() { static InputMethodSysEvent instance; return instance; } void InputMethodSysEvent::ServiceFaultReporter(const std::string &componentName, int32_t errCode) { IMSA_HILOGD("start."); int32_t ret = HiSysEventWrite(HiSysEventNameSpace::Domain::INPUTMETHOD, "SERVICE_INIT_FAILED", HiSysEventNameSpace::EventType::FAULT, "USER_ID", userId_, "COMPONENT_ID", componentName, "ERROR_CODE", errCode); if (ret != HiviewDFX::SUCCESS) { IMSA_HILOGE("hisysevent ServiceFaultReporter failed! ret: %{public}d, errCode: %{public}d", ret, errCode); } } void InputMethodSysEvent::InputmethodFaultReporter(int32_t errCode, const std::string &name, const std::string &info) { IMSA_HILOGD("start."); int32_t ret = HiSysEventWrite(HiSysEventNameSpace::Domain::INPUTMETHOD, "UNAVAILABLE_INPUTMETHOD", HiSysEventNameSpace::EventType::FAULT, "USER_ID", userId_, "APP_NAME", name, "ERROR_CODE", errCode, "INFO", info); if (ret != HiviewDFX::SUCCESS) { IMSA_HILOGE("hisysevent InputmethodFaultReporter failed! ret: %{public}d,errCode %{public}d", ret, errCode); } } void InputMethodSysEvent::ImeUsageBehaviourReporter() { IMSA_HILOGD("start."); int ret = HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::INPUTMETHOD, "IME_USAGE", HiSysEventNameSpace::EventType::STATISTIC, "IME_START", inputmethodBehaviour_[static_cast(IMEBehaviour::START_IME)], "IME_CHANGE", inputmethodBehaviour_[static_cast(IMEBehaviour::CHANGE_IME)]); if (ret != HiviewDFX::SUCCESS) { IMSA_HILOGE("hisysevent BehaviourReporter failed! ret: %{public}d", ret); } { std::lock_guard lock(behaviourMutex_); inputmethodBehaviour_[static_cast(IMEBehaviour::START_IME)] = 0; inputmethodBehaviour_[static_cast(IMEBehaviour::CHANGE_IME)] = 0; } StartTimerForReport(); } void InputMethodSysEvent::RecordEvent(IMEBehaviour behaviour) { IMSA_HILOGD("run in."); std::lock_guard lock(behaviourMutex_); if (behaviour == IMEBehaviour::START_IME) { ++inputmethodBehaviour_[static_cast(IMEBehaviour::START_IME)]; } else if (behaviour == IMEBehaviour::CHANGE_IME) { ++inputmethodBehaviour_[static_cast(IMEBehaviour::CHANGE_IME)]; } } void InputMethodSysEvent::OperateSoftkeyboardBehaviour(OperateIMEInfoCode infoCode) { IMSA_HILOGD("run in."); int32_t ret = HiSysEventWrite(HiSysEventNameSpace::Domain::INPUTMETHOD, "OPERATE_SOFTKEYBOARD", HiSysEventNameSpace::EventType::BEHAVIOR, "OPERATING", GetOperateAction(static_cast(infoCode)), "OPERATE_INFO", GetOperateInfo(static_cast(infoCode))); if (ret != HiviewDFX::SUCCESS) { IMSA_HILOGE("Hisysevent: operate soft keyboard report failed! ret: %{public}d", ret); } } void InputMethodSysEvent::ReportImeState(ImeState state, pid_t pid, const std::string &bundleName) { IMSA_HILOGD("run in."); int32_t ret = HiSysEventWrite(HiSysEventNameSpace::Domain::INPUTMETHOD, "IME_STATE_CHANGED", HiSysEventNameSpace::EventType::BEHAVIOR, "STATE", static_cast(state), "PID", pid, "BUNDLE_NAME", bundleName); if (ret != HiviewDFX::SUCCESS) { IMSA_HILOGE("ime: %{public}s state: %{public}d report failed! ret: %{public}d", bundleName.c_str(), static_cast(state), ret); } } const std::string InputMethodSysEvent::GetOperateInfo(int32_t infoCode) { auto iter = operateInfo_.find(static_cast(infoCode)); if (iter != operateInfo_.end()) { return iter->second; } return "unknow operating."; } std::string InputMethodSysEvent::GetOperateAction(int32_t infoCode) { switch (infoCode) { case static_cast(OperateIMEInfoCode::IME_SHOW_ATTACH): case static_cast(OperateIMEInfoCode::IME_SHOW_ENEDITABLE): case static_cast(OperateIMEInfoCode::IME_SHOW_NORMAL): return "show"; case static_cast(OperateIMEInfoCode::IME_UNBIND): return "unbind"; case static_cast(OperateIMEInfoCode::IME_HIDE_UNBIND): return "hide and unbind"; case static_cast(OperateIMEInfoCode::IME_HIDE_UNEDITABLE): case static_cast(OperateIMEInfoCode::IME_HIDE_NORMAL): case static_cast(OperateIMEInfoCode::IME_HIDE_UNFOCUSED): case static_cast(OperateIMEInfoCode::IME_HIDE_SELF): return "hide"; default: break; } return "unknow action."; } void InputMethodSysEvent::SetUserId(int32_t userId) { userId_ = userId; } void InputMethodSysEvent::StopTimer() { IMSA_HILOGD("start."); std::lock_guard lock(timerLock_); if (timer_ == nullptr) { IMSA_HILOGE("timer_ is nullptr."); return; } timer_->Unregister(timerId_); timer_->Shutdown(); } bool InputMethodSysEvent::StartTimer(const TimerCallback &callback, uint32_t interval) { IMSA_HILOGD("start."); if (timer_ == nullptr) { timer_ = std::make_shared("OS_imfTimer"); uint32_t ret = timer_->Setup(); if (ret != Utils::TIMER_ERR_OK) { IMSA_HILOGE("create Timer error."); return false; } timerId_ = timer_->Register(callback, interval, true); } else { IMSA_HILOGD("timer_ is not nullptr, Update timer."); timer_->Unregister(timerId_); timerId_ = timer_->Register(callback, interval, false); } return true; } bool InputMethodSysEvent::StartTimerForReport() { IMSA_HILOGD("start."); auto reportCallback = [this]() { ImeUsageBehaviourReporter(); }; std::lock_guard lock(timerLock_); return StartTimer(reportCallback, ONE_DAY_IN_HOURS * ONE_HOUR_IN_SECONDS * SECONDS_TO_MILLISECONDS); } } // namespace MiscServices } // namespace OHOS