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_source_handler.h"
17
18 #include <chrono>
19 #include <new>
20 #include <string>
21
22 #include "errors.h"
23 #include "hitrace_meter.h"
24 #include "idscreen_source_callback.h"
25 #include "if_system_ability_manager.h"
26 #include "iremote_broker.h"
27 #include "isystem_ability_load_callback.h"
28 #include "iservice_registry.h"
29
30 #include "dscreen_constants.h"
31 #include "dscreen_errcode.h"
32 #include "dscreen_hitrace.h"
33 #include "dscreen_hisysevent.h"
34 #include "dscreen_log.h"
35 #include "dscreen_source_load_callback.h"
36 #include "dscreen_util.h"
37
38 namespace OHOS {
39 namespace DistributedHardware {
40 IMPLEMENT_SINGLE_INSTANCE(DScreenSourceHandler);
41
DScreenSourceHandler()42 DScreenSourceHandler::DScreenSourceHandler()
43 {
44 DHLOGI("DScreenSourceHandler construct.");
45 std::lock_guard<std::mutex> lock(proxyMutex_);
46 if (sourceSvrRecipient_ == nullptr) {
47 sourceSvrRecipient_ = new (std::nothrow) DScreenSourceSvrRecipient();
48 }
49
50 if (dScreenSourceCallback_ == nullptr) {
51 dScreenSourceCallback_ = new (std::nothrow) DScreenSourceCallback();
52 }
53 }
54
InitSource(const std::string & params)55 int32_t DScreenSourceHandler::InitSource(const std::string ¶ms)
56 {
57 if (params.empty()) {
58 DHLOGE("InitSource params is invalid.");
59 return ERR_DH_SCREEN_INPUT_PARAM_INVALID;
60 }
61 DHLOGI("DScreenSourceHandler InitSource");
62 std::unique_lock<std::mutex> lock(proxyMutex_);
63 if (dScreenSourceProxy_ == nullptr) {
64 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
65 if (samgr == nullptr) {
66 DHLOGE("Failed to get system ability mgr.");
67 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_GET_SAMGR_FAIL, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID,
68 "dscreen source get samgr failed.");
69 return ERR_DH_SCREEN_SA_GET_SAMGR_FAIL;
70 }
71 sptr<DScreenSourceLoadCallback> loadCallback(new DScreenSourceLoadCallback(params));
72 StartTrace(DSCREEN_HITRACE_LABEL, DSCREEN_SOURCE_LOAD_SYSTEM_ABILITY_START);
73 int32_t ret = samgr->LoadSystemAbility(DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID, loadCallback);
74 if (ret != ERR_OK) {
75 DHLOGE("Failed to Load systemAbility, systemAbilityId:%{public}" PRId32 ", ret code:%{public}" PRId32,
76 DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID, ret);
77 ReportSaFail(DSCREEN_INIT_FAIL, ret, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID,
78 "dscreen source LoadSystemAbility call failed.");
79 return ERR_DH_SCREEN_SA_GET_SOURCEPROXY_FAIL;
80 }
81 }
82
83 auto waitStatus = proxyConVar_.wait_for(lock, std::chrono::milliseconds(SCREEN_LOADSA_TIMEOUT_MS),
84 [this]() { return (dScreenSourceProxy_ != nullptr); });
85 if (!waitStatus) {
86 DHLOGE("screen load sa timeout.");
87 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_LOAD_TIMEOUT, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID,
88 "dscreen source sa load timeout.");
89 return ERR_DH_SCREEN_SA_LOAD_TIMEOUT;
90 }
91
92 FinishTrace(DSCREEN_HITRACE_LABEL);
93 return DH_SUCCESS;
94 }
95
FinishStartSA(const std::string & params,const sptr<IRemoteObject> & remoteObject)96 void DScreenSourceHandler::FinishStartSA(const std::string ¶ms, const sptr<IRemoteObject> &remoteObject)
97 {
98 DHLOGI("DScreenSourceHandler FinishStartSA");
99 std::lock_guard<std::mutex> lock(proxyMutex_);
100 if (remoteObject == nullptr) {
101 DHLOGE("remoteObject is nullptr.");
102 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID,
103 "remoteObject is nullptr.");
104 return;
105 }
106 if (sourceSvrRecipient_ == nullptr) {
107 DHLOGE("sourceSvrRecipient is nullptr.");
108 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID,
109 "sourceSvrRecipient is nullptr.");
110 return;
111 }
112 remoteObject->AddDeathRecipient(sourceSvrRecipient_);
113 dScreenSourceProxy_ = iface_cast<IDScreenSource>(remoteObject);
114 if ((dScreenSourceProxy_ == nullptr) || (dScreenSourceProxy_->AsObject() == nullptr)) {
115 DHLOGE("Failed to get dscreen source proxy.");
116 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID,
117 "dscreen source get proxy failed.");
118 return;
119 }
120 if (dScreenSourceCallback_ == nullptr) {
121 DHLOGE("dScreenSourceCallback is nullptr.");
122 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID,
123 "dScreenSourceCallback is nullptr.");
124 return;
125 }
126 dScreenSourceProxy_->InitSource(params, dScreenSourceCallback_);
127 proxyConVar_.notify_one();
128 ReportSaEvent(DSCREEN_INIT, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID, "dscreen source sa load success.");
129 }
130
ReleaseSource()131 int32_t DScreenSourceHandler::ReleaseSource()
132 {
133 DHLOGI("DScreenSourceHandler ReleaseSource");
134 std::lock_guard<std::mutex> lock(proxyMutex_);
135 if (dScreenSourceProxy_ == nullptr) {
136 DHLOGE("screen source proxy not init.");
137 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID,
138 "dscreen source proxy not init.");
139 return ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT;
140 }
141 int32_t ret = dScreenSourceProxy_->ReleaseSource();
142 dScreenSourceProxy_ = nullptr;
143 return ret;
144 }
145
RegisterDistributedHardware(const std::string & devId,const std::string & dhId,const EnableParam & param,std::shared_ptr<RegisterCallback> callback)146 int32_t DScreenSourceHandler::RegisterDistributedHardware(const std::string &devId,
147 const std::string &dhId, const EnableParam ¶m, std::shared_ptr<RegisterCallback> callback)
148 {
149 if (devId.empty() || dhId.empty()) {
150 DHLOGE("device id or dh id empty.");
151 return ERR_DH_SCREEN_STRING_PARAM_EMPTY;
152 }
153 if (callback == nullptr) {
154 DHLOGE("callback is nullptr.");
155 return ERR_DH_SCREEN_REGISTER_CALLBACK_NOT_INIT;
156 }
157 DHLOGI("RegisterDistributedHardware, devId: %{public}s, dhId: %{public}s", GetAnonyString(devId).c_str(),
158 GetAnonyString(dhId).c_str());
159 std::lock_guard<std::mutex> lock(proxyMutex_);
160 if (dScreenSourceProxy_ == nullptr) {
161 DHLOGE("screen source proxy not init");
162 return ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT;
163 }
164 if (dScreenSourceCallback_ == nullptr) {
165 DHLOGE("screen source callback is null.");
166 return ERR_DH_SCREEN_SA_SOURCEPCALLBACK_NOT_INIT;
167 }
168
169 std::string reqId = GetRandomID();
170 dScreenSourceCallback_->PushRegRegisterCallback(reqId, callback);
171 return dScreenSourceProxy_->RegisterDistributedHardware(devId, dhId, param, reqId);
172 }
173
UnregisterDistributedHardware(const std::string & devId,const std::string & dhId,std::shared_ptr<UnregisterCallback> callback)174 int32_t DScreenSourceHandler::UnregisterDistributedHardware(const std::string &devId,
175 const std::string &dhId, std::shared_ptr<UnregisterCallback> callback)
176 {
177 if (devId.empty() || dhId.empty()) {
178 DHLOGE("device id or dh id empty.");
179 return ERR_DH_SCREEN_STRING_PARAM_EMPTY;
180 }
181 if (callback == nullptr) {
182 DHLOGE("callback is nullptr.");
183 return ERR_DH_SCREEN_REGISTER_CALLBACK_NOT_INIT;
184 }
185 DHLOGI("UnregisterDistributedHardware, devId: %{public}s, dhId: %{public}s", GetAnonyString(devId).c_str(),
186 GetAnonyString(dhId).c_str());
187 std::lock_guard<std::mutex> lock(proxyMutex_);
188 if (dScreenSourceProxy_ == nullptr) {
189 DHLOGE("screen source proxy not init.");
190 return ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT;
191 }
192 if (dScreenSourceCallback_ == nullptr) {
193 DHLOGE("screen source callback is null.");
194 return ERR_DH_SCREEN_SA_SOURCEPCALLBACK_NOT_INIT;
195 }
196
197 std::string reqId = GetRandomID();
198 dScreenSourceCallback_->PushUnregisterCallback(reqId, callback);
199 return dScreenSourceProxy_->UnregisterDistributedHardware(devId, dhId, reqId);
200 }
201
ConfigDistributedHardware(const std::string & devId,const std::string & dhId,const std::string & key,const std::string & value)202 int32_t DScreenSourceHandler::ConfigDistributedHardware(const std::string &devId,
203 const std::string &dhId, const std::string &key, const std::string &value)
204 {
205 DHLOGI("ConfigDistributedHardware");
206 return DH_SUCCESS;
207 }
208
RegisterDistributedHardwareStateListener(std::shared_ptr<DistributedHardwareStateListener> listener)209 void DScreenSourceHandler::RegisterDistributedHardwareStateListener(
210 std::shared_ptr<DistributedHardwareStateListener> listener)
211 {
212 (void)listener;
213 }
214
UnregisterDistributedHardwareStateListener()215 void DScreenSourceHandler::UnregisterDistributedHardwareStateListener()
216 {
217 }
218
RegisterDataSyncTriggerListener(std::shared_ptr<DataSyncTriggerListener> listener)219 void DScreenSourceHandler::RegisterDataSyncTriggerListener(std::shared_ptr<DataSyncTriggerListener> listener)
220 {
221 (void)listener;
222 }
223
UnregisterDataSyncTriggerListener()224 void DScreenSourceHandler::UnregisterDataSyncTriggerListener()
225 {
226 }
227
OnRemoteDied(const wptr<IRemoteObject> & remote)228 void DScreenSourceHandler::DScreenSourceSvrRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
229 {
230 if (remote == nullptr) {
231 DHLOGI("OnRemoteDied remote is nullptr.");
232 return;
233 }
234 DHLOGI("DScreenSourceSvrRecipient OnRemoteDied");
235 DScreenSourceHandler::GetInstance().OnRemoteSourceSvrDied(remote);
236 }
237
OnRemoteSourceSvrDied(const wptr<IRemoteObject> & remote)238 void DScreenSourceHandler::OnRemoteSourceSvrDied(const wptr<IRemoteObject> &remote)
239 {
240 DHLOGI("OnRemoteSourceSvrDied");
241 std::lock_guard<std::mutex> lock(proxyMutex_);
242 if (dScreenSourceProxy_ == nullptr) {
243 DHLOGE("dScreenSourceProxy is nullptr.");
244 return;
245 }
246 sptr<IRemoteObject> remoteObject = remote.promote();
247 if (remoteObject == nullptr) {
248 DHLOGE("OnRemoteDied remote promoted failed");
249 return;
250 }
251
252 if (dScreenSourceProxy_->AsObject() != remoteObject) {
253 DHLOGE("OnRemoteSourceSvrDied not found remote object.");
254 return;
255 }
256
257 dScreenSourceProxy_->AsObject()->RemoveDeathRecipient(sourceSvrRecipient_);
258 dScreenSourceProxy_ = nullptr;
259 }
260
GetSourceHardwareHandler()261 IDistributedHardwareSource *GetSourceHardwareHandler()
262 {
263 DHLOGI("GetSourceHardwareHandler");
264 return &DScreenSourceHandler::GetInstance();
265 }
266 } // namespace DistributedHardware
267 } // namespace OHOS
268