1/*
2 * Copyright (c) 2021-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 "distributed_input_sink_handler.h"
17
18#include "dinput_errcode.h"
19#include "dinput_log.h"
20#include "hisysevent_util.h"
21#include "i_distributed_sink_input.h"
22#include "load_d_input_sink_callback.h"
23
24namespace OHOS {
25namespace DistributedHardware {
26namespace DistributedInput {
27IMPLEMENT_SINGLE_INSTANCE(DistributedInputSinkHandler);
28
29DistributedInputSinkHandler::DistributedInputSinkHandler()
30{
31    DHLOGI("DInputSinkHandler construct.");
32    std::lock_guard<std::mutex> lock(proxyMutex_);
33    if (sinkSvrRecipient_ == nullptr) {
34        sinkSvrRecipient_ = new (std::nothrow) DInputSinkSvrRecipient();
35    }
36}
37
38DistributedInputSinkHandler::~DistributedInputSinkHandler()
39{
40    DHLOGI("~DistributedInputSinkHandler");
41}
42
43int32_t DistributedInputSinkHandler::InitSink(const std::string &params)
44{
45    DHLOGI("DistributedInputSinkHandler InitSink begin");
46    std::unique_lock<std::mutex> lock(proxyMutex_);
47    sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
48    if (!samgr) {
49        DHLOGE("Failed to get system ability mgr.");
50        return ERR_DH_INPUT_SINK_HANDLER_INIT_SINK_SA_FAIL;
51    }
52    sptr<LoadDInputSinkCallback> loadCallback(new LoadDInputSinkCallback(params));
53    HisyseventUtil::GetInstance().SysEventWriteBehavior(DINPUT_INIT,
54        "dinput sink LoadSystemAbility call");
55    int32_t ret = samgr->LoadSystemAbility(DISTRIBUTED_HARDWARE_INPUT_SINK_SA_ID, loadCallback);
56    if (ret != ERR_OK) {
57        DHLOGE("Failed to Load systemAbility, systemAbilityId:%{public}d, ret code:%{public}d",
58               DISTRIBUTED_HARDWARE_INPUT_SINK_SA_ID, ret);
59        return ERR_DH_INPUT_SINK_HANDLER_INIT_SINK_SA_FAIL;
60    }
61
62    auto waitStatus = proxyConVar_.wait_for(lock, std::chrono::milliseconds(INPUT_LOAD_SA_TIMEOUT_MS),
63        [this]() { return (DInputSAManager::GetInstance().HasDInputSinkProxy()); });
64    if (!waitStatus) {
65        DHLOGE("dinput load sink sa timeout.");
66        return ERR_DH_INPUT_SINK_HANDLER_INIT_SINK_SA_FAIL;
67    }
68
69    DHLOGI("DistributedInputSinkHandler InitSink end");
70    return DH_SUCCESS;
71}
72
73void DistributedInputSinkHandler::FinishStartSA(const std::string &params, const sptr<IRemoteObject> &remoteObject)
74{
75    DHLOGI("DInputSinkHandler FinishStartSA");
76    std::lock_guard<std::mutex> lock(proxyMutex_);
77    if (sinkSvrRecipient_ == nullptr) {
78        DHLOGE("sinkSvrRecipient is nullptr.");
79        return;
80    }
81    remoteObject->AddDeathRecipient(sinkSvrRecipient_);
82    dInputSinkProxy_ = iface_cast<IDistributedSinkInput>(remoteObject);
83    DInputSAManager::GetInstance().SetDInputSinkProxy(remoteObject);
84    if ((dInputSinkProxy_ == nullptr) || (dInputSinkProxy_->AsObject() == nullptr)) {
85        DHLOGE("Faild to get input sink proxy.");
86        return;
87    }
88    DistributedInputClient::GetInstance().InitSink();
89    proxyConVar_.notify_all();
90}
91
92int32_t DistributedInputSinkHandler::ReleaseSink()
93{
94    return DistributedInputClient::GetInstance().ReleaseSink();
95}
96
97int32_t DistributedInputSinkHandler::SubscribeLocalHardware(const std::string &dhId, const std::string &params)
98{
99    return DH_SUCCESS;
100}
101
102int32_t DistributedInputSinkHandler::UnsubscribeLocalHardware(const std::string &dhId)
103{
104    return DH_SUCCESS;
105}
106
107void DistributedInputSinkHandler::SALoadSinkCb::OnLoadSystemAbilitySuccess(int32_t systemAbilityId,
108    const OHOS::sptr<IRemoteObject> &remoteObject)
109{
110    currSystemAbilityId = systemAbilityId;
111    currRemoteObject = remoteObject;
112    DHLOGI("DistributedInputSinkHandler OnLoadSystemAbilitySuccess. systemAbilityId=%{public}d", systemAbilityId);
113}
114
115void DistributedInputSinkHandler::SALoadSinkCb::OnLoadSystemAbilityFail(int32_t systemAbilityId)
116{
117    currSystemAbilityId = systemAbilityId;
118    DHLOGE("DistributedInputSinkHandler OnLoadSystemAbilityFail. systemAbilityId=%{public}d", systemAbilityId);
119}
120
121void DistributedInputSinkHandler::DInputSinkSvrRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
122{
123    if (remote == nullptr) {
124        DHLOGE("OnRemoteDied remote is nullptr.");
125        return;
126    }
127    DHLOGI("DInputSinkSvrRecipient OnRemoteDied.");
128    DistributedInputSinkHandler::GetInstance().OnRemoteSinkSvrDied(remote);
129}
130
131void DistributedInputSinkHandler::OnRemoteSinkSvrDied(const wptr<IRemoteObject> &remote)
132{
133    DHLOGI("DInputSinkHandle OnRemoteSinkSvrDied.");
134    std::lock_guard<std::mutex> lock(proxyMutex_);
135    if (dInputSinkProxy_ == nullptr) {
136        DHLOGE("dInputSinkProxy_ is nullptr.");
137        return;
138    }
139    if (dInputSinkProxy_->AsObject() == nullptr) {
140        DHLOGE("AsObject is nullptr.");
141        return;
142    }
143    sptr<IRemoteObject> remoteObject = remote.promote();
144    if (remoteObject == nullptr) {
145        DHLOGE("OnRemoteDied remote promoted failed");
146        return;
147    }
148
149    if (dInputSinkProxy_->AsObject() != remoteObject) {
150        DHLOGE("OnRemoteSinkSvrDied not found remote object.");
151        return;
152    }
153    dInputSinkProxy_->AsObject()->RemoveDeathRecipient(sinkSvrRecipient_);
154    dInputSinkProxy_ = nullptr;
155}
156
157int32_t DistributedInputSinkHandler::RegisterPrivacyResources(std::shared_ptr<PrivacyResourcesListener> listener)
158{
159    return DH_SUCCESS;
160}
161
162int32_t DistributedInputSinkHandler::PauseDistributedHardware(const std::string &networkId)
163{
164    return DH_SUCCESS;
165}
166
167int32_t DistributedInputSinkHandler::ResumeDistributedHardware(const std::string &networkId)
168{
169    return DH_SUCCESS;
170}
171
172int32_t DistributedInputSinkHandler::StopDistributedHardware(const std::string &networkId)
173{
174    return DH_SUCCESS;
175}
176
177IDistributedHardwareSink *GetSinkHardwareHandler()
178{
179    return &DistributedInputSinkHandler::GetInstance();
180}
181} // namespace DistributedInput
182} // namespace DistributedHardware
183} // namespace OHOS
184