1/*
2 * Copyright (c) 2022-2024 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 "dinput_context.h"
17
18#include "constants.h"
19
20#include "dinput_errcode.h"
21#include "dinput_utils_tool.h"
22
23namespace OHOS {
24namespace DistributedHardware {
25namespace DistributedInput {
26IMPLEMENT_SINGLE_INSTANCE(DInputContext);
27
28DInputContext::~DInputContext()
29{
30    sinkScreenInfoMap_.clear();
31    srcScreenInfoMap_.clear();
32}
33
34std::string DInputContext::GetScreenInfoKey(const std::string &devId, const uint64_t sourceWinId)
35{
36    DHLOGI("GetScreenInfoKey screenInfoKey: %{public}s, sourceWinId: %{public}" PRIu64 "",
37        GetAnonyString(devId).c_str(), sourceWinId);
38    return devId + RESOURCE_SEPARATOR + std::to_string(sourceWinId);
39}
40
41int32_t DInputContext::RemoveSinkScreenInfo(const std::string &screenInfoKey)
42{
43    DHLOGI("RemoveSinkScreenInfo screenInfoKey: %{public}s", GetAnonyString(screenInfoKey).c_str());
44    std::lock_guard<std::mutex> lock(sinkMapMutex_);
45    sinkScreenInfoMap_.erase(screenInfoKey);
46    return DH_SUCCESS;
47}
48
49int32_t DInputContext::UpdateSinkScreenInfo(const std::string &screenInfoKey, const SinkScreenInfo &sinkScreenInfo)
50{
51    DHLOGI("UpdateSinkScreenInfo screenInfoKey: %{public}s", GetAnonyString(screenInfoKey).c_str());
52    std::lock_guard<std::mutex> lock(sinkMapMutex_);
53    if (sinkScreenInfoMap_.count(screenInfoKey) <= 0) {
54        DHLOGE("source window id not exist");
55        return ERR_DH_INPUT_CONTEXT_KEY_NOT_EXIST;
56    }
57
58    SinkScreenInfo tmp = sinkScreenInfo;
59    if (CalculateTransformInfo(tmp) != DH_SUCCESS) {
60        DHLOGE("calculate transform infomation failed");
61    }
62
63    sinkScreenInfoMap_[screenInfoKey] = tmp;
64    return DH_SUCCESS;
65}
66
67SinkScreenInfo DInputContext::GetSinkScreenInfo(const std::string &screenInfoKey)
68{
69    DHLOGI("GetSinkScreenInfo screenInfoKey: %{public}s", GetAnonyString(screenInfoKey).c_str());
70    std::lock_guard<std::mutex> lock(sinkMapMutex_);
71    if (sinkScreenInfoMap_.count(screenInfoKey) <= 0) {
72        DHLOGE("screenInfoKey not exist");
73        SinkScreenInfo sinkScreenInfo;
74        sinkScreenInfoMap_[screenInfoKey] = sinkScreenInfo;
75    }
76
77    return sinkScreenInfoMap_[screenInfoKey];
78}
79
80const std::unordered_map<std::string, SinkScreenInfo> &DInputContext::GetAllSinkScreenInfo()
81{
82    std::lock_guard<std::mutex> lock(sinkMapMutex_);
83    return sinkScreenInfoMap_;
84}
85
86int32_t DInputContext::RemoveSrcScreenInfo(const std::string &screenInfoKey)
87{
88    DHLOGI("RemoveSrcScreenInfo screenInfoKey: %{public}s", GetAnonyString(screenInfoKey).c_str());
89    std::lock_guard<std::mutex> lock(srcMapMutex_);
90    srcScreenInfoMap_.erase(screenInfoKey);
91    return DH_SUCCESS;
92}
93
94int32_t DInputContext::UpdateSrcScreenInfo(const std::string &screenInfoKey, const SrcScreenInfo &srcScreenInfo)
95{
96    std::lock_guard<std::mutex> lock(srcMapMutex_);
97    DHLOGI("UpdateSrcScreenInfo screenInfoKey: %{public}s", GetAnonyString(screenInfoKey).c_str());
98    if (srcScreenInfoMap_.count(screenInfoKey) <= 0) {
99        DHLOGE("source window id not exist");
100        return ERR_DH_INPUT_CONTEXT_KEY_NOT_EXIST;
101    }
102
103    srcScreenInfoMap_[screenInfoKey] = srcScreenInfo;
104    return DH_SUCCESS;
105}
106
107SrcScreenInfo DInputContext::GetSrcScreenInfo(const std::string &screenInfoKey)
108{
109    DHLOGI("GetSrcScreenInfo screenInfoKey: %{public}s", GetAnonyString(screenInfoKey).c_str());
110    std::lock_guard<std::mutex> lock(srcMapMutex_);
111    if (srcScreenInfoMap_.count(screenInfoKey) <= 0) {
112        DHLOGE("source window id not exist");
113        SrcScreenInfo srcScreenInfo;
114        srcScreenInfoMap_[screenInfoKey] = srcScreenInfo;
115    }
116
117    return srcScreenInfoMap_[screenInfoKey];
118}
119
120void DInputContext::SetLocalTouchScreenInfo(const LocalTouchScreenInfo &localTouchScreenInfo)
121{
122    std::lock_guard<std::mutex> lock(localTouchScreenInfoMutex_);
123    localTouchScreenInfo_ = localTouchScreenInfo;
124}
125
126LocalTouchScreenInfo DInputContext::GetLocalTouchScreenInfo()
127{
128    std::lock_guard<std::mutex> lock(localTouchScreenInfoMutex_);
129    return localTouchScreenInfo_;
130}
131
132int32_t DInputContext::CalculateTransformInfo(SinkScreenInfo &sinkScreenInfo)
133{
134    if (sinkScreenInfo.sinkShowHeight == 0 || sinkScreenInfo.sinkShowWidth == 0) {
135        DHLOGE("can not calculate transform infomation");
136        return ERR_DH_INPUT_CONTEXT_CALCULATE_FAIL;
137    }
138    TransformInfo transformInfo;
139    transformInfo.sinkWinPhyX = static_cast<uint32_t>(sinkScreenInfo.sinkWinShowX /
140        static_cast<double>(sinkScreenInfo.sinkShowWidth)) * sinkScreenInfo.sinkPhyWidth;
141    transformInfo.sinkWinPhyY = static_cast<uint32_t>(sinkScreenInfo.sinkWinShowY /
142        static_cast<double>(sinkScreenInfo.sinkShowHeight)) * sinkScreenInfo.sinkPhyHeight;
143    transformInfo.sinkProjPhyWidth = static_cast<uint32_t>((sinkScreenInfo.sinkProjShowWidth /
144        static_cast<double>(sinkScreenInfo.sinkShowWidth)) * sinkScreenInfo.sinkPhyWidth);
145    transformInfo.sinkProjPhyHeight = static_cast<uint32_t>((sinkScreenInfo.sinkProjShowHeight /
146        static_cast<double>(sinkScreenInfo.sinkShowHeight)) * sinkScreenInfo.sinkPhyHeight);
147    if (transformInfo.sinkProjPhyWidth == 0 || transformInfo.sinkProjPhyHeight == 0) {
148        DHLOGE("can not calculate transform infomation");
149        return ERR_DH_INPUT_CONTEXT_CALCULATE_FAIL;
150    }
151
152    // coefficient of the sink projection area in the source touch driver
153    transformInfo.coeffWidth = static_cast<double>(sinkScreenInfo.srcScreenInfo.sourcePhyWidth /
154        static_cast<double>(transformInfo.sinkProjPhyWidth));
155    transformInfo.coeffHeight = static_cast<double>(sinkScreenInfo.srcScreenInfo.sourcePhyHeight /
156        static_cast<double>(transformInfo.sinkProjPhyHeight));
157
158    DHLOGI("CalculateTransformInfo sinkWinPhyX = %{public}d, sinkWinPhyY = %{public}d, sinkProjPhyWidth = %{public}d, "
159        "sinkProjPhyHeight = %{public}d, coeffWidth = %{public}f, coeffHeight = %{public}f", transformInfo.sinkWinPhyX,
160        transformInfo.sinkWinPhyY, transformInfo.sinkProjPhyWidth, transformInfo.sinkProjPhyHeight,
161        transformInfo.coeffWidth, transformInfo.coeffHeight);
162    sinkScreenInfo.transformInfo = transformInfo;
163    return DH_SUCCESS;
164}
165
166std::shared_ptr<DistributedHardwareFwkKit> DInputContext::GetDHFwkKit()
167{
168    std::lock_guard<std::mutex> lock(dhFwkKitMutex_);
169    if (dhFwkKit_ == nullptr) {
170        dhFwkKit_ = std::make_shared<DistributedHardwareFwkKit>();
171    }
172    return dhFwkKit_;
173}
174
175sptr<IRemoteObject> DInputContext::GetRemoteObject(const int32_t saId)
176{
177    DHLOGI("GetDScreenSrcSA start");
178    {
179        std::lock_guard<std::mutex> lock(remoteObjectsMutex_);
180        if (remoteObjects_.find(saId) != remoteObjects_.end()) {
181            DHLOGI("dScreenSrcSA get from cache!");
182            return remoteObjects_[saId];
183        }
184    }
185
186    auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
187    if (samgr == nullptr) {
188        DHLOGE("GetSystemAbilityManager fail!");
189        return nullptr;
190    }
191    auto remoteObject = samgr->GetSystemAbility(saId);
192    if (remoteObject == nullptr) {
193        DHLOGE("GetSystemAbility remoteObject is nullptr");
194        return nullptr;
195    }
196    return remoteObject;
197}
198
199void DInputContext::AddRemoteObject(const int32_t saId, const sptr<IRemoteObject> &remoteObject)
200{
201    std::lock_guard<std::mutex> lock(remoteObjectsMutex_);
202    remoteObjects_[saId] = remoteObject;
203}
204
205void DInputContext::RemoveRemoteObject(const int32_t saId)
206{
207    std::lock_guard<std::mutex> lock(remoteObjectsMutex_);
208    remoteObjects_.erase(saId);
209}
210} // namespace DistributedInput
211} // namespace DistributedHardware
212} // namespace OHOS