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 "dscreen_sink_handler.h"
17
18 #include <chrono>
19 #include <new>
20
21 #include "errors.h"
22 #include "hitrace_meter.h"
23 #include "iremote_broker.h"
24 #include "if_system_ability_manager.h"
25 #include "iservice_registry.h"
26 #include "isystem_ability_load_callback.h"
27
28 #include "dscreen_constants.h"
29 #include "dscreen_errcode.h"
30 #include "dscreen_hitrace.h"
31 #include "dscreen_hisysevent.h"
32 #include "dscreen_log.h"
33 #include "dscreen_sink_load_callback.h"
34 #include "dscreen_util.h"
35
36 namespace OHOS {
37 namespace DistributedHardware {
38 IMPLEMENT_SINGLE_INSTANCE(DScreenSinkHandler);
39
DScreenSinkHandler()40 DScreenSinkHandler::DScreenSinkHandler()
41 {
42 DHLOGI("DScreenSinkHandler construct.");
43 std::lock_guard<std::mutex> lock(proxyMutex_);
44 if (sinkSvrRecipient_ == nullptr) {
45 sinkSvrRecipient_ = new (std::nothrow) DScreenSinkSvrRecipient();
46 }
47 }
48
~DScreenSinkHandler()49 DScreenSinkHandler::~DScreenSinkHandler()
50 {
51 DHLOGI("~DScreenSinkHandler.");
52 }
53
InitSink(const std::string & params)54 int32_t DScreenSinkHandler::InitSink(const std::string ¶ms)
55 {
56 if (params.empty()) {
57 DHLOGE("InitSink params is invalid.");
58 return ERR_DH_SCREEN_INPUT_PARAM_INVALID;
59 }
60 DHLOGI("DScreenSinkHandler InitSink");
61 std::unique_lock<std::mutex> lock(proxyMutex_);
62 if (dScreenSinkProxy_ == nullptr) {
63 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
64 if (samgr == nullptr) {
65 DHLOGE("Failed to get system ability mgr.");
66 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_GET_SAMGR_FAIL, DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID,
67 "dscreen sink get samgr failed.");
68 return ERR_DH_SCREEN_SA_GET_SAMGR_FAIL;
69 }
70 sptr<DScreenSinkLoadCallback> loadCallback(new DScreenSinkLoadCallback(params));
71 if (loadCallback == nullptr) {
72 DHLOGE("loadCallback is nullptr.");
73 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_GET_SAMGR_FAIL, DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID,
74 "loadCallback is nullptr.");
75 return ERR_DH_SCREEN_SA_GET_SAMGR_FAIL;
76 }
77 StartTrace(DSCREEN_HITRACE_LABEL, DSCREEN_SINK_LOAD_SYSTEM_ABILITY_START);
78 int32_t ret = samgr->LoadSystemAbility(DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID, loadCallback);
79 if (ret != ERR_OK) {
80 DHLOGE("Failed to Load systemAbility, systemAbilityId:%{public}" PRId32 ", ret code:%{public}" PRId32,
81 DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID, ret);
82 ReportSaFail(DSCREEN_INIT_FAIL, ret, DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID,
83 "dscreen sink LoadSystemAbility call failed.");
84 return ERR_DH_SCREEN_SA_GET_SINKPROXY_FAIL;
85 }
86 }
87
88 auto waitStatus = proxyConVar_.wait_for(lock, std::chrono::milliseconds(SCREEN_LOADSA_TIMEOUT_MS),
89 [this]() { return dScreenSinkProxy_ != nullptr; });
90 if (!waitStatus) {
91 DHLOGE("screen load sa timeout");
92 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_LOAD_TIMEOUT, DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID,
93 "dscreen sink sa load timeout.");
94 return ERR_DH_SCREEN_SA_LOAD_TIMEOUT;
95 }
96
97 FinishTrace(DSCREEN_HITRACE_LABEL);
98 return DH_SUCCESS;
99 }
100
FinishStartSA(const std::string & params,const sptr<IRemoteObject> & remoteObject)101 void DScreenSinkHandler::FinishStartSA(const std::string ¶ms, const sptr<IRemoteObject> &remoteObject)
102 {
103 DHLOGI("DScreenSinkHandler FinishStartSA");
104 std::lock_guard<std::mutex> lock(proxyMutex_);
105 if (remoteObject == nullptr) {
106 DHLOGE("remoteObject is nullptr.");
107 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_SINKPROXY_NOT_INIT, DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID,
108 "remoteObject is nullptr.");
109 return;
110 }
111 if (sinkSvrRecipient_ == nullptr) {
112 DHLOGE("sinkSvrRecipient is nullptr.");
113 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_SINKPROXY_NOT_INIT, DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID,
114 "sinkSvrRecipient is nullptr.");
115 return;
116 }
117 remoteObject->AddDeathRecipient(sinkSvrRecipient_);
118 dScreenSinkProxy_ = iface_cast<IDScreenSink>(remoteObject);
119 if ((dScreenSinkProxy_ == nullptr) || (dScreenSinkProxy_->AsObject() == nullptr)) {
120 DHLOGE("Failed to get dscreen sink proxy.");
121 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_SINKPROXY_NOT_INIT, DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID,
122 "dscreen sink get proxy failed.");
123 return;
124 }
125 dScreenSinkProxy_->InitSink(params);
126 proxyConVar_.notify_one();
127 ReportSaEvent(DSCREEN_INIT, DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID, "dscreen sink sa load success.");
128 }
129
ReleaseSink()130 int32_t DScreenSinkHandler::ReleaseSink()
131 {
132 DHLOGI("DScreenSinkHandler ReleaseSink");
133 std::lock_guard<std::mutex> lock(proxyMutex_);
134 if (dScreenSinkProxy_ == nullptr) {
135 DHLOGE("screen sink proxy not init.");
136 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_SINKPROXY_NOT_INIT, DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID,
137 "dscreen sink proxy not init.");
138 return ERR_DH_SCREEN_SA_SINKPROXY_NOT_INIT;
139 }
140
141 int32_t ret = dScreenSinkProxy_->ReleaseSink();
142 dScreenSinkProxy_ = nullptr;
143 return ret;
144 }
145
SubscribeLocalHardware(const std::string & dhId,const std::string & param)146 int32_t DScreenSinkHandler::SubscribeLocalHardware(const std::string &dhId, const std::string ¶m)
147 {
148 DHLOGI("DScreenSinkHandler SubscribeLocalHardware dhId: %{public}s", GetAnonyString(dhId).c_str());
149 std::lock_guard<std::mutex> lock(proxyMutex_);
150 if (dScreenSinkProxy_ == nullptr) {
151 DHLOGE("screen sink proxy not init.");
152 return ERR_DH_SCREEN_SA_SINKPROXY_NOT_INIT;
153 }
154
155 return dScreenSinkProxy_->SubscribeLocalHardware(dhId, param);
156 }
157
UnsubscribeLocalHardware(const std::string & dhId)158 int32_t DScreenSinkHandler::UnsubscribeLocalHardware(const std::string &dhId)
159 {
160 DHLOGI("DScreenSinkHandler UnsubscribeLocalHardware dhId: %{public}s", GetAnonyString(dhId).c_str());
161 std::lock_guard<std::mutex> lock(proxyMutex_);
162 if (dScreenSinkProxy_ == nullptr) {
163 DHLOGE("screen sink proxy not init.");
164 return ERR_DH_SCREEN_SA_SINKPROXY_NOT_INIT;
165 }
166
167 return dScreenSinkProxy_->UnsubscribeLocalHardware(dhId);
168 }
169
OnRemoteDied(const wptr<IRemoteObject> & remote)170 void DScreenSinkHandler::DScreenSinkSvrRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
171 {
172 if (remote == nullptr) {
173 DHLOGI("OnRemoteDied remote is nullptr.");
174 return;
175 }
176 DHLOGI("DScreenSinkSvrRecipient OnRemoteDied.");
177 DScreenSinkHandler::GetInstance().OnRemoteSinkSvrDied(remote);
178 }
179
OnRemoteSinkSvrDied(const wptr<IRemoteObject> & remote)180 void DScreenSinkHandler::OnRemoteSinkSvrDied(const wptr<IRemoteObject> &remote)
181 {
182 DHLOGI("DScreenSinkHandler OnRemoteSinkSvrDied");
183 std::lock_guard<std::mutex> lock(proxyMutex_);
184 if (dScreenSinkProxy_ == nullptr) {
185 DHLOGE("dScreenSinkProxy is nullptr.");
186 return;
187 }
188 sptr<IRemoteObject> remoteObject = remote.promote();
189 if (remoteObject == nullptr) {
190 DHLOGE("OnRemoteDied remote promoted failed");
191 return;
192 }
193
194 if (dScreenSinkProxy_->AsObject() != remoteObject) {
195 DHLOGE("OnRemoteSinkSvrDied not found remote object.");
196 return;
197 }
198
199 dScreenSinkProxy_->AsObject()->RemoveDeathRecipient(sinkSvrRecipient_);
200 dScreenSinkProxy_ = nullptr;
201 }
202
RegisterPrivacyResources(std::shared_ptr<PrivacyResourcesListener> listener)203 int32_t DScreenSinkHandler::RegisterPrivacyResources(std::shared_ptr<PrivacyResourcesListener> listener)
204 {
205 return DH_SUCCESS;
206 }
207
PauseDistributedHardware(const std::string & networkId)208 int32_t DScreenSinkHandler::PauseDistributedHardware(const std::string &networkId)
209 {
210 return DH_SUCCESS;
211 }
212
ResumeDistributedHardware(const std::string & networkId)213 int32_t DScreenSinkHandler::ResumeDistributedHardware(const std::string &networkId)
214 {
215 return DH_SUCCESS;
216 }
217
StopDistributedHardware(const std::string & networkId)218 int32_t DScreenSinkHandler::StopDistributedHardware(const std::string &networkId)
219 {
220 return DH_SUCCESS;
221 }
222
GetSinkHardwareHandler()223 IDistributedHardwareSink *GetSinkHardwareHandler()
224 {
225 DHLOGI("GetSinkHardwareHandler");
226 return &DScreenSinkHandler::GetInstance();
227 }
228 } // namespace DistributedHardware
229 } // namespace OHOS
230