1/* 2 * Copyright (c) 2022-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "inputmethod_sysevent.h" 17 18#include <unistd.h> 19 20#include "common_timer_errors.h" 21#include "hisysevent.h" 22 23namespace OHOS { 24namespace MiscServices { 25namespace { 26using HiSysEventNameSpace = OHOS::HiviewDFX::HiSysEvent; 27} // namespace 28 29const std::unordered_map<int32_t, std::string> InputMethodSysEvent::operateInfo_ = { 30 { static_cast<int32_t>(OperateIMEInfoCode::IME_SHOW_ATTACH), "Attach: attach, bind and show soft keyboard." }, 31 { static_cast<int32_t>(OperateIMEInfoCode::IME_SHOW_ENEDITABLE), "ShowTextInput: enter editable state, show soft " 32 "keyboard." }, 33 { static_cast<int32_t>(OperateIMEInfoCode::IME_SHOW_NORMAL), "ShowSoftKeyboard: show soft keyboard." }, 34 { static_cast<int32_t>(OperateIMEInfoCode::IME_UNBIND), "Close: unbind." }, 35 { static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_UNBIND), "Close: hide soft keyboard, and unbind." }, 36 { static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_UNEDITABLE), "HideTextInput: hide soft keyboard, quit " 37 "editable state." }, 38 { static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_NORMAL), "HideSoftKeyboard, hide soft keyboard." }, 39 { static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_UNFOCUSED), "OnUnfocused: unfocused, hide soft keyboard." }, 40 { static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_SELF), "HideKeyboardSelf: hide soft keyboard self." }, 41 { static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_FORCE), "HidePanel: force hide soft keyboard." } 42}; 43 44std::map<int32_t, int32_t> InputMethodSysEvent::inputmethodBehaviour_ = { 45 { static_cast<int32_t>(IMEBehaviour::START_IME), 0 }, { static_cast<int32_t>(IMEBehaviour::CHANGE_IME), 0 } 46}; 47 48InputMethodSysEvent::~InputMethodSysEvent() 49{ 50 StopTimer(); 51} 52 53InputMethodSysEvent &InputMethodSysEvent::GetInstance() 54{ 55 static InputMethodSysEvent instance; 56 return instance; 57} 58 59void InputMethodSysEvent::ServiceFaultReporter(const std::string &componentName, int32_t errCode) 60{ 61 IMSA_HILOGD("start."); 62 int32_t ret = HiSysEventWrite(HiSysEventNameSpace::Domain::INPUTMETHOD, "SERVICE_INIT_FAILED", 63 HiSysEventNameSpace::EventType::FAULT, "USER_ID", userId_, "COMPONENT_ID", componentName, "ERROR_CODE", 64 errCode); 65 if (ret != HiviewDFX::SUCCESS) { 66 IMSA_HILOGE("hisysevent ServiceFaultReporter failed! ret: %{public}d, errCode: %{public}d", ret, errCode); 67 } 68} 69 70void InputMethodSysEvent::InputmethodFaultReporter(int32_t errCode, const std::string &name, const std::string &info) 71{ 72 IMSA_HILOGD("start."); 73 int32_t ret = HiSysEventWrite(HiSysEventNameSpace::Domain::INPUTMETHOD, "UNAVAILABLE_INPUTMETHOD", 74 HiSysEventNameSpace::EventType::FAULT, "USER_ID", userId_, "APP_NAME", name, "ERROR_CODE", errCode, "INFO", 75 info); 76 if (ret != HiviewDFX::SUCCESS) { 77 IMSA_HILOGE("hisysevent InputmethodFaultReporter failed! ret: %{public}d,errCode %{public}d", ret, errCode); 78 } 79} 80 81void InputMethodSysEvent::ImeUsageBehaviourReporter() 82{ 83 IMSA_HILOGD("start."); 84 int ret = HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::INPUTMETHOD, "IME_USAGE", 85 HiSysEventNameSpace::EventType::STATISTIC, "IME_START", 86 inputmethodBehaviour_[static_cast<int32_t>(IMEBehaviour::START_IME)], "IME_CHANGE", 87 inputmethodBehaviour_[static_cast<int32_t>(IMEBehaviour::CHANGE_IME)]); 88 if (ret != HiviewDFX::SUCCESS) { 89 IMSA_HILOGE("hisysevent BehaviourReporter failed! ret: %{public}d", ret); 90 } 91 { 92 std::lock_guard<std::mutex> lock(behaviourMutex_); 93 inputmethodBehaviour_[static_cast<int32_t>(IMEBehaviour::START_IME)] = 0; 94 inputmethodBehaviour_[static_cast<int32_t>(IMEBehaviour::CHANGE_IME)] = 0; 95 } 96 StartTimerForReport(); 97} 98 99void InputMethodSysEvent::RecordEvent(IMEBehaviour behaviour) 100{ 101 IMSA_HILOGD("run in."); 102 std::lock_guard<std::mutex> lock(behaviourMutex_); 103 if (behaviour == IMEBehaviour::START_IME) { 104 ++inputmethodBehaviour_[static_cast<int32_t>(IMEBehaviour::START_IME)]; 105 } else if (behaviour == IMEBehaviour::CHANGE_IME) { 106 ++inputmethodBehaviour_[static_cast<int32_t>(IMEBehaviour::CHANGE_IME)]; 107 } 108} 109 110void InputMethodSysEvent::OperateSoftkeyboardBehaviour(OperateIMEInfoCode infoCode) 111{ 112 IMSA_HILOGD("run in."); 113 int32_t ret = HiSysEventWrite(HiSysEventNameSpace::Domain::INPUTMETHOD, "OPERATE_SOFTKEYBOARD", 114 HiSysEventNameSpace::EventType::BEHAVIOR, "OPERATING", GetOperateAction(static_cast<int32_t>(infoCode)), 115 "OPERATE_INFO", GetOperateInfo(static_cast<int32_t>(infoCode))); 116 if (ret != HiviewDFX::SUCCESS) { 117 IMSA_HILOGE("Hisysevent: operate soft keyboard report failed! ret: %{public}d", ret); 118 } 119} 120 121void InputMethodSysEvent::ReportImeState(ImeState state, pid_t pid, const std::string &bundleName) 122{ 123 IMSA_HILOGD("run in."); 124 int32_t ret = HiSysEventWrite(HiSysEventNameSpace::Domain::INPUTMETHOD, "IME_STATE_CHANGED", 125 HiSysEventNameSpace::EventType::BEHAVIOR, "STATE", static_cast<int32_t>(state), "PID", pid, "BUNDLE_NAME", 126 bundleName); 127 if (ret != HiviewDFX::SUCCESS) { 128 IMSA_HILOGE("ime: %{public}s state: %{public}d report failed! ret: %{public}d", bundleName.c_str(), 129 static_cast<int32_t>(state), ret); 130 } 131} 132 133const std::string InputMethodSysEvent::GetOperateInfo(int32_t infoCode) 134{ 135 auto iter = operateInfo_.find(static_cast<int32_t>(infoCode)); 136 if (iter != operateInfo_.end()) { 137 return iter->second; 138 } 139 return "unknow operating."; 140} 141 142std::string InputMethodSysEvent::GetOperateAction(int32_t infoCode) 143{ 144 switch (infoCode) { 145 case static_cast<int32_t>(OperateIMEInfoCode::IME_SHOW_ATTACH): 146 case static_cast<int32_t>(OperateIMEInfoCode::IME_SHOW_ENEDITABLE): 147 case static_cast<int32_t>(OperateIMEInfoCode::IME_SHOW_NORMAL): 148 return "show"; 149 case static_cast<int32_t>(OperateIMEInfoCode::IME_UNBIND): 150 return "unbind"; 151 case static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_UNBIND): 152 return "hide and unbind"; 153 case static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_UNEDITABLE): 154 case static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_NORMAL): 155 case static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_UNFOCUSED): 156 case static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_SELF): 157 case static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_FORCE): 158 return "hide"; 159 default: 160 break; 161 } 162 return "unknow action."; 163} 164 165void InputMethodSysEvent::SetUserId(int32_t userId) 166{ 167 userId_ = userId; 168} 169 170void InputMethodSysEvent::StopTimer() 171{ 172 IMSA_HILOGD("start."); 173 std::lock_guard<std::mutex> lock(timerLock_); 174 if (timer_ == nullptr) { 175 IMSA_HILOGE("timer_ is nullptr."); 176 return; 177 } 178 timer_->Unregister(timerId_); 179 timer_->Shutdown(); 180} 181 182bool InputMethodSysEvent::StartTimer(const TimerCallback &callback, uint32_t interval) 183{ 184 IMSA_HILOGD("start."); 185 if (timer_ == nullptr) { 186 timer_ = std::make_shared<Utils::Timer>("OS_imfTimer"); 187 uint32_t ret = timer_->Setup(); 188 if (ret != Utils::TIMER_ERR_OK) { 189 IMSA_HILOGE("create Timer error."); 190 return false; 191 } 192 timerId_ = timer_->Register(callback, interval, true); 193 } else { 194 IMSA_HILOGD("timer_ is not nullptr, Update timer."); 195 timer_->Unregister(timerId_); 196 timerId_ = timer_->Register(callback, interval, false); 197 } 198 return true; 199} 200 201bool InputMethodSysEvent::StartTimerForReport() 202{ 203 IMSA_HILOGD("start."); 204 auto reportCallback = [this]() { ImeUsageBehaviourReporter(); }; 205 std::lock_guard<std::mutex> lock(timerLock_); 206 return StartTimer(reportCallback, ONE_DAY_IN_HOURS * ONE_HOUR_IN_SECONDS * SECONDS_TO_MILLISECONDS); 207} 208} // namespace MiscServices 209} // namespace OHOS