1/*
2 * Copyright (c) 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 "callback_manager.h"
17
18#include <algorithm>
19#include "event_listener.h"
20#include "event_manager.h"
21#include "page/page_manager.h"
22
23namespace Updater {
24constexpr auto CB_FIELD = "callbacks";
25
26std::vector<CallbackCfg> CallbackManager::callbackCfgs_;
27
28std::unordered_map<std::string, EventType> CallbackManager::evtTypes_ = {
29    {"TOUCHEVENT", EventType::TOUCHEVENT},
30    {"CLICKEVENT", EventType::CLICKEVENT}
31};
32
33bool CallbackManager::LoadCallbacks(const JsonNode &node)
34{
35    const JsonNode &cbNodes = node[CB_FIELD];
36    if (cbNodes.Type() != NodeType::ARRAY) {
37        LOG(ERROR) << "callback config node type should be array";
38        return false;
39    }
40    CallbackCfg cbCfg;
41    for (const auto &cbNode : cbNodes) {
42        cbCfg = {};
43        if (!Visit<SETVAL>(cbNode.get(), cbCfg)) {
44            LOG(ERROR) << "callback config parse failed";
45            return false;
46        }
47        callbackCfgs_.push_back(std::move(cbCfg));
48    }
49    return true;
50}
51
52bool CallbackManager::RegisterFunc(const std::string &name, Callback cb)
53{
54    if (!GetFuncs().insert({name, cb}).second) {
55        LOG(ERROR) << "register fun failed for " << name;
56        return false;
57    }
58    return true;
59}
60
61std::unordered_map<std::string, Callback> &CallbackManager::GetFuncs()
62{
63    static std::unordered_map<std::string, Callback> funcs;
64    return funcs;
65}
66
67void CallbackManager::Register(const CallbackCfg &cbCfg)
68{
69    auto it = evtTypes_.find(cbCfg.type);
70    if (it == evtTypes_.end()) {
71        LOG(ERROR) << "not recognized event type: " << cbCfg.type;
72        return;
73    }
74    auto &funcs = GetFuncs();
75    auto itFunc = funcs.find(cbCfg.func);
76    if (itFunc == funcs.end()) {
77        LOG(ERROR) << "not recognized event type: " << cbCfg.func;
78        return;
79    }
80    EventManager::GetInstance().Add(ComInfo {cbCfg.pageId, cbCfg.comId}, it->second, itFunc->second);
81    LOG(DEBUG) << "register " << cbCfg.func << " for " << ComInfo {cbCfg.pageId, cbCfg.comId} << " succeed";
82}
83
84void CallbackManager::Init(bool hasFocus)
85{
86    [[maybe_unused]] static bool isInited = [hasFocus] () {
87        for (auto &cb : callbackCfgs_) {
88            Register(cb);
89        }
90
91        if (hasFocus) {
92            // for focus manager
93            EventManager::GetInstance().AddKeyListener();
94        }
95
96        // for long press warning
97        LOG(DEBUG) << "register key action listerner succeed";
98        return true;
99    } ();
100}
101}