• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "iservice_registry.h"
17 #include "system_ability_definition.h"
18 #include "sane_service_load_callback.h"
19 #include "sane_manager_client.h"
20 
21 namespace OHOS::Scan {
22 constexpr int32_t SANE_SERVICE_ID = 3709;
23 constexpr int32_t LOAD_SA_TIMEOUT_MS = 15000;
24 std::mutex SaneManagerClient::instanceLock_;
25 std::shared_mutex SaneManagerClient::serviceLock_;
26 sptr<SaneManagerClient> SaneManagerClient::instance_;
27 
SaneManagerClient()28 SaneManagerClient::SaneManagerClient() : proxy_(nullptr)
29 {
30     deathRecipient_ = new SaneSaDeathRecipient();
31 }
~SaneManagerClient()32 SaneManagerClient::~SaneManagerClient()
33 {
34     proxy_ = nullptr;
35     deathRecipient_ = nullptr;
36 }
37 
GetInstance()38 sptr<SaneManagerClient> SaneManagerClient::GetInstance()
39 {
40     if (instance_ == nullptr) {
41         std::lock_guard<std::mutex> autoLock(instanceLock_);
42         if (instance_ == nullptr) {
43             instance_ = new SaneManagerClient;
44         }
45     }
46     return instance_;
47 }
48 
GetSaneServiceProxy()49 sptr<ISaneBackends> SaneManagerClient::GetSaneServiceProxy()
50 {
51     {
52         std::unique_lock<std::shared_mutex> lock(serviceLock_);
53         if (proxy_ != nullptr) {
54             SCAN_HILOGD("already get proxy_");
55             return proxy_;
56         }
57         auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
58         if (samgrProxy == nullptr) {
59             SCAN_HILOGE("samgrProxy is a nullptr");
60             return nullptr;
61         }
62         auto object = samgrProxy->CheckSystemAbility(SANE_SERVICE_ID);
63         if (object != nullptr) {
64             object->AddDeathRecipient(deathRecipient_);
65             proxy_ = iface_cast<ISaneBackends>(object);
66             return proxy_;
67         }
68     }
69     if (LoadSaneService()) {
70         std::unique_lock<std::shared_mutex> lock(serviceLock_);
71         return proxy_;
72     }
73     return nullptr;
74 }
75 
LoadSaneService()76 bool SaneManagerClient::LoadSaneService()
77 {
78     std::unique_lock<std::shared_mutex> lock(serviceLock_);
79     sptr<SaneServiceLoadCallback> lockCallback = new SaneServiceLoadCallback();
80     if (lockCallback == nullptr) {
81         SCAN_HILOGE("lockCallback is a nullptr");
82         return false;
83     }
84     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
85     if (samgrProxy == nullptr) {
86         SCAN_HILOGE("get samgr failed");
87         return false;
88     }
89     int32_t ret = samgrProxy->LoadSystemAbility(SANE_SERVICE_ID, lockCallback);
90     if (ret != ERR_OK) {
91         SCAN_HILOGE("LoadSystemAbility failed");
92         return false;
93     }
94     auto waitStatus = syncCon_.wait_for(lock, std::chrono::milliseconds(LOAD_SA_TIMEOUT_MS),
95         [this]() { return proxy_ != nullptr; });
96     if (!waitStatus) {
97         return false;
98     }
99     return true;
100 }
101 
LoadSystemAbilitysuccess(const sptr<IRemoteObject> & remoteObject)102 void SaneManagerClient::LoadSystemAbilitysuccess(const sptr<IRemoteObject> &remoteObject)
103 {
104     std::unique_lock<std::shared_mutex> lock(serviceLock_);
105     SCAN_HILOGI("sane_service LoadSystemAbilitysuccess");
106     if (remoteObject != nullptr) {
107         remoteObject->AddDeathRecipient(deathRecipient_);
108         proxy_ = iface_cast<ISaneBackends>(remoteObject);
109         syncCon_.notify_one();
110     }
111 }
112 
LoadSystemAbilityFail()113 void SaneManagerClient::LoadSystemAbilityFail()
114 {
115     std::unique_lock<std::shared_mutex> lock(serviceLock_);
116     SCAN_HILOGI("sane_service LoadSystemAbilityFail");
117     proxy_ = nullptr;
118 }
119 
OnRemoteSaDied(const wptr<IRemoteObject> & object)120 void SaneManagerClient::OnRemoteSaDied(const wptr<IRemoteObject>& object)
121 {
122     std::unique_lock<std::shared_mutex> lock(serviceLock_);
123     proxy_ = nullptr;
124 }
125 
SaneInit()126 SaneStatus SaneManagerClient::SaneInit()
127 {
128     SCAN_HILOGI("SaneManagerClient SaneInit start.");
129     if (proxy_ == nullptr) {
130         SCAN_HILOGW("do GetSaneServiceProxy");
131         proxy_ = GetSaneServiceProxy();
132     }
133     std::shared_lock<std::shared_mutex> lock(serviceLock_);
134     if (proxy_ == nullptr) {
135         SCAN_HILOGE("On quit because redoing GetSaneServiceProxy failed..");
136         return SANE_STATUS_SERVER_FAILURE;
137     }
138     int32_t saneStatus = SANE_STATUS_GOOD;
139     int32_t ret = proxy_->SaneInit(saneStatus);
140     if (ret != ERR_NONE) {
141         SCAN_HILOGE("proxy_->SaneInit error exit, ret = [%{public}d]", ret);
142         return SANE_STATUS_RPC_FAILURE;
143     }
144     SCAN_HILOGI("SaneManagerClient SaneInit end, saneStatus = [%{public}d].", saneStatus);
145     return static_cast<SaneStatus>(saneStatus);
146 }
147 
SaneExit()148 SaneStatus SaneManagerClient::SaneExit()
149 {
150     SCAN_HILOGI("SaneManagerClient SaneExit start.");
151     if (proxy_ == nullptr) {
152         SCAN_HILOGW("do GetSaneServiceProxy");
153         proxy_ = GetSaneServiceProxy();
154     }
155     std::shared_lock<std::shared_mutex> lock(serviceLock_);
156     if (proxy_ == nullptr) {
157         SCAN_HILOGE("On quit because redoing GetSaneServiceProxy failed..");
158         return SANE_STATUS_SERVER_FAILURE;
159     }
160     int32_t ret = proxy_->SaneExit();
161     if (ret != ERR_NONE) {
162         SCAN_HILOGE("proxy_->SaneExit error exit, ret = [%{public}d]", ret);
163         return SANE_STATUS_RPC_FAILURE;
164     }
165     SCAN_HILOGI("SaneManagerClient SaneExit end.");
166     return SANE_STATUS_GOOD;
167 }
168 
SaneOpen(const std::string & scannerId)169 SaneStatus SaneManagerClient::SaneOpen(const std::string& scannerId)
170 {
171     SCAN_HILOGI("SaneManagerClient SaneOpen start.");
172     if (proxy_ == nullptr) {
173         SCAN_HILOGW("do GetSaneServiceProxy");
174         proxy_ = GetSaneServiceProxy();
175     }
176     std::shared_lock<std::shared_mutex> lock(serviceLock_);
177     if (proxy_ == nullptr) {
178         SCAN_HILOGE("On quit because redoing GetSaneServiceProxy failed..");
179         return SANE_STATUS_SERVER_FAILURE;
180     }
181     int32_t saneStatus = SANE_STATUS_GOOD;
182     int32_t ret = proxy_->SaneOpen(scannerId, saneStatus);
183     if (ret != ERR_NONE) {
184         SCAN_HILOGE("proxy_->SaneOpen error exit, ret = [%{public}d]", ret);
185         return SANE_STATUS_RPC_FAILURE;
186     }
187     SCAN_HILOGI("SaneManagerClient SaneOpen end, saneStatus = [%{public}d].", saneStatus);
188     return static_cast<SaneStatus>(saneStatus);
189 }
190 
SaneClose(const std::string & scannerId)191 SaneStatus SaneManagerClient::SaneClose(const std::string& scannerId)
192 {
193     SCAN_HILOGI("SaneManagerClient SaneClose start.");
194     if (proxy_ == nullptr) {
195         SCAN_HILOGW("do GetSaneServiceProxy");
196         proxy_ = GetSaneServiceProxy();
197     }
198     std::shared_lock<std::shared_mutex> lock(serviceLock_);
199     if (proxy_ == nullptr) {
200         SCAN_HILOGE("On quit because redoing GetSaneServiceProxy failed..");
201         return SANE_STATUS_SERVER_FAILURE;
202     }
203     int32_t ret = proxy_->SaneClose(scannerId);
204     if (ret != ERR_NONE) {
205         SCAN_HILOGE("proxy_->SaneClose error exit, ret = [%{public}d]", ret);
206         return SANE_STATUS_RPC_FAILURE;
207     }
208     SCAN_HILOGI("SaneManagerClient SaneClose end.");
209     return SANE_STATUS_GOOD;
210 }
211 
SaneStart(const std::string & scannerId)212 SaneStatus SaneManagerClient::SaneStart(const std::string& scannerId)
213 {
214     SCAN_HILOGI("SaneManagerClient SaneStart start.");
215     if (proxy_ == nullptr) {
216         SCAN_HILOGW("do GetSaneServiceProxy");
217         proxy_ = GetSaneServiceProxy();
218     }
219     std::shared_lock<std::shared_mutex> lock(serviceLock_);
220     if (proxy_ == nullptr) {
221         SCAN_HILOGE("On quit because redoing GetSaneServiceProxy failed..");
222         return SANE_STATUS_SERVER_FAILURE;
223     }
224     int32_t saneStatus = SANE_STATUS_GOOD;
225     int32_t ret = proxy_->SaneStart(scannerId, saneStatus);
226     if (ret != ERR_NONE) {
227         SCAN_HILOGE("proxy_->SaneStart error exit, ret = [%{public}d]", ret);
228         return SANE_STATUS_RPC_FAILURE;
229     }
230     SCAN_HILOGI("SaneManagerClient SaneStart end, saneStatus = [%{public}d].", saneStatus);
231     return static_cast<SaneStatus>(saneStatus);
232 }
233 
SaneCancel(const std::string & scannerId)234 SaneStatus SaneManagerClient::SaneCancel(const std::string& scannerId)
235 {
236     SCAN_HILOGI("SaneManagerClient SaneCancel start.");
237     if (proxy_ == nullptr) {
238         SCAN_HILOGW("do GetSaneServiceProxy");
239         proxy_ = GetSaneServiceProxy();
240     }
241     std::shared_lock<std::shared_mutex> lock(serviceLock_);
242     if (proxy_ == nullptr) {
243         SCAN_HILOGE("On quit because redoing GetSaneServiceProxy failed..");
244         return SANE_STATUS_SERVER_FAILURE;
245     }
246     int32_t ret = proxy_->SaneCancel(scannerId);
247     if (ret != ERR_NONE) {
248         SCAN_HILOGE("proxy_->SaneCancel error exit, ret = [%{public}d]", ret);
249         return SANE_STATUS_RPC_FAILURE;
250     }
251     SCAN_HILOGI("SaneManagerClient SaneCancel end.");
252     return SANE_STATUS_GOOD;
253 }
254 
SaneGetOptionDescriptor(const std::string & scannerId,const int32_t & option,SaneOptionDescriptor & desc)255 SaneStatus SaneManagerClient::SaneGetOptionDescriptor(const std::string& scannerId, const int32_t& option,
256     SaneOptionDescriptor& desc)
257 {
258     SCAN_HILOGI("SaneManagerClient SaneGetOptionDescriptor start.");
259     if (proxy_ == nullptr) {
260         SCAN_HILOGW("do GetSaneServiceProxy");
261         proxy_ = GetSaneServiceProxy();
262     }
263     std::shared_lock<std::shared_mutex> lock(serviceLock_);
264     if (proxy_ == nullptr) {
265         SCAN_HILOGE("On quit because redoing GetSaneServiceProxy failed..");
266         return SANE_STATUS_SERVER_FAILURE;
267     }
268     int32_t saneStatus = SANE_STATUS_GOOD;
269     int32_t ret = proxy_->SaneGetOptionDescriptor(scannerId, option, desc, saneStatus);
270     if (ret != ERR_NONE) {
271         SCAN_HILOGE("proxy_->SaneGetOptionDescriptor error exit, ret = [%{public}d]", ret);
272         return SANE_STATUS_RPC_FAILURE;
273     }
274     SCAN_HILOGI("SaneManagerClient SaneGetOptionDescriptor end, saneStatus = [%{public}d].", saneStatus);
275     return static_cast<SaneStatus>(saneStatus);
276 }
277 
SaneGetParameters(const std::string & scannerId,SaneParameters & params)278 SaneStatus SaneManagerClient::SaneGetParameters(const std::string& scannerId, SaneParameters& params)
279 {
280     SCAN_HILOGI("SaneManagerClient SaneGetParameters start.");
281     if (proxy_ == nullptr) {
282         SCAN_HILOGW("do GetSaneServiceProxy");
283         proxy_ = GetSaneServiceProxy();
284     }
285     std::shared_lock<std::shared_mutex> lock(serviceLock_);
286     if (proxy_ == nullptr) {
287         SCAN_HILOGE("On quit because redoing GetSaneServiceProxy failed..");
288         return SANE_STATUS_SERVER_FAILURE;
289     }
290     int32_t saneStatus = SANE_STATUS_GOOD;
291     int32_t ret = proxy_->SaneGetParameters(scannerId, params, saneStatus);
292     if (ret != ERR_NONE) {
293         SCAN_HILOGE("proxy_->SaneGetParameters error exit, ret = [%{public}d]", ret);
294         return SANE_STATUS_RPC_FAILURE;
295     }
296     SCAN_HILOGI("SaneManagerClient SaneGetParameters end, saneStatus = [%{public}d].", saneStatus);
297     return static_cast<SaneStatus>(saneStatus);
298 }
299 
SaneGetDevices(std::vector<SaneDevice> & deviceInfos)300 SaneStatus SaneManagerClient::SaneGetDevices(std::vector<SaneDevice>& deviceInfos)
301 {
302     SCAN_HILOGI("SaneManagerClient SaneGetDevices start.");
303     if (proxy_ == nullptr) {
304         SCAN_HILOGW("do GetSaneServiceProxy");
305         proxy_ = GetSaneServiceProxy();
306     }
307     std::shared_lock<std::shared_mutex> lock(serviceLock_);
308     if (proxy_ == nullptr) {
309         SCAN_HILOGE("On quit because redoing GetSaneServiceProxy failed..");
310         return SANE_STATUS_SERVER_FAILURE;
311     }
312     int32_t saneStatus = SANE_STATUS_GOOD;
313     int32_t ret = proxy_->SaneGetDevices(deviceInfos, saneStatus);
314     if (ret != ERR_NONE) {
315         SCAN_HILOGE("proxy_->SaneGetDevices error exit, ret = [%{public}d]", ret);
316         return SANE_STATUS_RPC_FAILURE;
317     }
318     SCAN_HILOGI("SaneManagerClient SaneGetDevices end, saneStatus = [%{public}d].", saneStatus);
319     return static_cast<SaneStatus>(saneStatus);
320 }
321 
SaneControlOption(const std::string & scannerId,SaneControlParam & controlParam,SaneOutParam & outParam)322 SaneStatus SaneManagerClient::SaneControlOption(const std::string& scannerId, SaneControlParam& controlParam,
323     SaneOutParam& outParam)
324 {
325     SCAN_HILOGI("SaneManagerClient SaneControlOption start.");
326     if (proxy_ == nullptr) {
327         SCAN_HILOGW("do GetSaneServiceProxy");
328         proxy_ = GetSaneServiceProxy();
329     }
330     std::shared_lock<std::shared_mutex> lock(serviceLock_);
331     if (proxy_ == nullptr) {
332         SCAN_HILOGE("On quit because redoing GetSaneServiceProxy failed..");
333         return SANE_STATUS_SERVER_FAILURE;
334     }
335     int32_t saneStatus = SANE_STATUS_GOOD;
336     int32_t ret = proxy_->SaneControlOption(scannerId, controlParam, outParam, saneStatus);
337     if (ret != ERR_NONE) {
338         SCAN_HILOGE("proxy_->SaneControlOption error exit, ret = [%{public}d]", ret);
339         return SANE_STATUS_RPC_FAILURE;
340     }
341     SCAN_HILOGI("SaneManagerClient SaneControlOption end, saneStatus = [%{public}d].", saneStatus);
342     return static_cast<SaneStatus>(saneStatus);
343 }
344 
SaneRead(const std::string & scannerId,const int32_t buflen,SanePictureData & pictureData)345 SaneStatus SaneManagerClient::SaneRead(const std::string& scannerId, const int32_t buflen,
346     SanePictureData& pictureData)
347 {
348     SCAN_HILOGI("SaneManagerClient SaneRead start.");
349     if (proxy_ == nullptr) {
350         SCAN_HILOGW("do GetSaneServiceProxy");
351         proxy_ = GetSaneServiceProxy();
352     }
353     std::shared_lock<std::shared_mutex> lock(serviceLock_);
354     if (proxy_ == nullptr) {
355         SCAN_HILOGE("On quit because redoing GetSaneServiceProxy failed..");
356         return SANE_STATUS_SERVER_FAILURE;
357     }
358     int32_t saneStatus = SANE_STATUS_GOOD;
359     int32_t ret = proxy_->SaneRead(scannerId, buflen, pictureData, saneStatus);
360     if (ret != ERR_NONE) {
361         SCAN_HILOGE("proxy_->SaneRead error exit, ret = [%{public}d]", ret);
362         return SANE_STATUS_RPC_FAILURE;
363     }
364     SCAN_HILOGI("SaneManagerClient SaneRead end, saneStatus = [%{public}d].", saneStatus);
365     return static_cast<SaneStatus>(saneStatus);
366 }
367 
UnloadSystemAbility()368 SaneStatus SaneManagerClient::UnloadSystemAbility()
369 {
370     SCAN_HILOGI("SaneManagerClient UnloadSystemAbility start.");
371     if (proxy_ == nullptr) {
372         SCAN_HILOGW("do GetSaneServiceProxy");
373         proxy_ = GetSaneServiceProxy();
374     }
375     std::shared_lock<std::shared_mutex> lock(serviceLock_);
376     if (proxy_ == nullptr) {
377         SCAN_HILOGE("On quit because redoing GetSaneServiceProxy failed..");
378         return SANE_STATUS_SERVER_FAILURE;
379     }
380     int32_t ret = proxy_->UnloadSystemAbility();
381     if (ret != ERR_NONE) {
382         SCAN_HILOGE("proxy_->UnloadSystemAbility error exit, ret = [%{public}d]", ret);
383         return SANE_STATUS_RPC_FAILURE;
384     }
385     SCAN_HILOGI("SaneManagerClient UnloadSystemAbility end.");
386     return SANE_STATUS_GOOD;
387 }
388 }  // namespace OHOS::Scan