1 /*
2 * Copyright (c) 2022 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:%d, ret code:%d",
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 (sourceSvrRecipient_ == nullptr) {
101 DHLOGE("sourceSvrRecipient is nullptr.");
102 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID,
103 "sourceSvrRecipient is nullptr.");
104 return;
105 }
106 remoteObject->AddDeathRecipient(sourceSvrRecipient_);
107 dScreenSourceProxy_ = iface_cast<IDScreenSource>(remoteObject);
108 if ((dScreenSourceProxy_ == nullptr) || (dScreenSourceProxy_->AsObject() == nullptr)) {
109 DHLOGE("Failed to get dscreen source proxy.");
110 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID,
111 "dscreen source get proxy failed.");
112 return;
113 }
114 if (dScreenSourceCallback_ == nullptr) {
115 DHLOGE("dScreenSourceCallback is nullptr.");
116 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID,
117 "dScreenSourceCallback is nullptr.");
118 return;
119 }
120 dScreenSourceProxy_->InitSource(params, dScreenSourceCallback_);
121 proxyConVar_.notify_one();
122 ReportSaEvent(DSCREEN_INIT, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID, "dscreen source sa load success.");
123 }
124
ReleaseSource()125 int32_t DScreenSourceHandler::ReleaseSource()
126 {
127 DHLOGI("DScreenSourceHandler ReleaseSource");
128 std::lock_guard<std::mutex> lock(proxyMutex_);
129 if (dScreenSourceProxy_ == nullptr) {
130 DHLOGE("screen source proxy not init.");
131 ReportSaFail(DSCREEN_INIT_FAIL, ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID,
132 "dscreen source proxy not init.");
133 return ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT;
134 }
135 int32_t ret = dScreenSourceProxy_->ReleaseSource();
136 dScreenSourceProxy_ = nullptr;
137 return ret;
138 }
139
RegisterDistributedHardware(const std::string & devId,const std::string & dhId,const EnableParam & param,std::shared_ptr<RegisterCallback> callback)140 int32_t DScreenSourceHandler::RegisterDistributedHardware(const std::string &devId,
141 const std::string &dhId, const EnableParam ¶m, std::shared_ptr<RegisterCallback> callback)
142 {
143 if (devId.empty() || dhId.empty()) {
144 DHLOGE("device id or dh id empty.");
145 return ERR_DH_SCREEN_STRING_PARAM_EMPTY;
146 }
147 if (callback == nullptr) {
148 DHLOGE("callback is nullptr.");
149 return ERR_DH_SCREEN_REGISTER_CALLBACK_NOT_INIT;
150 }
151 DHLOGI("RegisterDistributedHardware, devId: %s, dhId: %s", GetAnonyString(devId).c_str(),
152 GetAnonyString(dhId).c_str());
153 std::lock_guard<std::mutex> lock(proxyMutex_);
154 if (dScreenSourceProxy_ == nullptr) {
155 DHLOGE("screen source proxy not init.");
156 return ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT;
157 }
158 if (dScreenSourceCallback_ == nullptr) {
159 DHLOGE("screen source callback is null.");
160 return ERR_DH_SCREEN_SA_SOURCEPCALLBACK_NOT_INIT;
161 }
162
163 std::string reqId = GetRandomID();
164 dScreenSourceCallback_->PushRegRegisterCallback(reqId, callback);
165 return dScreenSourceProxy_->RegisterDistributedHardware(devId, dhId, param, reqId);
166 }
167
UnregisterDistributedHardware(const std::string & devId,const std::string & dhId,std::shared_ptr<UnregisterCallback> callback)168 int32_t DScreenSourceHandler::UnregisterDistributedHardware(const std::string &devId,
169 const std::string &dhId, std::shared_ptr<UnregisterCallback> callback)
170 {
171 if (devId.empty() || dhId.empty()) {
172 DHLOGE("device id or dh id empty.");
173 return ERR_DH_SCREEN_STRING_PARAM_EMPTY;
174 }
175 if (callback == nullptr) {
176 DHLOGE("callback is nullptr.");
177 return ERR_DH_SCREEN_REGISTER_CALLBACK_NOT_INIT;
178 }
179 DHLOGI("UnregisterDistributedHardware, devId: %s, dhId: %s", GetAnonyString(devId).c_str(),
180 GetAnonyString(dhId).c_str());
181 std::lock_guard<std::mutex> lock(proxyMutex_);
182 if (dScreenSourceProxy_ == nullptr) {
183 DHLOGE("screen source proxy not init.");
184 return ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT;
185 }
186 if (dScreenSourceCallback_ == nullptr) {
187 DHLOGE("screen source callback is null.");
188 return ERR_DH_SCREEN_SA_SOURCEPCALLBACK_NOT_INIT;
189 }
190
191 std::string reqId = GetRandomID();
192 dScreenSourceCallback_->PushUnregisterCallback(reqId, callback);
193 return dScreenSourceProxy_->UnregisterDistributedHardware(devId, dhId, reqId);
194 }
195
ConfigDistributedHardware(const std::string & devId,const std::string & dhId,const std::string & key,const std::string & value)196 int32_t DScreenSourceHandler::ConfigDistributedHardware(const std::string &devId,
197 const std::string &dhId, const std::string &key, const std::string &value)
198 {
199 DHLOGI("ConfigDistributedHardware");
200 return DH_SUCCESS;
201 }
202
OnRemoteDied(const wptr<IRemoteObject> & remote)203 void DScreenSourceHandler::DScreenSourceSvrRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
204 {
205 if (remote == nullptr) {
206 DHLOGI("OnRemoteDied remote is nullptr.");
207 return;
208 }
209 DHLOGI("DScreenSourceSvrRecipient OnRemoteDied");
210 DScreenSourceHandler::GetInstance().OnRemoteSourceSvrDied(remote);
211 }
212
OnRemoteSourceSvrDied(const wptr<IRemoteObject> & remote)213 void DScreenSourceHandler::OnRemoteSourceSvrDied(const wptr<IRemoteObject> &remote)
214 {
215 DHLOGI("OnRemoteSourceSvrDied");
216 std::lock_guard<std::mutex> lock(proxyMutex_);
217 if (dScreenSourceProxy_ == nullptr) {
218 DHLOGE("dScreenSourceProxy is nullptr.");
219 return;
220 }
221 sptr<IRemoteObject> remoteObject = remote.promote();
222 if (remoteObject == nullptr) {
223 DHLOGE("OnRemoteDied remote promoted failed");
224 return;
225 }
226
227 if (dScreenSourceProxy_->AsObject() != remoteObject) {
228 DHLOGE("OnRemoteSourceSvrDied not found remote object.");
229 return;
230 }
231
232 dScreenSourceProxy_->AsObject()->RemoveDeathRecipient(sourceSvrRecipient_);
233 dScreenSourceProxy_ = nullptr;
234 }
235
GetSourceHardwareHandler()236 IDistributedHardwareSource *GetSourceHardwareHandler()
237 {
238 DHLOGI("GetSourceHardwareHandler");
239 return &DScreenSourceHandler::GetInstance();
240 }
241 }
242 }