122736c2fSopenharmony_ci/*
222736c2fSopenharmony_ci * Copyright (c) 2022-2022 Huawei Device Co., Ltd.
322736c2fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
422736c2fSopenharmony_ci * you may not use this file except in compliance with the License.
522736c2fSopenharmony_ci * You may obtain a copy of the License at
622736c2fSopenharmony_ci *
722736c2fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
822736c2fSopenharmony_ci *
922736c2fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1022736c2fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1122736c2fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1222736c2fSopenharmony_ci * See the License for the specific language governing permissions and
1322736c2fSopenharmony_ci * limitations under the License.
1422736c2fSopenharmony_ci */
1522736c2fSopenharmony_ci
1622736c2fSopenharmony_ci#include "inputmethod_sysevent.h"
1722736c2fSopenharmony_ci
1822736c2fSopenharmony_ci#include <unistd.h>
1922736c2fSopenharmony_ci
2022736c2fSopenharmony_ci#include "common_timer_errors.h"
2122736c2fSopenharmony_ci#include "hisysevent.h"
2222736c2fSopenharmony_ci
2322736c2fSopenharmony_cinamespace OHOS {
2422736c2fSopenharmony_cinamespace MiscServices {
2522736c2fSopenharmony_cinamespace {
2622736c2fSopenharmony_ciusing HiSysEventNameSpace = OHOS::HiviewDFX::HiSysEvent;
2722736c2fSopenharmony_ci} // namespace
2822736c2fSopenharmony_ci
2922736c2fSopenharmony_ciconst std::unordered_map<int32_t, std::string> InputMethodSysEvent::operateInfo_ = {
3022736c2fSopenharmony_ci    { static_cast<int32_t>(OperateIMEInfoCode::IME_SHOW_ATTACH), "Attach: attach, bind and show soft keyboard." },
3122736c2fSopenharmony_ci    { static_cast<int32_t>(OperateIMEInfoCode::IME_SHOW_ENEDITABLE), "ShowTextInput: enter editable state, show soft "
3222736c2fSopenharmony_ci                                                                     "keyboard." },
3322736c2fSopenharmony_ci    { static_cast<int32_t>(OperateIMEInfoCode::IME_SHOW_NORMAL), "ShowSoftKeyboard: show soft keyboard." },
3422736c2fSopenharmony_ci    { static_cast<int32_t>(OperateIMEInfoCode::IME_UNBIND), "Close: unbind." },
3522736c2fSopenharmony_ci    { static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_UNBIND), "Close: hide soft keyboard, and unbind." },
3622736c2fSopenharmony_ci    { static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_UNEDITABLE), "HideTextInput: hide soft keyboard, quit "
3722736c2fSopenharmony_ci                                                                     "editable state." },
3822736c2fSopenharmony_ci    { static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_NORMAL), "HideSoftKeyboard, hide soft keyboard." },
3922736c2fSopenharmony_ci    { static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_UNFOCUSED), "OnUnfocused: unfocused, hide soft keyboard." },
4022736c2fSopenharmony_ci    { static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_SELF), "HideKeyboardSelf: hide soft keyboard self." },
4122736c2fSopenharmony_ci    { static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_FORCE), "HidePanel: force hide soft keyboard." }
4222736c2fSopenharmony_ci};
4322736c2fSopenharmony_ci
4422736c2fSopenharmony_cistd::map<int32_t, int32_t> InputMethodSysEvent::inputmethodBehaviour_ = {
4522736c2fSopenharmony_ci    { static_cast<int32_t>(IMEBehaviour::START_IME), 0 }, { static_cast<int32_t>(IMEBehaviour::CHANGE_IME), 0 }
4622736c2fSopenharmony_ci};
4722736c2fSopenharmony_ci
4822736c2fSopenharmony_ciInputMethodSysEvent::~InputMethodSysEvent()
4922736c2fSopenharmony_ci{
5022736c2fSopenharmony_ci    StopTimer();
5122736c2fSopenharmony_ci}
5222736c2fSopenharmony_ci
5322736c2fSopenharmony_ciInputMethodSysEvent &InputMethodSysEvent::GetInstance()
5422736c2fSopenharmony_ci{
5522736c2fSopenharmony_ci    static InputMethodSysEvent instance;
5622736c2fSopenharmony_ci    return instance;
5722736c2fSopenharmony_ci}
5822736c2fSopenharmony_ci
5922736c2fSopenharmony_civoid InputMethodSysEvent::ServiceFaultReporter(const std::string &componentName, int32_t errCode)
6022736c2fSopenharmony_ci{
6122736c2fSopenharmony_ci    IMSA_HILOGD("start.");
6222736c2fSopenharmony_ci    int32_t ret = HiSysEventWrite(HiSysEventNameSpace::Domain::INPUTMETHOD, "SERVICE_INIT_FAILED",
6322736c2fSopenharmony_ci        HiSysEventNameSpace::EventType::FAULT, "USER_ID", userId_, "COMPONENT_ID", componentName, "ERROR_CODE",
6422736c2fSopenharmony_ci        errCode);
6522736c2fSopenharmony_ci    if (ret != HiviewDFX::SUCCESS) {
6622736c2fSopenharmony_ci        IMSA_HILOGE("hisysevent ServiceFaultReporter failed! ret: %{public}d, errCode: %{public}d", ret, errCode);
6722736c2fSopenharmony_ci    }
6822736c2fSopenharmony_ci}
6922736c2fSopenharmony_ci
7022736c2fSopenharmony_civoid InputMethodSysEvent::InputmethodFaultReporter(int32_t errCode, const std::string &name, const std::string &info)
7122736c2fSopenharmony_ci{
7222736c2fSopenharmony_ci    IMSA_HILOGD("start.");
7322736c2fSopenharmony_ci    int32_t ret = HiSysEventWrite(HiSysEventNameSpace::Domain::INPUTMETHOD, "UNAVAILABLE_INPUTMETHOD",
7422736c2fSopenharmony_ci        HiSysEventNameSpace::EventType::FAULT, "USER_ID", userId_, "APP_NAME", name, "ERROR_CODE", errCode, "INFO",
7522736c2fSopenharmony_ci        info);
7622736c2fSopenharmony_ci    if (ret != HiviewDFX::SUCCESS) {
7722736c2fSopenharmony_ci        IMSA_HILOGE("hisysevent InputmethodFaultReporter failed! ret: %{public}d,errCode %{public}d", ret, errCode);
7822736c2fSopenharmony_ci    }
7922736c2fSopenharmony_ci}
8022736c2fSopenharmony_ci
8122736c2fSopenharmony_civoid InputMethodSysEvent::ImeUsageBehaviourReporter()
8222736c2fSopenharmony_ci{
8322736c2fSopenharmony_ci    IMSA_HILOGD("start.");
8422736c2fSopenharmony_ci    int ret = HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::INPUTMETHOD, "IME_USAGE",
8522736c2fSopenharmony_ci        HiSysEventNameSpace::EventType::STATISTIC, "IME_START",
8622736c2fSopenharmony_ci        inputmethodBehaviour_[static_cast<int32_t>(IMEBehaviour::START_IME)], "IME_CHANGE",
8722736c2fSopenharmony_ci        inputmethodBehaviour_[static_cast<int32_t>(IMEBehaviour::CHANGE_IME)]);
8822736c2fSopenharmony_ci    if (ret != HiviewDFX::SUCCESS) {
8922736c2fSopenharmony_ci        IMSA_HILOGE("hisysevent BehaviourReporter failed! ret: %{public}d", ret);
9022736c2fSopenharmony_ci    }
9122736c2fSopenharmony_ci    {
9222736c2fSopenharmony_ci        std::lock_guard<std::mutex> lock(behaviourMutex_);
9322736c2fSopenharmony_ci        inputmethodBehaviour_[static_cast<int32_t>(IMEBehaviour::START_IME)] = 0;
9422736c2fSopenharmony_ci        inputmethodBehaviour_[static_cast<int32_t>(IMEBehaviour::CHANGE_IME)] = 0;
9522736c2fSopenharmony_ci    }
9622736c2fSopenharmony_ci    StartTimerForReport();
9722736c2fSopenharmony_ci}
9822736c2fSopenharmony_ci
9922736c2fSopenharmony_civoid InputMethodSysEvent::RecordEvent(IMEBehaviour behaviour)
10022736c2fSopenharmony_ci{
10122736c2fSopenharmony_ci    IMSA_HILOGD("run in.");
10222736c2fSopenharmony_ci    std::lock_guard<std::mutex> lock(behaviourMutex_);
10322736c2fSopenharmony_ci    if (behaviour == IMEBehaviour::START_IME) {
10422736c2fSopenharmony_ci        ++inputmethodBehaviour_[static_cast<int32_t>(IMEBehaviour::START_IME)];
10522736c2fSopenharmony_ci    } else if (behaviour == IMEBehaviour::CHANGE_IME) {
10622736c2fSopenharmony_ci        ++inputmethodBehaviour_[static_cast<int32_t>(IMEBehaviour::CHANGE_IME)];
10722736c2fSopenharmony_ci    }
10822736c2fSopenharmony_ci}
10922736c2fSopenharmony_ci
11022736c2fSopenharmony_civoid InputMethodSysEvent::OperateSoftkeyboardBehaviour(OperateIMEInfoCode infoCode)
11122736c2fSopenharmony_ci{
11222736c2fSopenharmony_ci    IMSA_HILOGD("run in.");
11322736c2fSopenharmony_ci    int32_t ret = HiSysEventWrite(HiSysEventNameSpace::Domain::INPUTMETHOD, "OPERATE_SOFTKEYBOARD",
11422736c2fSopenharmony_ci        HiSysEventNameSpace::EventType::BEHAVIOR, "OPERATING", GetOperateAction(static_cast<int32_t>(infoCode)),
11522736c2fSopenharmony_ci        "OPERATE_INFO", GetOperateInfo(static_cast<int32_t>(infoCode)));
11622736c2fSopenharmony_ci    if (ret != HiviewDFX::SUCCESS) {
11722736c2fSopenharmony_ci        IMSA_HILOGE("Hisysevent: operate soft keyboard report failed! ret: %{public}d", ret);
11822736c2fSopenharmony_ci    }
11922736c2fSopenharmony_ci}
12022736c2fSopenharmony_ci
12122736c2fSopenharmony_civoid InputMethodSysEvent::ReportImeState(ImeState state, pid_t pid, const std::string &bundleName)
12222736c2fSopenharmony_ci{
12322736c2fSopenharmony_ci    IMSA_HILOGD("run in.");
12422736c2fSopenharmony_ci    int32_t ret = HiSysEventWrite(HiSysEventNameSpace::Domain::INPUTMETHOD, "IME_STATE_CHANGED",
12522736c2fSopenharmony_ci        HiSysEventNameSpace::EventType::BEHAVIOR, "STATE", static_cast<int32_t>(state), "PID", pid, "BUNDLE_NAME",
12622736c2fSopenharmony_ci        bundleName);
12722736c2fSopenharmony_ci    if (ret != HiviewDFX::SUCCESS) {
12822736c2fSopenharmony_ci        IMSA_HILOGE("ime: %{public}s state: %{public}d report failed! ret: %{public}d", bundleName.c_str(),
12922736c2fSopenharmony_ci            static_cast<int32_t>(state), ret);
13022736c2fSopenharmony_ci    }
13122736c2fSopenharmony_ci}
13222736c2fSopenharmony_ci
13322736c2fSopenharmony_ciconst std::string InputMethodSysEvent::GetOperateInfo(int32_t infoCode)
13422736c2fSopenharmony_ci{
13522736c2fSopenharmony_ci    auto iter = operateInfo_.find(static_cast<int32_t>(infoCode));
13622736c2fSopenharmony_ci    if (iter != operateInfo_.end()) {
13722736c2fSopenharmony_ci        return iter->second;
13822736c2fSopenharmony_ci    }
13922736c2fSopenharmony_ci    return "unknow operating.";
14022736c2fSopenharmony_ci}
14122736c2fSopenharmony_ci
14222736c2fSopenharmony_cistd::string InputMethodSysEvent::GetOperateAction(int32_t infoCode)
14322736c2fSopenharmony_ci{
14422736c2fSopenharmony_ci    switch (infoCode) {
14522736c2fSopenharmony_ci        case static_cast<int32_t>(OperateIMEInfoCode::IME_SHOW_ATTACH):
14622736c2fSopenharmony_ci        case static_cast<int32_t>(OperateIMEInfoCode::IME_SHOW_ENEDITABLE):
14722736c2fSopenharmony_ci        case static_cast<int32_t>(OperateIMEInfoCode::IME_SHOW_NORMAL):
14822736c2fSopenharmony_ci            return "show";
14922736c2fSopenharmony_ci        case static_cast<int32_t>(OperateIMEInfoCode::IME_UNBIND):
15022736c2fSopenharmony_ci            return "unbind";
15122736c2fSopenharmony_ci        case static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_UNBIND):
15222736c2fSopenharmony_ci            return "hide and unbind";
15322736c2fSopenharmony_ci        case static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_UNEDITABLE):
15422736c2fSopenharmony_ci        case static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_NORMAL):
15522736c2fSopenharmony_ci        case static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_UNFOCUSED):
15622736c2fSopenharmony_ci        case static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_SELF):
15722736c2fSopenharmony_ci        case static_cast<int32_t>(OperateIMEInfoCode::IME_HIDE_FORCE):
15822736c2fSopenharmony_ci            return "hide";
15922736c2fSopenharmony_ci        default:
16022736c2fSopenharmony_ci            break;
16122736c2fSopenharmony_ci    }
16222736c2fSopenharmony_ci    return "unknow action.";
16322736c2fSopenharmony_ci}
16422736c2fSopenharmony_ci
16522736c2fSopenharmony_civoid InputMethodSysEvent::SetUserId(int32_t userId)
16622736c2fSopenharmony_ci{
16722736c2fSopenharmony_ci    userId_ = userId;
16822736c2fSopenharmony_ci}
16922736c2fSopenharmony_ci
17022736c2fSopenharmony_civoid InputMethodSysEvent::StopTimer()
17122736c2fSopenharmony_ci{
17222736c2fSopenharmony_ci    IMSA_HILOGD("start.");
17322736c2fSopenharmony_ci    std::lock_guard<std::mutex> lock(timerLock_);
17422736c2fSopenharmony_ci    if (timer_ == nullptr) {
17522736c2fSopenharmony_ci        IMSA_HILOGE("timer_ is nullptr.");
17622736c2fSopenharmony_ci        return;
17722736c2fSopenharmony_ci    }
17822736c2fSopenharmony_ci    timer_->Unregister(timerId_);
17922736c2fSopenharmony_ci    timer_->Shutdown();
18022736c2fSopenharmony_ci}
18122736c2fSopenharmony_ci
18222736c2fSopenharmony_cibool InputMethodSysEvent::StartTimer(const TimerCallback &callback, uint32_t interval)
18322736c2fSopenharmony_ci{
18422736c2fSopenharmony_ci    IMSA_HILOGD("start.");
18522736c2fSopenharmony_ci    if (timer_ == nullptr) {
18622736c2fSopenharmony_ci        timer_ = std::make_shared<Utils::Timer>("OS_imfTimer");
18722736c2fSopenharmony_ci        uint32_t ret = timer_->Setup();
18822736c2fSopenharmony_ci        if (ret != Utils::TIMER_ERR_OK) {
18922736c2fSopenharmony_ci            IMSA_HILOGE("create Timer error.");
19022736c2fSopenharmony_ci            return false;
19122736c2fSopenharmony_ci        }
19222736c2fSopenharmony_ci        timerId_ = timer_->Register(callback, interval, true);
19322736c2fSopenharmony_ci    } else {
19422736c2fSopenharmony_ci        IMSA_HILOGD("timer_ is not nullptr, Update timer.");
19522736c2fSopenharmony_ci        timer_->Unregister(timerId_);
19622736c2fSopenharmony_ci        timerId_ = timer_->Register(callback, interval, false);
19722736c2fSopenharmony_ci    }
19822736c2fSopenharmony_ci    return true;
19922736c2fSopenharmony_ci}
20022736c2fSopenharmony_ci
20122736c2fSopenharmony_cibool InputMethodSysEvent::StartTimerForReport()
20222736c2fSopenharmony_ci{
20322736c2fSopenharmony_ci    IMSA_HILOGD("start.");
20422736c2fSopenharmony_ci    auto reportCallback = [this]() { ImeUsageBehaviourReporter(); };
20522736c2fSopenharmony_ci    std::lock_guard<std::mutex> lock(timerLock_);
20622736c2fSopenharmony_ci    return StartTimer(reportCallback, ONE_DAY_IN_HOURS * ONE_HOUR_IN_SECONDS * SECONDS_TO_MILLISECONDS);
20722736c2fSopenharmony_ci}
20822736c2fSopenharmony_ci} // namespace MiscServices
20922736c2fSopenharmony_ci} // namespace OHOS