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 = 1; 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 }
254 SCAN_HILOGI("ConvertSaneDescriptor end");
255 }
256
SaneGetParameters(const std::string & scannerId,SaneParameters & spm,int32_t & status)257 ErrCode SaneServerManager::SaneGetParameters(const std::string& scannerId, SaneParameters& spm, int32_t& status)
258 {
259 SCAN_HILOGI("SaneGetParameters start");
260 if (!CheckPermission()) {
261 SCAN_HILOGE("no permission to access sane_service");
262 return SANE_STATUS_NO_PERMISSION;
263 }
264 SANE_Handle handle = GetScanHandle(scannerId);
265 if (handle == nullptr) {
266 SCAN_HILOGE("handle is a nullptr");
267 status = SANE_STATUS_INVAL;
268 return ERR_OK;
269 }
270 SANE_Parameters params;
271 SANE_Status saneStatus = sane_get_parameters(handle, ¶ms);
272 if (saneStatus != ::SANE_STATUS_GOOD) {
273 status = static_cast<int32_t>(saneStatus);
274 SCAN_HILOGE("sane_get_parameters error, ret = [%{public}d]", status);
275 return ERR_OK;
276 }
277 spm.format_ = static_cast<SaneFrame>(params.format);
278 spm.lastFrame_ = params.last_frame;
279 spm.bytesPerLine_ = params.bytes_per_line;
280 spm.pixelsPerLine_ = params.pixels_per_line;
281 spm.lines_ = params.lines;
282 spm.depth_ = params.depth;
283 status = SANE_STATUS_GOOD;
284 SCAN_HILOGI("SaneGetParameters end");
285 return ERR_OK;
286 }
287
SaneGetDevices(std::vector<SaneDevice> & deviceInfos,int32_t & status)288 ErrCode SaneServerManager::SaneGetDevices(std::vector<SaneDevice>& deviceInfos, int32_t& status)
289 {
290 SCAN_HILOGI("SaneGetDevices start");
291 if (!CheckPermission()) {
292 SCAN_HILOGE("no permission to access sane_service");
293 return SANE_STATUS_NO_PERMISSION;
294 }
295 const SANE_Device **deviceList = nullptr;
296 SANE_Status saneStatus = sane_get_devices(&deviceList, SANE_FALSE);
297 if (saneStatus != ::SANE_STATUS_GOOD) {
298 status = static_cast<int32_t>(saneStatus);
299 SCAN_HILOGE("sane_get_devices error, ret = [%{public}d]", status);
300 return ERR_OK;
301 }
302 for (int32_t i = 0; deviceList[i] != nullptr; i++) {
303 SaneDevice device;
304 if (deviceList[i]->name != nullptr) {
305 device.name_ = std::string(deviceList[i]->name);
306 }
307 if (deviceList[i]->vendor != nullptr) {
308 device.vendor_ = std::string(deviceList[i]->vendor);
309 }
310 if (deviceList[i]->model != nullptr) {
311 device.model_ = std::string(deviceList[i]->model);
312 }
313 if (deviceList[i]->type != nullptr) {
314 device.type_ = std::string(deviceList[i]->type);
315 }
316 device.Dump();
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("valueType = [%{public}d], option = [%{public}d], action = [%{public}u]",
414 valueType, option, action);
415 SANE_Status saneStatus = ::SANE_STATUS_GOOD;
416 if (valueType == SCAN_VALUE_STR) {
417 std::string value = controlParam.valueStr_;
418 saneStatus = sane_control_option(handle, option, action, const_cast<char*>(&value.front()), &info);
419 SCAN_HILOGD("SetControlOption, value = [%{public}s]", value.c_str());
420 } else {
421 int32_t value = controlParam.valueNumber_;
422 saneStatus = sane_control_option(handle, option, action, &value, &info);
423 SCAN_HILOGD("SetControlOption, value = [%{public}d]", value);
424 }
425 if (saneStatus != ::SANE_STATUS_GOOD) {
426 SCAN_HILOGE("Set sane_control_option error, ret = [%{public}u]", saneStatus);
427 return static_cast<SaneStatus>(saneStatus);
428 }
429 return SANE_STATUS_GOOD;
430 }
431
SaneRead(const std::string & scannerId,const int32_t buflen,SanePictureData & pictureData,int32_t & status)432 ErrCode SaneServerManager::SaneRead(const std::string& scannerId,
433 const int32_t buflen, SanePictureData& pictureData, int32_t& status)
434 {
435 SCAN_HILOGI("SaneRead start");
436 if (!CheckPermission()) {
437 SCAN_HILOGE("no permission to access sane_service");
438 return SANE_STATUS_NO_PERMISSION;
439 }
440 if (buflen < 0 || buflen > MAX_BUFLEN) {
441 SCAN_HILOGE("invalid buflen, buflen = %{public}d", buflen);
442 status = SANE_STATUS_INVAL;
443 return ERR_OK;
444 }
445 SANE_Handle handle = GetScanHandle(scannerId);
446 if (handle == nullptr) {
447 SCAN_HILOGE("handle is a nullptr");
448 status = SANE_STATUS_INVAL;
449 return ERR_OK;
450 }
451 constexpr int32_t zero = 0;
452 SANE_Int curReadSize = zero;
453 std::vector<SANE_Byte> valueBuffer(buflen);
454 SANE_Status saneStatus = ::SANE_STATUS_GOOD;
455 do {
456 saneStatus = sane_read(handle, valueBuffer.data(), buflen, &curReadSize);
457 } while (saneStatus == ::SANE_STATUS_GOOD && curReadSize == zero);
458 status = static_cast<int32_t>(saneStatus);
459 if (saneStatus != ::SANE_STATUS_GOOD && saneStatus != ::SANE_STATUS_EOF) {
460 SCAN_HILOGE("sane_read error, ret = [%{public}d]", status);
461 pictureData.ret_ = SANE_READ_FAIL;
462 return ERR_OK;
463 }
464 if (curReadSize > 0) {
465 valueBuffer.resize(curReadSize);
466 }
467 pictureData.dataBuffer_ = std::move(valueBuffer);
468 pictureData.ret_ = SANE_READ_OK;
469 SCAN_HILOGI("SaneRead end");
470 return ERR_OK;
471 }
472
UnloadSystemAbility()473 ErrCode SaneServerManager::UnloadSystemAbility()
474 {
475 SCAN_HILOGI("UnloadSystemAbility start");
476 if (!CheckPermission()) {
477 SCAN_HILOGE("no permission to access sane_service");
478 return SANE_STATUS_NO_PERMISSION;
479 }
480 std::lock_guard<std::mutex> autoLock(scannerHandleListlock_);
481 for (const auto& scanner : scannerHandleList_) {
482 sane_cancel(scanner.second);
483 sane_close(scanner.second);
484 }
485 scannerHandleList_.clear();
486 sane_exit();
487 const std::string dataTmpDir = "/data/service/el2/public/print_service/sane/tmp";
488 std::vector<std::string> files;
489 GetDirFiles(dataTmpDir, files);
490 for (const auto& file : files) {
491 if (!RemoveFile(file)) {
492 SCAN_HILOGW("RemoveFile failed");
493 }
494 }
495 auto task = [this] () {
496 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
497 if (samgrProxy == nullptr) {
498 SCAN_HILOGE("get samgr failed");
499 return;
500 }
501 int32_t ret = samgrProxy->UnloadSystemAbility(SANE_SERVICE_ID);
502 if (ret != ERR_OK) {
503 SCAN_HILOGE("unload sane_service failed");
504 return;
505 }
506 SCAN_HILOGI("unload sane_service successfull.");
507 };
508 std::thread unloadThead(task);
509 unloadThead.detach();
510 return ERR_OK;
511 }
512 }
513 }