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 <ipc_skeleton.h>
17 #include <system_ability_definition.h>
18 #include <iservice_registry.h>
19 #include <thread>
20 #include "accesstoken_kit.h"
21 #include "directory_ex.h"
22 #include "sane/sane.h"
23 #include "sane/saneopts.h"
24 #include "sane_service_ability.h"
25 #include "sane_device.h"
26
27 namespace OHOS {
28 namespace Scan {
29
30 constexpr int32_t SANE_SERVICE_ID = 3709;
31
32 REGISTER_SYSTEM_ABILITY_BY_ID(SaneServerManager, SANE_SERVICE_ID, true);
33
SaneServerManager(int32_t saId,bool runOnCreate)34 SaneServerManager::SaneServerManager(int32_t saId, bool runOnCreate) : SystemAbility(SANE_SERVICE_ID, true)
35 {
36 SCAN_HILOGI("SaneServerManager init");
37 }
38
OnStart()39 void SaneServerManager::OnStart()
40 {
41 SCAN_HILOGI("SaneServerManager::OnStart()");
42 if (!Publish(this)) {
43 SCAN_HILOGE("SaneServerManager::OnStart() failed");
44 return;
45 }
46 SCAN_HILOGI("SaneServerManager start success");
47 }
48
GetScanHandle(const std::string & scannerId)49 SANE_Handle SaneServerManager::GetScanHandle(const std::string& scannerId)
50 {
51 auto it = scannerHandleList_.find(scannerId);
52 if (it == scannerHandleList_.end()) {
53 SCAN_HILOGE("ScannerId is not openned!");
54 return nullptr;
55 }
56 return it->second;
57 }
58
CheckPermission()59 bool SaneServerManager::CheckPermission()
60 {
61 using namespace Security::AccessToken;
62 AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
63 TypeATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
64 if (tokenType != TOKEN_NATIVE) {
65 SCAN_HILOGE("invalid tokenType, type = [%{public}u]", tokenType);
66 return false;
67 }
68 static const std::string PERMISSION_NAME_PRINT = "ohos.permission.PRINT";
69 int result = AccessTokenKit::VerifyAccessToken(tokenId, PERMISSION_NAME_PRINT);
70 if (result != PERMISSION_GRANTED) {
71 SCAN_HILOGE("Current tokenId permission is denied.");
72 return false;
73 }
74 return true;
75 }
76
SaneInit(int32_t & status)77 ErrCode SaneServerManager::SaneInit(int32_t& status)
78 {
79 SCAN_HILOGI("SaneInit start");
80 if (!CheckPermission()) {
81 SCAN_HILOGE("no permission to access sane_service");
82 return SANE_STATUS_NO_PERMISSION;
83 }
84 int32_t scanVersion = 0;
85 SANE_Status saneStatus = sane_init(&scanVersion, nullptr);
86 status = static_cast<int32_t>(saneStatus);
87 SCAN_HILOGI("sane_init successfully, version [%{public}d]", scanVersion);
88 return ERR_OK;
89 }
90
SaneExit()91 ErrCode SaneServerManager::SaneExit()
92 {
93 SCAN_HILOGI("SaneExit start");
94 if (!CheckPermission()) {
95 SCAN_HILOGE("no permission to access sane_service");
96 return SANE_STATUS_NO_PERMISSION;
97 }
98 sane_exit();
99 SCAN_HILOGI("SaneExit end");
100 return ERR_OK;
101 }
102
SaneOpen(const std::string & scannerId,int32_t & status)103 ErrCode SaneServerManager::SaneOpen(const std::string& scannerId, int32_t& status)
104 {
105 SCAN_HILOGI("SaneOpen start");
106 if (!CheckPermission()) {
107 SCAN_HILOGE("no permission to access sane_service");
108 return SANE_STATUS_NO_PERMISSION;
109 }
110 std::lock_guard<std::mutex> autoLock(scannerHandleListlock_);
111 if (scannerHandleList_.find(scannerId) != scannerHandleList_.end()) {
112 status = SANE_STATUS_GOOD;
113 return ERR_OK;
114 }
115 SANE_Handle handle = nullptr;
116 SANE_Status saneStatus = sane_open(scannerId.c_str(), &handle);
117 if (saneStatus != ::SANE_STATUS_GOOD) {
118 status = static_cast<int32_t>(saneStatus);
119 SCAN_HILOGE("sane_open error, ret = [%{public}d]", status);
120 return ERR_OK;
121 }
122 if (handle == nullptr) {
123 SCAN_HILOGE("handle is a nullptr.");
124 status = SANE_STATUS_INVAL;
125 return ERR_OK;
126 }
127 scannerHandleList_.insert({scannerId, handle});
128 SCAN_HILOGI("sane_open end, ret = [%{public}d]", status);
129 return ERR_OK;
130 }
131
SaneClose(const std::string & scannerId)132 ErrCode SaneServerManager::SaneClose(const std::string& scannerId)
133 {
134 SCAN_HILOGI("SaneClose start");
135 if (!CheckPermission()) {
136 SCAN_HILOGE("no permission to access sane_service");
137 return SANE_STATUS_NO_PERMISSION;
138 }
139 std::lock_guard<std::mutex> autoLock(scannerHandleListlock_);
140 auto it = scannerHandleList_.find(scannerId);
141 if (it != scannerHandleList_.end()) {
142 sane_close(it->second);
143 scannerHandleList_.erase(it);
144 }
145 SCAN_HILOGI("SaneClose end");
146 return ERR_OK;
147 }
148
SaneStart(const std::string & scannerId,int32_t & status)149 ErrCode SaneServerManager::SaneStart(const std::string& scannerId, int32_t& status)
150 {
151 SCAN_HILOGI("SaneStart start");
152 if (!CheckPermission()) {
153 SCAN_HILOGE("no permission to access sane_service");
154 return SANE_STATUS_NO_PERMISSION;
155 }
156 SANE_Handle handle = GetScanHandle(scannerId);
157 if (handle == nullptr) {
158 SCAN_HILOGE("handle is a nullptr");
159 status = SANE_STATUS_INVAL;
160 return ERR_OK;
161 }
162 SANE_Status saneStatus = sane_start(handle);
163 status = static_cast<int32_t>(saneStatus);
164 SCAN_HILOGI("sane_start end, ret = [%{public}d]", status);
165 return ERR_OK;
166 }
167
SaneCancel(const std::string & scannerId)168 ErrCode SaneServerManager::SaneCancel(const std::string& scannerId)
169 {
170 SCAN_HILOGI("SaneCancel start");
171 if (!CheckPermission()) {
172 SCAN_HILOGE("no permission to access sane_service");
173 return SANE_STATUS_NO_PERMISSION;
174 }
175 SANE_Handle handle = GetScanHandle(scannerId);
176 if (handle == nullptr) {
177 SCAN_HILOGE("handle is a nullptr");
178 return ERR_OK;
179 }
180 sane_cancel(handle);
181 SCAN_HILOGI("sane_cancel end");
182 return ERR_OK;
183 }
184
SaneGetOptionDescriptor(const std::string & scannerId,int32_t saneOption,SaneOptionDescriptor & saneOptDes,int32_t & status)185 ErrCode SaneServerManager::SaneGetOptionDescriptor(const std::string& scannerId, int32_t saneOption,
186 SaneOptionDescriptor& saneOptDes, int32_t& status)
187 {
188 SCAN_HILOGI("SaneGetOptionDescriptor start");
189 if (!CheckPermission()) {
190 SCAN_HILOGE("no permission to access sane_service");
191 return SANE_STATUS_NO_PERMISSION;
192 }
193 SANE_Handle handle = GetScanHandle(scannerId);
194 if (handle == nullptr) {
195 SCAN_HILOGE("handle is a nullptr");
196 status = SANE_STATUS_INVAL;
197 return ERR_OK;
198 }
199 SCAN_HILOGD("saneOption %{public}d", saneOption);
200 const SANE_Option_Descriptor* saneDesc = sane_get_option_descriptor(handle, saneOption);
201 if (saneDesc == nullptr) {
202 SCAN_HILOGE("saneDesc is a nullptr");
203 status = SANE_STATUS_INVAL;
204 return ERR_OK;
205 }
206 ConvertSaneDescriptor(saneDesc, saneOptDes);
207 saneOptDes.Dump();
208 SCAN_HILOGI("SaneGetOptionDescriptor end");
209 status = SANE_STATUS_GOOD;
210 return ERR_OK;
211 }
212
ConvertSaneDescriptor(const SANE_Option_Descriptor * saneDesc,SaneOptionDescriptor & saneOptDes)213 void SaneServerManager::ConvertSaneDescriptor(const SANE_Option_Descriptor* saneDesc,
214 SaneOptionDescriptor& saneOptDes)
215 {
216 SCAN_HILOGI("ConvertSaneDescriptor start");
217 if (saneDesc == nullptr) {
218 SCAN_HILOGE("saneDesc is a nullptr");
219 return;
220 }
221 if (saneDesc->name != nullptr) {
222 saneOptDes.optionName_ = std::string(saneDesc->name);
223 }
224 if (saneDesc->title != nullptr) {
225 saneOptDes.optionTitle_ = std::string(saneDesc->title);
226 }
227 if (saneDesc->desc != nullptr) {
228 saneOptDes.optionDesc_ = std::string(saneDesc->desc);
229 }
230 saneOptDes.optionType_ = static_cast<int32_t>(saneDesc->type);
231 saneOptDes.optionUnit_ = static_cast<int32_t>(saneDesc->unit);
232 saneOptDes.optionSize_ = saneDesc->size;
233 saneOptDes.optionCap_ = saneDesc->cap;
234 saneOptDes.optionConstraintType_ = static_cast<int32_t>(saneDesc->constraint_type);
235 if (saneDesc->constraint_type == ::SANE_CONSTRAINT_RANGE && saneDesc->constraint.range != nullptr) {
236 saneOptDes.minValue_ = saneDesc->constraint.range->min;
237 saneOptDes.maxValue_ = saneDesc->constraint.range->max;
238 saneOptDes.quantValue_ = saneDesc->constraint.range->quant;
239 } else if (saneDesc->constraint_type == ::SANE_CONSTRAINT_WORD_LIST
240 && saneDesc->constraint.word_list != nullptr) {
241 saneOptDes.optionConstraintNumber_.clear();
242 int32_t sizeNumber = saneDesc->constraint.word_list[0];
243 for (int32_t i = 0; i < sizeNumber; i++) {
244 SCAN_HILOGD("SANE_CONSTRAINT_WORD_LIST: %{public}d", saneDesc->constraint.word_list[i]);
245 saneOptDes.optionConstraintNumber_.push_back(saneDesc->constraint.word_list[i]);
246 }
247 } else if (saneDesc->constraint_type == ::SANE_CONSTRAINT_STRING_LIST
248 && saneDesc->constraint.string_list != nullptr) {
249 for (int32_t i = 0; saneDesc->constraint.string_list[i] != nullptr; i++) {
250 SCAN_HILOGD("SANE_CONSTRAINT_STRING_LIST: %{public}s", saneDesc->constraint.string_list[i]);
251 saneOptDes.optionConstraintString_.push_back(std::string(saneDesc->constraint.string_list[i]));
252 }
253 saneOptDes.optionConstraintString_.push_back("null");
254 }
255 SCAN_HILOGI("ConvertSaneDescriptor end");
256 }
257
SaneGetParameters(const std::string & scannerId,SaneParameters & spm,int32_t & status)258 ErrCode SaneServerManager::SaneGetParameters(const std::string& scannerId, SaneParameters& spm, int32_t& status)
259 {
260 SCAN_HILOGI("SaneGetParameters start");
261 if (!CheckPermission()) {
262 SCAN_HILOGE("no permission to access sane_service");
263 return SANE_STATUS_NO_PERMISSION;
264 }
265 SANE_Handle handle = GetScanHandle(scannerId);
266 if (handle == nullptr) {
267 SCAN_HILOGE("handle is a nullptr");
268 status = SANE_STATUS_INVAL;
269 return ERR_OK;
270 }
271 SANE_Parameters params;
272 SANE_Status saneStatus = sane_get_parameters(handle, ¶ms);
273 if (saneStatus != ::SANE_STATUS_GOOD) {
274 status = static_cast<int32_t>(saneStatus);
275 SCAN_HILOGE("sane_get_parameters error, ret = [%{public}d]", status);
276 return ERR_OK;
277 }
278 spm.format_ = static_cast<SaneFrame>(params.format);
279 spm.lastFrame_ = params.last_frame;
280 spm.bytesPerLine_ = params.bytes_per_line;
281 spm.pixelsPerLine_ = params.pixels_per_line;
282 spm.lines_ = params.lines;
283 spm.depth_ = params.depth;
284 status = SANE_STATUS_GOOD;
285 SCAN_HILOGI("SaneGetParameters end");
286 return ERR_OK;
287 }
288
SaneGetDevices(std::vector<SaneDevice> & deviceInfos,int32_t & status)289 ErrCode SaneServerManager::SaneGetDevices(std::vector<SaneDevice>& deviceInfos, int32_t& status)
290 {
291 SCAN_HILOGI("SaneGetDevices start");
292 if (!CheckPermission()) {
293 SCAN_HILOGE("no permission to access sane_service");
294 return SANE_STATUS_NO_PERMISSION;
295 }
296 const SANE_Device **deviceList = nullptr;
297 SANE_Status saneStatus = sane_get_devices(&deviceList, SANE_FALSE);
298 if (saneStatus != ::SANE_STATUS_GOOD) {
299 status = static_cast<int32_t>(saneStatus);
300 SCAN_HILOGE("sane_get_devices error, ret = [%{public}d]", status);
301 return ERR_OK;
302 }
303 for (int32_t i = 0; deviceList[i] != nullptr; i++) {
304 SaneDevice device;
305 if (deviceList[i]->name != nullptr) {
306 device.name_ = std::string(deviceList[i]->name);
307 }
308 if (deviceList[i]->vendor != nullptr) {
309 device.vendor_ = std::string(deviceList[i]->vendor);
310 }
311 if (deviceList[i]->model != nullptr) {
312 device.model_ = std::string(deviceList[i]->model);
313 }
314 if (deviceList[i]->type != nullptr) {
315 device.type_ = std::string(deviceList[i]->type);
316 }
317 deviceInfos.push_back(device);
318 }
319 status = SANE_STATUS_GOOD;
320 SCAN_HILOGI("SaneGetDevices end");
321 return ERR_OK;
322 }
323
SaneControlOption(const std::string & scannerId,const SaneControlParam & controlParam,SaneOutParam & outParam,int32_t & status)324 ErrCode SaneServerManager::SaneControlOption(const std::string& scannerId, const SaneControlParam& controlParam,
325 SaneOutParam& outParam, int32_t& status)
326 {
327 SCAN_HILOGI("SaneControlOption start");
328 if (!CheckPermission()) {
329 SCAN_HILOGE("no permission to access sane_service");
330 return SANE_STATUS_NO_PERMISSION;
331 }
332 SANE_Handle handle = GetScanHandle(scannerId);
333 if (handle == nullptr) {
334 SCAN_HILOGE("handle is a nullptr");
335 status = SANE_STATUS_INVAL;
336 return ERR_OK;
337 }
338 SANE_Int option = controlParam.option_;
339 SANE_Action action = static_cast<SANE_Action>(controlParam.action_);
340 if (controlParam.action_ == SANE_ACTION_SET_AUTO) {
341 SANE_Status saneStatus = sane_control_option(handle, option, action, nullptr, nullptr);
342 if (saneStatus != ::SANE_STATUS_GOOD) {
343 status = static_cast<int32_t>(saneStatus);
344 SCAN_HILOGE("sane_control_option error, ret = [%{public}d]", status);
345 return ERR_OK;
346 }
347 } else if (controlParam.action_ == SANE_ACTION_GET_VALUE) {
348 SaneStatus saneStatus = GetControlOption(handle, controlParam, outParam);
349 if (saneStatus != SANE_STATUS_GOOD) {
350 status = static_cast<int32_t>(saneStatus);
351 SCAN_HILOGE("Get sane_control_option error, ret = [%{public}d]", status);
352 return ERR_OK;
353 }
354 } else if (controlParam.action_ == SANE_ACTION_SET_VALUE) {
355 SaneStatus saneStatus = SetControlOption(handle, controlParam, outParam);
356 if (saneStatus != SANE_STATUS_GOOD) {
357 status = static_cast<int32_t>(saneStatus);
358 SCAN_HILOGE("Set sane_control_option error, ret = [%{public}d]", status);
359 return ERR_OK;
360 }
361 } else {
362 status = SANE_STATUS_INVAL;
363 SCAN_HILOGE("action is invalid, action = [%{public}u]", controlParam.action_);
364 return ERR_OK;
365 }
366 SCAN_HILOGI("SaneControlOption end");
367 return ERR_OK;
368 }
369
GetControlOption(SANE_Handle & handle,const SaneControlParam & controlParam,SaneOutParam & outParam)370 SaneStatus SaneServerManager::GetControlOption(SANE_Handle& handle,
371 const SaneControlParam& controlParam, SaneOutParam& outParam)
372 {
373 if (handle == nullptr) {
374 SCAN_HILOGE("handle is a nullptr");
375 return SANE_STATUS_INVAL;
376 }
377 SANE_Int option = controlParam.option_;
378 int32_t valueType = controlParam.valueType_;
379 SANE_Status saneStatus = ::SANE_STATUS_GOOD;
380 SCAN_HILOGD("valueSize_ = [%{public}d], valueType = [%{public}u]", controlParam.valueSize_, valueType);
381 if (valueType == SCAN_VALUE_NUM) {
382 int32_t value = 0;
383 saneStatus = sane_control_option(handle, option, ::SANE_ACTION_GET_VALUE, &value, nullptr);
384 outParam.valueNumber_ = value;
385 } else if (valueType == SCAN_VALUE_STR) {
386 std::string value;
387 value.resize(controlParam.valueSize_ + 1);
388 saneStatus = sane_control_option(handle, option, ::SANE_ACTION_GET_VALUE, &value.front(), nullptr);
389 outParam.valueStr_ = value;
390 } else if (valueType == SCAN_VALUE_BOOL) {
391 int32_t value = 0;
392 saneStatus = sane_control_option(handle, option, ::SANE_ACTION_GET_VALUE, &value, nullptr);
393 outParam.valueBool_ = value > 0 ? true : false;
394 }
395 if (saneStatus != ::SANE_STATUS_GOOD) {
396 SCAN_HILOGE("Get sane_control_option error, ret = [%{public}u]", saneStatus);
397 return static_cast<SaneStatus>(saneStatus);
398 }
399 return SANE_STATUS_GOOD;
400 }
401
SetControlOption(SANE_Handle & handle,const SaneControlParam & controlParam,SaneOutParam & outParam)402 SaneStatus SaneServerManager::SetControlOption(SANE_Handle& handle,
403 const SaneControlParam& controlParam, SaneOutParam& outParam)
404 {
405 if (handle == nullptr) {
406 SCAN_HILOGE("handle is a nullptr");
407 return SANE_STATUS_INVAL;
408 }
409 SANE_Int option = controlParam.option_;
410 SANE_Action action = static_cast<SANE_Action>(controlParam.action_);
411 SANE_Int& info = outParam.info_;
412 int32_t valueType = controlParam.valueType_;
413 SCAN_HILOGD("SetControlOption, valueType = [%{public}d]", valueType);
414 SANE_Status saneStatus = ::SANE_STATUS_GOOD;
415 if (valueType == SCAN_VALUE_NUM) {
416 int32_t value = controlParam.valueNumber_;
417 saneStatus = sane_control_option(handle, option, action, &value, &info);
418 } else if (valueType == SCAN_VALUE_STR) {
419 std::string value = controlParam.valueStr_;
420 saneStatus = sane_control_option(handle, option, action, const_cast<char*>(&value.front()), &info);
421 }
422 if (saneStatus != ::SANE_STATUS_GOOD) {
423 SCAN_HILOGE("Set sane_control_option error, ret = [%{public}u]", saneStatus);
424 return static_cast<SaneStatus>(saneStatus);
425 }
426 return SANE_STATUS_GOOD;
427 }
428
SaneRead(const std::string & scannerId,const int32_t buflen,SanePictureData & pictureData,int32_t & status)429 ErrCode SaneServerManager::SaneRead(const std::string& scannerId,
430 const int32_t buflen, SanePictureData& pictureData, int32_t& status)
431 {
432 SCAN_HILOGI("SaneRead start");
433 if (!CheckPermission()) {
434 SCAN_HILOGE("no permission to access sane_service");
435 return SANE_STATUS_NO_PERMISSION;
436 }
437 if (buflen < 0 || buflen > MAX_BUFLEN) {
438 SCAN_HILOGE("invalid buflen, buflen = %{public}d", buflen);
439 status = SANE_STATUS_INVAL;
440 return ERR_OK;
441 }
442 SANE_Handle handle = GetScanHandle(scannerId);
443 if (handle == nullptr) {
444 SCAN_HILOGE("handle is a nullptr");
445 status = SANE_STATUS_INVAL;
446 return ERR_OK;
447 }
448 constexpr int32_t zero = 0;
449 SANE_Int curReadSize = zero;
450 std::vector<SANE_Byte> valueBuffer(buflen);
451 SANE_Status saneStatus = ::SANE_STATUS_GOOD;
452 do {
453 saneStatus = sane_read(handle, valueBuffer.data(), buflen, &curReadSize);
454 } while (saneStatus == ::SANE_STATUS_GOOD && curReadSize == zero);
455 status = static_cast<int32_t>(saneStatus);
456 if (saneStatus != ::SANE_STATUS_GOOD && saneStatus != ::SANE_STATUS_EOF) {
457 SCAN_HILOGE("sane_read error, ret = [%{public}d]", status);
458 pictureData.ret_ = SANE_READ_FAIL;
459 return ERR_OK;
460 }
461 if (curReadSize > 0) {
462 valueBuffer.resize(curReadSize);
463 }
464 pictureData.dataBuffer_ = std::move(valueBuffer);
465 pictureData.ret_ = SANE_READ_OK;
466 SCAN_HILOGI("SaneRead end");
467 return ERR_OK;
468 }
469
UnloadSystemAbility()470 ErrCode SaneServerManager::UnloadSystemAbility()
471 {
472 SCAN_HILOGI("UnloadSystemAbility start");
473 if (!CheckPermission()) {
474 SCAN_HILOGE("no permission to access sane_service");
475 return SANE_STATUS_NO_PERMISSION;
476 }
477 std::lock_guard<std::mutex> autoLock(scannerHandleListlock_);
478 for (const auto& scanner : scannerHandleList_) {
479 sane_cancel(scanner.second);
480 sane_close(scanner.second);
481 }
482 scannerHandleList_.clear();
483 sane_exit();
484 const std::string dataTmpDir = "/data/service/el2/public/print_service/sane/tmp";
485 std::vector<std::string> files;
486 GetDirFiles(dataTmpDir, files);
487 for (const auto& file : files) {
488 if (!RemoveFile(file)) {
489 SCAN_HILOGW("RemoveFile failed");
490 }
491 }
492 auto task = [this] () {
493 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
494 if (samgrProxy == nullptr) {
495 SCAN_HILOGE("get samgr failed");
496 return;
497 }
498 int32_t ret = samgrProxy->UnloadSystemAbility(SANE_SERVICE_ID);
499 if (ret != ERR_OK) {
500 SCAN_HILOGE("unload sane_service failed");
501 return;
502 }
503 SCAN_HILOGI("unload sane_service successfull.");
504 };
505 std::thread unloadThead(task);
506 unloadThead.detach();
507 return ERR_OK;
508 }
509 }
510 }