1/*
2 * Copyright (c) 2023 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 "intention_manager.h"
17
18#include "devicestatus_define.h"
19#include "drag_data.h"
20
21#undef LOG_TAG
22#define LOG_TAG "IntentionManager"
23
24namespace OHOS {
25namespace Msdp {
26namespace DeviceStatus {
27namespace {
28constexpr int32_t INDEX_MAIN { 0 };
29constexpr int32_t INDEX_FULL { 1 };
30constexpr size_t POLICY_VEC_SIZE { 2 };
31const std::string SCREEN_ROTATION { "1" };
32} // namespace
33
34IntentionManager::IntentionManager()
35{
36    tunnel_ = std::make_shared<TunnelClient>();
37}
38
39IntentionManager::~IntentionManager()
40{
41    client_.reset();
42}
43
44void IntentionManager::InitClient()
45{
46    CALL_DEBUG_ENTER;
47    std::lock_guard<std::mutex> guard(mutex_);
48    if (client_ != nullptr) {
49        return;
50    }
51    client_ = std::make_unique<SocketClient>(tunnel_);
52    InitMsgHandler();
53    client_->Start();
54    GetRotatePolicy(isScreenRotation_, foldRotatePolicys_);
55}
56
57void IntentionManager::InitMsgHandler()
58{
59    CALL_DEBUG_ENTER;
60    std::map<MessageId, std::function<int32_t(const StreamClient&, NetPacket&)>> funs {
61#ifdef OHOS_BUILD_ENABLE_COORDINATION
62        {MessageId::COORDINATION_ADD_LISTENER, [this](const StreamClient &client, NetPacket &pkt) {
63            return this->cooperate_.OnCoordinationListener(client, pkt);
64        }},
65        {MessageId::COORDINATION_MESSAGE, [this](const StreamClient &client, NetPacket &pkt) {
66            return this->cooperate_.OnCoordinationMessage(client, pkt);
67        }},
68        {MessageId::COORDINATION_GET_STATE, [this](const StreamClient &client, NetPacket &pkt) {
69            return this->cooperate_.OnCoordinationState(client, pkt);
70        }},
71        {MessageId::HOT_AREA_ADD_LISTENER, [this](const StreamClient &client, NetPacket &pkt) {
72            return this->cooperate_.OnHotAreaListener(client, pkt);
73        }},
74        {MessageId::MOUSE_LOCATION_ADD_LISTENER, [this](const StreamClient &client, NetPacket &pkt) {
75            return this->cooperate_.OnMouseLocationListener(client, pkt);
76        }},
77#endif // OHOS_BUILD_ENABLE_COORDINATION
78
79        {MessageId::DRAG_NOTIFY_RESULT, [this](const StreamClient &client, NetPacket &pkt) {
80            return this->drag_.OnNotifyResult(client, pkt);
81        }},
82        {MessageId::DRAG_STATE_LISTENER, [this](const StreamClient &client, NetPacket &pkt) {
83            return this->drag_.OnStateChangedMessage(client, pkt);
84        }},
85        {MessageId::DRAG_NOTIFY_HIDE_ICON, [this](const StreamClient &client, NetPacket &pkt) {
86            return this->drag_.OnNotifyHideIcon(client, pkt);
87        }},
88        {MessageId::DRAG_STYLE_LISTENER, [this](const StreamClient &client, NetPacket &pkt) {
89            return this->drag_.OnDragStyleChangedMessage(client, pkt);
90        }},
91        {MessageId::ADD_SELECTED_PIXELMAP_RESULT, [this](const StreamClient &client, NetPacket &pkt) {
92            return this->drag_.OnAddSelectedPixelMapResult(client, pkt);
93        }}
94    };
95    CHKPV(client_);
96    for (auto &[id, cb] : funs) {
97        if (!client_->RegisterEvent(id, cb)) {
98            FI_HILOGI("RegistER event handler msg:%{publid}d already exists", id);
99        }
100    }
101}
102
103int32_t IntentionManager::SubscribeCallback(Type type, ActivityEvent event, ReportLatencyNs latency,
104    sptr<IRemoteDevStaCallback> callback)
105{
106    return stationary_.SubscribeCallback(*tunnel_, type, event, latency, callback);
107}
108
109int32_t IntentionManager::UnsubscribeCallback(Type type, ActivityEvent event, sptr<IRemoteDevStaCallback> callback)
110{
111    return stationary_.UnsubscribeCallback(*tunnel_, type, event, callback);
112}
113
114Data IntentionManager::GetDeviceStatusData(const Type type)
115{
116    return stationary_.GetDeviceStatusData(*tunnel_, type);
117}
118
119int32_t IntentionManager::RegisterCoordinationListener(
120    std::shared_ptr<ICoordinationListener> listener, bool isCompatible)
121{
122    CALL_INFO_TRACE;
123#ifdef OHOS_BUILD_ENABLE_COORDINATION
124    InitClient();
125    return cooperate_.RegisterListener(*tunnel_, listener, isCompatible);
126#else
127    FI_HILOGW("Coordination does not support");
128    (void)(listener);
129    (void)(isCompatible);
130    return ERROR_UNSUPPORT;
131#endif // OHOS_BUILD_ENABLE_COORDINATION
132}
133
134int32_t IntentionManager::UnregisterCoordinationListener(
135    std::shared_ptr<ICoordinationListener> listener, bool isCompatible)
136{
137    CALL_INFO_TRACE;
138#ifdef OHOS_BUILD_ENABLE_COORDINATION
139    return cooperate_.UnregisterListener(*tunnel_, listener, isCompatible);
140#else
141    FI_HILOGW("Coordination does not support");
142    (void)(listener);
143    (void)(isCompatible);
144    return ERROR_UNSUPPORT;
145#endif // OHOS_BUILD_ENABLE_COORDINATION
146}
147
148int32_t IntentionManager::PrepareCoordination(CooperateMsgInfoCallback callback, bool isCompatible)
149{
150    CALL_INFO_TRACE;
151#ifdef OHOS_BUILD_ENABLE_COORDINATION
152    InitClient();
153    return cooperate_.Enable(*tunnel_, callback, isCompatible);
154#else
155    FI_HILOGW("Coordination does not support");
156    (void)(callback);
157    (void)(isCompatible);
158    return ERROR_UNSUPPORT;
159#endif // OHOS_BUILD_ENABLE_COORDINATION
160}
161
162int32_t IntentionManager::UnprepareCoordination(CooperateMsgInfoCallback callback, bool isCompatible)
163{
164    CALL_INFO_TRACE;
165#ifdef OHOS_BUILD_ENABLE_COORDINATION
166    InitClient();
167    return cooperate_.Disable(*tunnel_, callback, isCompatible);
168#else
169    FI_HILOGW("Coordination does not support");
170    (void)(callback);
171    (void)(isCompatible);
172    return ERROR_UNSUPPORT;
173#endif // OHOS_BUILD_ENABLE_COORDINATION
174}
175
176int32_t IntentionManager::ActivateCoordination(const std::string &remoteNetworkId, int32_t startDeviceId,
177    CooperateMsgInfoCallback callback, bool isCompatible)
178{
179    CALL_INFO_TRACE;
180#ifdef OHOS_BUILD_ENABLE_COORDINATION
181    InitClient();
182    return cooperate_.Start(*tunnel_, remoteNetworkId, startDeviceId, callback, isCompatible);
183#else
184    FI_HILOGW("Coordination does not support");
185    (void)(remoteNetworkId);
186    (void)(startDeviceId);
187    (void)(callback);
188    (void)(isCompatible);
189    return ERROR_UNSUPPORT;
190#endif // OHOS_BUILD_ENABLE_COORDINATION
191}
192
193int32_t IntentionManager::DeactivateCoordination(bool isUnchained,
194    CooperateMsgInfoCallback callback, bool isCompatible)
195{
196    CALL_INFO_TRACE;
197#ifdef OHOS_BUILD_ENABLE_COORDINATION
198    InitClient();
199    return cooperate_.Stop(*tunnel_, isUnchained, callback, isCompatible);
200#else
201    FI_HILOGW("Coordination does not support");
202    (void)(callback);
203    (void)(isCompatible);
204    return ERROR_UNSUPPORT;
205#endif // OHOS_BUILD_ENABLE_COORDINATION
206}
207
208int32_t IntentionManager::GetCoordinationState(
209    const std::string &networkId, std::function<void(bool)> callback, bool isCompatible)
210{
211    CALL_INFO_TRACE;
212#ifdef OHOS_BUILD_ENABLE_COORDINATION
213    InitClient();
214    return cooperate_.GetCooperateState(*tunnel_, networkId, callback, isCompatible);
215#else
216    (void)(networkId);
217    (void)(callback);
218    (void)(isCompatible);
219    FI_HILOGW("Coordination does not support");
220    return ERROR_UNSUPPORT;
221#endif // OHOS_BUILD_ENABLE_COORDINATION
222}
223
224int32_t IntentionManager::GetCoordinationState(const std::string &udId, bool &state)
225{
226    CALL_INFO_TRACE;
227#ifdef OHOS_BUILD_ENABLE_COORDINATION
228    InitClient();
229    return cooperate_.GetCooperateState(*tunnel_, udId, state);
230#else
231    (void)(udId);
232    (void)(state);
233    FI_HILOGW("Coordination does not support");
234    return ERROR_UNSUPPORT;
235#endif // OHOS_BUILD_ENABLE_COORDINATION
236}
237
238int32_t IntentionManager::RegisterEventListener(const std::string &networkId, std::shared_ptr<IEventListener> listener)
239{
240    CALL_INFO_TRACE;
241#ifdef OHOS_BUILD_ENABLE_COORDINATION
242    InitClient();
243    return cooperate_.RegisterEventListener(*tunnel_, networkId, listener);
244#else
245    (void)(networkId);
246    (void)(listener);
247    FI_HILOGW("Coordination does not support");
248    return ERROR_UNSUPPORT;
249#endif // OHOS_BUILD_ENABLE_COORDINATION
250}
251
252int32_t IntentionManager::UnregisterEventListener(const std::string &networkId,
253    std::shared_ptr<IEventListener> listener)
254{
255    CALL_INFO_TRACE;
256#ifdef OHOS_BUILD_ENABLE_COORDINATION
257    InitClient();
258    return cooperate_.UnregisterEventListener(*tunnel_, networkId, listener);
259#else
260    (void)(networkId);
261    (void)(listener);
262    FI_HILOGW("Coordination does not support");
263    return ERROR_UNSUPPORT;
264#endif // OHOS_BUILD_ENABLE_COORDINATION
265}
266
267int32_t IntentionManager::UpdateDragStyle(DragCursorStyle style)
268{
269    CALL_DEBUG_ENTER;
270    return drag_.UpdateDragStyle(*tunnel_, style);
271}
272
273int32_t IntentionManager::StartDrag(const DragData &dragData, std::shared_ptr<IStartDragListener> listener)
274{
275    CALL_DEBUG_ENTER;
276    InitClient();
277    return drag_.StartDrag(*tunnel_, dragData, listener);
278}
279
280int32_t IntentionManager::StopDrag(const DragDropResult &dropResult)
281{
282    CALL_DEBUG_ENTER;
283    return drag_.StopDrag(*tunnel_, dropResult);
284}
285
286int32_t IntentionManager::GetDragTargetPid()
287{
288    CALL_DEBUG_ENTER;
289    return drag_.GetDragTargetPid(*tunnel_);
290}
291
292int32_t IntentionManager::GetUdKey(std::string &udKey)
293{
294    CALL_DEBUG_ENTER;
295    return drag_.GetUdKey(*tunnel_, udKey);
296}
297
298int32_t IntentionManager::AddDraglistener(DragListenerPtr listener)
299{
300    CALL_DEBUG_ENTER;
301    InitClient();
302    return drag_.AddDraglistener(*tunnel_, listener);
303}
304
305int32_t IntentionManager::RemoveDraglistener(DragListenerPtr listener)
306{
307    CALL_DEBUG_ENTER;
308    return drag_.RemoveDraglistener(*tunnel_, listener);
309}
310
311int32_t IntentionManager::AddSubscriptListener(SubscriptListenerPtr listener)
312{
313    CALL_DEBUG_ENTER;
314    InitClient();
315    return drag_.AddSubscriptListener(*tunnel_, listener);
316}
317
318int32_t IntentionManager::RemoveSubscriptListener(SubscriptListenerPtr listener)
319{
320    CALL_DEBUG_ENTER;
321    return drag_.RemoveSubscriptListener(*tunnel_, listener);
322}
323
324int32_t IntentionManager::SetDragWindowVisible(bool visible, bool isForce)
325{
326    CALL_DEBUG_ENTER;
327    return drag_.SetDragWindowVisible(*tunnel_, visible, isForce);
328}
329
330int32_t IntentionManager::GetShadowOffset(ShadowOffset &shadowOffset)
331{
332    CALL_DEBUG_ENTER;
333    return drag_.GetShadowOffset(*tunnel_, shadowOffset);
334}
335
336int32_t IntentionManager::UpdateShadowPic(const ShadowInfo &shadowInfo)
337{
338    CALL_DEBUG_ENTER;
339    return drag_.UpdateShadowPic(*tunnel_, shadowInfo);
340}
341
342int32_t IntentionManager::GetDragData(DragData &dragData)
343{
344    CALL_DEBUG_ENTER;
345    return drag_.GetDragData(*tunnel_, dragData);
346}
347
348int32_t IntentionManager::GetDragState(DragState &dragState)
349{
350    CALL_DEBUG_ENTER;
351    return drag_.GetDragState(*tunnel_, dragState);
352}
353
354int32_t IntentionManager::GetDragAction(DragAction &dragAction)
355{
356    CALL_DEBUG_ENTER;
357    return drag_.GetDragAction(*tunnel_, dragAction);
358}
359
360int32_t IntentionManager::GetExtraInfo(std::string &extraInfo)
361{
362    CALL_DEBUG_ENTER;
363    return drag_.GetExtraInfo(*tunnel_, extraInfo);
364}
365
366int32_t IntentionManager::AddHotAreaListener(std::shared_ptr<IHotAreaListener> listener)
367{
368    CALL_DEBUG_ENTER;
369#ifdef OHOS_BUILD_ENABLE_COORDINATION
370    InitClient();
371    return cooperate_.AddHotAreaListener(*tunnel_, listener);
372#else
373    FI_HILOGW("Coordination does not support");
374    (void)(listener);
375    return ERROR_UNSUPPORT;
376#endif // OHOS_BUILD_ENABLE_COORDINATION
377}
378
379int32_t IntentionManager::RemoveHotAreaListener(std::shared_ptr<IHotAreaListener> listener)
380{
381    CALL_DEBUG_ENTER;
382#ifdef OHOS_BUILD_ENABLE_COORDINATION
383    return cooperate_.RemoveHotAreaListener(*tunnel_, listener);
384#else
385    FI_HILOGW("Coordination does not support");
386    (void)(listener);
387    return ERROR_UNSUPPORT;
388#endif // OHOS_BUILD_ENABLE_COORDINATION
389}
390
391int32_t IntentionManager::UpdatePreviewStyle(const PreviewStyle &previewStyle)
392{
393    CALL_DEBUG_ENTER;
394    return drag_.UpdatePreviewStyle(*tunnel_, previewStyle);
395}
396
397int32_t IntentionManager::UpdatePreviewStyleWithAnimation(const PreviewStyle &previewStyle,
398    const PreviewAnimation &animation)
399{
400    CALL_DEBUG_ENTER;
401    return drag_.UpdatePreviewStyleWithAnimation(*tunnel_, previewStyle, animation);
402}
403
404int32_t IntentionManager::RotateDragWindowSync(const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
405{
406    CALL_DEBUG_ENTER;
407    if (isScreenRotation_) {
408        FI_HILOGW("Screen rotation, not need rotate drag window");
409        return RET_OK;
410    }
411    if (Rosen::DisplayManager::GetInstance().IsFoldable()) {
412        if ((foldRotatePolicys_.empty()) || (foldRotatePolicys_.size() < POLICY_VEC_SIZE)) {
413            FI_HILOGE("foldRotatePolicys_ is invalid");
414            return drag_.RotateDragWindowSync(*tunnel_, rsTransaction);
415        }
416        if (Rosen::DisplayManager::GetInstance().GetFoldDisplayMode() == Rosen::FoldDisplayMode::FULL) {
417            if (foldRotatePolicys_[INDEX_FULL] == SCREEN_ROTATION) {
418                FI_HILOGD("Full display rotation, not need rotate drag window");
419                return RET_OK;
420            }
421        } else if (Rosen::DisplayManager::GetInstance().GetFoldDisplayMode() == Rosen::FoldDisplayMode::MAIN) {
422            if (foldRotatePolicys_[INDEX_MAIN] == SCREEN_ROTATION) {
423                FI_HILOGD("Main display rotation, not need rotate drag window");
424                return RET_OK;
425            }
426        }
427    }
428    return drag_.RotateDragWindowSync(*tunnel_, rsTransaction);
429}
430
431int32_t IntentionManager::SetDragWindowScreenId(uint64_t displayId, uint64_t screenId)
432{
433    CALL_DEBUG_ENTER;
434    return drag_.SetDragWindowScreenId(*tunnel_, displayId, screenId);
435}
436
437int32_t IntentionManager::GetDragSummary(std::map<std::string, int64_t> &summarys)
438{
439    CALL_DEBUG_ENTER;
440    return drag_.GetDragSummary(*tunnel_, summarys);
441}
442
443int32_t IntentionManager::EnterTextEditorArea(bool enable)
444{
445    CALL_DEBUG_ENTER;
446    return drag_.EnterTextEditorArea(*tunnel_, enable);
447}
448
449int32_t IntentionManager::AddPrivilege()
450{
451    CALL_DEBUG_ENTER;
452    return drag_.AddPrivilege(*tunnel_);
453}
454
455int32_t IntentionManager::EraseMouseIcon()
456{
457    CALL_DEBUG_ENTER;
458    return drag_.EraseMouseIcon(*tunnel_);
459}
460
461int32_t IntentionManager::AddSelectedPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap,
462    std::function<void(bool)> callback)
463{
464    CALL_DEBUG_ENTER;
465    return drag_.AddSelectedPixelMap(*tunnel_, pixelMap, callback);
466}
467} // namespace DeviceStatus
468} // namespace Msdp
469} // namespace OHOS
470