diff --git a/bundle.json b/bundle.json index bae86f9..a48b868 100644 --- a/bundle.json +++ b/bundle.json @@ -46,14 +46,14 @@ "usb_manager", "wifi", "cJSON", - "ace_engine" + "ace_engine", + "libjpeg-turbo" ], "third_party": [ "zlib", "cups", "cups-filters", - "backends", - "libjpeg-turbo" + "backends" ] }, "build": { @@ -61,24 +61,32 @@ "base_group": [], "fwk_group":[ "//base/print/print_fwk/interfaces/kits/napi/print_napi:print_napi", + "//base/print/print_fwk/interfaces/kits/napi/scan_napi:scan_napi", "//base/print/print_fwk/interfaces/kits/jsnapi/print_extension:printextensionability_napi", "//base/print/print_fwk/interfaces/kits/jsnapi/print_extensionctx:printextensioncontext_napi", "//base/print/print_fwk/frameworks/kits/extension:print_extension_framework", "//base/print/print_fwk/frameworks/kits/extension:print_extension_module", "//base/print/print_fwk/frameworks/innerkitsimpl/print_impl:print_client", + "//base/print/print_fwk/frameworks/innerkitsimpl/scan_impl:scan_client", "//base/print/print_fwk/frameworks/helper/print_helper:print_helper", + "//base/print/print_fwk/frameworks/helper/scan_helper:scan_helper", "//base/print/print_fwk/frameworks/models/print_models:print_models", - "//base/print/print_fwk/frameworks/ohprint:ohprint" + "//base/print/print_fwk/frameworks/ohprint:ohprint", + "//base/print/print_fwk/frameworks/ohscan:ohscan" ], "service_group":[ "//base/print/print_fwk/services/print_service:print_service", + "//base/print/print_fwk/services/scan_service:scan_service", "//base/print/print_fwk/etc/init:printservice.rc", + "//base/print/print_fwk/etc/init:scanservice.rc", "//base/print/print_fwk/profile:print_sa_profiles", + "//base/print/print_fwk/profile:scan_sa_profiles", "//base/print/print_fwk/etc/init:cups-files.conf", "//base/print/print_fwk/etc/init:cupsd.conf", "//base/print/print_fwk/etc/init:cups_service.cfg", "//base/print/print_fwk/etc/param:print.para", - "//base/print/print_fwk/etc/param:print.para.dac" + "//base/print/print_fwk/etc/param:print.para.dac", + "//base/print/print_fwk/etc/init:scanservice.cfg" ] }, "inner_kits": [ @@ -90,6 +98,14 @@ "header_base":"//base/print/print_fwk/frameworks/innerkitsimpl/print_impl/include" } }, + { + "name": "//base/print/print_fwk/frameworks/innerkitsimpl/scan_impl:scan_client", + "header": { + "header_files": [ + ], + "header_base":"//base/print/print_fwk/frameworks/innerkitsimpl/scan_impl/include" + } + }, { "name": "//base/print/print_fwk/frameworks/helper/print_helper:print_helper", "header": { @@ -98,6 +114,14 @@ "header_base":"//base/print/print_fwk/frameworks/helper/print_helper/include" } }, + { + "name": "//base/print/print_fwk/frameworks/helper/scan_helper:scan_helper", + "header": { + "header_files": [ + ], + "header_base":"//base/print/print_fwk/frameworks/helper/scan_helper/include" + } + }, { "name": "//base/print/print_fwk/frameworks/models/print_models:print_models", "header": { diff --git a/etc/init/BUILD.gn b/etc/init/BUILD.gn index bd28809..c4d81f2 100644 --- a/etc/init/BUILD.gn +++ b/etc/init/BUILD.gn @@ -42,3 +42,17 @@ ohos_prebuilt_etc("cups_service.cfg") { part_name = "print_fwk" subsystem_name = "print" } + +ohos_prebuilt_etc("scanservice.rc") { + source = "scanservice.rc" + relative_install_dir = "init" + part_name = "print_fwk" + subsystem_name = "print" +} + +ohos_prebuilt_etc("scanservice.cfg") { + source = "scanservice.cfg" + relative_install_dir = "init" + part_name = "print_fwk" + subsystem_name = "print" +} diff --git a/etc/init/printservice.cfg b/etc/init/printservice.cfg index 2007513..a7f24f1 100644 --- a/etc/init/printservice.cfg +++ b/etc/init/printservice.cfg @@ -13,7 +13,13 @@ "mkdir /data/service/el1/public/print_service/cups/serverbin/backend 0750 print print", "mkdir /data/service/el1/public/print_service/cups/serverbin/filter 0750 print print", "mkdir /data/service/el1/public/print_service/cups/datadir 0750 print print", - "mkdir /data/service/el1/public/print_service/cups/datadir/model 0750 print print" + "mkdir /data/service/el1/public/print_service/cups/datadir/model 0750 print print", + "mkdir /data/service/el1/public/print_service/sane 0755 print print", + "mkdir /data/service/el1/public/print_service/sane/backend 0755 print print", + "mkdir /data/service/el1/public/print_service/sane/config 0755 print print", + "mkdir /data/service/el1/public/print_service/sane/data 0755 print print", + "mkdir /data/service/el1/public/print_service/sane/lock 0755 print print", + "mkdir /data/service/el1/public/print_service/sane/tmp 0700 root root" ] } ], @@ -29,7 +35,8 @@ "ohos.permission.MANAGE_PRINT_JOB", "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED", "ohos.permission.MANAGE_USB_CONFIG", - "ohos.permission.MANAGE_LOCAL_ACCOUNTS" + "ohos.permission.MANAGE_LOCAL_ACCOUNTS", + "ohos.permission.CONNECT_PRINT_EXTENSION" ] } ] diff --git a/etc/init/scanservice.cfg b/etc/init/scanservice.cfg new file mode 100644 index 0000000..ea6d632 --- /dev/null +++ b/etc/init/scanservice.cfg @@ -0,0 +1,15 @@ +{ + "services" : [{ + "name" : "scan_service", + "path" : ["/system/bin/sa_main", "/system/profile/scan_service.json"], + "ondemand" : true, + "uid" : "print", + "gid" : ["print", "shell"], + "secon" : "u:r:scan_service:s0", + "permission" : [ + "ohos.permission.MANAGE_USB_CONFIG", + "ohos.permission.MANAGE_PRINT_JOB" + ] + } + ] +} diff --git a/etc/init/scanservice.rc b/etc/init/scanservice.rc new file mode 100644 index 0000000..be4932b --- /dev/null +++ b/etc/init/scanservice.rc @@ -0,0 +1,20 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +on boot + start scan_service +service scan_service /system/bin/sa_main /system/profile/scan_service.json + class z_core + user system + group system shell + seclabel u:r:scan_service:s0 diff --git a/frameworks/helper/scan_helper/BUILD.gn b/frameworks/helper/scan_helper/BUILD.gn new file mode 100644 index 0000000..a6f38bb --- /dev/null +++ b/frameworks/helper/scan_helper/BUILD.gn @@ -0,0 +1,80 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//base/print/print_fwk/print.gni") +import("//build/ohos.gni") + +config("scan_interfaces_kits_napi_config") { + visibility = [ ":*" ] + include_dirs = [ "include" ] + + cflags_cc = [ "-fno-exceptions" ] +} +ohos_shared_library("scan_helper") { + include_dirs = [ + "${print_path}/frameworks/innerkitsimpl/scan_impl/include", + "${print_utils_path}/include", + ] + public_configs = [ ":scan_interfaces_kits_napi_config" ] + + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + boundary_sanitize = true + debug = false + integer_overflow = true + ubsan = true + } + + if (debug_enable) { + cflags_cc += [ "-DDEBUG_ENABLE" ] + } + + sources = [ + "src/napi_scan_utils.cpp", + "src/scan_option_descriptor.cpp", + "src/scan_option_descriptor_helper.cpp", + "src/scan_option_value.cpp", + "src/scan_option_value_helper.cpp", + "src/scan_parameters.cpp", + "src/scan_parameters_helper.cpp", + "src/scan_progress.cpp", + "src/scan_progress_helper.cpp", + "src/scan_range.cpp", + "src/scan_range_helper.cpp", + "src/scanner_info.cpp", + "src/scanner_info_helper.cpp", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:data_ability_helper", + "ability_runtime:napi_base_context", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "eventhandler:libeventhandler", + "hilog:libhilog", + "ipc:ipc_core", + "napi:ace_napi", + "samgr:samgr_proxy", + ] + + #relative_install_dir = "module" + install_enable = true + subsystem_name = "print" + innerapi_tags = [ "platformsdk" ] + part_name = "print_fwk" +} diff --git a/frameworks/helper/scan_helper/include/napi_scan_utils.h b/frameworks/helper/scan_helper/include/napi_scan_utils.h new file mode 100644 index 0000000..758a3cc --- /dev/null +++ b/frameworks/helper/scan_helper/include/napi_scan_utils.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NAPI_SCAN_UTILS_H +#define NAPI_SCAN_UTILS_H + +#include +#include +#include + +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "scan_constant.h" +#include "scan_log.h" + +namespace OHOS::Scan { +class NapiScanUtils { +public: + static constexpr size_t MAX_ARGC = 6; + static constexpr size_t ARGC_ZERO = 0; + static constexpr size_t ARGC_ONE = 1; + static constexpr size_t ARGC_TWO = 2; + static constexpr size_t ARGC_THREE = 3; + static constexpr size_t ARGC_FOUR = 4; + static constexpr size_t ARGC_FIVE = 5; + static constexpr size_t ARGC_SIX = 6; + + static constexpr uint32_t INDEX_ZERO = 0; + static constexpr uint32_t INDEX_ONE = 1; + static constexpr uint32_t INDEX_TWO = 2; + static constexpr uint32_t INDEX_THREE = 3; + static constexpr uint32_t INDEX_FOUR = 4; + static constexpr uint32_t INDEX_FIVE = 5; + + static constexpr int32_t MAX_NUMBER_BYTES = 8; + static constexpr int32_t MAX_LEN = 4096; + static constexpr int32_t MAX_JOBSTRING_LENGTH = 10; + + static napi_valuetype GetValueType(napi_env env, napi_value value); + static bool HasNamedProperty(napi_env env, napi_value object, const std::string &propertyName); + static napi_value GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName); + static void SetNamedProperty(napi_env env, napi_value object, const std::string &name, napi_value value); + static std::vector GetPropertyNames(napi_env env, napi_value object); + static napi_value CreateUint32(napi_env env, uint32_t code); + static uint32_t GetUint32FromValue(napi_env env, napi_value value); + static uint32_t GetUint32Property(napi_env env, napi_value object, const std::string &propertyName); + static void SetUint32Property(napi_env env, napi_value object, const std::string &name, uint32_t value); + static napi_value CreateInt32(napi_env env, int32_t code); + static int32_t GetInt32FromValue(napi_env env, napi_value value); + static int32_t GetInt32Property(napi_env env, napi_value object, const std::string &propertyName); + static void SetInt32Property(napi_env env, napi_value object, const std::string &name, int32_t value); + static napi_value CreateStringUtf8(napi_env env, const std::string &str); + static std::string GetStringFromValueUtf8(napi_env env, napi_value value); + static std::string GetStringPropertyUtf8(napi_env env, napi_value object, const std::string &propertyName); + static void SetStringPropertyUtf8( + napi_env env, napi_value object, const std::string &name, const std::string &value); + static std::string GetValueString(napi_env env, napi_value value); + static bool ValueIsArrayBuffer(napi_env env, napi_value value); + static void *GetInfoFromArrayBufferValue(napi_env env, napi_value value, size_t *length); + static napi_value CreateArrayBuffer(napi_env env, size_t length, void **data); + static napi_value CreateObject(napi_env env); + static napi_value GetUndefined(napi_env env); + static napi_value CallFunction(napi_env env, napi_value recv, napi_value func, size_t argc, const napi_value *argv); + static napi_value CreateFunction(napi_env env, const std::string &name, napi_callback func, void *arg); + static napi_ref CreateReference(napi_env env, napi_value callback); + static napi_value GetReference(napi_env env, napi_ref callbackRef); + static void DeleteReference(napi_env env, napi_ref callbackRef); + static napi_value CreateBoolean(napi_env env, bool value); + static bool GetBooleanFromValue(napi_env env, napi_value value); + static bool GetBooleanProperty(napi_env env, napi_value object, const std::string &propertyName); + static void SetBooleanProperty(napi_env env, napi_value object, const std::string &name, bool value); + static void DefineProperties( + napi_env env, napi_value object, const std::initializer_list &properties); + static std::string ToLower(const std::string &s); + static std::string GetExtensionId(const std::string &globalId); + static std::string GetGlobalId(const std::string& extensionId, const std::string& localId); + static std::string GetLocalId(const std::string& globalId, const std::string& extensionId); + static std::string EncodeExtensionCid(const std::string &extensionId, uint32_t callbackId); + static bool DecodeExtensionCid(const std::string &cid, std::string &extensionId, uint32_t &callbackId); + static std::string GetTaskEventId(const std::string &taskId, const std::string &type); + static int32_t OpenFile(const std::string &filePath); + static bool IsPathValid(const std::string &filePath); + static uint32_t GetIdFromFdPath(const std::string &fdPath); + static size_t GetJsVal(napi_env env, napi_callback_info info, napi_value argv[], size_t length); +}; +} // namespace OHOS::Scan +#endif // NAPI_SCAN_UTILS_H \ No newline at end of file diff --git a/frameworks/helper/scan_helper/include/scan_option_descriptor.h b/frameworks/helper/scan_helper/include/scan_option_descriptor.h new file mode 100644 index 0000000..fce2b35 --- /dev/null +++ b/frameworks/helper/scan_helper/include/scan_option_descriptor.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_OPTION_DESCRIPTOR_H +#define SCAN_OPTION_DESCRIPTOR_H + +#include "parcel.h" +#include "scan_range.h" + +namespace OHOS::Scan { +class ScanOptionDescriptor final : public Parcelable { +public: + explicit ScanOptionDescriptor(); + ScanOptionDescriptor(const ScanOptionDescriptor &right); + ~ScanOptionDescriptor() = default; + + ScanOptionDescriptor &operator=(const ScanOptionDescriptor &right); + + void SetOptionName(const std::string &optionName); + void SetOptionTitle(const std::string &optionTitle); + void SetOptionDesc(const std::string &optionDesc); + void SetOptionType(const uint32_t &optionType); + void SetOptionUnit(const uint32_t &optionUnit); + + void SetOptionSize(const int32_t &optionSize); + void SetOptionCap(const int32_t &optionCap); + + void SetOptionConstraintType(const uint32_t &optionConstraintType); + void SetOptionConstraintString(const std::vector &optionConstraintString); + void SetOptionConstraintNumber(const std::vector &optionConstraintNumber); + void SetOptionConstraintRange(const ScanRange& optionConstraintRange); + + [[nodiscard]] std::string GetOptionName() const; + [[nodiscard]] std::string GetOptionTitle() const; + [[nodiscard]] std::string GetOptionDesc() const; + [[nodiscard]] uint32_t GetOptionType() const; + [[nodiscard]] uint32_t GetOptionUnit() const; + + [[nodiscard]] int32_t GetOptionSize() const; + [[nodiscard]] int32_t GetOptionCap() const; + + [[nodiscard]] uint32_t GetOptionConstraintType() const; + void GetOptionConstraintString(std::vector &optionConstraintString) const; + void GetOptionConstraintNumber(std::vector &optionConstraintNumber) const; + void GetOptionConstraintRange(ScanRange &optionConstraintRange) const; + + virtual bool Marshalling(Parcel &parcel) const override; + + static std::shared_ptr Unmarshalling(Parcel &parcel); + + void Dump(); + +private: + void ReadFromParcel(Parcel &parcel); + +private: + std::string optionName_; + std::string optionTitle_; + std::string optionDesc_; + uint32_t optionType_; + uint32_t optionUnit_; + + int32_t optionSize_; + int32_t optionCap_; + + uint32_t optionConstraintType_; + std::vector optionConstraintString_; + std::vector optionConstraintNumber_; + ScanRange optionConstraintRange_; +}; +} // namespace OHOS::Scan +#endif // SCAN_OPTION_DESCRIPTOR_H diff --git a/frameworks/helper/scan_helper/include/scan_option_descriptor_helper.h b/frameworks/helper/scan_helper/include/scan_option_descriptor_helper.h new file mode 100644 index 0000000..8f7ee2b --- /dev/null +++ b/frameworks/helper/scan_helper/include/scan_option_descriptor_helper.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_OPTION_DESCRIPTOR_HELPER +#define SCAN_OPTION_DESCRIPTOR_HELPER + +#include +#include "napi/native_api.h" +#include "scan_option_descriptor.h" + +namespace OHOS::Scan { +class ScanOptionDescriptorHelper { +public: + static napi_value MakeJsObject(napi_env env, const ScanOptionDescriptor &info); + static std::shared_ptr BuildFromJs(napi_env env, napi_value jsValue); +private: + static napi_value GetValueFromJs(napi_env env, napi_value jsValue, + std::shared_ptr &nativeObj); + static napi_value ObjSetOptionConstraintString(napi_env env, napi_value jsValue, + std::shared_ptr &nativeObj); + static napi_value ObjSetOptionConstraintNumber(napi_env env, napi_value jsValue, + std::shared_ptr &nativeObj); + static napi_value ObjSetOptionConstraintRange(napi_env env, napi_value jsValue, + std::shared_ptr &nativeObj); +}; +} // namespace OHOS::Scan +#endif // SCAN_OPTION_DESCRIPTOR_HELPER diff --git a/frameworks/helper/scan_helper/include/scan_option_value.h b/frameworks/helper/scan_helper/include/scan_option_value.h new file mode 100644 index 0000000..cb5216c --- /dev/null +++ b/frameworks/helper/scan_helper/include/scan_option_value.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_OPTION_VALUE_H +#define SCAN_OPTION_VALUE_H + +#include +#include "parcel.h" +#include "scan_constant.h" + +namespace OHOS::Scan { +class ScanOptionValue final : public Parcelable { +public: + explicit ScanOptionValue(); + + ScanOptionValue(const ScanOptionValue &right); + + ScanOptionValue &operator=(const ScanOptionValue &right); + + virtual ~ScanOptionValue(); + + void Reset(); + void Dump(); + + void SetScanOptionValueType(const ScanOptionValueType &valueType); + void SetValueSize(const int32_t &valueSize); + void SetNumValue(const int32_t &numValue); + void SetNumListValue(const std::vector &numListValue); + void SetStrValue(const std::string &strValue); + void SetBoolValue(const bool &boolValue); + + [[nodiscard]] ScanOptionValueType GetScanOptionValueType() const; + [[nodiscard]] int32_t GetValueSize() const; + [[nodiscard]] int32_t GetNumValue() const; + void GetNumListValue(std::vector &numListValue) const; + [[nodiscard]] std::string GetStrValue() const; + [[nodiscard]] bool GetBoolValue() const; + + virtual bool Marshalling(Parcel &parcel) const override; + static std::shared_ptr Unmarshalling(Parcel &parcel); +private: + void ReadFromParcel(Parcel &parcel); + +private: + ScanOptionValueType valueType_; + int32_t valueSize_; + int32_t numValue_; + std::vector numListValue_; + std::string strValue_; + bool boolValue_; +}; +} // namespace OHOS::Scan +#endif // SCAN_OPTION_VALUE_H diff --git a/frameworks/helper/scan_helper/include/scan_option_value_helper.h b/frameworks/helper/scan_helper/include/scan_option_value_helper.h new file mode 100644 index 0000000..e9581be --- /dev/null +++ b/frameworks/helper/scan_helper/include/scan_option_value_helper.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_OPTION_VALUE_HELPER_H +#define SCAN_OPTION_VALUE_HELPER_H + +#include +#include "napi/native_api.h" +#include "scan_option_value.h" + +namespace OHOS::Scan { +class ScanOptionValueHelper { +public: + static napi_value MakeJsObject(napi_env env, const ScanOptionValue &value); + static std::shared_ptr BuildFromJs(napi_env env, napi_value jsValue); + +private: + static bool ValidateProperty(napi_env env, napi_value object); +}; +} // namespace OHOS::Scan +#endif // SCAN_OPTION_VALUE_HELPER_H diff --git a/frameworks/helper/scan_helper/include/scan_parameters.h b/frameworks/helper/scan_helper/include/scan_parameters.h new file mode 100644 index 0000000..9c5dfc1 --- /dev/null +++ b/frameworks/helper/scan_helper/include/scan_parameters.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_PARAMETERS_H +#define SCAN_PARAMETERS_H + +#include +#include "parcel.h" +#include "scan_constant.h" + +namespace OHOS::Scan { +class ScanParameters final : public Parcelable { +public: + explicit ScanParameters(); + ScanParameters(const ScanParameters &right); + ScanParameters &operator=(const ScanParameters &right); + virtual ~ScanParameters(); + + void Reset(); + void Dump(); + + void SetFormat(const ScanFrame &format); + void SetLastFrame(const bool &lastFrame); + void SetBytesPerLine(const int32_t &bytesPerLine); + void SetPixelsPerLine(const int32_t &pixelsPerLine); + void SetLines(const int32_t &lines); + void SetDepth(const int32_t &depth); + + [[nodiscard]] ScanFrame GetFormat() const; + [[nodiscard]] bool GetLastFrame() const; + [[nodiscard]] int32_t GetBytesPerLine() const; + [[nodiscard]] int32_t GetPixelsPerLine() const; + [[nodiscard]] int32_t GetLines() const; + [[nodiscard]] int32_t GetDepth() const; + + virtual bool Marshalling(Parcel &parcel) const override; + static std::shared_ptr Unmarshalling(Parcel &parcel); +private: + void ReadFromParcel(Parcel &parcel); + +private: + ScanFrame format_; + bool lastFrame_; + int32_t bytesPerLine_; + int32_t pixelsPerLine_; + int32_t lines_; + int32_t depth_; +}; +} // namespace OHOS::Scan +#endif // SCAN_PARAMETERS_H diff --git a/frameworks/helper/scan_helper/include/scan_parameters_helper.h b/frameworks/helper/scan_helper/include/scan_parameters_helper.h new file mode 100644 index 0000000..10134d7 --- /dev/null +++ b/frameworks/helper/scan_helper/include/scan_parameters_helper.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_PARAMETERS_HELPER_H +#define SCAN_PARAMETERS_HELPER_H + +#include +#include "napi/native_api.h" +#include "scan_parameters.h" + +namespace OHOS::Scan { +class ScanParametersHelper { +public: + static napi_value MakeJsObject(napi_env env, const ScanParameters ¶); + static std::shared_ptr BuildFromJs(napi_env env, napi_value jsValue); + +private: + static bool ValidateProperty(napi_env env, napi_value object); +}; +} // namespace OHOS::Scan +#endif // SCAN_PARAMETERS_H diff --git a/frameworks/helper/scan_helper/include/scan_progress.h b/frameworks/helper/scan_helper/include/scan_progress.h new file mode 100644 index 0000000..7c8b13e --- /dev/null +++ b/frameworks/helper/scan_helper/include/scan_progress.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_PROGRESS_H +#define SCAN_PROGRESS_H + +#include +#include +#include "parcel.h" +#include "scan_constant.h" + + +namespace OHOS::Scan { +using SteadyTimePoint = std::chrono::steady_clock::time_point; +class ScanProgress final : public Parcelable { +public: + explicit ScanProgress(); + ScanProgress(const ScanProgress &right); + ScanProgress &operator=(const ScanProgress &right); + virtual ~ScanProgress(); + + void SetScanProgress(const int32_t progress); + void SetScanPictureFd(const int32_t fd); + void SetIsFinal(const bool isFinal); + void SetPictureId(const int32_t pictureId); + void SetScanTime(SteadyTimePoint nowTime); + void SetTaskCode(ScanErrorCode taskCode); + void Dump() const; + + [[nodiscard]] int32_t GetScanProgress() const; + [[nodiscard]] int32_t GetScanPictureFd() const; + [[nodiscard]] bool GetIsFinal() const; + [[nodiscard]] int32_t GetPictureId() const; + [[nodiscard]] SteadyTimePoint GetScanTime() const; + [[nodiscard]] ScanErrorCode GetTaskCode() const; + + virtual bool Marshalling(Parcel &parcel) const override; + static std::shared_ptr Unmarshalling(Parcel &parcel); +private: + void ReadFromParcel(Parcel &parcel); + +private: + int32_t progress; // 0~100 + int32_t fd; + bool isFinal; + int32_t pictureId; + SteadyTimePoint timePoint; + ScanErrorCode taskCode; +}; +} // namespace OHOS::Scan +#endif // SCAN_PROGRESS_H diff --git a/frameworks/helper/scan_helper/include/scan_progress_helper.h b/frameworks/helper/scan_helper/include/scan_progress_helper.h new file mode 100644 index 0000000..588089c --- /dev/null +++ b/frameworks/helper/scan_helper/include/scan_progress_helper.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_PROGRESS_HELPER_H +#define SCAN_PROGRESS_HELPER_H + +#include +#include "napi/native_api.h" +#include "scan_progress.h" + +namespace OHOS::Scan { +class ScanProgressHelper { +public: + static napi_value MakeJsObject(napi_env env, const ScanProgress &prog); +}; +} // namespace OHOS::Scan +#endif // SCAN_PROGRESS_HELPER_H diff --git a/frameworks/helper/scan_helper/include/scan_range.h b/frameworks/helper/scan_helper/include/scan_range.h new file mode 100644 index 0000000..84f367e --- /dev/null +++ b/frameworks/helper/scan_helper/include/scan_range.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_RANGE_H +#define SCAN_RANGE_H + +#include +#include "parcel.h" + +namespace OHOS::Scan { +class ScanRange final : public Parcelable { +public: + explicit ScanRange(); + + ScanRange(const ScanRange &right); + + ScanRange &operator=(const ScanRange &right); + + virtual ~ScanRange(); + + void Reset(); + + void SetMinValue(const int32_t &minValue); + + void SetMaxValue(const int32_t &maxValue); + + void SetQuantValue(const int32_t &quantValue); + + [[nodiscard]] int32_t GetMinValue() const; + + [[nodiscard]] int32_t GetMaxValue() const; + + [[nodiscard]] int32_t GetQuantValue() const; + + virtual bool Marshalling(Parcel &parcel) const override; + + static std::shared_ptr Unmarshalling(Parcel &parcel); + + void Dump(); + +private: + void ReadFromParcel(Parcel &parcel); + +private: + int32_t minValue_; + + int32_t maxValue_; + + int32_t quantValue_; +}; +} // namespace OHOS::Scan +#endif // SCAN_RANGE_H diff --git a/frameworks/helper/scan_helper/include/scan_range_helper.h b/frameworks/helper/scan_helper/include/scan_range_helper.h new file mode 100644 index 0000000..9852098 --- /dev/null +++ b/frameworks/helper/scan_helper/include/scan_range_helper.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_RANGE_HELPER_H +#define SCAN_RANGE_HELPER_H + +#include +#include "napi/native_api.h" +#include "scan_range.h" + +namespace OHOS::Scan { +class ScanRangeHelper { +public: + static napi_value MakeJsObject(napi_env env, const ScanRange &range); + static std::shared_ptr BuildFromJs(napi_env env, napi_value jsValue); + +private: + static bool ValidateProperty(napi_env env, napi_value object); +}; +} // namespace OHOS::Scan +#endif // SCAN_RANGE_HELPER_H diff --git a/frameworks/helper/scan_helper/include/scanner_info.h b/frameworks/helper/scan_helper/include/scanner_info.h new file mode 100644 index 0000000..21619c2 --- /dev/null +++ b/frameworks/helper/scan_helper/include/scanner_info.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_DEVICE_INFO_H +#define SCAN_DEVICE_INFO_H +#define TDD_ENABLE 1 + +#include +#include "napi/native_api.h" +#include "parcel.h" + +#include "napi_scan_utils.h" + + +namespace OHOS::Scan { +class ScanDeviceInfoTCP final : public Parcelable { +public: + explicit ScanDeviceInfoTCP(); + + ScanDeviceInfoTCP(const ScanDeviceInfoTCP &right); + + ScanDeviceInfoTCP &operator=(const ScanDeviceInfoTCP &ScanDeviceInfoTCP); + + ~ScanDeviceInfoTCP() = default; + + void SetDeviceName(const std::string &deviceName_); + void SetUuid(const std::string &uuid_); + void SetModel(const std::string &model_); + void SetManufacturer(const std::string &manufacturer_); + void SetDeviceType(const std::string &deviceType_); + void SetPort(const std::string &port_); + void SetAddr(const std::string &addr_); + void SetButton(const std::string &button_); + void SetFeeder(const std::string &feeder_); + void SetDeviceState(const uint32_t &deviceState_); + void SetInfoType(const std::string &infoType_); + + [[nodiscard]] const std::string &GetDeviceName() const; + [[nodiscard]] const std::string &GetUuid() const; + [[nodiscard]] const std::string &GetModel() const; + [[nodiscard]] const std::string &GetManufacturer() const; + [[nodiscard]] const std::string &GetDeviceType() const; + [[nodiscard]] const std::string &GetPort() const; + [[nodiscard]] const std::string &GetAddr() const; + [[nodiscard]] const std::string &GetButton() const; + [[nodiscard]] const std::string &GetFeeder() const; + [[nodiscard]] const uint32_t &GetDeviceState() const; + [[nodiscard]] const std::string &GetInfoType() const; + + virtual bool Marshalling(Parcel &parcel) const override; + + static std::shared_ptr Unmarshalling(Parcel &parcel); + +#ifndef TDD_ENABLE +private: +#endif + bool ReadFromParcel(Parcel &parcel); + + static bool ValidateProperty(napi_env env, napi_value object); + +#ifndef TDD_ENABLE +private: +#endif + std::string deviceName; + std::string uuid; + std::string model; + std::string manufacturer; + std::string deviceType; + std::string port; + std::string addr; + std::string button; + std::string feeder; + uint32_t deviceState; +}; + +class ScanDeviceInfo final : public Parcelable { +public: + explicit ScanDeviceInfo(); + + ScanDeviceInfo(const ScanDeviceInfo &right); + + ScanDeviceInfo &operator=(const ScanDeviceInfo &ScanDeviceInfo); + + ~ScanDeviceInfo() = default; + + void SetDeviceId(const std::string &newDeviceId); + void SetManufacturer(const std::string &newManufacturer); + void SetModel(const std::string &newModel); + void SetDeviceType(const std::string &newDeviceType); + void SetDeviceState(const uint32_t &newDeviceState); + void Dump(); + void SetDiscoverMode(const std::string &newDiscoverMode); + void SetSerialNumber(const std::string &newSerialNumber); + void SetDeviceName(const std::string &newDeviceName); + + [[nodiscard]] const std::string &GetDeviceId() const; + [[nodiscard]] const std::string &GetManufacturer() const; + [[nodiscard]] const std::string &GetModel() const; + [[nodiscard]] const std::string &GetDeviceType() const; + [[nodiscard]] const uint32_t &GetDeviceState() const; + [[nodiscard]] const std::string &GetDiscoverMode() const; + [[nodiscard]] const std::string &GetSerialNumber() const; + [[nodiscard]] const std::string &GetDeviceName() const; + + virtual bool Marshalling(Parcel &parcel) const override; + + static std::shared_ptr Unmarshalling(Parcel &parcel); + +#ifndef TDD_ENABLE +private: +#endif + bool ReadFromParcel(Parcel &parcel); + +#ifndef TDD_ENABLE +private: +#endif + std::string deviceId; + std::string manufacturer; + std::string model; + std::string deviceType; + uint32_t deviceState; + std::string discoverMode; + std::string serialNumber; + std::string deviceName; +}; + +class ScanDeviceInfoSync final : public Parcelable { +public: + explicit ScanDeviceInfoSync(); + + ScanDeviceInfoSync(const ScanDeviceInfoSync &right); + + ScanDeviceInfoSync &operator=(const ScanDeviceInfoSync &ScanDeviceInfoSync); + + ~ScanDeviceInfoSync() = default; + + void SetDeviceId(const std::string &newDeviceId); + void SetDiscoverMode(const std::string &newDiscoverMode); + void SetSerialNumber(const std::string &newSerialNumber); + void SetSyncMode(const std::string &newSyncMode); + void SetDeviceState(const uint32_t &newDeviceState); + + [[nodiscard]] const std::string &GetDeviceId() const; + [[nodiscard]] const std::string &GetDiscoverMode() const; + [[nodiscard]] const std::string &GetSerialNumber() const; + [[nodiscard]] const std::string &GetSyncMode() const; + [[nodiscard]] const uint32_t &GetDeviceState() const; + + virtual bool Marshalling(Parcel &parcel) const override; + + static std::shared_ptr Unmarshalling(Parcel &parcel); + +#ifndef TDD_ENABLE +private: +#endif + void ReadFromParcel(Parcel &parcel); + +#ifndef TDD_ENABLE +private: +#endif + std::string deviceId; + std::string discoverMode; + std::string serialNumber; + std::string syncMode; + uint32_t deviceState; +}; + +} // namespace OHOS::Scan +#endif // SCAN_DEVICE_INFO_H diff --git a/frameworks/helper/scan_helper/include/scanner_info_helper.h b/frameworks/helper/scan_helper/include/scanner_info_helper.h new file mode 100644 index 0000000..c54d63f --- /dev/null +++ b/frameworks/helper/scan_helper/include/scanner_info_helper.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCANNER_INFO_HELPER_H +#define SCANNER_INFO_HELPER_H + +#include +#include "napi/native_api.h" +#include "scanner_info.h" + +namespace OHOS::Scan { + +class ScannerInfoHelperTCP { +public: + static napi_value MakeJsObject(napi_env env, const ScanDeviceInfoTCP &info); +}; + +class ScannerInfoHelper { +public: + static napi_value MakeJsObject(napi_env env, const ScanDeviceInfo &info); +}; + +class ScannerInfoSyncHelper { +public: + static napi_value MakeJsObject(napi_env env, const ScanDeviceInfoSync &info); +}; + +} +#endif diff --git a/frameworks/helper/scan_helper/src/napi_scan_utils.cpp b/frameworks/helper/scan_helper/src/napi_scan_utils.cpp new file mode 100644 index 0000000..be09296 --- /dev/null +++ b/frameworks/helper/scan_helper/src/napi_scan_utils.cpp @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi_scan_utils.h" + +#include +#include "ability.h" +#include "napi_base_context.h" +#include "scan_log.h" +#include "securec.h" + +namespace OHOS::Scan { +static constexpr const int MAX_STRING_LENGTH = 65536; +const std::string GLOBAL_ID_DELIMITER = ":"; +const std::string EXTENSION_CID_DELIMITER = ":"; +const std::string TASK_EVENT_DELIMITER = "-"; + +napi_valuetype NapiScanUtils::GetValueType(napi_env env, napi_value value) +{ + if (value == nullptr) { + return napi_undefined; + } + + napi_valuetype valueType = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, value, &valueType), napi_undefined); + return valueType; +} + +/* named property */ +bool NapiScanUtils::HasNamedProperty(napi_env env, napi_value object, const std::string &propertyName) +{ + bool hasProperty = false; + SCAN_CALL_BASE(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty), false); + return hasProperty; +} + +napi_value NapiScanUtils::GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName) +{ + napi_value value = nullptr; + bool hasProperty = false; + SCAN_CALL(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty)); + if (!hasProperty) { + return value; + } + SCAN_CALL(env, napi_get_named_property(env, object, propertyName.c_str(), &value)); + return value; +} + +void NapiScanUtils::SetNamedProperty(napi_env env, napi_value object, const std::string &name, napi_value value) +{ + (void)napi_set_named_property(env, object, name.c_str(), value); +} + +std::vector NapiScanUtils::GetPropertyNames(napi_env env, napi_value object) +{ + std::vector ret; + napi_value names = nullptr; + SCAN_CALL_BASE(env, napi_get_property_names(env, object, &names), ret); + uint32_t length = 0; + SCAN_CALL_BASE(env, napi_get_array_length(env, names, &length), ret); + for (uint32_t index = 0; index < length; ++index) { + napi_value name = nullptr; + if (napi_get_element(env, names, index, &name) != napi_ok) { + continue; + } + if (GetValueType(env, name) != napi_string) { + continue; + } + ret.emplace_back(GetStringFromValueUtf8(env, name)); + } + return ret; +} + +/* UINT32 */ +napi_value NapiScanUtils::CreateUint32(napi_env env, uint32_t code) +{ + napi_value value = nullptr; + if (napi_create_uint32(env, code, &value) != napi_ok) { + return nullptr; + } + return value; +} + +uint32_t NapiScanUtils::GetUint32FromValue(napi_env env, napi_value value) +{ + uint32_t ret = 0; + SCAN_CALL_BASE(env, napi_get_value_uint32(env, value, &ret), 0); + return ret; +} + +uint32_t NapiScanUtils::GetUint32Property(napi_env env, napi_value object, const std::string &propertyName) +{ + if (!HasNamedProperty(env, object, propertyName)) { + return 0; + } + napi_value value = GetNamedProperty(env, object, propertyName); + return GetUint32FromValue(env, value); +} + +void NapiScanUtils::SetUint32Property(napi_env env, napi_value object, const std::string &name, uint32_t value) +{ + napi_value jsValue = CreateUint32(env, value); + if (GetValueType(env, jsValue) != napi_number) { + return; + } + + napi_set_named_property(env, object, name.c_str(), jsValue); +} + +/* INT32 */ +napi_value NapiScanUtils::CreateInt32(napi_env env, int32_t code) +{ + napi_value value = nullptr; + if (napi_create_int32(env, code, &value) != napi_ok) { + return nullptr; + } + return value; +} + +int32_t NapiScanUtils::GetInt32FromValue(napi_env env, napi_value value) +{ + int32_t ret = 0; + SCAN_CALL_BASE(env, napi_get_value_int32(env, value, &ret), 0); + return ret; +} + +int32_t NapiScanUtils::GetInt32Property(napi_env env, napi_value object, const std::string &propertyName) +{ + if (!HasNamedProperty(env, object, propertyName)) { + return 0; + } + napi_value value = GetNamedProperty(env, object, propertyName); + return GetInt32FromValue(env, value); +} + +void NapiScanUtils::SetInt32Property(napi_env env, napi_value object, const std::string &name, int32_t value) +{ + napi_value jsValue = CreateInt32(env, value); + if (GetValueType(env, jsValue) != napi_number) { + return; + } + + napi_set_named_property(env, object, name.c_str(), jsValue); +} + +/* String UTF8 */ +napi_value NapiScanUtils::CreateStringUtf8(napi_env env, const std::string &str) +{ + napi_value value = nullptr; + if (napi_create_string_utf8(env, str.c_str(), strlen(str.c_str()), &value) != napi_ok) { + return nullptr; + } + return value; +} + +std::string NapiScanUtils::GetStringFromValueUtf8(napi_env env, napi_value value) +{ + std::string result; + std::vector str(MAX_STRING_LENGTH + 1, '\0'); + size_t length = 0; + SCAN_CALL_BASE(env, napi_get_value_string_utf8(env, value, &str[0], MAX_STRING_LENGTH, &length), result); + if (length > 0) { + return result.append(&str[0], length); + } + return result; +} + +std::string NapiScanUtils::GetStringPropertyUtf8(napi_env env, napi_value object, const std::string &propertyName) +{ + if (!HasNamedProperty(env, object, propertyName)) { + return ""; + } + napi_value value = GetNamedProperty(env, object, propertyName); + return GetStringFromValueUtf8(env, value); +} + +void NapiScanUtils::SetStringPropertyUtf8( + napi_env env, napi_value object, const std::string &name, const std::string &value) +{ + napi_value jsValue = CreateStringUtf8(env, value); + if (GetValueType(env, jsValue) != napi_string) { + return; + } + napi_set_named_property(env, object, name.c_str(), jsValue); +} + +/* array buffer */ + +napi_value NapiScanUtils::CreateArrayBuffer(napi_env env, size_t length, void **data) +{ + napi_value object = nullptr; + SCAN_CALL(env, napi_create_arraybuffer(env, length, data, &object)); + return object; +} + +bool NapiScanUtils::ValueIsArrayBuffer(napi_env env, napi_value value) +{ + bool isArrayBuffer = false; + SCAN_CALL_BASE(env, napi_is_arraybuffer(env, value, &isArrayBuffer), false); + return isArrayBuffer; +} + +void *NapiScanUtils::GetInfoFromArrayBufferValue(napi_env env, napi_value value, size_t *length) +{ + if (length == nullptr) { + return nullptr; + } + + void *data = nullptr; + SCAN_CALL(env, napi_get_arraybuffer_info(env, value, &data, length)); + return data; +} + +/* object */ +napi_value NapiScanUtils::CreateObject(napi_env env) +{ + napi_value object = nullptr; + SCAN_CALL(env, napi_create_object(env, &object)); + return object; +} + +/* undefined */ +napi_value NapiScanUtils::GetUndefined(napi_env env) +{ + napi_value undefined = nullptr; + SCAN_CALL(env, napi_get_undefined(env, &undefined)); + return undefined; +} + +/* function */ +napi_value NapiScanUtils::CallFunction( + napi_env env, napi_value recv, napi_value func, size_t argc, const napi_value *argv) +{ + napi_value res = nullptr; + SCAN_CALL(env, napi_call_function(env, recv, func, argc, argv, &res)); + return res; +} + +/* reference */ +napi_ref NapiScanUtils::CreateReference(napi_env env, napi_value callback) +{ + napi_ref callbackRef = nullptr; + SCAN_CALL(env, napi_create_reference(env, callback, 1, &callbackRef)); + return callbackRef; +} + +napi_value NapiScanUtils::GetReference(napi_env env, napi_ref callbackRef) +{ + napi_value callback = nullptr; + SCAN_CALL(env, napi_get_reference_value(env, callbackRef, &callback)); + return callback; +} + +void NapiScanUtils::DeleteReference(napi_env env, napi_ref callbackRef) +{ + (void)napi_delete_reference(env, callbackRef); +} + +/* boolean */ +napi_value NapiScanUtils::CreateBoolean(napi_env env, bool value) +{ + napi_value jsValue = nullptr; + if (napi_get_boolean(env, value, &jsValue) != napi_ok) { + return nullptr; + } + return jsValue; +} + +bool NapiScanUtils::GetBooleanFromValue(napi_env env, napi_value value) +{ + bool ret = 0; + SCAN_CALL_BASE(env, napi_get_value_bool(env, value, &ret), 0); + return ret; +} + +bool NapiScanUtils::GetBooleanProperty(napi_env env, napi_value object, const std::string &propertyName) +{ + if (!HasNamedProperty(env, object, propertyName)) { + return false; + } + napi_value value = GetNamedProperty(env, object, propertyName); + bool ret = false; + SCAN_CALL_BASE(env, napi_get_value_bool(env, value, &ret), false); + return ret; +} + +void NapiScanUtils::SetBooleanProperty(napi_env env, napi_value object, const std::string &name, bool value) +{ + napi_value jsValue = nullptr; + SCAN_CALL_RETURN_VOID(env, napi_get_boolean(env, value, &jsValue)); + if (GetValueType(env, jsValue) != napi_boolean) { + return; + } + + napi_set_named_property(env, object, name.c_str(), jsValue); +} + +/* define properties */ +void NapiScanUtils::DefineProperties( + napi_env env, napi_value object, const std::initializer_list &properties) +{ + napi_property_descriptor descriptors[properties.size()]; + std::copy(properties.begin(), properties.end(), descriptors); + + (void)napi_define_properties(env, object, properties.size(), descriptors); +} + +std::string NapiScanUtils::ToLower(const std::string &s) +{ + std::string res = s; + std::transform(res.begin(), res.end(), res.begin(), tolower); + return res; +} + +std::string NapiScanUtils::GetValueString(napi_env env, napi_value value) +{ + std::string resultValue = ""; + char value_string[256]; + size_t value_size = 256; + size_t result; + napi_get_value_string_utf8(env, value, value_string, value_size, &result); + resultValue = value_string; + return resultValue; +} + +std::string NapiScanUtils::GetExtensionId(const std::string &globalId) +{ + auto pos = globalId.find(GLOBAL_ID_DELIMITER); + if (pos == std::string::npos) { + return ""; + } + return globalId.substr(0, pos); +} + +std::string NapiScanUtils::GetGlobalId(const std::string& extensionId, const std::string& localId) +{ + return extensionId + GLOBAL_ID_DELIMITER + localId; +} + +std::string NapiScanUtils::GetLocalId(const std::string& globalId, const std::string& extensionId) +{ + auto pos = globalId.find(GLOBAL_ID_DELIMITER); + if (pos == std::string::npos) { + return ""; + } + + if (globalId.substr(0, pos) != extensionId) { + return ""; + } + return globalId.substr(pos + 1); +} + +std::string NapiScanUtils::EncodeExtensionCid(const std::string &extensionId, uint32_t callbackId) +{ + return extensionId + EXTENSION_CID_DELIMITER + std::to_string(callbackId); +} + +bool NapiScanUtils::DecodeExtensionCid(const std::string &cid, std::string &extensionId, uint32_t &callbackId) +{ + auto pos = cid.find(EXTENSION_CID_DELIMITER); + if (pos == std::string::npos) { + return false; + } + extensionId = cid.substr(0, pos); + callbackId = static_cast(atoi(cid.substr(pos + 1).c_str())); + return true; +} + +std::string NapiScanUtils::GetTaskEventId(const std::string &taskId, const std::string &type) +{ + return type + TASK_EVENT_DELIMITER + taskId; +} + +int32_t NapiScanUtils::OpenFile(const std::string &filePath) +{ + if (!IsPathValid(filePath)) { + return SCAN_INVALID_ID; + } + char realFilePath[PATH_MAX] = {}; + if (realpath(filePath.c_str(), realFilePath) == nullptr) { + SCAN_HILOGE("The realFilePath is null."); + return SCAN_INVALID_ID; + } + int32_t fd = open(realFilePath, O_RDONLY); + SCAN_HILOGD("fd: %{public}d", fd); + if (fd < 0) { + SCAN_HILOGE("Failed to open file errno: %{public}s", std::to_string(errno).c_str()); + return SCAN_INVALID_ID; + } + return fd; +} + +bool NapiScanUtils::IsPathValid(const std::string &filePath) +{ + auto path = filePath.substr(0, filePath.rfind('/')); + char resolvedPath[PATH_MAX + 1] = { 0 }; + if (path.length() > PATH_MAX || realpath(path.c_str(), resolvedPath) == nullptr || + strncmp(resolvedPath, path.c_str(), path.length()) != 0) { + SCAN_HILOGE("invalid file path!"); + return false; + } + return true; +} + +uint32_t NapiScanUtils::GetIdFromFdPath(const std::string &fdPath) +{ + std::string fd_str = fdPath.substr(fdPath.rfind('/') + 1, fdPath.length()); + std::stringstream getStrStream(fd_str); + uint32_t fd; + if (!(getStrStream >> fd)) { + SCAN_HILOGD("failed to convert to uint32"); + } + return fd; +} + +size_t NapiScanUtils::GetJsVal(napi_env env, napi_callback_info info, napi_value argv[], size_t length) +{ + size_t argc = length; + napi_value thisVal = nullptr; + void *data = nullptr; + napi_get_cb_info(env, info, &argc, argv, &thisVal, &data); + return argc; +} + +} // namespace OHOS::Scan diff --git a/frameworks/helper/scan_helper/src/scan_option_descriptor.cpp b/frameworks/helper/scan_helper/src/scan_option_descriptor.cpp new file mode 100644 index 0000000..199c1f3 --- /dev/null +++ b/frameworks/helper/scan_helper/src/scan_option_descriptor.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_option_descriptor.h" +#include "scan_log.h" + +namespace OHOS::Scan { +ScanOptionDescriptor::ScanOptionDescriptor() : optionName_(""), optionTitle_(""), optionDesc_(""), + optionType_(0), optionUnit_(0), optionSize_(0), optionCap_(0), optionConstraintType_(0) { + optionConstraintString_.clear(); + optionConstraintNumber_.clear(); +} + +ScanOptionDescriptor::ScanOptionDescriptor(const ScanOptionDescriptor &right) +{ + optionName_ = right.optionName_; + optionTitle_ = right.optionTitle_; + optionDesc_ = right.optionDesc_; + optionType_ = right.optionType_; + optionUnit_ = right.optionUnit_; + + optionSize_ = right.optionSize_; + optionCap_ = right.optionCap_; + + optionConstraintType_ = right.optionConstraintType_; + optionConstraintString_.assign(right.optionConstraintString_.begin(), right.optionConstraintString_.end()); + optionConstraintNumber_.assign(right.optionConstraintNumber_.begin(), right.optionConstraintNumber_.end()); + optionConstraintRange_ = right.optionConstraintRange_; +} + +ScanOptionDescriptor &ScanOptionDescriptor::operator=(const ScanOptionDescriptor &right) +{ + if (this != &right) { + optionName_ = right.optionName_; + optionTitle_ = right.optionTitle_; + optionDesc_ = right.optionDesc_; + optionType_ = right.optionType_; + optionUnit_ = right.optionUnit_; + + optionSize_ = right.optionSize_; + optionCap_ = right.optionCap_; + + optionConstraintType_ = right.optionConstraintType_; + optionConstraintString_.assign(right.optionConstraintString_.begin(), right.optionConstraintString_.end()); + optionConstraintNumber_.assign(right.optionConstraintNumber_.begin(), right.optionConstraintNumber_.end()); + optionConstraintRange_ = right.optionConstraintRange_; + } + return *this; +} + +void ScanOptionDescriptor::SetOptionName(const std::string &optionName) +{ + optionName_ = optionName; +} + +void ScanOptionDescriptor::SetOptionTitle(const std::string &optionTitle) +{ + optionTitle_ = optionTitle; +} + +void ScanOptionDescriptor::SetOptionDesc(const std::string &optionDesc) +{ + optionDesc_ = optionDesc; +} + +void ScanOptionDescriptor::SetOptionType(const uint32_t &optionType) +{ + optionType_ = optionType; +} + +void ScanOptionDescriptor::SetOptionUnit(const uint32_t &optionUnit) +{ + optionUnit_ = optionUnit; +} + +void ScanOptionDescriptor::SetOptionSize(const int32_t &optionSize) +{ + optionSize_ = optionSize; +} + +void ScanOptionDescriptor::SetOptionCap(const int32_t &optionCap) +{ + optionCap_ = optionCap; +} + +void ScanOptionDescriptor::SetOptionConstraintType(const uint32_t &optionConstraintType) +{ + optionConstraintType_ = optionConstraintType; +} + +void ScanOptionDescriptor::SetOptionConstraintString(const std::vector &optionConstraintString) +{ + optionConstraintString_.assign(optionConstraintString.begin(), optionConstraintString.end()); +} + +void ScanOptionDescriptor::SetOptionConstraintNumber(const std::vector &optionConstraintNumber) +{ + optionConstraintNumber_.assign(optionConstraintNumber.begin(), optionConstraintNumber.end()); +} + +void ScanOptionDescriptor::SetOptionConstraintRange(const ScanRange &optionConstraintRange) +{ + optionConstraintRange_ = optionConstraintRange; +} + +std::string ScanOptionDescriptor::GetOptionName() const +{ + return optionName_; +} + +std::string ScanOptionDescriptor::GetOptionTitle() const +{ + return optionTitle_; +} + +std::string ScanOptionDescriptor::GetOptionDesc() const +{ + return optionDesc_; +} + +uint32_t ScanOptionDescriptor::GetOptionType() const +{ + return optionType_; +} + +uint32_t ScanOptionDescriptor::GetOptionUnit() const +{ + return optionUnit_; +} + +int32_t ScanOptionDescriptor::GetOptionSize() const +{ + return optionSize_; +} + +int32_t ScanOptionDescriptor::GetOptionCap() const +{ + return optionCap_; +} + +uint32_t ScanOptionDescriptor::GetOptionConstraintType() const +{ + return optionConstraintType_; +} + +void ScanOptionDescriptor::GetOptionConstraintString(std::vector &optionConstraintString) const +{ + optionConstraintString.assign(optionConstraintString_.begin(), optionConstraintString_.end()); +} + +void ScanOptionDescriptor::GetOptionConstraintNumber(std::vector &optionConstraintNumber) const +{ + optionConstraintNumber.assign(optionConstraintNumber_.begin(), optionConstraintNumber_.end()); +} + +void ScanOptionDescriptor::GetOptionConstraintRange(ScanRange &optionConstraintRange) const +{ + optionConstraintRange = optionConstraintRange_; +} + +void ScanOptionDescriptor::ReadFromParcel(Parcel &parcel) +{ + SetOptionName(parcel.ReadString()); + SetOptionTitle(parcel.ReadString()); + SetOptionDesc(parcel.ReadString()); + SetOptionType(parcel.ReadUint32()); + SetOptionUnit(parcel.ReadUint32()); + + SetOptionSize(parcel.ReadInt32()); + SetOptionCap(parcel.ReadInt32()); + + SetOptionConstraintType(parcel.ReadUint32()); + + std::vector optionConstraintString; + parcel.ReadStringVector(&optionConstraintString); + if (optionConstraintString.size() > 0) { + SetOptionConstraintString(optionConstraintString); + } + + std::vector optionConstraintNumber; + parcel.ReadInt32Vector(&optionConstraintNumber); + if (optionConstraintNumber.size() > 0) { + SetOptionConstraintNumber(optionConstraintNumber); + } + + auto scanRange = ScanRange::Unmarshalling(parcel); + if (scanRange != nullptr) { + ScanRange optionConstraintRange = *scanRange; + SetOptionConstraintRange(optionConstraintRange); + } +} + +bool ScanOptionDescriptor::Marshalling(Parcel &parcel) const +{ + parcel.WriteString(optionName_); + parcel.WriteString(optionTitle_); + parcel.WriteString(optionDesc_); + parcel.WriteUint32(optionType_); + parcel.WriteUint32(optionUnit_); + + parcel.WriteInt32(optionSize_); + parcel.WriteInt32(optionCap_); + + parcel.WriteUint32(optionConstraintType_); + + parcel.WriteStringVector(optionConstraintString_); + + parcel.WriteInt32Vector(optionConstraintNumber_); + + optionConstraintRange_.Marshalling(parcel); + return true; +} + +std::shared_ptr ScanOptionDescriptor::Unmarshalling(Parcel &parcel) +{ + auto nativeObj = std::make_shared(); + nativeObj->ReadFromParcel(parcel); + return nativeObj; +} + +void ScanOptionDescriptor::Dump() +{ + SCAN_HILOGD("optionName = %{public}s", optionName_.c_str()); + SCAN_HILOGD("optionTitle = %{public}s", optionTitle_.c_str()); + SCAN_HILOGD("optionDesc = %{public}s", optionDesc_.c_str()); + SCAN_HILOGD("optionType = %{public}d", optionType_); + SCAN_HILOGD("optionUnit = %{public}d", optionUnit_); + + SCAN_HILOGD("optionSize = %{public}d", optionSize_); + SCAN_HILOGD("optionCap = %{public}d", optionCap_); + + SCAN_HILOGD("optionConstraintType = %{public}d", optionConstraintType_); +} +} // namespace OHOS::Scan diff --git a/frameworks/helper/scan_helper/src/scan_option_descriptor_helper.cpp b/frameworks/helper/scan_helper/src/scan_option_descriptor_helper.cpp new file mode 100644 index 0000000..6c9e80f --- /dev/null +++ b/frameworks/helper/scan_helper/src/scan_option_descriptor_helper.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_option_descriptor_helper.h" +#include "scan_range_helper.h" +#include "napi_scan_utils.h" +#include "scan_log.h" + +namespace OHOS::Scan { +static constexpr const char *PARAM_OPTION_NAME = "optionName"; +static constexpr const char *PARAM_OPTION_TITLE = "optionTitle"; +static constexpr const char *PARAM_OPTION_DESC = "optionDesc"; +static constexpr const char *PARAM_OPTION_TYPE = "optionType"; +static constexpr const char *PARAM_OPTION_UNIT = "optionUnit"; +static constexpr const char *PARAM_OPTION_SIZE = "optionSize"; +static constexpr const char *PARAM_OPTION_CAP = "optionCap"; +static constexpr const char *PARAM_OPTION_CONSTRAINT_TYPE = "optionConstraintType"; +static constexpr const char *PARAM_OPTION_CONSTRAINT_STRING = "optionConstraintString"; +static constexpr const char *PARAM_OPTION_CONSTRAINT_NUMBER = "optionConstraintNumber"; +static constexpr const char *PARAM_OPTION_CONSTRAINT_RANGE = "optionConstraintRange"; + +napi_value ScanOptionDescriptorHelper::MakeJsObject(napi_env env, const ScanOptionDescriptor &desc) +{ + napi_value jsObj = nullptr; + + napi_create_object(env, &jsObj); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_OPTION_NAME, desc.GetOptionName()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_OPTION_TITLE, desc.GetOptionTitle()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_OPTION_DESC, desc.GetOptionDesc()); + NapiScanUtils::SetUint32Property(env, jsObj, PARAM_OPTION_TYPE, desc.GetOptionType()); + NapiScanUtils::SetUint32Property(env, jsObj, PARAM_OPTION_UNIT, desc.GetOptionUnit()); + + NapiScanUtils::SetInt32Property(env, jsObj, PARAM_OPTION_SIZE, desc.GetOptionSize()); + NapiScanUtils::SetInt32Property(env, jsObj, PARAM_OPTION_CAP, desc.GetOptionCap()); + + NapiScanUtils::SetUint32Property(env, jsObj, PARAM_OPTION_CONSTRAINT_TYPE, desc.GetOptionConstraintType()); + + std::vector optionConstraintString; + desc.GetOptionConstraintString(optionConstraintString); + napi_value arrOptionConstraintString = nullptr; + SCAN_CALL(env, napi_create_array(env, &arrOptionConstraintString)); + uint32_t arrOptionConstraintStringLength = optionConstraintString.size(); + for (uint32_t i = 0; i < arrOptionConstraintStringLength; i++) { + napi_value value = NapiScanUtils::CreateStringUtf8(env, optionConstraintString[i]); + SCAN_CALL(env, napi_set_element(env, arrOptionConstraintString, i, value)); + } + SCAN_CALL(env, napi_set_named_property(env, jsObj, PARAM_OPTION_CONSTRAINT_STRING, arrOptionConstraintString)); + + std::vector optionConstraintNumber; + desc.GetOptionConstraintNumber(optionConstraintNumber); + napi_value arrOptionConstraintNumber = nullptr; + SCAN_CALL(env, napi_create_array(env, &arrOptionConstraintNumber)); + uint32_t arrOptionConstraintNumberLength = optionConstraintNumber.size(); + for (uint32_t i = 0; i < arrOptionConstraintNumberLength; i++) { + napi_value value; + SCAN_CALL(env, napi_create_int32(env, optionConstraintNumber[i], &value)); + SCAN_CALL(env, napi_set_element(env, arrOptionConstraintNumber, i, value)); + } + SCAN_CALL(env, napi_set_named_property(env, jsObj, PARAM_OPTION_CONSTRAINT_NUMBER, arrOptionConstraintNumber)); + + ScanRange optionConstraintRange; + desc.GetOptionConstraintRange(optionConstraintRange); + napi_value scanRange = ScanRangeHelper::MakeJsObject(env, optionConstraintRange); + SCAN_CALL(env, napi_set_named_property(env, jsObj, PARAM_OPTION_CONSTRAINT_RANGE, scanRange)); + + return jsObj; +} + +napi_value ScanOptionDescriptorHelper::GetValueFromJs(napi_env env, napi_value jsValue, + std::shared_ptr &nativeObj) +{ + std::string optionName = NapiScanUtils::GetStringPropertyUtf8(env, jsValue, PARAM_OPTION_NAME); + nativeObj->SetOptionName(optionName); + + std::string optionTitle = NapiScanUtils::GetStringPropertyUtf8(env, jsValue, PARAM_OPTION_TITLE); + nativeObj->SetOptionTitle(optionTitle); + + std::string optionDesc = NapiScanUtils::GetStringPropertyUtf8(env, jsValue, PARAM_OPTION_DESC); + nativeObj->SetOptionDesc(optionDesc); + + uint32_t optionType = NapiScanUtils::GetUint32Property(env, jsValue, PARAM_OPTION_TYPE); + nativeObj->SetOptionType(optionType); + + uint32_t optionUnit = NapiScanUtils::GetUint32Property(env, jsValue, PARAM_OPTION_UNIT); + nativeObj->SetOptionUnit(optionUnit); + + int32_t optionSize = NapiScanUtils::GetInt32Property(env, jsValue, PARAM_OPTION_SIZE); + nativeObj->SetOptionSize(optionSize); + + int32_t optionCap = NapiScanUtils::GetInt32Property(env, jsValue, PARAM_OPTION_CAP); + nativeObj->SetOptionCap(optionCap); + + uint32_t optionConstraintType = NapiScanUtils::GetUint32Property(env, jsValue, PARAM_OPTION_CONSTRAINT_TYPE); + nativeObj->SetOptionConstraintType(optionConstraintType); + return nullptr; +} + +napi_value ScanOptionDescriptorHelper::ObjSetOptionConstraintString(napi_env env, napi_value jsValue, + std::shared_ptr &nativeObj) +{ + napi_value jsOptionConstraintString = NapiScanUtils::GetNamedProperty(env, jsValue, PARAM_OPTION_CONSTRAINT_STRING); + bool isArray = false; + if (jsOptionConstraintString != nullptr) { + std::vector optionConstraintString; + SCAN_CALL(env, napi_is_array(env, jsOptionConstraintString, &isArray)); + if (!isArray) { + SCAN_HILOGE("Invalid list of option constraint string"); + return nullptr; + } + uint32_t arrayLength = 0; + SCAN_CALL(env, napi_get_array_length(env, jsOptionConstraintString, &arrayLength)); + for (uint32_t index = 0; index < arrayLength; index++) { + napi_value jsConstraintString; + std::string constraintString; + SCAN_CALL(env, napi_get_element(env, jsOptionConstraintString, index, &jsConstraintString)); + constraintString = NapiScanUtils::GetValueString(env, jsConstraintString); + optionConstraintString.emplace_back(constraintString); + } + nativeObj->SetOptionConstraintString(optionConstraintString); + } + return nullptr; +} + +napi_value ScanOptionDescriptorHelper::ObjSetOptionConstraintNumber(napi_env env, napi_value jsValue, + std::shared_ptr &nativeObj) +{ + napi_value jsOptionConstraintNumber = NapiScanUtils::GetNamedProperty(env, jsValue, PARAM_OPTION_CONSTRAINT_NUMBER); + bool isArray = false; + if (jsOptionConstraintNumber != nullptr) { + std::vector optionConstraintNumber; + SCAN_CALL(env, napi_is_array(env, jsOptionConstraintNumber, &isArray)); + if (!isArray) { + SCAN_HILOGE("Invalid list of option constraint number"); + return nullptr; + } + uint32_t arrayLength = 0; + SCAN_CALL(env, napi_get_array_length(env, jsOptionConstraintNumber, &arrayLength)); + for (uint32_t index = 0; index < arrayLength; index++) { + napi_value jsConstraintNumber; + int32_t constraintNumber; + SCAN_CALL(env, napi_get_element(env, jsOptionConstraintNumber, index, &jsConstraintNumber)); + SCAN_CALL(env, napi_get_value_int32(env, jsConstraintNumber, &constraintNumber)); + optionConstraintNumber.emplace_back(constraintNumber); + } + nativeObj->SetOptionConstraintNumber(optionConstraintNumber); + } + return nullptr; +} + +napi_value ScanOptionDescriptorHelper::ObjSetOptionConstraintRange(napi_env env, napi_value jsValue, + std::shared_ptr &nativeObj) +{ + auto jsOptionConstraintRange = NapiScanUtils::GetNamedProperty(env, jsValue, PARAM_OPTION_CONSTRAINT_RANGE); + if (jsOptionConstraintRange != nullptr) { + auto scanRange = ScanRangeHelper::BuildFromJs(env, jsOptionConstraintRange); + if (scanRange == nullptr) { + SCAN_HILOGE("Failed to get scan range from js"); + return nullptr; + } + nativeObj->SetOptionConstraintRange(*scanRange); + } + return nullptr; +} + +std::shared_ptr ScanOptionDescriptorHelper::BuildFromJs(napi_env env, napi_value jsValue) +{ + auto nativeObj = std::make_shared(); + + auto names = NapiScanUtils::GetPropertyNames(env, jsValue); + for (auto name : names) { + SCAN_HILOGD("Property: %{public}s", name.c_str()); + } + + GetValueFromJs(env, jsValue, nativeObj); + ObjSetOptionConstraintString(env, jsValue, nativeObj); + ObjSetOptionConstraintNumber(env, jsValue, nativeObj); + ObjSetOptionConstraintRange(env, jsValue, nativeObj); + return nativeObj; +} +} // namespace OHOS::Scan diff --git a/frameworks/helper/scan_helper/src/scan_option_value.cpp b/frameworks/helper/scan_helper/src/scan_option_value.cpp new file mode 100644 index 0000000..60f507e --- /dev/null +++ b/frameworks/helper/scan_helper/src/scan_option_value.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_option_value.h" +#include "scan_log.h" + +namespace OHOS::Scan { +ScanOptionValue::ScanOptionValue() : valueType_(SCAN_VALUE_NONE + ), valueSize_(0), numValue_(0), strValue_(""), boolValue_(false) +{ + numListValue_.clear(); +} + +ScanOptionValue::ScanOptionValue(const ScanOptionValue &right) +{ + valueType_ = right.valueType_; + valueSize_ = right.valueSize_; + numValue_ = right.numValue_; + strValue_ = right.strValue_; + boolValue_ = right.boolValue_; + numListValue_.assign(right.numListValue_.begin(), right.numListValue_.end()); +} + +ScanOptionValue &ScanOptionValue::operator=(const ScanOptionValue &right) +{ + if (this != &right) { + valueType_ = right.valueType_; + valueSize_ = right.valueSize_; + numValue_ = right.numValue_; + strValue_ = right.strValue_; + boolValue_ = right.boolValue_; + numListValue_.assign(right.numListValue_.begin(), right.numListValue_.end()); + } + return *this; +} + +ScanOptionValue::~ScanOptionValue() +{} + +void ScanOptionValue::Reset() +{ + valueType_ = SCAN_VALUE_NONE; + valueSize_ = 0; + numValue_ = 0; + strValue_ = ""; + boolValue_ = false; + numListValue_.clear(); +} + +void ScanOptionValue::SetScanOptionValueType(const ScanOptionValueType &valueType) +{ + valueType_ = valueType; +} + +void ScanOptionValue::SetValueSize(const int32_t &valueSize) +{ + valueSize_ = valueSize; +} + +void ScanOptionValue::SetNumValue(const int32_t &numValue) +{ + numValue_ = numValue; +} + +void ScanOptionValue::SetNumListValue(const std::vector &numListValue) +{ + numListValue_.assign(numListValue.begin(), numListValue.end()); +} + +void ScanOptionValue::SetStrValue(const std::string &strValue) +{ + strValue_ = strValue; +} + +void ScanOptionValue::SetBoolValue(const bool &boolValue) +{ + boolValue_ = boolValue; +} + +ScanOptionValueType ScanOptionValue::GetScanOptionValueType() const +{ + return valueType_; +} + +int32_t ScanOptionValue::GetValueSize() const +{ + return valueSize_; +} + +int32_t ScanOptionValue::GetNumValue() const +{ + return numValue_; +} + +void ScanOptionValue::GetNumListValue(std::vector &numListValue) const +{ + numListValue.assign(numListValue_.begin(), numListValue_.end()); +} + +std::string ScanOptionValue::GetStrValue() const +{ + return strValue_; +} + +bool ScanOptionValue::GetBoolValue() const +{ + return boolValue_; +} + +void ScanOptionValue::ReadFromParcel(Parcel &parcel) +{ + SetScanOptionValueType((ScanOptionValueType)parcel.ReadUint32()); + SetValueSize(parcel.ReadInt32()); + if (valueType_ == SCAN_VALUE_NUM) { + SetNumValue(parcel.ReadInt32()); + } else if (valueType_ == SCAN_VALUE_NUM_LIST) { + parcel.ReadInt32Vector(&numListValue_); + } else if (valueType_ == SCAN_VALUE_STR) { + SetStrValue(parcel.ReadString()); + } else if (valueType_ == SCAN_VALUE_BOOL) { + SetBoolValue(parcel.ReadBool()); + } +} + +bool ScanOptionValue::Marshalling(Parcel &parcel) const +{ + parcel.WriteUint32(valueType_); + parcel.WriteInt32(valueSize_); + if (valueType_ == SCAN_VALUE_NUM) { + parcel.WriteInt32(numValue_); + } else if (valueType_ == SCAN_VALUE_NUM_LIST) { + parcel.WriteInt32Vector(numListValue_); + } else if (valueType_ == SCAN_VALUE_STR) { + parcel.WriteString(strValue_); + } else if (valueType_ == SCAN_VALUE_BOOL) { + parcel.WriteBool(boolValue_); + } + return true; +} + +std::shared_ptr ScanOptionValue::Unmarshalling(Parcel &parcel) +{ + auto nativeObj = std::make_shared(); + nativeObj->ReadFromParcel(parcel); + return nativeObj; +} + +void ScanOptionValue::Dump() +{ + SCAN_HILOGE("ValueType = %{public}d", valueType_); + SCAN_HILOGE("ValueSize = %{public}d", valueSize_); + if (valueType_ == SCAN_VALUE_NUM) { + SCAN_HILOGE("NumValue = %{public}d", numValue_); + } else if (valueType_ == SCAN_VALUE_NUM_LIST) { + for (auto &num : numListValue_) { + SCAN_HILOGE("NumValue = %{public}d", num); + } + } else if (valueType_ == SCAN_VALUE_STR) { + SCAN_HILOGE("StrValue = %{public}s", strValue_.c_str()); + } else if (valueType_ == SCAN_VALUE_BOOL) { + SCAN_HILOGE("BoolValue = %{public}d", boolValue_); + } +} +} // namespace OHOS::Scan diff --git a/frameworks/helper/scan_helper/src/scan_option_value_helper.cpp b/frameworks/helper/scan_helper/src/scan_option_value_helper.cpp new file mode 100644 index 0000000..272da34 --- /dev/null +++ b/frameworks/helper/scan_helper/src/scan_option_value_helper.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_option_value_helper.h" +#include "napi_scan_utils.h" +#include "scan_constant.h" +#include "scan_log.h" + +namespace OHOS::Scan { +static constexpr const char *PARAM_SCAN_OPTION_VALUE_TYPE = "valueType"; +static constexpr const char *PARAM_SCAN_OPTION_VALUE_SIZE = "valueSize"; +static constexpr const char *PARAM_SCAN_OPTION_NUM_VALUE = "numValue"; +static constexpr const char *PARAM_SCAN_OPTION_NUM_LIST_VALUE = "numListValue"; +static constexpr const char *PARAM_SCAN_OPTION_STR_VALUE = "strValue"; +static constexpr const char *PARAM_SCAN_OPTION_BOOL_VALUE = "boolValue"; + +napi_value ScanOptionValueHelper::MakeJsObject(napi_env env, const ScanOptionValue &optionValue) +{ + napi_value jsObj = nullptr; + SCAN_CALL(env, napi_create_object(env, &jsObj)); + + ScanOptionValueType valueType = optionValue.GetScanOptionValueType(); + NapiScanUtils::SetUint32Property(env, jsObj, PARAM_SCAN_OPTION_VALUE_TYPE, valueType); + + int32_t valueSize = optionValue.GetValueSize(); + NapiScanUtils::SetInt32Property(env, jsObj, PARAM_SCAN_OPTION_VALUE_SIZE, valueSize); + + if (valueType == SCAN_VALUE_NUM) { + NapiScanUtils::SetInt32Property(env, jsObj, PARAM_SCAN_OPTION_NUM_VALUE, optionValue.GetNumValue()); + } else if (valueType == SCAN_VALUE_NUM_LIST) { + std::vector numListValue; + optionValue.GetNumListValue(numListValue); + napi_value arrNumListValue = nullptr; + SCAN_CALL(env, napi_create_array(env, &arrNumListValue)); + uint32_t arrNumListValueLength = numListValue.size(); + for (uint32_t i = 0; i < arrNumListValueLength; i++) { + napi_value value; + SCAN_CALL(env, napi_create_int32(env, numListValue[i], &value)); + SCAN_CALL(env, napi_set_element(env, arrNumListValue, i, value)); + } + SCAN_CALL(env, napi_set_named_property(env, jsObj, PARAM_SCAN_OPTION_NUM_LIST_VALUE, arrNumListValue)); + } else if (valueType == SCAN_VALUE_STR) { + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_SCAN_OPTION_STR_VALUE, optionValue.GetStrValue()); + } else if (valueType == SCAN_VALUE_BOOL) { + NapiScanUtils::SetBooleanProperty(env, jsObj, PARAM_SCAN_OPTION_BOOL_VALUE, optionValue.GetBoolValue()); + } + return jsObj; +} + +std::shared_ptr ScanOptionValueHelper::BuildFromJs(napi_env env, napi_value jsValue) +{ + auto nativeObj = std::make_shared(); + if (!ValidateProperty(env, jsValue)) { + SCAN_HILOGE("Invalid property of scan option value object"); + return nullptr; + } + ScanOptionValueType valueType = (ScanOptionValueType + ) NapiScanUtils::GetUint32Property(env, jsValue, PARAM_SCAN_OPTION_VALUE_TYPE); + nativeObj->SetScanOptionValueType(valueType); + int32_t valueSize = NapiScanUtils::GetInt32Property(env, jsValue, PARAM_SCAN_OPTION_VALUE_SIZE); + nativeObj->SetValueSize(valueSize); + if (valueType == SCAN_VALUE_NUM) { + int32_t numValue = NapiScanUtils::GetInt32Property(env, jsValue, PARAM_SCAN_OPTION_NUM_VALUE); + nativeObj->SetNumValue(numValue); + } else if (valueType == SCAN_VALUE_NUM_LIST) { + napi_value jsNumListValue = NapiScanUtils::GetNamedProperty(env, jsValue, PARAM_SCAN_OPTION_NUM_LIST_VALUE); + if (jsNumListValue != nullptr) { + std::vector numListValue; + bool isArray = false; + SCAN_CALL(env, napi_is_array(env, jsNumListValue, &isArray)); + if (!isArray) { + SCAN_HILOGE("Invalid list of scan option number value"); + return nullptr; + } + uint32_t arrayLength = 0; + SCAN_CALL(env, napi_get_array_length(env, jsNumListValue, &arrayLength)); + for (uint32_t index = 0; index < arrayLength; index++) { + napi_value jsNumInList; + int32_t numInList; + SCAN_CALL(env, napi_get_element(env, jsNumListValue, index, &jsNumInList)); + SCAN_CALL(env, napi_get_value_int32(env, jsNumInList, &numInList)); + numListValue.emplace_back(numInList); + } + nativeObj->SetNumListValue(numListValue); + } + } else if (valueType == SCAN_VALUE_STR) { + std::string strValue = NapiScanUtils::GetStringPropertyUtf8(env, jsValue, PARAM_SCAN_OPTION_STR_VALUE); + nativeObj->SetStrValue(strValue); + } else if (valueType == SCAN_VALUE_BOOL) { + bool boolValue = NapiScanUtils::GetBooleanProperty(env, jsValue, PARAM_SCAN_OPTION_BOOL_VALUE); + nativeObj->SetBoolValue(boolValue); + } + SCAN_HILOGE("Build scan option value succeed"); + return nativeObj; +} + +bool ScanOptionValueHelper::ValidateProperty(napi_env env, napi_value object) +{ + std::map propertyList = { + {PARAM_SCAN_OPTION_VALUE_TYPE, SCAN_PARAM_OPT}, + {PARAM_SCAN_OPTION_VALUE_SIZE, SCAN_PARAM_OPT}, + {PARAM_SCAN_OPTION_NUM_VALUE, SCAN_PARAM_OPT}, + {PARAM_SCAN_OPTION_NUM_LIST_VALUE, SCAN_PARAM_OPT}, + {PARAM_SCAN_OPTION_STR_VALUE, SCAN_PARAM_OPT}, + {PARAM_SCAN_OPTION_BOOL_VALUE, SCAN_PARAM_OPT}, + }; + auto names = NapiScanUtils::GetPropertyNames(env, object); + for (auto name : names) { + if (propertyList.find(name) == propertyList.end()) { + SCAN_HILOGE("Invalid property: %{public}s", name.c_str()); + return false; + } + propertyList[name] = SCAN_PARAM_SET; + } + bool hasValueType = propertyList[PARAM_SCAN_OPTION_VALUE_TYPE] == SCAN_PARAM_SET; + bool hasValueSize = propertyList[PARAM_SCAN_OPTION_VALUE_SIZE] == SCAN_PARAM_SET; + if (!hasValueType || !hasValueSize) { + return false; + } + return true; +} +} // namespace OHOS::Scan diff --git a/frameworks/helper/scan_helper/src/scan_parameters.cpp b/frameworks/helper/scan_helper/src/scan_parameters.cpp new file mode 100644 index 0000000..b99beed --- /dev/null +++ b/frameworks/helper/scan_helper/src/scan_parameters.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_parameters.h" +#include "scan_log.h" + +namespace OHOS::Scan { +ScanParameters::ScanParameters() : format_(SCAN_FRAME_GRAY), + lastFrame_(false), bytesPerLine_(0), pixelsPerLine_(0), lines_(0), depth_(0) +{} + +ScanParameters::ScanParameters(const ScanParameters &right) +{ + format_ = right.format_; + lastFrame_ = right.lastFrame_; + bytesPerLine_ = right.bytesPerLine_; + pixelsPerLine_ = right.pixelsPerLine_; + lines_ = right.lines_; + depth_ = right.depth_; +} + +ScanParameters &ScanParameters::operator=(const ScanParameters &right) +{ + if (this != &right) { + format_ = right.format_; + lastFrame_ = right.lastFrame_; + bytesPerLine_ = right.bytesPerLine_; + pixelsPerLine_ = right.pixelsPerLine_; + lines_ = right.lines_; + depth_ = right.depth_; + } + return *this; +} + +ScanParameters::~ScanParameters() +{} + +void ScanParameters::Reset() +{ + format_ = SCAN_FRAME_GRAY; + lastFrame_ = false; + bytesPerLine_ = 0; + pixelsPerLine_ = 0; + lines_ = 0; + depth_ = 0; +} + +void ScanParameters::SetFormat(const ScanFrame &format) +{ + format_ = format; +} + +void ScanParameters::SetLastFrame(const bool &lastFrame) +{ + lastFrame_ = lastFrame; +} + +void ScanParameters::SetBytesPerLine(const int32_t &bytesPerLine) +{ + bytesPerLine_ = bytesPerLine; +} + +void ScanParameters::SetPixelsPerLine(const int32_t &pixelsPerLine) +{ + pixelsPerLine_ = pixelsPerLine; +} + +void ScanParameters::SetLines(const int32_t &lines) +{ + lines_ = lines; +} + +void ScanParameters::SetDepth(const int32_t &depth) +{ + depth_ = depth; +} + +ScanFrame ScanParameters::GetFormat() const +{ + return format_; +} + +bool ScanParameters::GetLastFrame() const +{ + return lastFrame_; +} + +int32_t ScanParameters::GetBytesPerLine() const +{ + return bytesPerLine_; +} + +int32_t ScanParameters::GetPixelsPerLine() const +{ + return pixelsPerLine_; +} + +int32_t ScanParameters::GetLines() const +{ + return lines_; +} + +int32_t ScanParameters::GetDepth() const +{ + return depth_; +} + + +void ScanParameters::ReadFromParcel(Parcel &parcel) +{ + SetFormat((ScanFrame)parcel.ReadUint32()); + SetLastFrame(parcel.ReadBool()); + SetBytesPerLine(parcel.ReadInt32()); + SetPixelsPerLine(parcel.ReadInt32()); + SetLines(parcel.ReadInt32()); + SetDepth(parcel.ReadInt32()); +} + +bool ScanParameters::Marshalling(Parcel &parcel) const +{ + parcel.WriteUint32((uint32_t)format_); + parcel.WriteBool(lastFrame_); + parcel.WriteInt32(bytesPerLine_); + parcel.WriteInt32(pixelsPerLine_); + parcel.WriteInt32(lines_); + parcel.WriteInt32(depth_); + return true; +} + +std::shared_ptr ScanParameters::Unmarshalling(Parcel &parcel) +{ + auto nativeObj = std::make_shared(); + nativeObj->ReadFromParcel(parcel); + return nativeObj; +} + +void ScanParameters::Dump() +{ + SCAN_HILOGI("Format = %{public}u", format_); + SCAN_HILOGI("LastFrame = %{public}d", lastFrame_); + SCAN_HILOGI("BytesPerLine = %{public}d", bytesPerLine_); + SCAN_HILOGI("PixelsPerLine = %{public}d", pixelsPerLine_); + SCAN_HILOGI("Lines = %{public}d", lines_); + SCAN_HILOGI("Depth = %{public}d", depth_); +} +} // namespace OHOS::Scan diff --git a/frameworks/helper/scan_helper/src/scan_parameters_helper.cpp b/frameworks/helper/scan_helper/src/scan_parameters_helper.cpp new file mode 100644 index 0000000..e662e21 --- /dev/null +++ b/frameworks/helper/scan_helper/src/scan_parameters_helper.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_parameters_helper.h" +#include "napi_scan_utils.h" +#include "scan_constant.h" +#include "scan_log.h" + +namespace OHOS::Scan { +static constexpr const char *PARAM_SCAN_PARA_FORMAT = "format"; +static constexpr const char *PARAM_SCAN_PARA_LAST_FRAME = "lastFrame"; +static constexpr const char *PARAM_SCAN_PARA_BYTES = "bytesPerLine"; +static constexpr const char *PARAM_SCAN_PARA_PIXELS = "pixelsPerLine"; +static constexpr const char *PARAM_SCAN_PARA_LINES = "lines"; +static constexpr const char *PARAM_SCAN_PARA_DEPTH = "depth"; + +napi_value ScanParametersHelper::MakeJsObject(napi_env env, const ScanParameters ¶) +{ + napi_value jsObj = nullptr; + SCAN_CALL(env, napi_create_object(env, &jsObj)); + NapiScanUtils::SetUint32Property(env, jsObj, PARAM_SCAN_PARA_FORMAT, para.GetFormat()); + NapiScanUtils::SetBooleanProperty(env, jsObj, PARAM_SCAN_PARA_LAST_FRAME, para.GetLastFrame()); + NapiScanUtils::SetInt32Property(env, jsObj, PARAM_SCAN_PARA_BYTES, para.GetBytesPerLine()); + NapiScanUtils::SetInt32Property(env, jsObj, PARAM_SCAN_PARA_PIXELS, para.GetPixelsPerLine()); + NapiScanUtils::SetInt32Property(env, jsObj, PARAM_SCAN_PARA_LINES, para.GetLines()); + NapiScanUtils::SetInt32Property(env, jsObj, PARAM_SCAN_PARA_DEPTH, para.GetDepth()); + return jsObj; +} + +std::shared_ptr ScanParametersHelper::BuildFromJs(napi_env env, napi_value jsValue) +{ + auto nativeObj = std::make_shared(); + + if (!ValidateProperty(env, jsValue)) { + SCAN_HILOGE("Invalid property of scan parameters"); + return nullptr; + } + + ScanFrame format = (ScanFrame)NapiScanUtils::GetUint32Property(env, jsValue, PARAM_SCAN_PARA_FORMAT); + nativeObj->SetFormat(format); + bool lastFrame = NapiScanUtils::GetBooleanProperty(env, jsValue, PARAM_SCAN_PARA_LAST_FRAME); + nativeObj->SetLastFrame(lastFrame); + int32_t bytesPerLine = NapiScanUtils::GetInt32Property(env, jsValue, PARAM_SCAN_PARA_BYTES); + nativeObj->SetBytesPerLine(bytesPerLine); + int32_t pixelsPerLine = NapiScanUtils::GetInt32Property(env, jsValue, PARAM_SCAN_PARA_PIXELS); + nativeObj->SetPixelsPerLine(pixelsPerLine); + int32_t lines = NapiScanUtils::GetInt32Property(env, jsValue, PARAM_SCAN_PARA_LINES); + nativeObj->SetLines(lines); + int32_t depth = NapiScanUtils::GetInt32Property(env, jsValue, PARAM_SCAN_PARA_DEPTH); + nativeObj->SetDepth(depth); + + SCAN_HILOGE("Build Scan Parameters succeed"); + return nativeObj; +} + +bool ScanParametersHelper::ValidateProperty(napi_env env, napi_value object) +{ + std::map propertyList = { + {PARAM_SCAN_PARA_FORMAT, SCAN_PARAM_OPT}, + {PARAM_SCAN_PARA_LAST_FRAME, SCAN_PARAM_OPT}, + {PARAM_SCAN_PARA_BYTES, SCAN_PARAM_OPT}, + {PARAM_SCAN_PARA_PIXELS, SCAN_PARAM_OPT}, + {PARAM_SCAN_PARA_LINES, SCAN_PARAM_OPT}, + {PARAM_SCAN_PARA_DEPTH, SCAN_PARAM_OPT}, + }; + + auto names = NapiScanUtils::GetPropertyNames(env, object); + for (auto name : names) { + if (propertyList.find(name) == propertyList.end()) { + SCAN_HILOGE("Invalid property: %{public}s", name.c_str()); + return false; + } + propertyList[name] = SCAN_PARAM_SET; + } + bool hasFormat = propertyList[PARAM_SCAN_PARA_FORMAT] == SCAN_PARAM_SET; + bool hasFrame = propertyList[PARAM_SCAN_PARA_LAST_FRAME] == SCAN_PARAM_SET; + bool hasBytes = propertyList[PARAM_SCAN_PARA_BYTES] == SCAN_PARAM_SET; + bool hasPixels = propertyList[PARAM_SCAN_PARA_PIXELS] == SCAN_PARAM_SET; + bool hasLines = propertyList[PARAM_SCAN_PARA_LINES] == SCAN_PARAM_SET; + bool hasDepth = propertyList[PARAM_SCAN_PARA_DEPTH] == SCAN_PARAM_SET; + + if (!hasFormat || !hasFrame || !hasBytes || !hasPixels || !hasLines || !hasDepth) { + return false; + } + return true; +} +} // namespace OHOS::Scan diff --git a/frameworks/helper/scan_helper/src/scan_progress.cpp b/frameworks/helper/scan_helper/src/scan_progress.cpp new file mode 100644 index 0000000..49944c3 --- /dev/null +++ b/frameworks/helper/scan_helper/src/scan_progress.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_progress.h" +#include "scan_log.h" +#include "message_parcel.h" + +namespace OHOS::Scan { +using SteadyTimePoint = std::chrono::steady_clock::time_point; +ScanProgress::ScanProgress() : progress(0), + fd(0), isFinal(true), pictureId(0), taskCode(E_SCAN_GOOD) +{} + +ScanProgress::ScanProgress(const ScanProgress &right) +{ + progress = right.progress; + fd = right.fd; + isFinal = right.isFinal; + pictureId = right.pictureId; + timePoint = right.timePoint; + taskCode = right.taskCode; +} + +ScanProgress &ScanProgress::operator=(const ScanProgress &right) +{ + if (this != &right) { + progress = right.progress; + fd = right.fd; + isFinal = right.isFinal; + pictureId = right.pictureId; + timePoint = right.timePoint; + taskCode = right.taskCode; + } + return *this; +} + +ScanProgress::~ScanProgress() +{} + +void ScanProgress::SetScanProgress(const int32_t progress) +{ + this->progress = progress; +} + +void ScanProgress::SetScanPictureFd(const int32_t fd) +{ + this->fd = fd; +} + +void ScanProgress::SetIsFinal(const bool isFinal) +{ + this->isFinal = isFinal; +} + +void ScanProgress::SetPictureId(const int32_t pictureId) +{ + this->pictureId = pictureId; +} + +void ScanProgress::SetScanTime(SteadyTimePoint nowTime) +{ + this->timePoint = nowTime; +} + +void ScanProgress::SetTaskCode(ScanErrorCode taskCode) +{ + this->taskCode = taskCode; +} + +int32_t ScanProgress::GetScanProgress() const +{ + return progress; +} + +int32_t ScanProgress::GetScanPictureFd() const +{ + return fd; +} + +bool ScanProgress::GetIsFinal() const +{ + return isFinal; +} + +int32_t ScanProgress::GetPictureId() const +{ + return pictureId; +} + +SteadyTimePoint ScanProgress::GetScanTime() const +{ + return timePoint; +} + +ScanErrorCode ScanProgress::GetTaskCode() const +{ + return taskCode; +} + +void ScanProgress::ReadFromParcel(Parcel &parcel) +{ + auto mesgParcel = static_cast(&parcel); + SetScanProgress(parcel.ReadInt32()); + SetScanPictureFd(mesgParcel->ReadFileDescriptor()); + SetIsFinal(parcel.ReadBool()); +} + +bool ScanProgress::Marshalling(Parcel &parcel) const +{ + auto mesgParcel = static_cast(&parcel); + parcel.WriteInt32(progress); + mesgParcel->WriteFileDescriptor(fd); + parcel.WriteBool(isFinal); + return true; +} + +std::shared_ptr ScanProgress::Unmarshalling(Parcel &parcel) +{ + auto nativeObj = std::make_shared(); + nativeObj->ReadFromParcel(parcel); + return nativeObj; +} + +void ScanProgress::Dump() const +{ + SCAN_HILOGI("ScanProgress Dump"); + SCAN_HILOGI("ScanProgress: progress = %{public}d", progress); + SCAN_HILOGI("ScanProgress: fd = %{public}d", fd); + SCAN_HILOGI("ScanProgress: isFinal = %{public}d", isFinal); + SCAN_HILOGI("ScanProgress: pictureId = %{public}d", pictureId); + SCAN_HILOGI("ScanProgress: taskCode = %{public}d", taskCode); +} + +} // namespace OHOS::Scan diff --git a/frameworks/helper/scan_helper/src/scan_progress_helper.cpp b/frameworks/helper/scan_helper/src/scan_progress_helper.cpp new file mode 100644 index 0000000..6f2c3fe --- /dev/null +++ b/frameworks/helper/scan_helper/src/scan_progress_helper.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_progress_helper.h" +#include "napi_scan_utils.h" +#include "scan_constant.h" +#include "scan_log.h" + +namespace OHOS::Scan { + +static constexpr const char *PARAM_SCAN_PROGRESS = "progress"; +static constexpr const char *PARAM_PICTURE_FD = "pictureFd"; +static constexpr const char *PARAM_IS_FINAL = "isFinal"; + +napi_value ScanProgressHelper::MakeJsObject(napi_env env, const ScanProgress ¶) +{ + napi_value jsObj = nullptr; + SCAN_CALL(env, napi_create_object(env, &jsObj)); + NapiScanUtils::SetInt32Property(env, jsObj, PARAM_SCAN_PROGRESS, para.GetScanProgress()); + NapiScanUtils::SetInt32Property(env, jsObj, PARAM_PICTURE_FD, para.GetScanPictureFd()); + NapiScanUtils::SetBooleanProperty(env, jsObj, PARAM_IS_FINAL, para.GetIsFinal()); + return jsObj; +} + +} // namespace OHOS::Scan diff --git a/frameworks/helper/scan_helper/src/scan_range.cpp b/frameworks/helper/scan_helper/src/scan_range.cpp new file mode 100644 index 0000000..36d45b5 --- /dev/null +++ b/frameworks/helper/scan_helper/src/scan_range.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_range.h" +#include "scan_log.h" + +namespace OHOS::Scan { +ScanRange::ScanRange() : minValue_(0), maxValue_(0), quantValue_(0) +{} + +ScanRange::ScanRange(const ScanRange &right) +{ + minValue_ = right.minValue_; + maxValue_ = right.maxValue_; + quantValue_ = right.quantValue_; +} + +ScanRange &ScanRange::operator=(const ScanRange &right) +{ + if (this != &right) { + minValue_ = right.minValue_; + maxValue_ = right.maxValue_; + quantValue_ = right.quantValue_; + } + return *this; +} + +ScanRange::~ScanRange() +{} + +void ScanRange::Reset() +{ + minValue_ = 0; + maxValue_ = 0; + quantValue_ = 0; +} + +void ScanRange::SetMinValue(const int32_t &minValue) +{ + minValue_ = minValue; +} + +void ScanRange::SetMaxValue(const int32_t &maxValue) +{ + maxValue_ = maxValue; +} + +void ScanRange::SetQuantValue(const int32_t &quantValue) +{ + quantValue_ = quantValue; +} + +int32_t ScanRange::GetMinValue() const +{ + return minValue_; +} + +int32_t ScanRange::GetMaxValue() const +{ + return maxValue_; +} + +int32_t ScanRange::GetQuantValue() const +{ + return quantValue_; +} + +void ScanRange::ReadFromParcel(Parcel &parcel) +{ + SetMinValue(parcel.ReadInt32()); + + SetMaxValue(parcel.ReadInt32()); + + SetQuantValue(parcel.ReadInt32()); +} + +bool ScanRange::Marshalling(Parcel &parcel) const +{ + parcel.WriteInt32(minValue_); + + parcel.WriteInt32(maxValue_); + + parcel.WriteInt32(quantValue_); + return true; +} + +std::shared_ptr ScanRange::Unmarshalling(Parcel &parcel) +{ + auto nativeObj = std::make_shared(); + nativeObj->ReadFromParcel(parcel); + return nativeObj; +} + +void ScanRange::Dump() +{ + SCAN_HILOGD("MinValue = %{public}d", minValue_); + SCAN_HILOGD("MaxValue = %{public}d", maxValue_); + SCAN_HILOGD("QuantValue = %{public}d", quantValue_); +} +} // namespace OHOS::Scan diff --git a/frameworks/helper/scan_helper/src/scan_range_helper.cpp b/frameworks/helper/scan_helper/src/scan_range_helper.cpp new file mode 100644 index 0000000..056c928 --- /dev/null +++ b/frameworks/helper/scan_helper/src/scan_range_helper.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_range_helper.h" +#include "napi_scan_utils.h" +#include "scan_constant.h" +#include "scan_log.h" + +namespace OHOS::Scan { +static constexpr const char *PARAM_RANGE_MINVALUE = "minValue"; +static constexpr const char *PARAM_RANGE_MAXVALUE = "maxValue"; +static constexpr const char *PARAM_RANGE_QUANTVALUE = "quantValue"; + +napi_value ScanRangeHelper::MakeJsObject(napi_env env, const ScanRange &range) +{ + napi_value jsObj = nullptr; + SCAN_CALL(env, napi_create_object(env, &jsObj)); + + NapiScanUtils::SetInt32Property(env, jsObj, PARAM_RANGE_MINVALUE, range.GetMinValue()); + NapiScanUtils::SetInt32Property(env, jsObj, PARAM_RANGE_MAXVALUE, range.GetMaxValue()); + NapiScanUtils::SetInt32Property(env, jsObj, PARAM_RANGE_QUANTVALUE, range.GetQuantValue()); + + return jsObj; +} + +std::shared_ptr ScanRangeHelper::BuildFromJs(napi_env env, napi_value jsValue) +{ + auto nativeObj = std::make_shared(); + + if (!ValidateProperty(env, jsValue)) { + SCAN_HILOGE("Invalid property of scan range"); + return nullptr; + } + + auto jsMinValue = NapiScanUtils::GetNamedProperty(env, jsValue, PARAM_RANGE_MINVALUE); + if (jsMinValue != nullptr) { + nativeObj->SetMinValue(NapiScanUtils::GetInt32FromValue(env, jsMinValue)); + } + + auto jsMaxValue = NapiScanUtils::GetNamedProperty(env, jsValue, PARAM_RANGE_MAXVALUE); + if (jsMaxValue != nullptr) { + nativeObj->SetMaxValue(NapiScanUtils::GetInt32FromValue(env, jsMaxValue)); + } + + auto jsQuantValue = NapiScanUtils::GetNamedProperty(env, jsValue, PARAM_RANGE_QUANTVALUE); + if (jsQuantValue != nullptr) { + nativeObj->SetQuantValue(NapiScanUtils::GetInt32FromValue(env, jsQuantValue)); + } + + SCAN_HILOGE("Build Scan Range succeed"); + return nativeObj; +} + +bool ScanRangeHelper::ValidateProperty(napi_env env, napi_value object) +{ + std::map propertyList = { + {PARAM_RANGE_MINVALUE, SCAN_PARAM_OPT}, + {PARAM_RANGE_MAXVALUE, SCAN_PARAM_OPT}, + {PARAM_RANGE_QUANTVALUE, SCAN_PARAM_OPT}, + }; + + auto names = NapiScanUtils::GetPropertyNames(env, object); + for (auto name : names) { + if (propertyList.find(name) == propertyList.end()) { + SCAN_HILOGE("Invalid property: %{public}s", name.c_str()); + return false; + } + propertyList[name] = SCAN_PARAM_SET; + } + bool hasMinValue = propertyList[PARAM_RANGE_MINVALUE] == SCAN_PARAM_SET; + bool hasMaxValue = propertyList[PARAM_RANGE_MAXVALUE] == SCAN_PARAM_SET; + bool hasQuantValue = propertyList[PARAM_RANGE_QUANTVALUE] == SCAN_PARAM_SET; + if (!hasMinValue || !hasMaxValue || !hasQuantValue) { + return false; + } + return true; +} +} // namespace OHOS::Scan diff --git a/frameworks/helper/scan_helper/src/scanner_info.cpp b/frameworks/helper/scan_helper/src/scanner_info.cpp new file mode 100644 index 0000000..1ab9f84 --- /dev/null +++ b/frameworks/helper/scan_helper/src/scanner_info.cpp @@ -0,0 +1,467 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scanner_info.h" + +namespace OHOS::Scan { + + +//tcp +ScanDeviceInfoTCP::ScanDeviceInfoTCP() +{ + deviceName=""; + uuid=""; + model=""; + manufacturer=""; + deviceType=""; + port=""; + addr=""; + button=""; + feeder=""; + deviceState = 0; +} + +ScanDeviceInfoTCP::ScanDeviceInfoTCP(const ScanDeviceInfoTCP &right) +{ + deviceName = right.deviceName; + uuid = right.uuid; + model = right.model; + manufacturer = right.manufacturer; + deviceType = right.deviceType; + port = right.port; + addr = right.addr; + button = right.button; + feeder = right.feeder; + deviceState = right.deviceState; +} + +ScanDeviceInfoTCP &ScanDeviceInfoTCP::operator=(const ScanDeviceInfoTCP &right) +{ + if (this != &right) { + deviceName = right.deviceName; + uuid = right.uuid; + model = right.model; + manufacturer = right.manufacturer; + deviceType = right.deviceType; + port = right.port; + addr = right.addr; + button = right.button; + feeder = right.feeder; + deviceState = right.deviceState; + } + return *this; +} + +void ScanDeviceInfoTCP::SetDeviceName(const std::string& deviceName_) +{ + deviceName = deviceName_; +} + +void ScanDeviceInfoTCP::SetUuid(const std::string& uuid_) +{ + uuid = uuid_; +} + +void ScanDeviceInfoTCP::SetModel(const std::string& model_) +{ + model = model_; +} + +void ScanDeviceInfoTCP::SetManufacturer(const std::string& manufacturer_) +{ + manufacturer = manufacturer_; +} + +void ScanDeviceInfoTCP::SetDeviceType(const std::string& deviceType_) +{ + deviceType = deviceType_; +} + +void ScanDeviceInfoTCP::SetPort(const std::string& port_) +{ + port = port_; +} + +void ScanDeviceInfoTCP::SetAddr(const std::string& addr_) +{ + addr = addr_; +} + +void ScanDeviceInfoTCP::SetButton(const std::string& button_) +{ + button = button_; +} + +void ScanDeviceInfoTCP::SetFeeder(const std::string& feeder_) +{ + feeder = feeder_; +} + +void ScanDeviceInfoTCP::SetDeviceState(const uint32_t& deviceState_) +{ + deviceState = deviceState_; +} + +const std::string& ScanDeviceInfoTCP::GetDeviceName() const +{ + return deviceName; +} + +const std::string& ScanDeviceInfoTCP::GetUuid() const +{ + return uuid; +} + +const std::string& ScanDeviceInfoTCP::GetModel() const +{ + return model; +} + +const std::string& ScanDeviceInfoTCP::GetManufacturer() const +{ + return manufacturer; +} + +const std::string& ScanDeviceInfoTCP::GetDeviceType() const +{ + return deviceType; +} + +const std::string& ScanDeviceInfoTCP::GetPort() const +{ + return port; +} + +const std::string& ScanDeviceInfoTCP::GetAddr() const +{ + return addr; +} + +const std::string& ScanDeviceInfoTCP::GetButton() const +{ + return button; +} + +const std::string& ScanDeviceInfoTCP::GetFeeder() const +{ + return feeder; +} + +const uint32_t& ScanDeviceInfoTCP::GetDeviceState() const +{ + return deviceState; +} + +bool ScanDeviceInfoTCP::ReadFromParcel(Parcel &parcel) +{ + SetDeviceName(parcel.ReadString()); + SetUuid(parcel.ReadString()); + SetModel(parcel.ReadString()); + SetManufacturer(parcel.ReadString()); + SetDeviceType(parcel.ReadString()); + SetPort(parcel.ReadString()); + SetAddr(parcel.ReadString()); + SetButton(parcel.ReadString()); + SetFeeder(parcel.ReadString()); + return true; +} + +bool ScanDeviceInfoTCP::Marshalling(Parcel &parcel) const +{ + parcel.WriteString(GetDeviceName()); + parcel.WriteString(GetUuid()); + parcel.WriteString(GetModel()); + parcel.WriteString(GetManufacturer()); + parcel.WriteString(GetDeviceType()); + parcel.WriteString(GetPort()); + parcel.WriteString(GetAddr()); + parcel.WriteString(GetButton()); + parcel.WriteString(GetFeeder()); + return true; +} + +std::shared_ptr ScanDeviceInfoTCP::Unmarshalling(Parcel &parcel) +{ + auto nativeObj = std::make_shared(); + if (!nativeObj->ReadFromParcel(parcel)) { + SCAN_HILOGE("Failed to unmarshalling scaner info"); + return nullptr; + } + return nativeObj; +} + + +ScanDeviceInfo::ScanDeviceInfo() +{ + deviceId = ""; + manufacturer = ""; + model = ""; + deviceType = ""; + deviceState = 0; + discoverMode = ""; + serialNumber = ""; + deviceName = ""; +} + +ScanDeviceInfo::ScanDeviceInfo(const ScanDeviceInfo &right) +{ + deviceId = right.deviceId; + manufacturer = right.manufacturer; + model = right.model; + deviceType = right.deviceType; + deviceState = right.deviceState; + discoverMode = right.discoverMode; + serialNumber = right.serialNumber; + deviceName = right.deviceName; +} + +ScanDeviceInfo &ScanDeviceInfo::operator=(const ScanDeviceInfo &right) +{ + if (this != &right) { + deviceId = right.deviceId; + manufacturer = right.manufacturer; + model = right.model; + deviceType = right.deviceType; + deviceState = right.deviceState; + discoverMode = right.discoverMode; + serialNumber = right.serialNumber; + deviceName = right.deviceName; + } + return *this; +} + + +void ScanDeviceInfo::SetDeviceId(const std::string& newScannerId) +{ + deviceId = newScannerId; +} + +const std::string& ScanDeviceInfo::GetDeviceId() const +{ + return deviceId; +} + +void ScanDeviceInfo::SetManufacturer(const std::string& newManufacturer) +{ + manufacturer = newManufacturer; +} + +const std::string& ScanDeviceInfo::GetManufacturer() const +{ + return manufacturer; +} + +void ScanDeviceInfo::SetModel(const std::string& newModel) +{ + model = newModel; +} + +const std::string& ScanDeviceInfo::GetModel() const +{ + return model; +} + +void ScanDeviceInfo::SetDeviceType(const std::string& newDeviceType) +{ + deviceType = newDeviceType; +} + +const std::string& ScanDeviceInfo::GetDeviceType() const +{ + return deviceType; +} + +void ScanDeviceInfo::SetDeviceState(const uint32_t& newDeviceState) +{ + deviceState = newDeviceState; +} + +const uint32_t& ScanDeviceInfo::GetDeviceState() const +{ + return deviceState; +} + +void ScanDeviceInfo::SetDiscoverMode(const std::string& newDiscoverMode) +{ + discoverMode = newDiscoverMode; +} + +const std::string& ScanDeviceInfo::GetDiscoverMode() const +{ + return discoverMode; +} + +void ScanDeviceInfo::SetSerialNumber(const std::string& newSerialNumber) +{ + serialNumber = newSerialNumber; +} + +const std::string& ScanDeviceInfo::GetSerialNumber() const +{ + return serialNumber; +} + +void ScanDeviceInfo::SetDeviceName(const std::string& newDeviceName) +{ + deviceName = newDeviceName; +} + +const std::string& ScanDeviceInfo::GetDeviceName() const +{ + return deviceName; +} + +bool ScanDeviceInfo::ReadFromParcel(Parcel &parcel) +{ + SetDeviceId(parcel.ReadString()); + SetManufacturer(parcel.ReadString()); + SetModel(parcel.ReadString()); + SetDeviceType(parcel.ReadString()); + SetDiscoverMode(parcel.ReadString()); + SetSerialNumber(parcel.ReadString()); + SetDeviceName(parcel.ReadString()); + return true; +} + +bool ScanDeviceInfo::Marshalling(Parcel &parcel) const +{ + parcel.WriteString(deviceId); + parcel.WriteString(manufacturer); + parcel.WriteString(model); + parcel.WriteString(deviceType); + parcel.WriteString(discoverMode); + parcel.WriteString(serialNumber); + parcel.WriteString(deviceName); + return true; +} + +std::shared_ptr ScanDeviceInfo::Unmarshalling(Parcel &parcel) +{ + auto nativeObj = std::make_shared(); + if (!nativeObj->ReadFromParcel(parcel)) { + SCAN_HILOGE("Failed to unmarshalling scaner info"); + return nullptr; + } + return nativeObj; +} + +// ScanDeviceInfoSync + +ScanDeviceInfoSync::ScanDeviceInfoSync() +{ + deviceId = ""; + discoverMode = ""; + serialNumber = ""; + syncMode = ""; + deviceState = 0; +} + +ScanDeviceInfoSync::ScanDeviceInfoSync(const ScanDeviceInfoSync &right) +{ + deviceId = right.deviceId; + discoverMode = right.discoverMode; + serialNumber = right.serialNumber; + syncMode = right.syncMode; + deviceState = right.deviceState; +} + +ScanDeviceInfoSync &ScanDeviceInfoSync::operator=(const ScanDeviceInfoSync &right) +{ + if (this != &right) { + deviceId = right.deviceId; + discoverMode = right.discoverMode; + serialNumber = right.serialNumber; + syncMode = right.syncMode; + deviceState = right.deviceState; + } + return *this; +} + + +void ScanDeviceInfoSync::SetDeviceId(const std::string& newScannerId) +{ + deviceId = newScannerId; +} + +const std::string& ScanDeviceInfoSync::GetDeviceId() const +{ + return deviceId; +} + +void ScanDeviceInfoSync::SetDiscoverMode(const std::string& newDiscoverMode) +{ + discoverMode = newDiscoverMode; +} + +const std::string& ScanDeviceInfoSync::GetDiscoverMode() const +{ + return discoverMode; +} + +void ScanDeviceInfoSync::SetSerialNumber(const std::string& newSerialNumber) +{ + serialNumber = newSerialNumber; +} + +const std::string& ScanDeviceInfoSync::GetSerialNumber() const +{ + return serialNumber; +} + +void ScanDeviceInfoSync::SetSyncMode(const std::string& newSyncMode) +{ + syncMode = newSyncMode; +} + +const std::string& ScanDeviceInfoSync::GetSyncMode() const +{ + return syncMode; +} + +void ScanDeviceInfoSync::SetDeviceState(const uint32_t& newDeviceState) +{ + deviceState = newDeviceState; +} + +const uint32_t& ScanDeviceInfoSync::GetDeviceState() const +{ + return deviceState; +} + +void ScanDeviceInfoSync::ReadFromParcel(Parcel &parcel) +{ + SetDeviceId(parcel.ReadString()); + SetDiscoverMode(parcel.ReadString()); + SetSerialNumber(parcel.ReadString()); + SetSyncMode(parcel.ReadString()); +} + +bool ScanDeviceInfoSync::Marshalling(Parcel &parcel) const +{ + parcel.WriteString(deviceId); + parcel.WriteString(discoverMode); + parcel.WriteString(serialNumber); + parcel.WriteString(syncMode); + return true; +} + +std::shared_ptr ScanDeviceInfoSync::Unmarshalling(Parcel &parcel) +{ + auto nativeObj = std::make_shared(); + nativeObj->ReadFromParcel(parcel); + return nativeObj; +} + +} // namespace OHOS::Scan diff --git a/frameworks/helper/scan_helper/src/scanner_info_helper.cpp b/frameworks/helper/scan_helper/src/scanner_info_helper.cpp new file mode 100644 index 0000000..e245b6e --- /dev/null +++ b/frameworks/helper/scan_helper/src/scanner_info_helper.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scanner_info_helper.h" +#include "napi_scan_utils.h" +#include "scan_log.h" + +namespace OHOS::Scan { +static constexpr const char *PARAM_TCP_DEVICENAME = "deviceName"; +static constexpr const char *PARAM_TCP_UUID = "uuid"; +static constexpr const char *PARAM_TCP_MODEL = "model"; +static constexpr const char *PARAM_TCP_MANUFACTURER = "manufacturer"; +static constexpr const char *PARAM_TCP_DEVICETYPE = "deviceType"; +static constexpr const char *PARAM_TCP_PORT = "port"; +static constexpr const char *PARAM_TCP_ADDR = "address"; +static constexpr const char *PARAM_TCP_BUTTON = "button"; +static constexpr const char *PARAM_TCP_FEEDER = "feeder"; + + +static constexpr const char *PARAM_SCANNERID = "deviceId"; +static constexpr const char *PARAM_MANUFACTURER = "manufacturer"; +static constexpr const char *PARAM_MODEL = "model"; +static constexpr const char *PARAM_DEVICETYPE = "deviceType"; + +static constexpr const char *PARAM_INFO_DEVICESTATE = "deviceState"; +static constexpr const char *PARAM_INFO_DISCOVERMODE = "discoverMode"; +static constexpr const char *PARAM_INFO_SERIALNUMBER = "serialNumber"; +static constexpr const char *PARAM_INFO_DEVICENAME = "deviceName"; +static constexpr const char *PARAM_INFO_SYNCMODE = "syncMode"; + +napi_value ScannerInfoHelperTCP::MakeJsObject(napi_env env, const ScanDeviceInfoTCP &info) +{ + napi_value jsObj = nullptr; + SCAN_CALL(env, napi_create_object(env, &jsObj)); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_TCP_DEVICENAME, info.GetDeviceName()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_TCP_UUID, info.GetUuid()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_TCP_MODEL, info.GetModel()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_TCP_MANUFACTURER, info.GetManufacturer()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_TCP_DEVICETYPE, info.GetDeviceType()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_TCP_PORT, info.GetPort()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_TCP_ADDR, info.GetAddr()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_TCP_BUTTON, info.GetButton()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_TCP_FEEDER, info.GetFeeder()); + NapiScanUtils::SetUint32Property(env, jsObj, PARAM_INFO_DEVICESTATE, info.GetDeviceState()); + return jsObj; +} + + +napi_value ScannerInfoHelper::MakeJsObject(napi_env env, const ScanDeviceInfo &info) +{ + napi_value jsObj = nullptr; + SCAN_CALL(env, napi_create_object(env, &jsObj)); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_SCANNERID, info.GetDeviceId()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_MANUFACTURER, info.GetManufacturer()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_MODEL, info.GetModel()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_DEVICETYPE, info.GetDeviceType()); + NapiScanUtils::SetUint32Property(env, jsObj, PARAM_INFO_DEVICESTATE, info.GetDeviceState()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_INFO_DISCOVERMODE, info.GetDiscoverMode()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_INFO_SERIALNUMBER, info.GetSerialNumber()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_INFO_DEVICENAME, info.GetDeviceName()); + return jsObj; +} + +napi_value ScannerInfoSyncHelper::MakeJsObject(napi_env env, const ScanDeviceInfoSync &info) +{ + napi_value jsObj = nullptr; + SCAN_CALL(env, napi_create_object(env, &jsObj)); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_SCANNERID, info.GetDeviceId()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_INFO_DISCOVERMODE, info.GetDiscoverMode()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_INFO_SERIALNUMBER, info.GetSerialNumber()); + NapiScanUtils::SetStringPropertyUtf8(env, jsObj, PARAM_INFO_SYNCMODE, info.GetSyncMode()); +#ifdef DEBUG_ENABLE + SCAN_HILOGD("ScannerInfoSyncHelper MakeJsObject DeviceId = %{public}s, DiscoverMode = %{public}s," + "SerialNumber = %{public}s SyncMode = %{public}s.", + info.GetDeviceId().c_str(), info.GetDiscoverMode().c_str(), + info.GetSerialNumber().c_str(), info.GetSyncMode().c_str()); +#endif + return jsObj; +} + + +} // namespace OHOS::Print diff --git a/frameworks/innerkitsimpl/scan_impl/BUILD.gn b/frameworks/innerkitsimpl/scan_impl/BUILD.gn new file mode 100644 index 0000000..cfb130f --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/BUILD.gn @@ -0,0 +1,73 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//base/print/print_fwk/print.gni") +import("//build/ohos.gni") + +config("scan_interfaces_kits_napi_config") { + visibility = [ ":*" ] + include_dirs = [ "include" ] + + cflags_cc = [ "-fno-exceptions" ] +} + +ohos_shared_library("scan_client") { + include_dirs = [ + "${print_utils_path}/include", + "${print_path}/frameworks/helper/scan_helper/include", + ] + + public_configs = [ ":scan_interfaces_kits_napi_config" ] + + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + boundary_sanitize = true + debug = false + integer_overflow = true + ubsan = true + } + + sources = [ + "src/scan_callback.cpp", + "src/scan_callback_stub.cpp", + "src/scan_manager_client.cpp", + "src/scan_sa_death_recipient.cpp", + "src/scan_service_proxy.cpp", + "src/scan_sync_load_callback.cpp", + ] + + deps = [ "${print_path}/frameworks/helper/scan_helper:scan_helper" ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:data_ability_helper", + "ability_runtime:napi_base_context", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "eventhandler:libeventhandler", + "hilog:libhilog", + "ipc:ipc_core", + "napi:ace_napi", + "samgr:samgr_proxy", + ] + + #relative_install_dir = "module" + install_enable = true + subsystem_name = "print" + innerapi_tags = [ "platformsdk" ] + part_name = "print_fwk" +} diff --git a/frameworks/innerkitsimpl/scan_impl/include/iscan_callback.h b/frameworks/innerkitsimpl/scan_impl/include/iscan_callback.h new file mode 100644 index 0000000..8bb16f5 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/include/iscan_callback.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ISCAN_CALLBACK_H +#define ISCAN_CALLBACK_H + +#include "iremote_broker.h" +#include "iremote_object.h" +#include "scanner_info.h" + +namespace OHOS::Scan { +class IScanCallback : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Scan.IScanCallback"); + virtual bool OnCallback(uint32_t state, const ScanDeviceInfoTCP &info) = 0; + virtual bool OnCallback(uint32_t state, const ScanDeviceInfo &info) = 0; + virtual bool OnCallbackSync(uint32_t state, const ScanDeviceInfoSync &info) = 0; + virtual bool OnGetFrameResCallback(bool isGetFrameSucc, int32_t sizeRead) = 0; + virtual bool OnScanInitCallback(int32_t &scanVersion) = 0; + virtual bool OnSendSearchMessage(std::string &message) = 0; + virtual bool OnGetDevicesList(std::vector &info) = 0; +}; + +enum { + SCAN_CALLBACK_DEVICE_TCP, + SCAN_CALLBACK_DEVICE, + SCAN_CALLBACK_DEVICE_SYNC, + SCAN_CALLBACK_GET_FRAME_RES, + SCAN_CALLBACK_SCAN_INIT, + SCAN_CALLBACK_SEND_MESSAGE, + SCAN_CALLBACK_DEVICE_LIST, +}; +} // namespace OHOS::Scan +#endif // ISCAN_CALLBACK_H diff --git a/frameworks/innerkitsimpl/scan_impl/include/iscan_service.h b/frameworks/innerkitsimpl/scan_impl/include/iscan_service.h new file mode 100644 index 0000000..5d17757 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/include/iscan_service.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_SERVICE_INTERFACE_H +#define SCAN_SERVICE_INTERFACE_H + +#include +#include + +#include "iscan_callback.h" +#include "iremote_broker.h" +#include "scanner_info.h" +#include "scan_option_descriptor.h" +#include "scan_option_value.h" +#include "scan_parameters.h" +#include "scanner_info.h" +#include "scan_progress.h" + +namespace OHOS::Scan { +class IScanService : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Scan.IScanService"); + virtual int32_t InitScan(int32_t &scanVersion) = 0; + virtual int32_t ExitScan() = 0; + virtual int32_t GetScannerList() = 0; + virtual int32_t StopDiscover() = 0; + virtual int32_t OpenScanner(const std::string scannerId) = 0; + virtual int32_t CloseScanner(const std::string scannerId) = 0; + virtual int32_t GetScanOptionDesc(const std::string scannerId, + const int32_t optionIndex, ScanOptionDescriptor &desc) = 0; + virtual int32_t OpScanOptionValue(const std::string scannerId, + const int32_t optionIndex, const ScanOptionOpType op, ScanOptionValue &value, int32_t &info) =0; + virtual int32_t GetScanParameters(const std::string scannerId, ScanParameters ¶) = 0; + virtual int32_t StartScan(const std::string scannerffId, const bool &batchMode) = 0; + virtual int32_t GetSingleFrameFD(const std::string scannerId, uint32_t &size, uint32_t fd) = 0; + virtual int32_t CancelScan(const std::string scannerId) = 0; + virtual int32_t SetScanIOMode(const std::string scannerId, const bool isNonBlocking) = 0; + virtual int32_t GetScanSelectFd(const std::string scannerId, int32_t &fd) = 0; + virtual int32_t GetScannerState(int32_t &scannerState) = 0; + virtual int32_t GetScanProgress(const std::string scannerId, ScanProgress &prog) = 0; + virtual int32_t AddScanner(const std::string& serialNumber, const std::string& discoverMode) = 0; + virtual int32_t DeleteScanner(const std::string& serialNumber, const std::string& discoverMode) = 0; + virtual int32_t GetAddedScanner(std::vector& allAddedScanner) = 0; + virtual int32_t UpdateScannerName(const std::string& serialNumber, + const std::string& discoverMode, const std::string& deviceName) = 0; + virtual int32_t AddPrinter(const std::string& serialNumber, const std::string& discoverMode) = 0; + + virtual int32_t On(const std::string taskId, const std::string &type, const sptr &listener) = 0; + virtual int32_t Off(const std::string taskId, const std::string &type) = 0; +}; + +enum { + CMD_INIT_SCAN, + CMD_EXIT_SCAN, + CMD_GET_SCANNER_LIST, + CMD_STOP_DISCOVER, + CMD_OPEN_SCANNER, + CMD_CLOSE_SCANNER, + CMD_GET_SCAN_OPTION_DESC, + CMD_OP_SCAN_OPTION_VALUE, + CMD_GET_SCAN_PARAMETERS, + CMD_START_SCAN, + CMD_GET_SINGLE_FRAME, + CMD_GET_SINGLE_FRAME_FD, + CMD_CANCEL_SCAN, + CMD_SET_SCAN_IO_MODE, + CMD_GET_SCAN_SELECT_FD, + CMD_GET_SCANNER_STATE, + CMD_GET_SCAN_PROGRESS, + CMD_CONNECT_SCANNER, + CMD_DISCONNECT_SCANNER, + CMD_GET_CONNECTED_SCANNER, + CMD_UPDATE_SCANNER_NAME, + CMD_ADD_PRINTER, + CMD_ON, + CMD_OFF +}; +} // namespace OHOS::Scan +#endif // SCAN_SERVICE_INTERFACE_H diff --git a/frameworks/innerkitsimpl/scan_impl/include/scan_callback.h b/frameworks/innerkitsimpl/scan_impl/include/scan_callback.h new file mode 100644 index 0000000..8c4ab22 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/include/scan_callback.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_CALLBACK_H +#define SCAN_CALLBACK_H +#define TDD_ENABLE 1 + +#include +#include +#include +#include "napi/native_api.h" +#include "scan_callback_stub.h" +#include "scanner_info_helper.h" + +namespace OHOS::Scan { +struct CallbackParam { + napi_env env; + napi_ref ref; + std::mutex* mutexPtr; + uint32_t state; + + bool isGetSucc; + int32_t sizeRead; + int32_t scanVersion; + std::string message; + + ScanDeviceInfoTCP deviceInfoTCP; + ScanDeviceInfo deviceInfo; + ScanDeviceInfoSync deviceInfoSync; + + void InitialCallbackParam(napi_env &env_, napi_ref &ref_, std::mutex &mutex_); + void SetCallbackParam(uint32_t &state, const ScanDeviceInfoTCP &deviceInfoTCP); + void SetCallbackParam(uint32_t &state, const ScanDeviceInfo &deviceInfo); + void SetCallbackSyncParam(uint32_t &state, const ScanDeviceInfoSync &deviceInfoSync); + void SetCallbackParam(bool &isGetSucc, int32_t &sizeRead); + void SetCallbackParam(int32_t &scanVersion); + void SetCallbackParam(std::string &message); +}; + +struct Param { + napi_env env; + napi_ref callbackRef; +}; + +typedef std::function uv_work_function; + +struct CallbackContext { + CallbackParam* callBackParam; + uv_work_function uvWorkLambda; + void SetCallbackContext(CallbackParam* &callBackParam, uv_work_function &uvWorkLambda, std::mutex &mutex_); +}; + + +class ScanCallback : public ScanCallbackStub { +public: + ScanCallback(napi_env env, napi_ref ref); + explicit ScanCallback(std::function &infos)> callbackFunction); + virtual ~ScanCallback(); + bool OnCallback(uint32_t state, const ScanDeviceInfoTCP &info) override; + bool OnCallback(uint32_t state, const ScanDeviceInfo &info) override; + bool OnCallbackSync(uint32_t state, const ScanDeviceInfoSync &info) override; + bool OnGetFrameResCallback(bool isGetSucc, int32_t sizeRead) override; + bool OnScanInitCallback(int32_t &scanVersion) override; + bool OnSendSearchMessage(std::string &message) override; + bool OnGetDevicesList(std::vector &info) override; + bool ExecuteUvQueueWork(CallbackContext* ¶m, uv_work_t* &work, uv_loop_s* &loop); + void CreateCallbackParam(uv_work_t *&work, CallbackParam *¶m, CallbackContext *&context, bool &flag); + +#ifndef TDD_ENABLE +private: +#endif + napi_env env_; + napi_ref ref_; + std::function &infos)> callbackFunction_; + std::mutex mutex_; +}; +} // namespace OHOS::Scan + +#endif // SCAN_CALLBACK_H diff --git a/frameworks/innerkitsimpl/scan_impl/include/scan_callback_stub.h b/frameworks/innerkitsimpl/scan_impl/include/scan_callback_stub.h new file mode 100644 index 0000000..b7b13a0 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/include/scan_callback_stub.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_CALLBACK_STUB_H +#define SCAN_CALLBACK_STUB_H +#define TDD_ENABLE 1 + +#include "iscan_callback.h" +#include "iremote_stub.h" +#include + +namespace OHOS::Scan { +class ScanCallbackStub : public IRemoteStub { +public: + ScanCallbackStub(); + virtual ~ScanCallbackStub() = default; + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +#ifndef TDD_ENABLE +private: +#endif + bool HandleDeviceInfoTcpEvent(MessageParcel &data, MessageParcel &reply); + bool HandleDeviceInfoEvent(MessageParcel &data, MessageParcel &reply); + bool HandleDeviceInfoSyncEvent(MessageParcel &data, MessageParcel &reply); + bool HandleGetFrameResEvent(MessageParcel &data, MessageParcel &reply); + bool HandleScanInitEvent(MessageParcel &data, MessageParcel &reply); + bool HandleSendSearchMessage(MessageParcel &data, MessageParcel &reply); + bool HandleSendDeviceList(MessageParcel &data, MessageParcel &reply); +#ifndef TDD_ENABLE +private: +#endif + using SCAN_EVENT_HANDLER = bool (ScanCallbackStub::*)(MessageParcel &, MessageParcel &); + std::map cmdMap_; +}; +} // namespace OHOS::Scan +#endif // SCAN_CALLBACK_STUB_H diff --git a/frameworks/innerkitsimpl/scan_impl/include/scan_manager_client.h b/frameworks/innerkitsimpl/scan_impl/include/scan_manager_client.h new file mode 100644 index 0000000..cb9fe77 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/include/scan_manager_client.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_MANAGER_CLIENT_H +#define SCAN_MANAGER_CLIENT_H +#define TDD_ENABLE 1 + +#include +#include +#include + +#include "iscan_callback.h" +#include "iscan_service.h" +#include "iremote_object.h" + +#include "scan_sync_load_callback.h" +#include "scan_sa_death_recipient.h" +#include "scanner_info.h" +#include "refbase.h" + +namespace OHOS::Scan { +class ScanManagerClient : public RefBase { +public: + ScanManagerClient(); + ~ScanManagerClient(); + static sptr GetInstance(); + + void OnRemoteSaDied(const wptr &object); + + int32_t InitScan(int32_t &scanVersion); + int32_t ExitScan(); + int32_t GetScannerList(); + int32_t StopDiscover(); + int32_t OpenScanner(const std::string scannerId); + int32_t CloseScanner(const std::string scannerId); + int32_t GetScanOptionDesc(const std::string scannerId, const int32_t optionIndex, ScanOptionDescriptor &desc); + int32_t OpScanOptionValue(const std::string scannerId, const int32_t optionIndex, + const ScanOptionOpType op, ScanOptionValue &value, int32_t &info); + int32_t GetScanParameters(const std::string scannerId, ScanParameters ¶); + int32_t StartScan(const std::string scannerId, const bool &batchMode); + int32_t GetSingleFrameFD(const std::string scannerId, uint32_t &size, uint32_t fd); + int32_t CancelScan(const std::string scannerId); + int32_t SetScanIOMode(const std::string scannerId, const bool isNonBlocking); + int32_t GetScanSelectFd(const std::string scannerId, int32_t &fd); + int32_t GetScannerState(int32_t &scannerState); + int32_t GetScanProgress(const std::string scannerId, ScanProgress &prog); + int32_t AddScanner(const std::string& serialNumber, const std::string& discoverMode); + int32_t DeleteScanner(const std::string& serialNumber, const std::string& discoverMode); + int32_t GetAddedScanner(std::vector& allAddedScanner); + int32_t UpdateScannerName(const std::string& serialNumber, + const std::string& discoverMode, const std::string& deviceName); + int32_t AddPrinter(const std::string& serialNumber, const std::string& discoverMode); + + int32_t On(const std::string &taskId, const std::string &type, const sptr &listener); + int32_t Off(const std::string &taskId, const std::string &type); + + void LoadServerSuccess(); + void LoadServerFail(); + +#ifndef TDD_ENABLE +private: +#endif + bool LoadServer(); + sptr GetScanServiceProxy(); + +#ifndef TDD_ENABLE +private: +#endif + static std::mutex instanceLock_; + static sptr instance_; + sptr scanServiceProxy_; + sptr deathRecipient_; + + std::mutex loadMutex_; + std::mutex conditionMutex_; + std::mutex proxyLock_; + std::condition_variable syncCon_; + bool ready_ = false; + static constexpr int LOAD_SA_TIMEOUT_MS = 15000; +}; +} // namespace OHOS::Scan +#endif // SCAN_MANAGER_CLIENT_H diff --git a/frameworks/innerkitsimpl/scan_impl/include/scan_sa_death_recipient.h b/frameworks/innerkitsimpl/scan_impl/include/scan_sa_death_recipient.h new file mode 100644 index 0000000..a1c61b3 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/include/scan_sa_death_recipient.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_SA_DEATH_RECIPIENT_H +#define SCAN_SA_DEATH_RECIPIENT_H +#define TDD_ENABLE 1 + +#include "iremote_object.h" +#include "refbase.h" + +namespace OHOS::Scan { +class ScanSaDeathRecipient : public IRemoteObject::DeathRecipient { +public: + explicit ScanSaDeathRecipient(); + ~ScanSaDeathRecipient() = default; + void OnRemoteDied(const wptr &object) override; +}; +} // namespace OHOS::Scan +#endif // SCAN_SA_DEATH_RECIPIENT_H \ No newline at end of file diff --git a/frameworks/innerkitsimpl/scan_impl/include/scan_service_proxy.h b/frameworks/innerkitsimpl/scan_impl/include/scan_service_proxy.h new file mode 100644 index 0000000..7439565 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/include/scan_service_proxy.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_SERVICE_PROXY_H +#define SCAN_SERVICE_PROXY_H + +#include "iscan_service.h" +#include "iremote_proxy.h" +#include "scanner_info.h" +#define TDD_ENABLE 1 + +namespace OHOS::Scan { +class ScanServiceProxy : public IRemoteProxy { +public: + explicit ScanServiceProxy(const sptr &object); + ~ScanServiceProxy() = default; + DISALLOW_COPY_AND_MOVE(ScanServiceProxy); + + int32_t InitScan(int32_t &scanVersion) override; + int32_t ExitScan() override; + int32_t GetScannerList() override; + int32_t StopDiscover() override; + int32_t OpenScanner(const std::string scannerId) override; + int32_t CloseScanner(const std::string scannerId) override; + int32_t GetScanOptionDesc(const std::string scannerId, + const int32_t optionIndex, ScanOptionDescriptor &desc) override; + int32_t OpScanOptionValue(const std::string scannerId, const int32_t optionIndex, + const ScanOptionOpType op, ScanOptionValue &value, int32_t &info) override; + int32_t GetScanParameters(const std::string scannerId, ScanParameters ¶) override; + int32_t StartScan(const std::string scannerId, const bool &batchMode) override; + int32_t GetSingleFrameFD(const std::string scannerId, uint32_t &size, uint32_t fd) override; + int32_t CancelScan(const std::string scannerId) override; + int32_t SetScanIOMode(const std::string scannerId, const bool isNonBlocking) override; + int32_t GetScanSelectFd(const std::string scannerId, int32_t &fd) override; + int32_t GetScannerState(int32_t &scannerState) override; + int32_t GetScanProgress(const std::string scannerId, ScanProgress &prog) override; + int32_t AddScanner(const std::string& serialNumber, const std::string& discoverMode) override; + int32_t DeleteScanner(const std::string& serialNumber, const std::string& discoverMode) override; + int32_t GetAddedScanner(std::vector& allAddedScanner) override; + int32_t UpdateScannerName(const std::string& serialNumber, + const std::string& discoverMode, const std::string& deviceName) override; + int32_t AddPrinter(const std::string& serialNumber, const std::string& discoverMode) override; + + int32_t On(const std::string taskId, const std::string &type, const sptr &listener) override; + int32_t Off(const std::string taskId, const std::string &type) override; + +#ifndef TDD_ENABLE +private: +#endif + int32_t GetResult(int32_t retCode, MessageParcel &reply); + static inline BrokerDelegator delegator_; +}; +} // namespace OHOS::Scan +#endif // SCAN_SERVICE_PROXY_H diff --git a/frameworks/innerkitsimpl/scan_impl/include/scan_sync_load_callback.h b/frameworks/innerkitsimpl/scan_impl/include/scan_sync_load_callback.h new file mode 100644 index 0000000..32b5937 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/include/scan_sync_load_callback.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_SYNC_LOAD_CALLBACK_H +#define SCAN_SYNC_LOAD_CALLBACK_H + +#include "system_ability_load_callback_stub.h" + +namespace OHOS::Scan { +class ScanSyncLoadCallback : public SystemAbilityLoadCallbackStub { +public: + void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr &remoteObject) override; + void OnLoadSystemAbilityFail(int32_t systemAbilityId) override; +}; +} // namespace OHOS::Scan +#endif // SCAN_SYNC_LOAD_CALLBACK_H \ No newline at end of file diff --git a/frameworks/innerkitsimpl/scan_impl/src/scan_callback.cpp b/frameworks/innerkitsimpl/scan_impl/src/scan_callback.cpp new file mode 100644 index 0000000..f7f11e6 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/src/scan_callback.cpp @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "scan_callback.h" +#include "napi_scan_utils.h" +#include "scan_log.h" + +namespace OHOS::Scan { +ScanCallback::ScanCallback(napi_env env, napi_ref ref) : env_(env), ref_(ref) +{ +} + +ScanCallback::ScanCallback(std::function &infos)> + callbackFunction) : callbackFunction_(callbackFunction) +{ +} + +ScanCallback::~ScanCallback() +{ + std::lock_guard autoLock(mutex_); + SCAN_HILOGI("callback has been destroyed"); + + uv_loop_s *loop = nullptr; + napi_get_uv_event_loop(env_, &loop); + Param *param = new (std::nothrow) Param; + if (param == nullptr) { + return; + } + param->env = env_; + param->callbackRef = ref_; + uv_work_t *work = new (std::nothrow) uv_work_t; + if (work == nullptr) { + delete param; + return; + } + work->data = reinterpret_cast(param); + int retVal = uv_queue_work(loop, work, [](uv_work_t *work) {}, [](uv_work_t *work, int _status) { + SCAN_HILOGI("uv_queue_work ScanCallback DeleteReference"); + Param *param_ = reinterpret_cast(work->data); + if (param_ == nullptr) { + delete work; + return; + } + napi_handle_scope scope = nullptr; + napi_open_handle_scope(param_->env, &scope); + if (scope == nullptr) { + delete param_; + delete work; + return; + } + napi_ref callbackRef_ = param_->callbackRef; + NapiScanUtils::DeleteReference(param_->env, callbackRef_); + napi_close_handle_scope(param_->env, scope); + delete param_; + delete work; + }); + if (retVal != 0) { + SCAN_HILOGE("Failed to get uv_queue_work."); + delete param; + delete work; + return; + } +} + +void CallbackParam::InitialCallbackParam(napi_env &env_, napi_ref &ref_, std::mutex &mutex_) +{ + std::lock_guard lock(mutex_); + this->env = env_; + this->ref = ref_; + this->mutexPtr = &mutex_; +} + +void CallbackParam::SetCallbackParam(uint32_t &state, const ScanDeviceInfoTCP &deviceInfoTCP) +{ + std::lock_guard lock(*mutexPtr); + this->state = state; + this->deviceInfoTCP = deviceInfoTCP; +} + +void CallbackParam::SetCallbackParam(uint32_t &state, const ScanDeviceInfo &deviceInfo) +{ + std::lock_guard lock(*mutexPtr); + this->state = state; + this->deviceInfo = deviceInfo; +} + +void CallbackParam::SetCallbackSyncParam(uint32_t &state, const ScanDeviceInfoSync &deviceInfoSync) +{ + std::lock_guard lock(*mutexPtr); + this->state = state; + this->deviceInfoSync = deviceInfoSync; +} + +void CallbackParam::SetCallbackParam(bool &isGetSucc, int32_t &sizeRead) +{ + std::lock_guard lock(*mutexPtr); + this->isGetSucc = isGetSucc; + this->sizeRead = sizeRead; +} + +void CallbackParam::SetCallbackParam(int32_t &scanVersion) +{ + std::lock_guard lock(*mutexPtr); + this->scanVersion = scanVersion; +} + +void CallbackParam::SetCallbackParam(std::string &message) +{ + std::lock_guard lock(*mutexPtr); + this->message = message; +} + +void CallbackContext::SetCallbackContext(CallbackParam* &callBackParam, + uv_work_function &uvWorkLambda, std::mutex &mutex_) +{ + std::lock_guard lock(mutex_); + this->callBackParam = callBackParam; + this->uvWorkLambda = uvWorkLambda; +} + +void ScanCallback::CreateCallbackParam(uv_work_t *&work, CallbackParam *¶m, CallbackContext *&context, bool &flag) +{ + work = new (std::nothrow) uv_work_t; + CHECK_AND_CREATE(work, "Failed to create uv_work_t work", flag); + param = new (std::nothrow) CallbackParam; + CHECK_AND_CREATE(param, "Failed to create CallbackParam param", flag); + context = new (std::nothrow) CallbackContext; + CHECK_AND_CREATE(context, "Failed to create CallbackContext context", flag); + if (!flag) { + DELETE_AND_NULLIFY(work); + DELETE_AND_NULLIFY(param); + DELETE_AND_NULLIFY(context); + } +} + +bool ScanCallback::ExecuteUvQueueWork(CallbackContext* &context, uv_work_t* &work, uv_loop_s *&loop) +{ + work->data = context; + int32_t retVal = uv_queue_work( + loop, work, [](uv_work_t *work) {}, + [](uv_work_t *work, int statusInt) { + CallbackContext *context = static_cast(work->data); + CallbackParam *cbParam = context->callBackParam; + napi_handle_scope scope = nullptr; + napi_open_handle_scope(cbParam->env, &scope); + if (scope != nullptr) { + auto uvWorkLambda = context->uvWorkLambda; + std::lock_guard autoLock(*cbParam->mutexPtr); + napi_value callbackFunc = NapiScanUtils::GetReference(cbParam->env, cbParam->ref); + napi_value callbackResult = nullptr; + uvWorkLambda(cbParam, callbackFunc, callbackResult); + SCAN_HILOGD("run napi call deviceInfo callback fun success"); + napi_close_handle_scope(cbParam->env, scope); + } + DELETE_AND_NULLIFY(work); + DELETE_AND_NULLIFY(cbParam); + DELETE_AND_NULLIFY(context); + }); + if (retVal != 0) { + SCAN_HILOGE("failed to get uv_queue_work."); + DELETE_AND_NULLIFY(work); + DELETE_AND_NULLIFY(context->callBackParam); + DELETE_AND_NULLIFY(context); + return false; + } + return true; +} + +bool ScanCallback::OnCallback(uint32_t state, const ScanDeviceInfoTCP &info) +{ + SCAN_HILOGD("Enter OnCallback::ScanDeviceInfoTCP"); + + INIT_CALLBACK_PARAMS; + + if (!flag) { + SCAN_HILOGE("ScanCallback::OnCallback ScanDeviceInfoTCP error exit"); + return false; + } + + uv_work_function uvWorkLambda = [](CallbackParam* &cbParam, napi_value &callbackFunc, napi_value &callbackResult) { + napi_value callbackValues[NapiScanUtils::ARGC_ONE] = { 0 }; + callbackValues[0] = ScannerInfoHelperTCP::MakeJsObject(cbParam->env, cbParam->deviceInfoTCP); + napi_call_function(cbParam->env, nullptr, callbackFunc, + NapiScanUtils::ARGC_ONE, callbackValues, &callbackResult); + }; + param->InitialCallbackParam(env_, ref_, mutex_); + param->SetCallbackParam(state, info); + context->SetCallbackContext(param, uvWorkLambda, mutex_); + + return ExecuteUvQueueWork(context, work, loop); +} + +bool ScanCallback::OnCallback(uint32_t state, const ScanDeviceInfo &info) +{ + SCAN_HILOGD("Enter OnCallback::ScanDeviceInfo"); + + INIT_CALLBACK_PARAMS; + + if (!flag) { + SCAN_HILOGE("ScanCallback::OnCallback ScanDeviceInfo error exit"); + return false; + } + + uv_work_function uvWorkLambda = [](CallbackParam* &cbParam, napi_value &callbackFunc, napi_value &callbackResult) { + napi_value callbackValues[NapiScanUtils::ARGC_ONE] = { 0 }; + callbackValues[0] = ScannerInfoHelper::MakeJsObject(cbParam->env, cbParam->deviceInfo); + napi_call_function(cbParam->env, nullptr, callbackFunc, NapiScanUtils::ARGC_ONE, + callbackValues, &callbackResult); + }; + param->InitialCallbackParam(env_, ref_, mutex_); + param->SetCallbackParam(state, info); + context->SetCallbackContext(param, uvWorkLambda, mutex_); + + return ExecuteUvQueueWork(context, work, loop); +} + +bool ScanCallback::OnCallbackSync(uint32_t state, const ScanDeviceInfoSync &info) +{ + SCAN_HILOGD("Enter OnCallback::ScanDeviceInfo"); + + INIT_CALLBACK_PARAMS; + + if (!flag) { + SCAN_HILOGE("ScanCallback::OnCallback ScanDeviceInfo error exit"); + return false; + } + + uv_work_function uvWorkLambda = [](CallbackParam* &cbParam, napi_value &callbackFunc, napi_value &callbackResult) { + napi_value callbackValues[NapiScanUtils::ARGC_ONE] = { 0 }; + callbackValues[0] = ScannerInfoSyncHelper::MakeJsObject(cbParam->env, cbParam->deviceInfoSync); + napi_call_function(cbParam->env, nullptr, callbackFunc, NapiScanUtils::ARGC_ONE, + callbackValues, &callbackResult); + }; + param->InitialCallbackParam(env_, ref_, mutex_); + param->SetCallbackSyncParam(state, info); + context->SetCallbackContext(param, uvWorkLambda, mutex_); + + return ExecuteUvQueueWork(context, work, loop); +} + +bool ScanCallback::OnGetFrameResCallback(bool isGetSucc, int32_t sizeRead) +{ + SCAN_HILOGD("Enter OnCallback::OnGetFrameResCallback"); + + INIT_CALLBACK_PARAMS; + + if (!flag) { + SCAN_HILOGE("ScanCallback::OnCallback OnGetFrameResCallback error exit"); + return false; + } + + uv_work_function uvWorkLambda = [](CallbackParam* &cbParam, napi_value &callbackFunc, napi_value &callbackResult) { + napi_value callbackValues[NapiScanUtils::ARGC_TWO] = { 0 }; + callbackValues[0] = NapiScanUtils::CreateBoolean(cbParam->env, cbParam->isGetSucc); + callbackValues[1] = NapiScanUtils::CreateInt32(cbParam->env, cbParam->sizeRead); + napi_call_function(cbParam->env, nullptr, callbackFunc, NapiScanUtils::ARGC_TWO, + callbackValues, &callbackResult); + }; + param->InitialCallbackParam(env_, ref_, mutex_); + param->SetCallbackParam(isGetSucc, sizeRead); + context->SetCallbackContext(param, uvWorkLambda, mutex_); + + return ExecuteUvQueueWork(context, work, loop); +} + +bool ScanCallback::OnScanInitCallback(int32_t &scanVersion) +{ + SCAN_HILOGD("Enter OnCallback::OnScanInitCallback"); + + INIT_CALLBACK_PARAMS; + + if (!flag) { + SCAN_HILOGE("ScanCallback::OnCallback OnScanInitCallback error exit"); + return false; + } + + uv_work_function uvWorkLambda = [](CallbackParam* &cbParam, napi_value &callbackFunc, napi_value &callbackResult) { + napi_value callbackValues[NapiScanUtils::ARGC_ONE] = { 0 }; + callbackValues[0] = NapiScanUtils::CreateInt32(cbParam->env, cbParam->scanVersion); + napi_call_function(cbParam->env, nullptr, callbackFunc, NapiScanUtils::ARGC_ONE, + callbackValues, &callbackResult); + }; + param->InitialCallbackParam(env_, ref_, mutex_); + param->SetCallbackParam(scanVersion); + context->SetCallbackContext(param, uvWorkLambda, mutex_); + + return ExecuteUvQueueWork(context, work, loop); +} + +bool ScanCallback::OnSendSearchMessage(std::string &message) +{ + SCAN_HILOGD("Enter OnCallback::OnSendSearchMessage"); + + INIT_CALLBACK_PARAMS; + + if (!flag) { + SCAN_HILOGE("ScanCallback::OnCallback OnSendSearchMessage error exit"); + return false; + } + + uv_work_function uvWorkLambda = [](CallbackParam* &cbParam, napi_value &callbackFunc, napi_value &callbackResult) { + napi_value callbackValues[NapiScanUtils::ARGC_ONE] = { 0 }; + callbackValues[0] = NapiScanUtils::CreateStringUtf8(cbParam->env, cbParam->message); + napi_call_function(cbParam->env, nullptr, callbackFunc, NapiScanUtils::ARGC_ONE, + callbackValues, &callbackResult); + }; + param->InitialCallbackParam(env_, ref_, mutex_); + param->SetCallbackParam(message); + context->SetCallbackContext(param, uvWorkLambda, mutex_); + + return ExecuteUvQueueWork(context, work, loop); +} + +bool ScanCallback::OnGetDevicesList(std::vector &infos) +{ + SCAN_HILOGI("Enter OnGetDevicesList"); + if (callbackFunction_ == nullptr) { + SCAN_HILOGE("callbackFunction_ is a nullptr"); + return false; + } + callbackFunction_(infos); + return true; +} +} // namespace OHOS::Scan diff --git a/frameworks/innerkitsimpl/scan_impl/src/scan_callback_stub.cpp b/frameworks/innerkitsimpl/scan_impl/src/scan_callback_stub.cpp new file mode 100644 index 0000000..b843b85 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/src/scan_callback_stub.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_callback_stub.h" + +#include "scan_constant.h" +#include "scan_log.h" + +namespace OHOS::Scan { +ScanCallbackStub::ScanCallbackStub() +{ + cmdMap_[SCAN_CALLBACK_DEVICE_TCP] = &ScanCallbackStub::HandleDeviceInfoTcpEvent; + cmdMap_[SCAN_CALLBACK_DEVICE] = &ScanCallbackStub::HandleDeviceInfoEvent; + cmdMap_[SCAN_CALLBACK_DEVICE] = &ScanCallbackStub::HandleDeviceInfoEvent; + cmdMap_[SCAN_CALLBACK_DEVICE_SYNC] = &ScanCallbackStub::HandleDeviceInfoSyncEvent; + cmdMap_[SCAN_CALLBACK_GET_FRAME_RES] = &ScanCallbackStub::HandleGetFrameResEvent; + cmdMap_[SCAN_CALLBACK_SCAN_INIT] = &ScanCallbackStub::HandleGetFrameResEvent; + cmdMap_[SCAN_CALLBACK_SEND_MESSAGE] = &ScanCallbackStub::HandleSendSearchMessage; + cmdMap_[SCAN_CALLBACK_DEVICE_LIST] = &ScanCallbackStub::HandleSendDeviceList; +} + +int32_t ScanCallbackStub::OnRemoteRequest( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + SCAN_HILOGD("OnRemoteRequest started, code = %{public}d", code); + auto descriptorToken = data.ReadInterfaceToken(); + if (descriptorToken != GetDescriptor()) { + SCAN_HILOGE("Remote descriptor not the same as local descriptor."); + return E_SCAN_RPC_FAILURE; + } + + auto itFunc = cmdMap_.find(code); + if (itFunc != cmdMap_.end()) { + auto requestFunc = itFunc->second; + if (requestFunc != nullptr) { + return (this->*requestFunc)(data, reply); + } + } + SCAN_HILOGW("default case, need check."); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} + +bool ScanCallbackStub::HandleDeviceInfoTcpEvent(MessageParcel &data, MessageParcel &reply) +{ + uint32_t state = data.ReadUint32(); + auto info = ScanDeviceInfoTCP::Unmarshalling(data); + if (info == nullptr) { + SCAN_HILOGE("invalid scaner info object"); + return false; + } + bool result = OnCallback(state, *info); + reply.WriteBool(result); + return true; +} + +bool ScanCallbackStub::HandleDeviceInfoEvent(MessageParcel &data, MessageParcel &reply) +{ + uint32_t state = data.ReadUint32(); + auto info = ScanDeviceInfo::Unmarshalling(data); + if (info == nullptr) { + SCAN_HILOGE("invalid scaner info object"); + return false; + } + bool result = OnCallback(state, *info); + reply.WriteBool(result); + return true; +} + +bool ScanCallbackStub::HandleDeviceInfoSyncEvent(MessageParcel &data, MessageParcel &reply) +{ + uint32_t state = data.ReadUint32(); + auto info = ScanDeviceInfoSync::Unmarshalling(data); + if (info == nullptr) { + SCAN_HILOGE("invalid scaner info object"); + return false; + } + bool result = OnCallbackSync(state, *info); + reply.WriteBool(result); + return true; +} + +bool ScanCallbackStub::HandleGetFrameResEvent(MessageParcel &data, MessageParcel &reply) +{ + bool isGetSucc = data.ReadBool(); + int32_t sizeRead = data.ReadInt32(); + bool result = OnGetFrameResCallback(isGetSucc, sizeRead); + reply.WriteBool(result); + return true; +} + +bool ScanCallbackStub::HandleScanInitEvent(MessageParcel &data, MessageParcel &reply) +{ + int32_t scanVersion = data.ReadInt32(); + bool result = OnScanInitCallback(scanVersion); + reply.WriteBool(result); + return true; +} + +bool ScanCallbackStub::HandleSendSearchMessage(MessageParcel &data, MessageParcel &reply) +{ + std::string message = data.ReadString(); + bool result = OnSendSearchMessage(message); + reply.WriteBool(result); + return true; +} + +bool ScanCallbackStub::HandleSendDeviceList(MessageParcel &data, MessageParcel &reply) +{ + std::vector infos; + int infosSize = data.ReadInt32(); + CHECK_IS_EXCEED_SCAN_RANGE_BOOL(infosSize); + SCAN_HILOGI("get infosSize : %{public}d", infosSize); + for (auto i = 0; i < infosSize; i++) { + auto info = ScanDeviceInfo::Unmarshalling(data); + if (info == nullptr) { + SCAN_HILOGE("invalid scaner info object"); + return false; + } + infos.emplace_back(*info); + } + bool result = OnGetDevicesList(infos); + reply.WriteBool(result); + return true; +} + +} // namespace OHOS::Scan + +// namespace OHOS::Scan diff --git a/frameworks/innerkitsimpl/scan_impl/src/scan_manager_client.cpp b/frameworks/innerkitsimpl/scan_impl/src/scan_manager_client.cpp new file mode 100644 index 0000000..0cc3437 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/src/scan_manager_client.cpp @@ -0,0 +1,638 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_manager_client.h" + +#include "iservice_registry.h" +#include "system_ability_definition.h" + +namespace OHOS::Scan { +std::mutex ScanManagerClient::instanceLock_; +sptr ScanManagerClient::instance_ = nullptr; + +ScanManagerClient::ScanManagerClient() : scanServiceProxy_(nullptr), deathRecipient_(nullptr) +{} + +ScanManagerClient::~ScanManagerClient() +{} + +sptr ScanManagerClient::GetInstance() +{ + if (instance_ == nullptr) { + std::lock_guard autoLock(instanceLock_); + if (instance_ == nullptr) { + instance_ = new ScanManagerClient; + } + } + return instance_; +} +sptr ScanManagerClient::GetScanServiceProxy() +{ + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + SCAN_HILOGE("Getting SystemAbilityManager failed."); + return nullptr; + } + if (scanServiceProxy_ != nullptr) { + SCAN_HILOGD("scanServiceProxy_ already get"); + return scanServiceProxy_; + } + auto systemAbility = systemAbilityManager->GetSystemAbility(SCAN_SERVICE_ID, ""); + if (systemAbility == nullptr) { + SCAN_HILOGE("Get SystemAbility failed."); + return nullptr; + } + if (deathRecipient_ == nullptr) { + deathRecipient_ = new ScanSaDeathRecipient(); + } + systemAbility->AddDeathRecipient(deathRecipient_); + sptr serviceProxy = iface_cast(systemAbility); + if (serviceProxy == nullptr) { + SCAN_HILOGE("Get ScanManagerClientProxy from SA failed."); + return nullptr; + } + SCAN_HILOGD("Getting ScanManagerClientProxy succeeded."); + return serviceProxy; +} + +void ScanManagerClient::OnRemoteSaDied(const wptr &remote) +{ + scanServiceProxy_ = nullptr; + ready_ = false; +} + +bool ScanManagerClient::LoadServer() +{ + if (ready_) { + return true; + } + std::lock_guard lock(loadMutex_); + if (ready_) { + return true; + } + + auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (sm == nullptr) { + SCAN_HILOGE("GetSystemAbilityManager return null"); + return false; + } + + sptr loadCallback_ = new (std::nothrow) ScanSyncLoadCallback(); + if (loadCallback_ == nullptr) { + SCAN_HILOGE("new ScanSyncLoadCallback fail"); + return false; + } + + int32_t result = sm->LoadSystemAbility(SCAN_SERVICE_ID, loadCallback_); + if (result != ERR_OK) { + SCAN_HILOGE("LoadSystemAbility %{public}d failed, result: %{public}d", SCAN_SERVICE_ID, result); + return false; + } + + { + std::unique_lock conditionLock(conditionMutex_); + auto waitStatus = syncCon_.wait_for( + conditionLock, std::chrono::milliseconds(LOAD_SA_TIMEOUT_MS), [this]() { return ready_; }); + if (!waitStatus) { + SCAN_HILOGE("scan server load sa timeout"); + return false; + } + } + return true; +} + +void ScanManagerClient::LoadServerSuccess() +{ + std::unique_lock lock(conditionMutex_); + ready_ = true; + syncCon_.notify_one(); + SCAN_HILOGD("load scan server success"); +} + +void ScanManagerClient::LoadServerFail() +{ + ready_ = false; + SCAN_HILOGE("load scan server fail"); +} + +int32_t ScanManagerClient::InitScan(int32_t &scanVersion) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient InitScan start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->InitScan(scanVersion); + SCAN_HILOGD("ScanManagerClient InitScan end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::ExitScan() +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient ExitScan start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->ExitScan(); + SCAN_HILOGD("ScanManagerClient ExitScan end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::GetScannerList() +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient GetScannerList start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->GetScannerList(); + SCAN_HILOGD("ScanManagerClient GetScannerList end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::StopDiscover() +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient StopDiscover start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->StopDiscover(); + SCAN_HILOGD("ScanManagerClient StopDiscover end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::OpenScanner(const std::string scannerId) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient OpenScanner start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->OpenScanner(scannerId); + SCAN_HILOGD("ScanManagerClient OpenScanner end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::CloseScanner(const std::string scannerId) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient CloseScanner start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->CloseScanner(scannerId); + SCAN_HILOGD("ScanManagerClient CloseScanner end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::GetScanOptionDesc( + const std::string scannerId, const int32_t optionIndex, ScanOptionDescriptor &desc) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient GetScanOptionDesc start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->GetScanOptionDesc(scannerId, optionIndex, desc); + SCAN_HILOGD("ScanManagerClient GetScanOptionDesc end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::OpScanOptionValue(const std::string scannerId, const int32_t optionIndex, + const ScanOptionOpType op, ScanOptionValue &value, int32_t &info) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient OpScanOptionValue start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->OpScanOptionValue(scannerId, optionIndex, op, value, info); + SCAN_HILOGD("ScanManagerClient OpScanOptionValue end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::GetScanParameters(const std::string scannerId, ScanParameters ¶) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient GetScanParameters start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->GetScanParameters(scannerId, para); + SCAN_HILOGD("ScanManagerClient GetScanParameters end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::StartScan(const std::string scannerId, const bool &batchMode) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient StartScan start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->StartScan(scannerId, batchMode); + SCAN_HILOGD("ScanManagerClient StartScan end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::GetSingleFrameFD(const std::string scannerId, uint32_t &size, uint32_t fd) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient GetSingleFrameFD start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->GetSingleFrameFD(scannerId, size, fd); + SCAN_HILOGD("ScanManagerClient GetSingleFrameFD end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::CancelScan(const std::string scannerId) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient CancelScan start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->CancelScan(scannerId); + SCAN_HILOGD("ScanManagerClient CancelScan end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::SetScanIOMode(const std::string scannerId, const bool isNonBlocking) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient SetScanIOMode start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->SetScanIOMode(scannerId, isNonBlocking); + SCAN_HILOGD("ScanManagerClient SetScanIOMode end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::GetScanSelectFd(const std::string scannerId, int32_t &fd) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient GetScanSelectFd start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->GetScanSelectFd(scannerId, fd); + SCAN_HILOGD("ScanManagerClient GetScanSelectFd end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::On(const std::string &taskId, const std::string &type, const sptr &listener) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient On start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->On(taskId, type, listener); + SCAN_HILOGD("ScanManagerClient On out ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::Off(const std::string &taskId, const std::string &type) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient Off start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("Off quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->Off(taskId, type); + SCAN_HILOGD("ScanManagerClient Off out ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::GetScannerState(int32_t &scannerState) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient GetScannerState start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->GetScannerState(scannerState); + SCAN_HILOGD("ScanManagerClient GetScannerState end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::GetScanProgress(const std::string scannerId, ScanProgress &prog) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGI("ScanManagerClient GetScanProgress start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + } + int32_t ret = scanServiceProxy_->GetScanProgress(scannerId, prog); + SCAN_HILOGI("ScanManagerClient GetScanProgress end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::AddScanner(const std::string& serialNumber, const std::string& discoverMode) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient AddScanner start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->AddScanner(serialNumber, discoverMode); + SCAN_HILOGD("ScanManagerClient AddScanner end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::DeleteScanner(const std::string& serialNumber, const std::string& discoverMode) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient DeleteScanner start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->DeleteScanner(serialNumber, discoverMode); + SCAN_HILOGD("ScanManagerClient DeleteScanner end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::GetAddedScanner(std::vector& allAddedScanner) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient GetAddedScanner start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->GetAddedScanner(allAddedScanner); + SCAN_HILOGD("ScanManagerClient GetAddedScanner end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::UpdateScannerName(const std::string& serialNumber, + const std::string& discoverMode, const std::string& deviceName) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient UpdateScannerName start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->UpdateScannerName(serialNumber, discoverMode, deviceName); + SCAN_HILOGD("ScanManagerClient UpdateScannerName end ret = [%{public}d].", ret); + return ret; +} + +int32_t ScanManagerClient::AddPrinter(const std::string& serialNumber, const std::string& discoverMode) +{ + std::lock_guard lock(proxyLock_); + SCAN_HILOGD("ScanManagerClient AddPrinter start."); + if (!LoadServer()) { + SCAN_HILOGE("load scan server fail"); + return E_SCAN_RPC_FAILURE; + } + + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGW("Redo GetScanServiceProxy"); + scanServiceProxy_ = GetScanServiceProxy(); + } + if (scanServiceProxy_ == nullptr) { + SCAN_HILOGE("On quit because redoing GetScanServiceProxy failed."); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = scanServiceProxy_->AddPrinter(serialNumber, discoverMode); + SCAN_HILOGD("ScanManagerClient AddPrinter end ret = [%{public}d].", ret); + return ret; +} +} // namespace OHOS::Scan diff --git a/frameworks/innerkitsimpl/scan_impl/src/scan_sa_death_recipient.cpp b/frameworks/innerkitsimpl/scan_impl/src/scan_sa_death_recipient.cpp new file mode 100644 index 0000000..5c5a7b6 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/src/scan_sa_death_recipient.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_sa_death_recipient.h" + +#include "scan_log.h" +#include "scan_manager_client.h" + +namespace OHOS::Scan { +ScanSaDeathRecipient::ScanSaDeathRecipient() {} + +void ScanSaDeathRecipient::OnRemoteDied(const wptr &object) +{ + SCAN_HILOGE("ScanSaDeathRecipient on remote systemAbility died."); + ScanManagerClient::GetInstance()->OnRemoteSaDied(object); +} +} // namespace OHOS::Scan diff --git a/frameworks/innerkitsimpl/scan_impl/src/scan_service_proxy.cpp b/frameworks/innerkitsimpl/scan_impl/src/scan_service_proxy.cpp new file mode 100644 index 0000000..a7ef0d6 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/src/scan_service_proxy.cpp @@ -0,0 +1,564 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "securec.h" +#include "iremote_broker.h" +#include "napi_scan_utils.h" +#include "scan_constant.h" +#include "scan_log.h" +#include "scanner_info.h" +#include "scan_service_proxy.h" + +namespace OHOS::Scan { +using namespace OHOS::HiviewDFX; + +ScanServiceProxy::ScanServiceProxy(const sptr &object) : IRemoteProxy(object) {} + +int32_t ScanServiceProxy::GetResult(int32_t retCode, MessageParcel &reply) +{ + if (retCode != ERR_NONE) { + SCAN_HILOGE("rpc error code = %{public}d", retCode); + return E_SCAN_RPC_FAILURE; + } + + retCode = reply.ReadInt32(); + SCAN_HILOGD("ScanServiceProxy end. ret = [%{public}d]", retCode); + return retCode; +} + +int32_t ScanServiceProxy::InitScan(int32_t &scanVersion) +{ + SCAN_HILOGD("ScanServiceProxy InitScan start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::InitScan remote is null"); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = remote->SendRequest(CMD_INIT_SCAN, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy InitScan failed"); + return ret; + } + scanVersion = reply.ReadInt32(); + SCAN_HILOGD("ScanServiceProxy InitScan end."); + return ret; +} + +int32_t ScanServiceProxy::ExitScan() +{ + SCAN_HILOGD("ScanServiceProxy ExitScan start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::ExitScan remote is null"); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = remote->SendRequest(CMD_EXIT_SCAN, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy ExitScan failed"); + return ret; + } + SCAN_HILOGD("ScanServiceProxy ExitScan end"); + return ret; +} + +int32_t ScanServiceProxy::GetScannerList() +{ + SCAN_HILOGD("ScanServiceProxy GetScannerList start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::GetScannerList remote is null"); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = remote->SendRequest(CMD_GET_SCANNER_LIST, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy GetScannerList failed"); + return ret; + } + SCAN_HILOGD("ScanServiceProxy GetScannerList end"); + return ret; +} + + +int32_t ScanServiceProxy::StopDiscover() +{ + SCAN_HILOGD("ScanServiceProxy StopDiscover start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::StopDiscover remote is null"); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = remote->SendRequest(CMD_STOP_DISCOVER, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy StopDiscover failed"); + return ret; + } + SCAN_HILOGD("ScanServiceProxy StopDiscover end"); + return ret; +} + + +int32_t ScanServiceProxy::OpenScanner(const std::string scannerId) +{ + SCAN_HILOGD("ScanServiceProxy OpenScanner start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::OpenScanner remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(scannerId); + int32_t ret = remote->SendRequest(CMD_OPEN_SCANNER, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy OpenScanner failed"); + return ret; + } + SCAN_HILOGD("ScanServiceProxy OpenScanner end"); + return ret; +} + +int32_t ScanServiceProxy::CloseScanner(const std::string scannerId) +{ + SCAN_HILOGD("ScanServiceProxy CloseScanner start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::CloseScanner remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(scannerId); + int32_t ret = remote->SendRequest(CMD_CLOSE_SCANNER, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy CloseScanner failed"); + return ret; + } + SCAN_HILOGD("ScanServiceProxy CloseScanner end"); + return ret; +} + +int32_t ScanServiceProxy::GetScanOptionDesc(const std::string scannerId, const int32_t optionIndex, + ScanOptionDescriptor &desc) +{ + SCAN_HILOGD("ScanServiceProxy GetScanOptionDesc start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::GetScanOptionDesc remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(scannerId); + data.WriteInt32(optionIndex); + int32_t ret = remote->SendRequest(CMD_GET_SCAN_OPTION_DESC, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy GetScanOptionDesc failed"); + return ret; + } + auto scanOptionDescriptor = ScanOptionDescriptor::Unmarshalling(reply); + desc = *scanOptionDescriptor; + SCAN_HILOGD("ScanServiceProxy GetScanOptionDesc end"); + return ret; +} + +int32_t ScanServiceProxy::OpScanOptionValue(const std::string scannerId, + const int32_t optionIndex, const ScanOptionOpType op, ScanOptionValue &value, int32_t &info) +{ + SCAN_HILOGD("ScanServiceProxy OpScanOptionValue start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::OpScanOptionValue remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(scannerId); + data.WriteInt32(optionIndex); + data.WriteUint32(op); + value.Marshalling(data); + int32_t ret = remote->SendRequest(CMD_OP_SCAN_OPTION_VALUE, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy OpScanOptionValue failed"); + return ret; + } + auto scanOptionValue = ScanOptionValue::Unmarshalling(reply); + value = *scanOptionValue; + if (op == SCAN_ACTION_GET_VALUE) { + info = reply.ReadInt32(); + } + SCAN_HILOGD("ScanServiceProxy OpScanOptionValue end"); + return ret; +} + +int32_t ScanServiceProxy::GetScanParameters(const std::string scannerId, ScanParameters ¶) +{ + SCAN_HILOGD("ScanServiceProxy GetScanParameters start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::GetScanParameters remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(scannerId); + int32_t ret = remote->SendRequest(CMD_GET_SCAN_PARAMETERS, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy GetScanParameters failed"); + return ret; + } + auto scanParameters = ScanParameters::Unmarshalling(reply); + para = *scanParameters; + SCAN_HILOGD("ScanServiceProxy GetScanParameters end"); + return ret; +} + +int32_t ScanServiceProxy::StartScan(const std::string scannerId, const bool &batchMode) +{ + SCAN_HILOGD("ScanServiceProxy StartScan start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::StartScan remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(scannerId); + data.WriteBool(batchMode); + int32_t ret = remote->SendRequest(CMD_START_SCAN, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy StartScan failed"); + return ret; + } + SCAN_HILOGD("ScanServiceProxy StartScan end"); + return ret; +} + +int32_t ScanServiceProxy::GetSingleFrameFD(const std::string scannerId, uint32_t &size, uint32_t fd) +{ + SCAN_HILOGE("ScanServiceProxy GetSingleFrameFD start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::GetSingleFrameFD remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(scannerId); + data.WriteFileDescriptor(fd); + int32_t ret = remote->SendRequest(CMD_GET_SINGLE_FRAME_FD, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy GetSingleFrameFD failed"); + return ret; + } + size = reply.ReadUint32(); + SCAN_HILOGD("ScanServiceProxy GetSingleFrameFD end"); + return ret; +} + +int32_t ScanServiceProxy::CancelScan(const std::string scannerId) +{ + SCAN_HILOGD("ScanServiceProxy CancelScan start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::CancelScan remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(scannerId); + int32_t ret = remote->SendRequest(CMD_CANCEL_SCAN, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy CancelScan failed"); + return ret; + } + SCAN_HILOGD("ScanServiceProxy CancelScan end"); + return ret; +} + +int32_t ScanServiceProxy::SetScanIOMode(const std::string scannerId, const bool isNonBlocking) +{ + SCAN_HILOGD("ScanServiceProxy SetScanIOMode start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::SetScanIOMode remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(scannerId); + data.WriteBool(isNonBlocking); + int32_t ret = remote->SendRequest(CMD_SET_SCAN_IO_MODE, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy SetScanIOMode failed"); + return ret; + } + SCAN_HILOGD("ScanServiceProxy SetScanIOMode end"); + return ret; +} + +int32_t ScanServiceProxy::GetScanSelectFd(const std::string scannerId, int32_t &fd) +{ + SCAN_HILOGD("ScanServiceProxy GetScanSelectFd start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::GetScanSelectFd remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(scannerId); + int32_t ret = remote->SendRequest(CMD_GET_SCAN_SELECT_FD, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy GetScanSelectFd failed"); + return ret; + } + fd = reply.ReadInt32(); + SCAN_HILOGD("ScanServiceProxy GetScanSelectFd end"); + return ret; +} + +int32_t ScanServiceProxy::On(const std::string taskId, const std::string &type, const sptr &listener) +{ + SCAN_HILOGD("ScanServiceProxy On start"); + if (listener == nullptr) { + SCAN_HILOGE("listener is nullptr"); + return E_SCAN_INVALID_PARAMETER; + } + + if (type.empty()) { + SCAN_HILOGE("ScanServiceProxy::On type is null."); + return E_SCAN_INVALID_PARAMETER; + } + + CREATE_PRC_MESSAGE; + data.WriteString(taskId); + data.WriteString(type); + data.WriteRemoteObject(listener->AsObject().GetRefPtr()); + + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::On remote is null"); + return E_SCAN_RPC_FAILURE; + } + + int32_t ret = remote->SendRequest(CMD_ON, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy On failed"); + return ret; + } + + SCAN_HILOGD("ScanServiceProxy On end"); + return ret; +} + +int32_t ScanServiceProxy::Off(const std::string taskId, const std::string &type) +{ + SCAN_HILOGD("ScanServiceProxy::Off start"); + + if (type.empty()) { + SCAN_HILOGE("ScanServiceProxy::Off type is null."); + return E_SCAN_INVALID_PARAMETER; + } + + CREATE_PRC_MESSAGE; + data.WriteString(taskId); + data.WriteString(type); + + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::SetScanIOMode remote is null"); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = remote->SendRequest(CMD_OFF, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy Off failed"); + return ret; + } + + SCAN_HILOGD("ScanServiceProxy Off out"); + return ret; +} + +int32_t ScanServiceProxy::GetScannerState(int32_t &scannerState) +{ + SCAN_HILOGD("ScanServiceProxy GetScannerState start"); + CREATE_PRC_MESSAGE; + + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::SetScanIOMode remote is null"); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = remote->SendRequest(CMD_GET_SCANNER_STATE, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy GetScannerState failed"); + return ret; + } + scannerState = reply.ReadInt32(); + SCAN_HILOGD("ScanServiceProxy GetScannerState end."); + return ret; +} + +int32_t ScanServiceProxy::GetScanProgress(const std::string scannerId, ScanProgress &prog) +{ + SCAN_HILOGI("ScanServiceProxy GetScanProgress start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::GetScanProgress remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(scannerId); + int32_t ret = remote->SendRequest(CMD_GET_SCAN_PROGRESS, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy GetScanProgress failed"); + return ret; + } + auto scanProgress = ScanProgress::Unmarshalling(reply); + if (scanProgress != nullptr) { + prog = *scanProgress; + } else { + SCAN_HILOGE("get scanProgress is a nullptr ptr."); + return E_SCAN_GENERIC_FAILURE; + } + SCAN_HILOGI("ScanServiceProxy GetScanProgress end"); + return ret; +} + +int32_t ScanServiceProxy::AddScanner(const std::string& serialNumber, const std::string& discoverMode) +{ + SCAN_HILOGD("ScanServiceProxy AddScanner start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::AddScanner remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(serialNumber); + data.WriteString(discoverMode); + int32_t ret = remote->SendRequest(CMD_CONNECT_SCANNER, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy AddScanner failed"); + return ret; + } + SCAN_HILOGD("ScanServiceProxy AddScanner end"); + return ret; +} + +int32_t ScanServiceProxy::DeleteScanner(const std::string& serialNumber, const std::string& discoverMode) +{ + SCAN_HILOGD("ScanServiceProxy DeleteScanner start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::DeleteScanner remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(serialNumber); + data.WriteString(discoverMode); + int32_t ret = remote->SendRequest(CMD_DISCONNECT_SCANNER, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy DeleteScanner failed"); + return ret; + } + SCAN_HILOGD("ScanServiceProxy DeleteScanner end"); + return ret; +} + +int32_t ScanServiceProxy::GetAddedScanner(std::vector& allAddedScanner) +{ + SCAN_HILOGD("ScanServiceProxy GetAddedScanner start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::GetAddedScanner remote is null"); + return E_SCAN_RPC_FAILURE; + } + int32_t ret = remote->SendRequest(CMD_GET_CONNECTED_SCANNER, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy GetAddedScanner failed"); + return ret; + } + uint32_t len = reply.ReadUint32(); + for (uint32_t i = 0; i < len; i++) { + auto infoPtr = ScanDeviceInfo::Unmarshalling(reply); + if (infoPtr == nullptr) { + SCAN_HILOGE("wrong scanDeviceInfo from data"); + return E_SCAN_GENERIC_FAILURE; + } + allAddedScanner.emplace_back(*infoPtr); + } + SCAN_HILOGD("ScanServiceProxy GetAddedScanner end"); + return ret; +} + +int32_t ScanServiceProxy::UpdateScannerName(const std::string& serialNumber, + const std::string& discoverMode, const std::string& deviceName) +{ + SCAN_HILOGD("ScanServiceProxy UpdateScannerName start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::UpdateScannerName remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(serialNumber); + data.WriteString(discoverMode); + data.WriteString(deviceName); + int32_t ret = remote->SendRequest(CMD_UPDATE_SCANNER_NAME, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy UpdateScannerName failed"); + return ret; + } + SCAN_HILOGD("ScanServiceProxy UpdateScannerName end"); + return ret; +} + +int32_t ScanServiceProxy::AddPrinter(const std::string& serialNumber, const std::string& discoverMode) +{ + SCAN_HILOGD("ScanServiceProxy AddPrinter start"); + CREATE_PRC_MESSAGE; + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceProxy::AddPrinter remote is null"); + return E_SCAN_RPC_FAILURE; + } + data.WriteString(serialNumber); + data.WriteString(discoverMode); + int32_t ret = remote->SendRequest(CMD_ADD_PRINTER, data, reply, option); + ret = GetResult(ret, reply); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceProxy AddPrinter failed"); + return ret; + } + SCAN_HILOGD("ScanServiceProxy AddPrinter end"); + return ret; +} +} // namespace OHOS::Scan diff --git a/frameworks/innerkitsimpl/scan_impl/src/scan_sync_load_callback.cpp b/frameworks/innerkitsimpl/scan_impl/src/scan_sync_load_callback.cpp new file mode 100644 index 0000000..69a1e82 --- /dev/null +++ b/frameworks/innerkitsimpl/scan_impl/src/scan_sync_load_callback.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_sync_load_callback.h" + +#include "iservice_registry.h" +#include "isystem_ability_load_callback.h" +#include "scan_log.h" +#include "scan_manager_client.h" +#include "system_ability_definition.h" + +namespace OHOS::Scan { +void ScanSyncLoadCallback::OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr &remoteObject) +{ + if (systemAbilityId != SCAN_SERVICE_ID) { + SCAN_HILOGE("start systemAbilityId is not scan server"); + return; + } + ScanManagerClient::GetInstance()->LoadServerSuccess(); +} + +void ScanSyncLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId) +{ + if (systemAbilityId != SCAN_SERVICE_ID) { + SCAN_HILOGE("start systemAbilityId is not scan server"); + return; + } + ScanManagerClient::GetInstance()->LoadServerFail(); +} +} // namespace OHOS::Scan \ No newline at end of file diff --git a/frameworks/ohscan/BUILD.gn b/frameworks/ohscan/BUILD.gn new file mode 100644 index 0000000..1dad967 --- /dev/null +++ b/frameworks/ohscan/BUILD.gn @@ -0,0 +1,78 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//base/print/print_fwk/print.gni") +import("//build/ohos.gni") + +config("scan_ndk_config") { + visibility = [ ":*" ] + include_dirs = [] + + cflags_cc = [ "-fno-exceptions" ] +} + +ohos_shared_library("ohscan") { + include_dirs = [ + "include", + "${print_path}/frameworks/innerkitsimpl/scan_impl/include", + "${print_path}/frameworks/helper/scan_helper/include", + "${print_utils_path}/include", + ] + public_configs = [ ":scan_ndk_config" ] + + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + boundary_sanitize = true + debug = false + integer_overflow = true + ubsan = true + } + + sources = [ "src/ohscan.cpp" ] + + deps = [ + "${print_path}/frameworks/helper/scan_helper:scan_helper", + "${print_path}/frameworks/innerkitsimpl/scan_impl:scan_client", + ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "access_token:libaccesstoken_sdk", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "eventhandler:libeventhandler", + "hilog:libhilog", + "hisysevent:libhisysevent", + "init:libbegetutil", + "ipc:ipc_core", + "napi:ace_napi", + "os_account:os_account_innerkits", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + relative_install_dir = "ndk" + output_name = "ohscan" + output_extension = "so" + + install_enable = true + subsystem_name = "print" + part_name = "print_fwk" +} diff --git a/frameworks/ohscan/include/ohscan.h b/frameworks/ohscan/include/ohscan.h new file mode 100644 index 0000000..e8b0dc9 --- /dev/null +++ b/frameworks/ohscan/include/ohscan.h @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup OH_Scan + * @{ + * + * @brief Provides the definition of the C interface for the scan module. + * + * @syscap SystemCapability.Print.PrintFramework + * + * @since 12 + * @version 1.0 + */ + +/** + * @file ohscan.h + * + * @brief Declares the APIs to discover and connect scanners, scan images from the scanner, + * obtain the page scanning progress and set scanned image parameters, and so on. + * + * @library libohscan.so + * @syscap SystemCapability.Print.PrintFramework + * @since 12 + * @version 1.0 + */ + +#ifndef OH_SCAN_H +#define OH_SCAN_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Defines error codes. + * + * @since 12 + * @version 1.0 + */ +typedef enum { + /** The operation is successful. */ + SCAN_ERROR_NONE = 0, + /** Permission verification failed. */ + SCAN_ERROR_NO_PERMISSION = 201, + /** The parameter is invalid. For example, the pointer is null or the character string is null. */ + SCAN_ERROR_INVALID_PARAMETER = 401, + /** General internal error. */ + SCAN_ERROR_GENERIC_FAILURE = 24300001, + /** RPC communication error. */ + SCAN_ERROR_RPC_FAILURE = 24300002, + /** Server error. */ + SCAN_ERROR_SERVER_FAILURE = 24300003, + /** Operation is not supported. **/ + SCAN_ERROR_UNSUPPORTED = 24300004, + /** Operation was cancelled. **/ + SCAN_ERROR_CANCELLED = 24300005, + /** Device is busy, try again later. **/ + SCAN_ERROR_DEVICE_BUSY = 24300006, + /** Data is invalid (includes no dev at open). **/ + SCAN_ERROR_INVAL = 24300007, + /** Document feeder jammed. **/ + SCAN_ERROR_JAMMED = 24300008, + /** Document feeder out of documents. **/ + SCAN_ERROR_NO_DOCS = 24300009, + /** Scanner cover is open. **/ + SCAN_ERROR_COVER_OPEN = 24300010, + /** Error during device I/O. **/ + SCAN_ERROR_IO_ERROR = 24300011, + /** Out of memory. **/ + SCAN_ERROR_NO_MEM = 24300012, +} Scan_ErrorCode; + +/** + * @brief Indicates scanner device information. + * + * @since 12 + */ +typedef struct { + /** Scanner id. */ + const char* scannerId; + /** Scanner manufacturer. */ + const char* manufacturer; + /** Scanner model. */ + const char* model; + /** Scanner discoverMode. */ + const char* discoverMode; + /** Scanner serialNumber. */ + const char* serialNumber; +} Scan_ScannerDevice; + +/** + * @brief Indicates the progress of scanning a picture by the scanner. + * + * @since 12 + */ +typedef struct { + /** Picture progress from 0 to 100. */ + int32_t progress; + /** scanner file handle. */ + int32_t fd; + /** Indicates whether the image is the last scanned image. */ + bool isFinal; +} Scan_ScanPictureProgress; + +/** + * @brief Indicates all parameter options for one scanner. + * + * @since 12 + */ +typedef struct { + /** Number of all options. */ + int32_t* options; + /** Title of an option. */ + char** titles; + /** Description of an option. */ + char** descriptions; + /** The range that an option can be set to. */ + char** ranges; + /** Number of parameter options that can be set. */ + int32_t optionCount; +} Scan_ScannerParameterOptions; + +/** + * @brief Scanner devices discovery callback. + * + * @param devices List of all discovered scanner devices. + * @param deviceCount Number of Scanners Found. + * @since 12 + */ +typedef void (*Scan_DiscoverScannerCallback)(Scan_ScannerDevice** devices, int32_t deviceCount); + +/** + * @brief This API checks and pulls up the scan service, initializes the scan client, + * and establishes a connection to the scan service. + * + * @permission {@code ohos.permission.PRINT} + * @return {@link Scan_ERROR_NONE} Indicates the scanning service is successfully started. + * {@link SCAN_ERROR_NO_PERMISSION} Indicates have no permission to use this interface. + * {@link SCAN_ERROR_RPC_FAILURE} Indicates an RPC communication error. + * {@link SCAN_ERROR_SERVER_FAILURE} Indicates An error occurs in the scan process. + * @syscap SystemCapability.Print.PrintFramework + * @since 12 + */ +int32_t OH_Scan_Init(); + +/** + * @brief This API starts discovering scanners, Register a callback to handle discovered scanner devices. + * + * @permission {@code ohos.permission.PRINT} + * @param callback The {@link Scan_DiscoverScannerCallback} of scanner discovery event. + * @return {@link Scan_ERROR_NONE} Indicates successful start of scanner search. + * {@link SCAN_ERROR_NO_PERMISSION} Indicates have no permission to use this interface. + * {@link SCAN_ERROR_RPC_FAILURE} Indicates an RPC communication error. + * {@link SCAN_ERROR_SERVER_FAILURE} Indicates An error occurs in the scan process. + * @syscap SystemCapability.Print.PrintFramework + * @since 12 + */ +int32_t OH_Scan_StartScannerDiscovery(Scan_DiscoverScannerCallback callback); + +/** + * @brief This API connects to scanner devices. + * + * @permission {@code ohos.permission.PRINT} + * @param scannerId The id used to connect to the scanner. + * @return {@link Scan_ERROR_NONE} Indicates that the scanner was successfully connected. + * {@link SCAN_ERROR_NO_PERMISSION} Indicates have no permission to use this interface. + * {@link SCAN_ERROR_RPC_FAILURE} Indicates an RPC communication error. + * {@link SCAN_ERROR_SERVER_FAILURE} Indicates An error occurs in the scan process. + * {@link SCAN_ERROR_DEVICE_BUSY} Indicates that the scanner is busy. + * {@link SCAN_ERROR_INVALID_PARAMETER} Indicates that the input parameter is invalid. + * {@link SCAN_ERROR_IO_ERROR} Indicates an error occured while communicating with the device. + * {@link SCAN_ERROR_NO_MEM} Indicates an insufficent amount of memory is available. + * @syscap SystemCapability.Print.PrintFramework + * @since 12 + */ +int32_t OH_Scan_OpenScanner(const char* scannerId); + +/** + * @brief This API is used to close the connected scanner device. + * + * @permission {@code ohos.permission.PRINT} + * @param scannerId The id to disconnect the scanner. + * @return {@link Scan_ERROR_NONE} Indicates that the scanner connection was successfully closed. + * {@link SCAN_ERROR_NO_PERMISSION} Indicates have no permission to use this interface. + * {@link SCAN_ERROR_RPC_FAILURE} Indicates an RPC communication error. + * {@link SCAN_ERROR_SERVER_FAILURE} Indicates An error occurs in the scan process. + * {@link SCAN_ERROR_INVALID_PARAMETER} Indicates that the input parameter is invalid. + * @syscap SystemCapability.Print.PrintFramework + * @since 12 + */ +int32_t OH_Scan_CloseScanner(const char* scannerId); + +/** + * @brief This API can be used to get a list of parameters that can be set by the scanner. + * + * @permission {@code ohos.permission.PRINT} + * @param scannerId The id used to obtain the scanner parameters. + * @param errorCode The errorCode returns {@link Scan_ErrorCode#Scan_ERROR_NONE} if the execution is successful, + * otherwise returns a specific error code, refer to {@link Print_ErrorCode}. + * @return {@link Scan_ERROR_NONE} Indicates that the scanner parameter options are successfully obtained. + * {@link SCAN_ERROR_NO_PERMISSION} Indicates have no permission to use this interface. + * {@link SCAN_ERROR_RPC_FAILURE} Indicates an RPC communication error. + * {@link SCAN_ERROR_SERVER_FAILURE} Indicates An error occurs in the scan process. + * @syscap SystemCapability.Print.PrintFramework + * @since 12 + */ +Scan_ScannerParameterOptions* OH_Scan_GetScannerParameter(const char* scannerId, int32_t* errorCode); + +/** + * @brief This API can be used to set one of the scanner's option parameters. + * + * @permission {@code ohos.permission.PRINT} + * @param scannerId This id is used to set the options for a specific scanner. + * @param option Parameter number to be set. + * @param value Option value to be set. + * @return {@link Scan_ERROR_NONE} Indicates that the scanner parameters were successfully set. + * {@link SCAN_ERROR_NO_PERMISSION} Indicates have no permission to use this interface. + * {@link SCAN_ERROR_RPC_FAILURE} Indicates an RPC communication error. + * {@link SCAN_ERROR_SERVER_FAILURE} Indicates An error occurs in the scan process. + * @syscap SystemCapability.Print.PrintFramework + * @since 12 + */ +int32_t OH_Scan_SetScannerParameter(const char* scannerId, const int32_t option, const char* value); + +/** + * @brief This API allows the scanner to start scanning. + * + * @permission {@code ohos.permission.PRINT} + * @param scannerId This id is used to start the scan job for the specified scanner. + * @param batchMode Whether to start the scanner in batch mode. + * @return {@link Scan_ERROR_NONE} Indicates that the scanner has successfully canceled the scan job. + * {@link SCAN_ERROR_NO_PERMISSION} Indicates have no permission to use this interface. + * {@link SCAN_ERROR_RPC_FAILURE} Indicates an RPC communication error. + * {@link SCAN_ERROR_SERVER_FAILURE} Indicates An error occurs in the scan process. + * {@link SCAN_ERROR_JAMMED} Indicates the document feeder is jammed. + * {@link SCAN_ERROR_NO_DOCS} Indicates the document feeder is out of documents. + * {@link SCAN_ERROR_COVER_OPEN} Indicates the scanner cover is open. + * {@link SCAN_ERROR_IO_ERROR} Indicates an error occurred while communicating with the device. + * {@link SCAN_ERROR_NO_MEM} Indicates an insufficent amount of memory is available. + * {@link SCAN_ERROR_INVALID_PARAMETER} Indicates that the input parameter is invalid. + * {@link SCAN_ERROR_DEVICE_BUSY} Indicates the device is busy, the operation should be retried later. + * @syscap SystemCapability.Print.PrintFramework + * @since 12 + */ +int32_t OH_Scan_StartScan(const char* scannerId, bool batchMode); + +/** + * @brief This API allows the scanner to cancel the scan. + * + * @permission {@code ohos.permission.PRINT} + * @param scannerId This id is used to cancel the scan job for the specified scanner. + * @return {@link Scan_ERROR_NONE} Indicates that the scanner has successfully canceled the scan job. + * {@link SCAN_ERROR_NO_PERMISSION} Indicates have no permission to use this interface. + * {@link SCAN_ERROR_INVALID_PARAMETER} Indicates if the pointer is null or the character string is null. + * {@link SCAN_ERROR_RPC_FAILURE} Indicates an RPC communication error. + * {@link SCAN_ERROR_SERVER_FAILURE} Indicates An error occurs in the scan process. + * @syscap SystemCapability.Print.PrintFramework + * @since 12 + */ +int32_t OH_Scan_CancelScan(const char* scannerId); + +/** + * @brief This API can get the progress of the scanner scanning the picture. + * + * @permission {@code ohos.permission.PRINT} + * @param scannerId The id for querying the image scanning progress of the scanner. + * @param prog The {@link Scan_ScanPictureProgress} of scanning pictures + * @return {@link Scan_ERROR_NONE} Indicates the scanner has successfully queried the progress of the scanned image. + * {@link SCAN_ERROR_NO_PERMISSION} Indicates have no permission to use this interface. + * {@link SCAN_ERROR_INVALID_PARAMETER} Indicates if the pointer is null or the character string is null. + * {@link SCAN_ERROR_RPC_FAILURE} Indicates an RPC communication error. + * {@link SCAN_ERROR_SERVER_FAILURE} Indicates An error occurs in the scan process. + * {@link SCAN_ERROR_JAMMED} Indicates the document feeder is jammed. + * {@link SCAN_ERROR_NO_DOCS} Indicates the document feeder is out of documents. + * {@link SCAN_ERROR_COVER_OPEN} Indicates the scanner cover is open. + * {@link SCAN_ERROR_IO_ERROR} Indicates an error occurred while communicating with the scanner. + * {@link SCAN_ERROR_NO_MEM} Indicates an insufficent amount of memory is available. + * {@link SCAN_ERROR_DEVICE_BUSY} Indicates the device is busy, the operation should be retried later. + * @syscap SystemCapability.Print.PrintFramework + * @since 12 + */ +int32_t OH_Scan_GetScanPictureProgress(const char* scannerId, Scan_ScanPictureProgress* prog); + +/** + * @brief This API can be used to exit the scanning service, free the Scan Framework Memory, + * and unregister the callback for scanner discover. + * + * @permission {@code ohos.permission.PRINT} + * @return {@link Scan_ERROR_NONE} Indicates the scan service exit successfully. + * {@link SCAN_ERROR_NO_PERMISSION} Indicates have no permission to use this interface. + * {@link SCAN_ERROR_RPC_FAILURE} Indicates an RPC communication error. + * {@link SCAN_ERROR_SERVER_FAILURE} Indicates An error occurs in the scan process. + * @syscap SystemCapability.Print.PrintFramework + * @since 12 + */ +int32_t OH_Scan_Exit(); + +#ifdef __cplusplus +} +#endif + +#endif // OH_SCAN_H +/** @} */ diff --git a/frameworks/ohscan/src/ohscan.cpp b/frameworks/ohscan/src/ohscan.cpp new file mode 100644 index 0000000..ba28098 --- /dev/null +++ b/frameworks/ohscan/src/ohscan.cpp @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include "securec.h" +#include "refbase.h" +#include "scan_callback.h" +#include "scan_manager_client.h" +#include "scan_constant.h" +#include "scan_log.h" +#include "scanner_info.h" +#include "scan_option_value.h" +#include "ohscan.h" + +using namespace OHOS::Scan; + +struct ValueMap { + uint32_t valueType; + int32_t optionIndex; + std::set numList; + std::set strList; +}; + +struct ScanParaTable { + std::vector titBuff; + std::vector desBuff; + std::vector rangesBuff; + int32_t lengthBuff; +}; + +static constexpr int32_t SCAN_INT_TYPE = 1; +static constexpr int32_t SCAN_STRING_TYPE = 3; +static constexpr int32_t SCAN_NUM_LIST = 2; +static constexpr int32_t SCAN_STRING_LIST = 3; +static std::map> g_valueMap; +static std::map g_scanParaTables; +static bool g_isListening = false; +static const char* GET_SCANNER_DEVICE_LIST = "GET_SCANNER_DEVICE_LIST"; +static Scan_DiscoverScannerCallback g_discoverCallback = nullptr; + + +static inline void FreeDeviceListMemory(Scan_ScannerDevice** devices, int32_t deviceCount) +{ + for (int32_t i = 0; i < deviceCount; i++) { + DELETE_AND_NULLIFY(devices[i]) + } + DELETE_ARRAY_AND_NULLIFY(devices) +} + +auto callbackFunction = [](std::vector &infos) { + int32_t deviceCount = infos.size(); + SCAN_HILOGI("deviceCount : [%{public}d]", deviceCount); + if (deviceCount == 0) { + SCAN_HILOGE("not found"); + g_discoverCallback(nullptr, 0); + return; + } + Scan_ScannerDevice** devices = new (std::nothrow) Scan_ScannerDevice* [deviceCount]; + if (devices == nullptr) { + SCAN_HILOGE("devices is a nullptr"); + g_discoverCallback(nullptr, 0); + } + int32_t devicesMemSize = deviceCount * sizeof(Scan_ScannerDevice*); + if (memset_s(devices, devicesMemSize, 0, devicesMemSize) != 0) { + SCAN_HILOGW("memset_s fail"); + FreeDeviceListMemory(devices, 0); + g_discoverCallback(nullptr, 0); + } + for (int i = 0; i < deviceCount; i++) { + Scan_ScannerDevice* device = new (std::nothrow) Scan_ScannerDevice(); + if (device == nullptr) { + SCAN_HILOGE("devices is a nullptr"); + deviceCount = i; + break; + } + if (memset_s(device, sizeof(Scan_ScannerDevice), 0, sizeof(Scan_ScannerDevice)) != 0) { + SCAN_HILOGW("memset_s fail"); + deviceCount = i; + break; + } + device->scannerId = infos[i].GetDeviceId().c_str(); + device->manufacturer = infos[i].GetManufacturer().c_str(); + device->model = infos[i].GetModel().c_str(); + device->serialNumber = infos[i].GetSerialNumber().c_str(); + device->discoverMode = infos[i].GetDiscoverMode().c_str(); + devices[i] = device; + } + g_discoverCallback(devices, deviceCount); + FreeDeviceListMemory(devices, deviceCount); +}; + +namespace { +int32_t GetScanParaDesc(const std::string &deviceId, ScanOptionValue &value) +{ + auto client = ScanManagerClient::GetInstance(); + ScanOptionDescriptor desc; + int32_t ret = client->GetScanOptionDesc(deviceId, 0, desc); + uint32_t optionType = desc.GetOptionType(); + int32_t optionSize = desc.GetOptionSize(); + value.SetScanOptionValueType(static_cast(optionType)); + value.SetValueSize(optionSize); + int32_t info = 0; + ret = client->OpScanOptionValue(deviceId, 0, SCAN_ACTION_GET_VALUE, value, info); + return ret; +} + +int32_t GetScanParaValues(const std::string &deviceId, ScanOptionValue &value, ScanParaTable ¶Table) +{ + std::set dataType = {SCAN_INT_TYPE, SCAN_STRING_TYPE}; + int32_t lengthBuff = 0; + for (int i = 1 ; i < value.GetNumValue(); i++) { + ScanOptionDescriptor desc; + auto client = ScanManagerClient::GetInstance(); + int32_t ret = client->GetScanOptionDesc(deviceId, i, desc); + if (ret != SCAN_ERROR_NONE) { + SCAN_HILOGE("Failed to get scanner parameters."); + return ret; + } + if (!dataType.count(desc.GetOptionType())) { + continue; + } + if (desc.GetOptionConstraintType() == SCAN_NUM_LIST) { + std::string tmp; + std::vector optionConstraintNumber; + desc.GetOptionConstraintNumber(optionConstraintNumber); + for (auto t : optionConstraintNumber) { + std::string numStr = std::to_string(t); + tmp.append(numStr).append(","); + g_valueMap[deviceId][lengthBuff].numList.insert(numStr); + g_valueMap[deviceId][lengthBuff].valueType = SCAN_INT_TYPE; + } + tmp.pop_back(); + paraTable.rangesBuff.emplace_back(tmp); + } else if (desc.GetOptionConstraintType() == SCAN_STRING_LIST) { + std::string tmp; + std::vector optionConstraintString; + desc.GetOptionConstraintString(optionConstraintString); + for (auto t : optionConstraintString) { + tmp.append(t).append(","); + g_valueMap[deviceId][lengthBuff].strList.insert(t); + g_valueMap[deviceId][lengthBuff].valueType = SCAN_STRING_TYPE; + } + tmp.pop_back(); + paraTable.rangesBuff.emplace_back(tmp); + } else { + continue; + } + paraTable.titBuff.emplace_back(desc.GetOptionTitle()); + paraTable.desBuff.emplace_back(desc.GetOptionDesc()); + g_valueMap[deviceId][lengthBuff].optionIndex = i; + lengthBuff++; + } + paraTable.lengthBuff = lengthBuff; + return SCAN_ERROR_NONE; +} + +void FreeScannerOptionsMemory(Scan_ScannerParameterOptions* scannerOptions) +{ + if (scannerOptions == nullptr) { + SCAN_HILOGW("scannerOptions is a nullptr."); + return; + } + DELETE_ARRAY_AND_NULLIFY(scannerOptions->options) + + for (int i = 0; i < scannerOptions->optionCount; i++) { + DELETE_AND_NULLIFY(scannerOptions->titles[i]) + } + DELETE_ARRAY_AND_NULLIFY(scannerOptions->titles) + + for (int i = 0; i < scannerOptions->optionCount; i++) { + DELETE_AND_NULLIFY(scannerOptions->descriptions[i]) + } + DELETE_ARRAY_AND_NULLIFY(scannerOptions->descriptions) + + for (int i = 0; i < scannerOptions->optionCount; i++) { + DELETE_AND_NULLIFY(scannerOptions->ranges[i]) + } + DELETE_ARRAY_AND_NULLIFY(scannerOptions->ranges) + DELETE_AND_NULLIFY(scannerOptions) +} + +Scan_ScannerParameterOptions* CreateScannerOptions(int32_t &optionCount) +{ + Scan_ScannerParameterOptions* scannerOptions = new (std::nothrow) Scan_ScannerParameterOptions(); + if (scannerOptions == nullptr) { + SCAN_HILOGE("scannerOptions is a nullptr"); + return nullptr; + } + int32_t scannerOptionsMemSize = sizeof(Scan_ScannerParameterOptions); + if (memset_s(scannerOptions, scannerOptionsMemSize, 0, scannerOptionsMemSize) != 0) { + SCAN_HILOGW("memset_s fail"); + FreeScannerOptionsMemory(scannerOptions); + return nullptr; + } + scannerOptions->options = new (std::nothrow) int[optionCount]; + scannerOptions->titles = new (std::nothrow) char* [optionCount]; + scannerOptions->descriptions = new (std::nothrow) char* [optionCount]; + scannerOptions->ranges = new (std::nothrow) char* [optionCount]; + scannerOptions->optionCount = optionCount; + if (scannerOptions->options == nullptr || scannerOptions->titles == nullptr || + scannerOptions->descriptions == nullptr || scannerOptions->ranges == nullptr) { + FreeScannerOptionsMemory(scannerOptions); + return nullptr; + } + int32_t integerMemSize = optionCount * sizeof(int32_t); + int32_t stringMemSize = optionCount * sizeof(char**); + if (memset_s(scannerOptions->options, integerMemSize, 0, integerMemSize) != 0 || + memset_s(scannerOptions->titles, stringMemSize, 0, stringMemSize) != 0 || + memset_s(scannerOptions->descriptions, stringMemSize, 0, stringMemSize) != 0 || + memset_s(scannerOptions->ranges, stringMemSize, 0, stringMemSize) != 0) { + SCAN_HILOGW("memset_s fail"); + FreeScannerOptionsMemory(scannerOptions); + return nullptr; + } + return scannerOptions; +} + +bool MemSetScannerOptions(Scan_ScannerParameterOptions* scannerOptions, int32_t &optionCount, ScanParaTable ¶Table) +{ + for (int i = 0; i < optionCount; i++) { + scannerOptions->options[i] = i; + auto bufferSize = paraTable.titBuff[i].length() + 1; + char* titleBuf = new (std::nothrow) char[bufferSize]; + if (titleBuf == nullptr) { + FreeScannerOptionsMemory(scannerOptions); + return false; + } + if (memset_s(titleBuf, bufferSize, 0, bufferSize) != 0) { + SCAN_HILOGW("memset_s fail"); + FreeScannerOptionsMemory(scannerOptions); + return false; + } + strncpy_s(titleBuf, bufferSize, paraTable.titBuff[i].c_str(), bufferSize); + scannerOptions->titles[i] = titleBuf; + bufferSize = paraTable.desBuff[i].length() + 1; + char* desBuf = new (std::nothrow) char[bufferSize]; + if (desBuf == nullptr) { + FreeScannerOptionsMemory(scannerOptions); + return false; + } + if (memset_s(desBuf, bufferSize, 0, bufferSize) != 0) { + SCAN_HILOGW("memset_s fail"); + FreeScannerOptionsMemory(scannerOptions); + return false; + } + strncpy_s(desBuf, bufferSize, paraTable.desBuff[i].c_str(), bufferSize); + scannerOptions->descriptions[i] = desBuf; + bufferSize = paraTable.rangesBuff[i].length() + 1; + char* rangeBuf = new (std::nothrow) char[bufferSize]; + if (rangeBuf == nullptr) { + FreeScannerOptionsMemory(scannerOptions); + return false; + } + if (memset_s(rangeBuf, bufferSize, 0, bufferSize) != 0) { + SCAN_HILOGW("memset_s fail"); + FreeScannerOptionsMemory(scannerOptions); + return false; + } + strncpy_s(rangeBuf, bufferSize, paraTable.rangesBuff[i].c_str(), bufferSize); + scannerOptions->ranges[i] = rangeBuf; + } + return true; +} + +Scan_ScannerParameterOptions* GetScanParaValue(ScanParaTable ¶Table) +{ + int32_t optionCount = paraTable.lengthBuff; + if (optionCount <= 0) { + SCAN_HILOGE("optionCount <= 0"); + return nullptr; + } + Scan_ScannerParameterOptions* scannerOptions = CreateScannerOptions(optionCount); + if (scannerOptions == nullptr) { + SCAN_HILOGE("scannerOptions is a nullptr"); + return nullptr; + } + if (!MemSetScannerOptions(scannerOptions, optionCount, paraTable)) { + SCAN_HILOGE("MemSetScannerOptions error"); + return nullptr; + } + return scannerOptions; +} +} + +int32_t OH_Scan_Init() +{ + SCAN_HILOGI("Enter OH_Scan_Init"); + auto client = ScanManagerClient::GetInstance(); + int32_t scanVersion = 0; + int32_t ret = client->InitScan(scanVersion); + if (ret != SCAN_ERROR_NONE) { + SCAN_HILOGE("InitScan failed, ErrorCode: [%{public}d]", ret); + return ret; + } else { + SCAN_HILOGI("InitScan successfully"); + return SCAN_ERROR_NONE; + } +} + +int32_t OH_Scan_StartScannerDiscovery(Scan_DiscoverScannerCallback callback) +{ + g_discoverCallback = callback; + auto client = ScanManagerClient::GetInstance(); + int32_t ret = SCAN_ERROR_NONE; + if (!g_isListening) { + OHOS::sptr call = new (std::nothrow) ScanCallback(callbackFunction); + if (call == nullptr) { + SCAN_HILOGE("call is null"); + return SCAN_ERROR_GENERIC_FAILURE; + } + ret = client->On("", std::string(GET_SCANNER_DEVICE_LIST), call); + if (ret != SCAN_ERROR_NONE) { + SCAN_HILOGE("Failed to register event"); + return ret; + } + g_isListening = true; + } + ret = client->GetScannerList(); + if (ret != SCAN_ERROR_NONE) { + SCAN_HILOGE("Failed to GetScannerList"); + return ret; + } + return SCAN_ERROR_NONE; +} + +int32_t OH_Scan_OpenScanner(const char* scannerId) +{ + if (scannerId == nullptr) { + SCAN_HILOGE("Invalid parameter."); + return SCAN_ERROR_INVALID_PARAMETER; + } + auto client = ScanManagerClient::GetInstance(); + int32_t ret = client->OpenScanner(std::string(scannerId)); + if (ret != SCAN_ERROR_NONE) { + SCAN_HILOGE("OpenScanner failed, ErrorCode: [%{public}d]", ret); + return ret; + } else { + SCAN_HILOGI("OpenScanner successfully"); + return SCAN_ERROR_NONE; + } +} + +int32_t OH_Scan_CloseScanner(const char* scannerId) +{ + if (scannerId == nullptr) { + SCAN_HILOGE("Invalid parameter."); + return SCAN_ERROR_INVALID_PARAMETER; + } + auto client = ScanManagerClient::GetInstance(); + int32_t ret = client->CloseScanner(std::string(scannerId)); + if (ret != SCAN_ERROR_NONE) { + SCAN_HILOGE("CloseScanner failed, ErrorCode: [%{public}d]", ret); + return ret; + } else { + SCAN_HILOGI("CloseScanner successfully"); + return SCAN_ERROR_NONE; + } +} + +Scan_ScannerParameterOptions* OH_Scan_GetScannerParameter(const char* scannerId, int32_t* errorCode) +{ + if (scannerId == nullptr || errorCode == nullptr) { + SCAN_HILOGE("Invalid parameter."); + return nullptr; + } + std::string deviceId = std::string(scannerId); + if (g_scanParaTables.find(deviceId) != g_scanParaTables.end()) { + SCAN_HILOGW("Device parameters have been obtained."); + *errorCode = SCAN_ERROR_NONE; + return g_scanParaTables[deviceId]; + } + int32_t status = SCAN_ERROR_NONE; + ScanOptionValue value; + status = GetScanParaDesc(deviceId, value); + if (status != SCAN_ERROR_NONE) { + SCAN_HILOGE("Failed to get scanner ScanOptionValue value."); + *errorCode = status; + return nullptr; + } + ScanParaTable paraTable; + status = GetScanParaValues(deviceId, value, paraTable); + if (status != SCAN_ERROR_NONE) { + SCAN_HILOGE("Failed to get scanner ScanParaTable paraTable."); + *errorCode = status; + return nullptr; + } + + Scan_ScannerParameterOptions* scaParaOptions = GetScanParaValue(paraTable); + if (scaParaOptions == nullptr) { + *errorCode = SCAN_ERROR_GENERIC_FAILURE; + return nullptr; + } + g_scanParaTables[scannerId] = scaParaOptions; + *errorCode = SCAN_ERROR_NONE; + return scaParaOptions; +} + +int32_t OH_Scan_SetScannerParameter(const char* scannerId, const int32_t option, const char* value) +{ + if (scannerId == nullptr || value == nullptr) { + SCAN_HILOGE("Invalid parameter."); + return SCAN_ERROR_INVALID_PARAMETER; + } + auto client = ScanManagerClient::GetInstance(); + if (g_valueMap.find(scannerId) == g_valueMap.end() || + g_valueMap[scannerId].find(option) == g_valueMap[scannerId].end()) { + SCAN_HILOGE("not exit this option: [%{public}d]", option); + return SCAN_ERROR_INVALID_PARAMETER; + } + auto t = g_valueMap[scannerId].find(option); + uint32_t valueType = g_valueMap[scannerId][option].valueType; + std::string strvalue = std::string(value); + ScanOptionValue optionValue; + + if (valueType == SCAN_INT_TYPE) { + if (!t->second.numList.count(strvalue)) { + SCAN_HILOGE("not exit this value: [%{public}s]", strvalue.c_str()); + return SCAN_ERROR_INVALID_PARAMETER; + } + optionValue.SetNumValue(std::stoi(strvalue)); + optionValue.SetScanOptionValueType(SCAN_VALUE_NUM); + } else if (valueType == SCAN_STRING_TYPE) { + if (!t->second.strList.count(strvalue)) { + SCAN_HILOGE("not exit this value: [%{public}s]", strvalue.c_str()); + return SCAN_ERROR_INVALID_PARAMETER; + } + optionValue.SetStrValue(strvalue); + optionValue.SetScanOptionValueType(SCAN_VALUE_STR); + } else { + SCAN_HILOGI("not exist this type "); + return SCAN_ERROR_GENERIC_FAILURE; + } + + int32_t optionIndex = t->second.optionIndex; + int32_t info; + int32_t ret = client->OpScanOptionValue(std::string(scannerId), + optionIndex, SCAN_ACTION_SET_VALUE, optionValue, info); + if (ret != SCAN_ERROR_NONE) { + SCAN_HILOGE("SetScannerParameter failed, ErxrorCode: [%{public}d]", ret); + return ret; + } else { + SCAN_HILOGI("SetScannerParameter successfully"); + return SCAN_ERROR_NONE; + } + return SCAN_ERROR_NONE; +} + +int32_t OH_Scan_StartScan(const char* scannerId, bool batchMode) +{ + if (scannerId == nullptr) { + SCAN_HILOGE("Invalid parameter."); + return SCAN_ERROR_INVALID_PARAMETER; + } + auto client = ScanManagerClient::GetInstance(); + int32_t ret = client->StartScan(std::string(scannerId), batchMode); + if (ret != SCAN_ERROR_NONE) { + SCAN_HILOGE("StartScan failed, ErxrorCode: [%{public}d]", ret); + return ret; + } else { + SCAN_HILOGI("StartScan successfully"); + return SCAN_ERROR_NONE; + } +} + +int32_t OH_Scan_CancelScan(const char* scannerId) +{ + if (scannerId == nullptr) { + SCAN_HILOGE("Invalid parameter."); + return SCAN_ERROR_INVALID_PARAMETER; + } + auto client = ScanManagerClient::GetInstance(); + int32_t ret = client->CancelScan(std::string(scannerId)); + if (ret != SCAN_ERROR_NONE) { + SCAN_HILOGE("CancelScan failed, ErxrorCode: [%{public}d]", ret); + return ret; + } else { + SCAN_HILOGI("CancelScan successfully"); + return SCAN_ERROR_NONE; + } +} + +int32_t OH_Scan_GetScanPictureProgress(const char* scannerId, Scan_ScanPictureProgress* prog) +{ + if (prog == nullptr) { + SCAN_HILOGE("Invalid parameter."); + return SCAN_ERROR_INVALID_PARAMETER; + } + ScanProgress scanProg; + auto client = ScanManagerClient::GetInstance(); + int32_t ret = client->GetScanProgress(std::string(scannerId), scanProg); + if (ret != SCAN_ERROR_NONE) { + SCAN_HILOGE("GetScanProgress failed, ErrorCode: [%{public}d]", ret); + return ret; + } else { + prog->progress = scanProg.GetScanProgress(); + prog->fd = scanProg.GetScanPictureFd(); + prog->isFinal = scanProg.GetIsFinal(); + SCAN_HILOGI("GetScanProgress successfully"); + return SCAN_ERROR_NONE; + } +} + +int32_t OH_Scan_Exit() +{ + auto client = ScanManagerClient::GetInstance(); + int32_t ret = client->ExitScan(); + if (ret != SCAN_ERROR_NONE) { + SCAN_HILOGE("ExitScan failed, ErrorCode: [%{public}d]", ret); + return ret; + } + for (auto table : g_scanParaTables) { + FreeScannerOptionsMemory(table.second); + } + g_scanParaTables.clear(); + if (g_isListening) { + client->Off("", std::string(GET_SCANNER_DEVICE_LIST)); + } + SCAN_HILOGI("ExitScan successfully"); + return SCAN_ERROR_NONE; +} \ No newline at end of file diff --git a/interfaces/kits/napi/scan_napi/BUILD.gn b/interfaces/kits/napi/scan_napi/BUILD.gn new file mode 100644 index 0000000..e837c42 --- /dev/null +++ b/interfaces/kits/napi/scan_napi/BUILD.gn @@ -0,0 +1,69 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//base/print/print_fwk/print.gni") +import("//build/ohos.gni") + +config("scan_interfaces_kits_napi_config") { + visibility = [ ":*" ] + include_dirs = [ "include" ] + + cflags_cc = [ "-fexceptions" ] +} + +ohos_shared_library("scan_napi") { + include_dirs = [ + "${print_utils_path}/include", + "${print_path}/frameworks/innerkitsimpl/scan_impl/include", + "${print_path}/frameworks/helper/scan_helper/include", + ] + public_configs = [ ":scan_interfaces_kits_napi_config" ] + + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + boundary_sanitize = true + debug = false + integer_overflow = true + ubsan = true + } + + sources = [ + "src/napi_inner_scan.cpp", + "src/scan_async_call.cpp", + "src/scan_module.cpp", + ] + + deps = [ + "${print_path}/frameworks/helper/scan_helper:scan_helper", + "${print_path}/frameworks/innerkitsimpl/scan_impl:scan_client", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:data_ability_helper", + "ability_runtime:napi_base_context", + "c_utils:utils", + "eventhandler:libeventhandler", + "hilog:libhilog", + "ipc:ipc_core", + "napi:ace_napi", + "samgr:samgr_proxy", + ] + relative_install_dir = "module" + subsystem_name = "print" + part_name = "print_fwk" +} diff --git a/interfaces/kits/napi/scan_napi/include/napi_inner_scan.h b/interfaces/kits/napi/scan_napi/include/napi_inner_scan.h new file mode 100644 index 0000000..3e15de8 --- /dev/null +++ b/interfaces/kits/napi/scan_napi/include/napi_inner_scan.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NAPI_INNER_SCAN_H +#define NAPI_INNER_SCAN_H +#define TDD_ENABLE 1 + +#include +#include + +#include "napi/native_api.h" +#include "scan_async_call.h" +#include "iscan_callback.h" +#include "scan_callback.h" +#include "scan_constant.h" +#include "scan_option_descriptor.h" +#include "scan_option_descriptor_helper.h" +#include "scan_option_value.h" +#include "scan_option_value_helper.h" +#include "scan_parameters.h" +#include "scan_parameters_helper.h" +#include "scanner_info.h" +#include "scanner_info_helper.h" +#include "scan_progress.h" +#include "scan_progress_helper.h" + + +namespace OHOS::Scan { + +class NapiInnerScan { +public: + static napi_value InitScan(napi_env env, napi_callback_info info); + static napi_value ExitScan(napi_env env, napi_callback_info info); + static napi_value GetScannerList(napi_env env, napi_callback_info info); + static napi_value StopDiscover(napi_env env, napi_callback_info info); + static napi_value OpenScanner(napi_env env, napi_callback_info info); + static napi_value CloseScanner(napi_env env, napi_callback_info info); + static napi_value GetScanOptionDesc(napi_env env, napi_callback_info info); + static napi_value SetScanOption(napi_env env, napi_callback_info info); + static napi_value SetScanAutoOption(napi_env env, napi_callback_info info); + static napi_value GetScanOption(napi_env env, napi_callback_info info); + static napi_value GetScanParameters(napi_env env, napi_callback_info info); + static napi_value StartScan(napi_env env, napi_callback_info info); + static napi_value GetSingleFrameFD(napi_env env, napi_callback_info info); + static napi_value CancelScan(napi_env env, napi_callback_info info); + static napi_value SetScanIOMode(napi_env env, napi_callback_info info); + static napi_value GetScanSelectFd(napi_env env, napi_callback_info info); + static napi_value GetScannerState(napi_env env, napi_callback_info info); + static napi_value GetScanProgress(napi_env env, napi_callback_info info); + static napi_value AddScanner(napi_env env, napi_callback_info info); + static napi_value DeleteScanner(napi_env env, napi_callback_info info); + static napi_value GetAddedScanner(napi_env env, napi_callback_info info); + static napi_value UpdateScannerName(napi_env env, napi_callback_info info); + static napi_value AddPrinter(napi_env env, napi_callback_info info); + + static napi_value On(napi_env env, napi_callback_info info); + static napi_value Off(napi_env env, napi_callback_info info); + +private: + static bool IsSupportType(const std::string& type); + +private: + struct NapiScanContext : public ScanAsyncCall::Context { + bool result = false; + std::string exeCMD = ""; + std::string exePath = ""; + + int32_t scanVersion = 0; + int32_t fd = 0; + int32_t optionIndex = 0; + std::string scannerId = ""; + std::string serialNumber = ""; + std::string discoverMode = ""; + std::string deviceName = ""; + std::vector allAddedScanner; + + bool isNonBlocking = false; + ScanOptionDescriptor desc; + ScanOptionValue optionValue; + int32_t info = 0; + ScanParameters para; + ScanProgress prog; + int32_t scannerState = 0; + + uint32_t frameSize = 0; + uint32_t image_fd = 0; + uint8_t *data = nullptr; + bool batchMode = 0; + + NapiScanContext() : Context(nullptr, nullptr) {}; + NapiScanContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)) {}; + virtual ~NapiScanContext() {}; + }; +}; +} // namespace OHOS::Scan +#endif // NAPI_INNER_SCAN_H diff --git a/interfaces/kits/napi/scan_napi/include/scan_async_call.h b/interfaces/kits/napi/scan_napi/include/scan_async_call.h new file mode 100644 index 0000000..05a6e6f --- /dev/null +++ b/interfaces/kits/napi/scan_napi/include/scan_async_call.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef SCAN_ASYNC_CALL_H +#define SCAN_ASYNC_CALL_H + +#include +#include +#include + +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" +#include "scan_constant.h" +#define TDD_ENABLE 1 + +namespace OHOS::Scan { + +class ScanAsyncCall final { +public: + class Context { + public: + using InputAction = std::function; + using OutputAction = std::function; + using ExecAction = std::function; + Context(InputAction input, OutputAction output) : input_(std::move(input)), output_(std::move(output)) {}; + + virtual ~Context() {}; + void SetAction(InputAction input, OutputAction output = nullptr) + { + input_ = input; + output_ = output; + } + + void SetAction(OutputAction output) + { + SetAction(nullptr, std::move(output)); + } + + virtual napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) + { + if (input_ == nullptr) { + return napi_ok; + } + return input_(env, argc, argv, self); + } + + virtual napi_status operator()(napi_env env, napi_value *result) + { + if (output_ == nullptr) { + *result = nullptr; + return napi_ok; + } + return output_(env, result); + } + + virtual void Exec() + { + if (exec_ == nullptr) { + return; + } + exec_(this); + }; + + void SetErrorIndex(uint32_t errorIndex) + { + errorIndex_ = errorIndex; + } + + uint32_t GetErrorIndex() + { + return errorIndex_; + } + #ifndef TDD_ENABLE + protected: + #endif + friend class ScanAsyncCall; + InputAction input_ = nullptr; + OutputAction output_ = nullptr; + ExecAction exec_ = nullptr; + uint32_t errorIndex_ = E_SCAN_NONE; + }; + + // The default AsyncCallback in the parameters is at the end position. + static constexpr size_t ASYNC_DEFAULT_POS = -1; + ScanAsyncCall(napi_env env, napi_callback_info info, std::shared_ptr context, + size_t pos = ASYNC_DEFAULT_POS); + ~ScanAsyncCall(); + napi_value Call(napi_env env, Context::ExecAction exec = nullptr); + napi_value SyncCall(napi_env env, Context::ExecAction exec = nullptr); + +#ifndef TDD_ENABLE +private: +#endif + enum { ARG_ERROR, ARG_DATA, ARG_BUTT }; + static void OnExecute(napi_env env, void *data); + static void OnComplete(napi_env env, napi_status status, void *data); + static std::string GetErrorText(uint32_t code); + struct AsyncContext { + std::shared_ptr ctx = nullptr; + napi_ref callback = nullptr; + napi_ref self = nullptr; + napi_deferred defer = nullptr; + napi_async_work work = nullptr; + napi_status paramStatus = napi_ok; + }; + static void DeleteContext(napi_env env, AsyncContext *context); + static std::map scanErrorCodeMap; + + AsyncContext *context_ = nullptr; + napi_env env_ = nullptr; +}; +} // namespace OHOS::Scan +#endif // REQUEST_ASYNC_CALL_H diff --git a/interfaces/kits/napi/scan_napi/src/napi_inner_scan.cpp b/interfaces/kits/napi/scan_napi/src/napi_inner_scan.cpp new file mode 100644 index 0000000..50efd69 --- /dev/null +++ b/interfaces/kits/napi/scan_napi/src/napi_inner_scan.cpp @@ -0,0 +1,892 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "securec.h" +#include "napi_scan_utils.h" +#include "scan_log.h" +#include "scan_callback.h" +#include "scan_manager_client.h" +#include "napi_inner_scan.h" + + +namespace OHOS::Scan { +const std::string GET_FRAME_RES_EVENT_TYPE = "getFrameResult"; +const std::string SCAN_DEVICE_FOUND_TCP = "scanDeviceFoundTCP"; +const std::string SCAN_DEVICE_FOUND = "scanDeviceFound"; +const std::string SCAN_DEVICE_SYNC = "scanDeviceSync"; +const std::string SCAN_DEVICE_ADD = "scanDeviceAdd"; +const std::string SCAN_DEVICE_DEL = "scanDeviceDel"; +const std::string SCAN_INIT_EVENT = "scanInitEvent"; + +napi_value NapiInnerScan::InitScan(napi_env env, napi_callback_info info) +{ + SCAN_HILOGE("Enter InitScan---->"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_ZERO, " should 0 parameter!", napi_invalid_arg); + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_create_int32(env, context->scanVersion, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->InitScan(context->scanVersion); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to init the scan fwk"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::ExitScan(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("Enter ExitScan---->"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_ZERO, " should 0 parameter!", napi_invalid_arg); + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_get_boolean(env, context->result, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->ExitScan(); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to exit"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::GetScannerList(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("Enter GetScannerList---->"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_ZERO, " should 0 parameter!", napi_invalid_arg); + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_get_boolean(env, context->result, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + auto ScanManagerClientPtr = ScanManagerClient::GetInstance(); + if (ScanManagerClientPtr == nullptr) { + SCAN_HILOGE("ScanManagerClientPtr is a nullptr"); + context->result = false; + context->SetErrorIndex(E_SCAN_GENERIC_FAILURE); + return; + } + int32_t ret = ScanManagerClientPtr->GetScannerList(); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to exit"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::StopDiscover(napi_env env, napi_callback_info info) +{ + SCAN_HILOGE("Enter StopDiscover---->"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_ZERO, " should 0 parameter!", napi_invalid_arg); + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_create_int32(env, context->scanVersion, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->StopDiscover(); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to StopDiscover"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::OpenScanner(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("start to OpenScanner"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg); + napi_valuetype valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scannerId is not a string", napi_string_expected); + std::string scannerId = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + SCAN_HILOGD("scannerId : %{public}s", scannerId.c_str()); + context->scannerId = scannerId; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_get_boolean(env, context->result, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->OpenScanner(context->scannerId); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to open the scanner"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::CloseScanner(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("start to CloseScanner"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg); + napi_valuetype valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scannerId is not a string", napi_string_expected); + std::string scannerId = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + SCAN_HILOGD("scannerId : %{public}s", scannerId.c_str()); + context->scannerId = scannerId; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_get_boolean(env, context->result, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->CloseScanner(context->scannerId); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to close the scanner"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::GetScanOptionDesc(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("start to GetScanOptionDesc"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_TWO, " should 2 parameter!", napi_invalid_arg); + napi_valuetype valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scannerId is not a string", napi_string_expected); + std::string scannerId = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + + valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ONE], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_number, "optionIndex is not a number", napi_number_expected); + int32_t optionIndex = NapiScanUtils::GetInt32FromValue(env, argv[NapiScanUtils::INDEX_ONE]); + context->scannerId = scannerId; + context->optionIndex = optionIndex; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + *result = ScanOptionDescriptorHelper::MakeJsObject(env, context->desc); + return napi_ok; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->GetScanOptionDesc(context->scannerId, context->optionIndex,\ + context->desc); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to get the scan option description"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::SetScanOption(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("Enter SetScanOption---->"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_THREE, " should 3 parameter!", napi_invalid_arg); + + napi_valuetype valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scannerId is not a string", napi_string_expected); + std::string scannerId = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + context->scannerId = scannerId; + + valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ONE], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_number, "optionIndex is not a number", napi_number_expected); + int32_t optionIndex = NapiScanUtils::GetInt32FromValue(env, argv[NapiScanUtils::INDEX_ONE]); + context->optionIndex = optionIndex; + + auto optionValue = ScanOptionValueHelper::BuildFromJs(env, argv[NapiScanUtils::INDEX_TWO]); + if (optionValue == nullptr) { + SCAN_HILOGE("Parse scan option value error!"); + context->SetErrorIndex(E_SCAN_INVALID_PARAMETER); + return napi_invalid_arg; + } + context->optionValue = *optionValue; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_create_int32(env, context->info, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->OpScanOptionValue(context->scannerId, context->optionIndex, + SCAN_ACTION_SET_VALUE, context->optionValue, context->info); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to set the scan option"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::SetScanAutoOption(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("Enter SetScanAutoOption---->"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_TWO, " should 2 parameter!", napi_invalid_arg); + + napi_valuetype valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scannerId is not a string", napi_string_expected); + std::string scannerId = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + context->scannerId = scannerId; + + valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ONE], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_number, "optionIndex is not a number", napi_number_expected); + int32_t optionIndex = NapiScanUtils::GetInt32FromValue(env, argv[NapiScanUtils::INDEX_ONE]); + context->optionIndex = optionIndex; + + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_create_int32(env, context->result, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->OpScanOptionValue(context->scannerId, + context->optionIndex, SCAN_ACTION_SET_AUTO, context->optionValue, context->info); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to set the auto scan option"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::GetScanOption(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("Enter GetScanOption---->"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_FOUR, " should 4 parameter!", napi_invalid_arg); + + napi_valuetype valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scannerId is not a string", napi_string_expected); + std::string scannerId = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + context->scannerId = scannerId; + + valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ONE], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_number, "optionIndex is not a number", napi_number_expected); + int32_t optionIndex = NapiScanUtils::GetInt32FromValue(env, argv[NapiScanUtils::INDEX_ONE]); + context->optionIndex = optionIndex; + + valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_TWO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_number, "valueType is not a number", napi_number_expected); + uint32_t valueType = NapiScanUtils::GetUint32FromValue(env, argv[NapiScanUtils::INDEX_TWO]); + context->optionValue.SetScanOptionValueType((ScanOptionValueType)valueType); + + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_THREE], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_number, "valueSize is not a number", napi_number_expected); + int32_t valueSize = NapiScanUtils::GetInt32FromValue(env, argv[NapiScanUtils::INDEX_THREE]); + context->optionValue.SetValueSize(valueSize); + + context->optionValue.Dump(); + SCAN_HILOGE("success to get the scan option"); + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + *result = ScanOptionValueHelper::MakeJsObject(env, context->optionValue); + return napi_ok; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->OpScanOptionValue(context->scannerId, + context->optionIndex, SCAN_ACTION_GET_VALUE, context->optionValue, context->info); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to get the scan option"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::GetScanParameters(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("start to GetScanParameters"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg); + napi_valuetype valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scannerId is not a string", napi_string_expected); + std::string scannerId = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + context->scannerId = scannerId; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + *result = ScanParametersHelper::MakeJsObject(env, context->para); + return napi_ok; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->GetScanParameters(context->scannerId, context->para); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to get the scan parameters description"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::StartScan(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("start to StartScan"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_TWO, " should 2 parameter!", napi_invalid_arg); + napi_valuetype valueType = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valueType), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valueType == napi_string, "scannerId is not a string", napi_string_expected); + std::string scannerId = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + SCAN_HILOGD("scannerId : %{public}s", scannerId.c_str()); + context->scannerId = scannerId; + valueType = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ONE], &valueType), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valueType == napi_boolean, "batchMode is not a boolean", napi_boolean_expected); + bool batchMode = NapiScanUtils::GetBooleanFromValue(env, argv[NapiScanUtils::INDEX_ONE]); + context->batchMode = batchMode; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_get_boolean(env, context->result, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->StartScan(context->scannerId, context->batchMode); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to start the scan job"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::GetSingleFrameFD(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("start to GetSingleFrameFD"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_TWO, " should 2 parameter!", napi_invalid_arg); + napi_valuetype valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scannerId is not a string", napi_string_expected); + std::string scannerId = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ONE], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_number, "fd is not a number", napi_number_expected); + uint32_t fd = NapiScanUtils::GetUint32FromValue(env, argv[NapiScanUtils::INDEX_ONE]); + SCAN_HILOGE("scannerId : %{public}s, fd: %{public}u", scannerId.c_str(), fd); + context->scannerId = scannerId; + context->image_fd = fd; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_create_int32(env, context->frameSize, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->GetSingleFrameFD( + context->scannerId, context->frameSize, context->image_fd); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to get a single frame"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::CancelScan(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("start to CancelScan"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg); + napi_valuetype valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scannerId is not a string", napi_string_expected); + std::string scannerId = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + SCAN_HILOGD("scannerId : %{public}s", scannerId.c_str()); + context->scannerId = scannerId; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_get_boolean(env, context->result, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->CancelScan(context->scannerId); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to cancel the scan job"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::SetScanIOMode(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("start to SetScanIOMode"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_TWO, " should 2 parameter!", napi_invalid_arg); + napi_valuetype valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scannerId is not a string", napi_string_expected); + + valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ONE], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_boolean, "isNonBlocking is not a boolean", napi_boolean_expected); + std::string scannerId = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + bool isNonBlocking = NapiScanUtils::GetBooleanFromValue(env, argv[NapiScanUtils::INDEX_ONE]); + SCAN_HILOGD("scannerId : %{public}s, isNonBlocking : %{public}d", scannerId.c_str(), isNonBlocking); + context->scannerId = scannerId; + context->isNonBlocking = isNonBlocking; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_get_boolean(env, context->result, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->SetScanIOMode(context->scannerId, context->isNonBlocking); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to set the scan IO mode"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::GetScanSelectFd(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("start to GetScanSelectFd"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg); + napi_valuetype valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scannerId is not a string", napi_string_expected); + std::string scannerId = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + SCAN_HILOGD("scannerId : %{public}s", scannerId.c_str()); + context->scannerId = scannerId; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_create_int32(env, context->fd, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->GetScanSelectFd(context->scannerId, context->fd); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to get the scan select fd"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::On(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("Enter on---->"); + size_t argc = NapiScanUtils::MAX_ARGC; + napi_value argv[NapiScanUtils::MAX_ARGC] = { nullptr }; + napi_value thisVal = nullptr; + void *data = nullptr; + SCAN_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, &data)); + SCAN_ASSERT(env, argc == NapiScanUtils::ARGC_TWO, "need 2 parameter!"); + + napi_valuetype valuetype = napi_undefined; + SCAN_CALL(env, napi_typeof(env, argv[0], &valuetype)); + SCAN_ASSERT(env, valuetype == napi_string, "type is not a string"); + std::string type = NapiScanUtils::GetStringFromValueUtf8(env, argv[0]); + SCAN_HILOGD("type : %{public}s", type.c_str()); + + if (!NapiInnerScan::IsSupportType(type)) { + SCAN_HILOGE("Event On type : %{public}s not support", type.c_str()); + return nullptr; + } + + valuetype = napi_undefined; + napi_typeof(env, argv[1], &valuetype); + SCAN_ASSERT(env, valuetype == napi_function, "callback is not a function"); + + napi_ref callbackRef = NapiScanUtils::CreateReference(env, argv[1]); + sptr callback = new (std::nothrow) ScanCallback(env, callbackRef); + if (callback == nullptr) { + SCAN_HILOGE("create scan callback object fail"); + return nullptr; + } + int32_t ret = ScanManagerClient::GetInstance()->On("", type, callback); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to register event"); + return nullptr; + } + return nullptr; +} + +napi_value NapiInnerScan::Off(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("Enter OFF---->"); + return nullptr; +} + +napi_value NapiInnerScan::GetScannerState(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("Enter GetScannerState---->"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_ZERO, " should 0 parameter!", napi_invalid_arg); + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_create_int32(env, context->scannerState, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->GetScannerState(context->scannerState); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to init the scan fwk"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::GetScanProgress(napi_env env, napi_callback_info info) +{ + SCAN_HILOGI("start to GetScanProgress"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg); + napi_valuetype valuetype = napi_undefined; + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scannerId is not a string", napi_string_expected); + std::string scannerId = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + context->scannerId = scannerId; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + *result = ScanProgressHelper::MakeJsObject(env, context->prog); + return napi_ok; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->GetScanProgress(context->scannerId, context->prog); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to get the scan progress"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::AddScanner(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("start to AddScanner"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_TWO, " should 2 parameter!", napi_invalid_arg); + napi_valuetype valuetype = napi_undefined; + + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scanner serialNumber is not a string", napi_string_expected); + std::string serialNumber = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + SCAN_HILOGD("serialNumber : %{public}s", serialNumber.c_str()); + context->serialNumber = serialNumber; + + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ONE], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "discoverMode is not a string", napi_string_expected); + std::string discoverMode = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ONE]); + SCAN_HILOGD("discoverMode : %{public}s", discoverMode.c_str()); + context->discoverMode = discoverMode; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_get_boolean(env, context->result, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->AddScanner(context->serialNumber, context->discoverMode); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to add the scanner"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::DeleteScanner(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("start to DeleteScanner"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_TWO, " should 2 parameter!", napi_invalid_arg); + napi_valuetype valuetype = napi_undefined; + + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scanner serialNumber is not a string", napi_string_expected); + std::string serialNumber = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + SCAN_HILOGD("serialNumber : %{public}s", serialNumber.c_str()); + context->serialNumber = serialNumber; + + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ONE], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "discoverMode is not a string", napi_string_expected); + std::string discoverMode = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ONE]); + SCAN_HILOGD("discoverMode : %{public}s", discoverMode.c_str()); + context->discoverMode = discoverMode; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_get_boolean(env, context->result, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->DeleteScanner(context->serialNumber, context->discoverMode); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to delete the scanner"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::GetAddedScanner(napi_env env, napi_callback_info info) +{ + SCAN_HILOGE("Enter GetAddedScanner---->"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_ZERO, " should 0 parameter!", napi_invalid_arg); + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_create_array(env, result); + uint32_t index = 0; + for (auto scanDeviceInfo : context->allAddedScanner) { + status = napi_set_element(env, *result, index++, ScannerInfoHelper::MakeJsObject(env, scanDeviceInfo)); + } + return napi_ok; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->GetAddedScanner(context->allAddedScanner); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to get added scanner"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::UpdateScannerName(napi_env env, napi_callback_info info) +{ + SCAN_HILOGD("start to UpdateScannerName"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_THREE, " should 3 parameter!", napi_invalid_arg); + napi_valuetype valuetype = napi_undefined; + + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scanner serialNumber is not a string", napi_string_expected); + std::string serialNumber = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + SCAN_HILOGD("serialNumber : %{public}s", serialNumber.c_str()); + context->serialNumber = serialNumber; + + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ONE], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "discoverMode is not a string", napi_string_expected); + std::string discoverMode = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ONE]); + SCAN_HILOGD("discoverMode : %{public}s", discoverMode.c_str()); + context->discoverMode = discoverMode; + + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_TWO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "deviceName is not a string", napi_string_expected); + std::string deviceName = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_TWO]); + SCAN_HILOGD("deviceName : %{public}s", deviceName.c_str()); + context->deviceName = deviceName; + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_get_boolean(env, context->result, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->UpdateScannerName(context->serialNumber, + context->discoverMode, context->deviceName); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to update scanner name"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +napi_value NapiInnerScan::AddPrinter(napi_env env, napi_callback_info info) +{ + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + SCAN_ASSERT_BASE(env, argc == NapiScanUtils::ARGC_TWO, " should 2 parameter!", napi_invalid_arg); + napi_valuetype valuetype = napi_undefined; + + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ZERO], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "scanner serialNumber is not a string", napi_string_expected); + std::string serialNumber = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ZERO]); + SCAN_HILOGD("serialNumber : %{public}s", serialNumber.c_str()); + context->serialNumber = serialNumber; + + SCAN_CALL_BASE(env, napi_typeof(env, argv[NapiScanUtils::INDEX_ONE], &valuetype), napi_invalid_arg); + SCAN_ASSERT_BASE(env, valuetype == napi_string, "discoverMode is not a string", napi_string_expected); + std::string discoverMode = NapiScanUtils::GetStringFromValueUtf8(env, argv[NapiScanUtils::INDEX_ONE]); + SCAN_HILOGD("discoverMode : %{public}s", discoverMode.c_str()); + context->discoverMode = discoverMode; + + return napi_ok; + }; + auto output = [context](napi_env env, napi_value *result) -> napi_status { + napi_status status = napi_get_boolean(env, context->result, result); + SCAN_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status); + return status; + }; + auto exec = [context](ScanAsyncCall::Context *ctx) { + int32_t ret = ScanManagerClient::GetInstance()->AddPrinter(context->serialNumber, context->discoverMode); + context->result = ret == E_SCAN_NONE; + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("Failed to add Printer"); + context->SetErrorIndex(ret); + } + }; + context->SetAction(std::move(input), std::move(output)); + ScanAsyncCall asyncCall(env, info, std::dynamic_pointer_cast(context)); + return asyncCall.Call(env, exec); +} + +bool NapiInnerScan::IsSupportType(const std::string& type) +{ + if (type == GET_FRAME_RES_EVENT_TYPE || type == SCAN_DEVICE_FOUND_TCP|| type == SCAN_DEVICE_FOUND + || type == SCAN_DEVICE_SYNC || type == SCAN_DEVICE_ADD || type == SCAN_DEVICE_DEL || type == SCAN_INIT_EVENT) { + return true; + } + return false; +} +} // namespace OHOS::Scan diff --git a/interfaces/kits/napi/scan_napi/src/scan_async_call.cpp b/interfaces/kits/napi/scan_napi/src/scan_async_call.cpp new file mode 100644 index 0000000..b843024 --- /dev/null +++ b/interfaces/kits/napi/scan_napi/src/scan_async_call.cpp @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_async_call.h" + +#include "napi_scan_utils.h" +#include "scan_log.h" + +namespace OHOS::Scan { + +std::map ScanAsyncCall::scanErrorCodeMap = {{E_SCAN_NO_PERMISSION, "E_SCAN_NO_PERMISSION"}, + {E_SCAN_INVALID_PARAMETER, "E_SCAN_INVALID_PARAMETER"}, + {E_SCAN_GENERIC_FAILURE, "E_SCAN_GENERIC_FAILURE"}, + {E_SCAN_RPC_FAILURE, "E_SCAN_RPC_FAILURE"}, + {E_SCAN_SERVER_FAILURE, "E_SCAN_SERVER_FAILURE"}, + {E_SCAN_GOOD, "E_SCAN_GOOD"}, + {E_SCAN_UNSUPPORTED, "E_SCAN_UNSUPPORTED"}, + {E_SCAN_CANCELLED, "E_SCAN_CANCELLED"}, + {E_SCAN_DEVICE_BUSY, "E_SCAN_DEVICE_BUSY"}, + {E_SCAN_INVAL, "E_SCAN_INVAL"}, + {E_SCAN_EOF, "E_SCAN_EOF"}, + {E_SCAN_JAMMED, "E_SCAN_JAMMED"}, + {E_SCAN_NO_DOCS, "E_SCAN_NO_DOCS"}, + {E_SCAN_COVER_OPEN, "E_SCAN_COVER_OPEN"}, + {E_SCAN_IO_ERROR, "E_SCAN_IO_ERROR"}, + {E_SCAN_NO_MEM, "E_SCAN_NO_MEM"}, + {E_SCAN_ACCESS_DENIED, "E_SCAN_ACCESS_DENIED"}}; + +ScanAsyncCall::ScanAsyncCall(napi_env env, napi_callback_info info, + std::shared_ptr context, size_t pos) : env_(env) +{ + context_ = new AsyncContext(); + size_t argc = NapiScanUtils::MAX_ARGC; + napi_value self = nullptr; + napi_value argv[NapiScanUtils::MAX_ARGC] = { nullptr }; + SCAN_CALL_RETURN_VOID(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr)); + if (argc > 0) { + pos = ((pos == ASYNC_DEFAULT_POS) ? (argc - 1) : pos); + } + if (pos >= 0 && pos < argc) { + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[pos], &valueType); + if (valueType == napi_function) { + napi_create_reference(env, argv[pos], 1, &context_->callback); + argc = pos; + } + } + context_->paramStatus = (*context)(env, argc, argv, self); + context_->ctx = std::move(context); + napi_create_reference(env, self, 1, &context_->self); +} + +ScanAsyncCall::~ScanAsyncCall() +{ + if (context_ == nullptr) { + return; + } + + DeleteContext(env_, context_); +} + +napi_value ScanAsyncCall::Call(napi_env env, Context::ExecAction exec) +{ + SCAN_HILOGD("async call exec"); + if (context_ != nullptr && context_->ctx != nullptr) { + context_->ctx->exec_ = std::move(exec); + } else { + SCAN_HILOGE("context_ is null or context->ctx is null"); + return nullptr; + } + napi_value promise = nullptr; + if (context_->callback == nullptr) { + napi_create_promise(env, &context_->defer, &promise); + } else { + napi_get_undefined(env, &promise); + } + napi_async_work work = context_->work; + napi_value resource = nullptr; + napi_create_string_utf8(env, "ScanAsyncCall", NAPI_AUTO_LENGTH, &resource); + napi_create_async_work(env, nullptr, resource, ScanAsyncCall::OnExecute, + ScanAsyncCall::OnComplete, context_, &work); + context_->work = work; + context_ = nullptr; + napi_queue_async_work(env, work); + SCAN_HILOGD("async call exec"); + return promise; +} + +napi_value ScanAsyncCall::SyncCall(napi_env env, ScanAsyncCall::Context::ExecAction exec) +{ + if (context_ != nullptr && context_->ctx != nullptr) { + context_->ctx->exec_ = std::move(exec); + } else { + SCAN_HILOGE("context_ is null or context->ctx is null"); + return nullptr; + } + napi_value promise = nullptr; + if (context_->callback == nullptr) { + napi_create_promise(env, &context_->defer, &promise); + } else { + napi_get_undefined(env, &promise); + } + ScanAsyncCall::OnExecute(env, context_); + ScanAsyncCall::OnComplete(env, napi_ok, context_); + return promise; +} + +void ScanAsyncCall::OnExecute(napi_env env, void *data) +{ + AsyncContext *context = reinterpret_cast(data); + if (context->ctx == nullptr) { + SCAN_HILOGE("context->ctx is null"); + return; + } + + SCAN_HILOGD("run the async runnable"); + if (context->ctx->GetErrorIndex() == E_SCAN_NONE) { + context->ctx->Exec(); + } +} + +void ScanAsyncCall::OnComplete(napi_env env, napi_status status, void *data) +{ + AsyncContext *context = reinterpret_cast(data); + if (context->ctx == nullptr || context->ctx->GetErrorIndex() != E_SCAN_NONE) { + status = napi_generic_failure; + } + napi_value output = nullptr; + napi_status runStatus = napi_generic_failure; + if (context->ctx != nullptr) { + runStatus = (*context->ctx)(env, &output); + } + SCAN_HILOGD("runStatus: [%{public}d], status: [%{public}d]", runStatus, status); + napi_value result[ARG_BUTT] = { 0 }; + if (status == napi_ok && runStatus == napi_ok) { + napi_get_undefined(env, &result[ARG_ERROR]); + if (output != nullptr) { + result[ARG_DATA] = output; + SCAN_HILOGD("async call napi_ok."); + } else { + napi_get_undefined(env, &result[ARG_DATA]); + } + } else { + napi_value message = nullptr; + uint32_t errorIndex = E_SCAN_NONE; + if (context->paramStatus != napi_ok) { + errorIndex = E_SCAN_INVALID_PARAMETER; + } else { + errorIndex = context->ctx->GetErrorIndex(); + } + SCAN_HILOGE("ErrorMessage: [%{public}s], ErrorIndex:[%{public}d]", + GetErrorText(errorIndex).c_str(), errorIndex); + napi_create_uint32(env, errorIndex, &message); + result[ARG_ERROR] = message; + napi_get_undefined(env, &result[ARG_DATA]); + } + if (context->defer != nullptr) { + if (status == napi_ok && runStatus == napi_ok) { + napi_resolve_deferred(env, context->defer, result[ARG_DATA]); + } else { + napi_reject_deferred(env, context->defer, result[ARG_ERROR]); + } + } else { + napi_value callback = nullptr; + napi_get_reference_value(env, context->callback, &callback); + napi_value returnValue; + napi_call_function(env, nullptr, callback, ARG_BUTT, result, &returnValue); + } + DeleteContext(env, context); +} + +void ScanAsyncCall::DeleteContext(napi_env env, AsyncContext *context) +{ + if (env != nullptr) { + napi_delete_reference(env, context->callback); + napi_delete_reference(env, context->self); + napi_delete_async_work(env, context->work); + } + delete context; +} + +std::string ScanAsyncCall::GetErrorText(uint32_t code) +{ + SCAN_HILOGD("GetErrorText from map start"); + auto it = scanErrorCodeMap.find(code); + if (it != scanErrorCodeMap.end()) { + return it->second; + } else { + SCAN_HILOGD("ErrorText not found"); + return "E_SCAN_NONE"; + } +} +} // namespace OHOS::Scan diff --git a/interfaces/kits/napi/scan_napi/src/scan_module.cpp b/interfaces/kits/napi/scan_napi/src/scan_module.cpp new file mode 100644 index 0000000..9046ef8 --- /dev/null +++ b/interfaces/kits/napi/scan_napi/src/scan_module.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi_inner_scan.h" +#include "scan_log.h" + +using namespace OHOS::Scan; + +static constexpr const char *FUNCTION_INIT_SCAN = "initScan"; +static constexpr const char *FUNCTION_EXIT_SCAN = "exitScan"; +static constexpr const char *FUNCTION_GET_SCANNER_LIST = "getScannerList"; +static constexpr const char *FUNCTION_STOP_DISCOVER = "stopDiscover"; +static constexpr const char *FUNCTION_OPEN_SCANNER = "openScanner"; +static constexpr const char *FUNCTION_CLOSE_SCANNER = "closeScanner"; +static constexpr const char *FUNCTION_GET_SCAN_OPTION_DESC = "getScanOptionDesc"; +static constexpr const char *FUNCTION_SET_SCAN_OPTION = "setScanOption"; +static constexpr const char *FUNCTION_SET_SCAN_AUTO_OPTION = "setScanAutoOption"; +static constexpr const char *FUNCTION_GET_SCAN_OPTION = "getScanOption"; +static constexpr const char *FUNCTION_GET_SCAN_PARAMETERS = "getScanParameters"; +static constexpr const char *FUNCTION_START_SCAN = "startScan"; +static constexpr const char *FUNCTION_GET_SINGLE_FRAME_FD = "getSingleFrameFD"; +static constexpr const char *FUNCTION_CANCEL_SCAN = "cancelScan"; +static constexpr const char *FUNCTION_SET_SCAN_IO_MODE = "setScanIOMode"; +static constexpr const char *FUNCTION_GET_SCAN_SELECT_FD = "getScanSelectFd"; +static constexpr const char *FUNCTION_GET_SCANNER_STATE = "getScannerState"; +static constexpr const char *FUNCTION_GET_SCAN_PROGRESS = "getScanProgress"; +static constexpr const char *FUNCTION_ADD_SCANNER = "addScanner"; +static constexpr const char *FUNCTION_DELETE_SCANNER = "deleteScanner"; +static constexpr const char *FUNCTION_GET_ADDED_SCANNER = "getAddedScanner"; +static constexpr const char *FUNCTION_UPDATE_SCANNER_NAME = "updateScannerName"; +static constexpr const char *FUNCTION_ADD_PRINTER = "addPrinter"; + +static constexpr const char *FUNCTION_REGISTER_EVENT = "on"; +static constexpr const char *FUNCTION_UNREGISTER_EVENT = "off"; + + +#define SCAN_NAPI_METHOD(name, func) \ + { \ + name, 0, func, 0, 0, 0, napi_default, 0 \ + } + +#define SCAN_NAPI_PROPERTY(name, val) \ + { \ + (name), nullptr, nullptr, nullptr, nullptr, val, napi_static, nullptr \ + } + + +static napi_value Init(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + SCAN_NAPI_METHOD(FUNCTION_INIT_SCAN, NapiInnerScan::InitScan), + SCAN_NAPI_METHOD(FUNCTION_EXIT_SCAN, NapiInnerScan::ExitScan), + SCAN_NAPI_METHOD(FUNCTION_GET_SCANNER_LIST, NapiInnerScan::GetScannerList), + SCAN_NAPI_METHOD(FUNCTION_STOP_DISCOVER, NapiInnerScan::StopDiscover), + SCAN_NAPI_METHOD(FUNCTION_OPEN_SCANNER, NapiInnerScan::OpenScanner), + SCAN_NAPI_METHOD(FUNCTION_CLOSE_SCANNER, NapiInnerScan::CloseScanner), + SCAN_NAPI_METHOD(FUNCTION_GET_SCAN_OPTION_DESC, NapiInnerScan::GetScanOptionDesc), + SCAN_NAPI_METHOD(FUNCTION_SET_SCAN_OPTION, NapiInnerScan::SetScanOption), + SCAN_NAPI_METHOD(FUNCTION_SET_SCAN_AUTO_OPTION, NapiInnerScan::SetScanAutoOption), + SCAN_NAPI_METHOD(FUNCTION_GET_SCAN_OPTION, NapiInnerScan::GetScanOption), + SCAN_NAPI_METHOD(FUNCTION_GET_SCAN_PARAMETERS, NapiInnerScan::GetScanParameters), + SCAN_NAPI_METHOD(FUNCTION_START_SCAN, NapiInnerScan::StartScan), + SCAN_NAPI_METHOD(FUNCTION_GET_SINGLE_FRAME_FD, NapiInnerScan::GetSingleFrameFD), + SCAN_NAPI_METHOD(FUNCTION_CANCEL_SCAN, NapiInnerScan::CancelScan), + SCAN_NAPI_METHOD(FUNCTION_SET_SCAN_IO_MODE, NapiInnerScan::SetScanIOMode), + SCAN_NAPI_METHOD(FUNCTION_GET_SCAN_SELECT_FD, NapiInnerScan::GetScanSelectFd), + SCAN_NAPI_METHOD(FUNCTION_GET_SCANNER_STATE, NapiInnerScan::GetScannerState), + SCAN_NAPI_METHOD(FUNCTION_GET_SCAN_PROGRESS, NapiInnerScan::GetScanProgress), + SCAN_NAPI_METHOD(FUNCTION_ADD_SCANNER, NapiInnerScan::AddScanner), + SCAN_NAPI_METHOD(FUNCTION_DELETE_SCANNER, NapiInnerScan::DeleteScanner), + SCAN_NAPI_METHOD(FUNCTION_GET_ADDED_SCANNER, NapiInnerScan::GetAddedScanner), + SCAN_NAPI_METHOD(FUNCTION_UPDATE_SCANNER_NAME, NapiInnerScan::UpdateScannerName), + SCAN_NAPI_METHOD(FUNCTION_ADD_PRINTER, NapiInnerScan::AddPrinter), + + SCAN_NAPI_METHOD(FUNCTION_REGISTER_EVENT, NapiInnerScan::On), + SCAN_NAPI_METHOD(FUNCTION_UNREGISTER_EVENT, NapiInnerScan::Off), + }; + + napi_status status = napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc); + SCAN_HILOGD("init scan module %{public}d", status); + return exports; +} + +static __attribute__((constructor)) void RegisterModule() +{ + static napi_module module = { .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "scan", + .nm_priv = ((void *)0), + .reserved = { 0 } }; + napi_module_register(&module); + SCAN_HILOGD("module register scan"); +} diff --git a/interfaces/kits/ndk/ohscan/BUILD.gn b/interfaces/kits/ndk/ohscan/BUILD.gn new file mode 100644 index 0000000..d45436b --- /dev/null +++ b/interfaces/kits/ndk/ohscan/BUILD.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") + +ohos_ndk_headers("ohscan_header") { + dest_dir = "$ndk_headers_out_dir/ohscan" + sources = [ "${print_path}/frameworks/ohscan/include/ohscan.h" ] +} + +ohos_ndk_library("libohscan_ndk") { + output_name = "ohscan" + output_extension = "so" + ndk_description_file = "./libohscan.ndk.json" + system_capability = "SystemCapability.Print.PrintFramework" + system_capability_headers = [ "ohscan/ohscan.h" ] +} diff --git a/interfaces/kits/ndk/ohscan/libohscan.ndk.json b/interfaces/kits/ndk/ohscan/libohscan.ndk.json new file mode 100644 index 0000000..fc6c236 --- /dev/null +++ b/interfaces/kits/ndk/ohscan/libohscan.ndk.json @@ -0,0 +1,42 @@ +[ + { + "first_introduced": "12", + "name": "OH_Scan_Init" + }, + { + "first_introduced": "12", + "name": "OH_Scan_StartScannerDiscovery" + }, + { + "first_introduced": "12", + "name": "OH_Scan_OpenScanner" + }, + { + "first_introduced": "12", + "name": "OH_Scan_CloseScanner" + }, + { + "first_introduced": "12", + "name": "OH_Scan_GetScannerParameter" + }, + { + "first_introduced": "12", + "name": "OH_Scan_SetScannerParameter" + }, + { + "first_introduced": "12", + "name": "OH_Scan_StartScan" + }, + { + "first_introduced": "12", + "name": "OH_Scan_CancelScan" + }, + { + "first_introduced": "12", + "name": "OH_Scan_GetScanPictureProgress" + }, + { + "first_introduced": "12", + "name": "OH_Scan_Exit" + } +] diff --git a/print.gni b/print.gni index b025d17..17c321b 100644 --- a/print.gni +++ b/print.gni @@ -25,6 +25,6 @@ if (!defined(global_parts_info) || security_guard_enabled = false } cups_enable = true -jpeg_enable = true debug_enable = false ipp_over_usb_enable = false +sane_enable = false diff --git a/profile/3708.json b/profile/3708.json new file mode 100644 index 0000000..b5a1d9a --- /dev/null +++ b/profile/3708.json @@ -0,0 +1,13 @@ +{ + "process": "scan_service", + "systemability": [ + { + "name": 3708, + "libpath": "libscan_service.z.so", + "run-on-create": false, + "auto-restart": true, + "distributed": false, + "dump_level": 1 + } + ] +} \ No newline at end of file diff --git a/profile/BUILD.gn b/profile/BUILD.gn index 7c59b1a..c851098 100644 --- a/profile/BUILD.gn +++ b/profile/BUILD.gn @@ -17,3 +17,8 @@ ohos_sa_profile("print_sa_profiles") { sources = [ "3707.json" ] part_name = "print_fwk" } + +ohos_sa_profile("scan_sa_profiles") { + sources = [ "3708.json" ] + part_name = "print_fwk" +} diff --git a/services/scan_service/BUILD.gn b/services/scan_service/BUILD.gn new file mode 100644 index 0000000..1d7242b --- /dev/null +++ b/services/scan_service/BUILD.gn @@ -0,0 +1,102 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//base/print/print_fwk/print.gni") +import("//build/ohos.gni") + +cflags_cc = [] + +config("scan_service_config") { + visibility = [ ":*" ] + include_dirs = [ + "include", + "${print_path}/frameworks/helper/scan_helper/include", + ] + + cflags_cc += [ "-fexceptions" ] +} + +ohos_shared_library("scan_service") { + sources = [ + "src/scan_callback_proxy.cpp", + "src/scan_event_subscriber.cpp", + "src/scan_mdns_service.cpp", + "src/scan_service_ability.cpp", + "src/scan_service_stub.cpp", + "src/scan_system_data.cpp", + "src/scan_usb_manager.cpp", + ] + + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + boundary_sanitize = true + debug = false + integer_overflow = true + ubsan = true + } + + public_configs = [ ":scan_service_config" ] + + include_dirs = [ + "${print_path}/frameworks/innerkitsimpl/scan_impl/include", + "${print_utils_path}/include", + ] + + deps = [ + "${print_path}/frameworks/helper/scan_helper:scan_helper", + "${print_path}/frameworks/innerkitsimpl/scan_impl:scan_client", + ] + + if (sane_enable) { + include_dirs += [ "//vendor/open_source/backends/include" ] + deps += [ "//vendor/open_source/backends:third_sane" ] + cflags_cc += [ "-DSANE_ENABLE" ] + } + + if (debug_enable) { + cflags_cc += [ "-DDEBUG_ENABLE" ] + } + + external_deps = [ + "ability_base:base", + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "access_token:libaccesstoken_sdk", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "cJSON:cjson", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "drivers_interface_usb:libusb_proxy_1.0", + "eventhandler:libeventhandler", + "hilog:libhilog", + "hisysevent:libhisysevent", + "init:libbegetutil", + "ipc:ipc_core", + "libjpeg-turbo:turbojpeg", + "napi:ace_napi", + "netmanager_ext:mdns_manager_if", + "netmanager_ext:mdns_manager_if", + "os_account:os_account_innerkits", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + "usb_manager:usbsrv_client", + ] + + subsystem_name = "print" + part_name = "print_fwk" +} diff --git a/services/scan_service/include/scan_callback_proxy.h b/services/scan_service/include/scan_callback_proxy.h new file mode 100644 index 0000000..e9590b9 --- /dev/null +++ b/services/scan_service/include/scan_callback_proxy.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_NOTIFY_PROXY_H +#define SCAN_NOTIFY_PROXY_H + +#include "iscan_callback.h" +#include "iremote_proxy.h" + +namespace OHOS::Scan { +class ScanCallbackProxy : public IRemoteProxy { +public: + explicit ScanCallbackProxy(const sptr &impl); + ~ScanCallbackProxy() = default; + + bool OnCallback(uint32_t state, const ScanDeviceInfoTCP &info) override; + bool OnCallback(uint32_t state, const ScanDeviceInfo &info) override; + bool OnCallbackSync(uint32_t state, const ScanDeviceInfoSync &info) override; + bool OnGetFrameResCallback(bool isGetSucc, int32_t sizeRead) override; + bool OnScanInitCallback(int32_t &scanVersion) override; + bool OnSendSearchMessage(std::string &message) override; + bool OnGetDevicesList(std::vector &info) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace OHOS::Scan + +#endif // SCAN_NOTIFY_PROXY_H diff --git a/services/scan_service/include/scan_event_subscriber.h b/services/scan_service/include/scan_event_subscriber.h new file mode 100644 index 0000000..9165541 --- /dev/null +++ b/services/scan_service/include/scan_event_subscriber.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_EVENT_SUBSCRIBER_H +#define SCAN_EVENT_SUBSCRIBER_H + +#include "common_event_data.h" +#include "common_event_subscriber.h" + +namespace OHOS { +namespace Scan { +class ScanEventSubscriber final : public EventFwk::CommonEventSubscriber { +public: + explicit ScanEventSubscriber(const EventFwk::CommonEventSubscribeInfo &subscribeInfo); + virtual ~ScanEventSubscriber(); + void OnReceiveEvent(const EventFwk::CommonEventData &data) override; +}; + +} // namespace Scan +} // namespace OHOS +#endif // SCAN_EVENT_SUBSCRIBER_H diff --git a/services/scan_service/include/scan_mdns_service.h b/services/scan_service/include/scan_mdns_service.h new file mode 100644 index 0000000..ba4166f --- /dev/null +++ b/services/scan_service/include/scan_mdns_service.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_MDNS_SERVICE_H +#define SCAN_MDNS_SERVICE_H + +#include +#include "i_mdns_event.h" +#include "mdns_event_stub.h" +#include "mdns_client.h" +#include "mdns_common.h" +#include "scanner_info.h" +#include "scan_log.h" +#ifdef SANE_ENABLE +#include "sane/sane.h" +#include "sane/saneopts.h" +#endif +#include "scan_service_ability.h" + +namespace OHOS::Scan { +using namespace OHOS::NetManagerStandard; + +class ScanMDnsDiscoveryObserver : public DiscoveryCallbackStub { +public: + explicit ScanMDnsDiscoveryObserver(const MDnsServiceInfo &info) : expected_(info) {} + virtual ~ScanMDnsDiscoveryObserver() = default; + void HandleStartDiscover(const MDnsServiceInfo &serviceInfo, int32_t retCode) override{} + void HandleStopDiscover(const MDnsServiceInfo &serviceInfo, int32_t retCode) override; + void HandleServiceLost(const MDnsServiceInfo &serviceInfo, int32_t retCode) override{} + void HandleServiceFound(const MDnsServiceInfo &info, int32_t retCode) override; + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override + { + SCAN_HILOGD("GetScannerList HandleSerieFound OnRemoteRequest"); + return DiscoveryCallbackStub::OnRemoteRequest(code, data, reply, option); + } +public: + MDnsServiceInfo expected_; +}; + +class ScanMDnsResolveObserver : public ResolveCallbackStub { +public: + explicit ScanMDnsResolveObserver(const MDnsServiceInfo &info):_serviceInfo(info) {} + virtual ~ScanMDnsResolveObserver() = default; + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption& option) override + { + SCAN_HILOGD("GetScannerList ScanMDnsResolveObserver OnRemoteRequest"); + return ResolveCallbackStub::OnRemoteRequest(code, data, reply, option); + } + void HandleResolveResult(const MDnsServiceInfo& info, int32_t retCode) override; +public: + MDnsServiceInfo _serviceInfo; +}; + +class ScanMdnsService { +public: + ScanMdnsService(const ScanMdnsService&) = delete; + ScanMdnsService& operator=(const ScanMdnsService&) = delete; + static ScanMdnsService& GetInstance() + { + static ScanMdnsService instance; + return instance; + } + void SetServiceInfo(const MDnsServiceInfo& info); + void SetMDnsResolveCallBack(sptr& cb); + void SetMDnsDiscoveryCallBack(sptr& cb); + void SetServiceType(std::string stype); + sptr GetMDnsResolveCallBack(); + sptr GetMDnsDiscoveryCallBack(); + MDnsServiceInfo& GetServiceInfo(); + static std::string GetServiceAttribute(MDnsServiceInfo& serviceInfo, std::string keyStr); + + bool onStartDiscoverService(); + bool onStopDiscoverService(); + bool onResolveService(MDnsServiceInfo& serviceInfo); + void ToMDnsScaner(MDnsServiceInfo& serviceInfo); + +public: + sptr _scanMDnsDiscoveryCallBack; + sptr _scanMDnsResolveCallBack; + +private: + ScanMdnsService(){}; + MDnsServiceInfo _serviceInfo; +}; +} +#endif // !SCAN_MDNS_SERVICE_H diff --git a/services/scan_service/include/scan_service_ability.h b/services/scan_service/include/scan_service_ability.h new file mode 100644 index 0000000..c3c76b9 --- /dev/null +++ b/services/scan_service/include/scan_service_ability.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_SERVICE_ABILITY_H +#define SCAN_SERVICE_ABILITY_H + +#include +#include +#include +#include +#include +#include + +#include "ability_manager_client.h" +#include "event_handler.h" +#include "extension_ability_info.h" +#include "iscan_callback.h" +#include "iremote_object.h" +#include "scan_constant.h" +#include "scan_service_stub.h" +#include "system_ability.h" +#ifdef SANE_ENABLE +#include "sane/sane.h" +#include "sane/saneopts.h" +#endif +#include "scanner_info.h" +#include "scan_mdns_service.h" +#include "scan_option_descriptor.h" +#include "jpeglib.h" +namespace OHOS::Scan { +enum class ServiceRunningState { STATE_NOT_START, STATE_RUNNING }; +class ScanServiceAbility : public SystemAbility, public ScanServiceStub { + DECLARE_SYSTEM_ABILITY(ScanServiceAbility); +public: + DISALLOW_COPY_AND_MOVE(ScanServiceAbility); + ScanServiceAbility(int32_t systemAbilityId, bool runOnCreate); + ScanServiceAbility(); + ~ScanServiceAbility(); + static sptr GetInstance(); + int32_t InitScan(int32_t &scanVersion) override; + int32_t ExitScan() override; + int32_t GetScannerList() override; + int32_t StopDiscover() override; + int32_t OpenScanner(const std::string scannerId) override; + int32_t CloseScanner(const std::string scannerId) override; + int32_t GetScanOptionDesc(const std::string scannerId, const int32_t optionIndex, + ScanOptionDescriptor &desc) override; + int32_t OpScanOptionValue(const std::string scannerId, const int32_t optionIndex, + const ScanOptionOpType op, ScanOptionValue &value, int32_t &info) override; + int32_t GetScanParameters(const std::string scannerId, ScanParameters ¶) override; + int32_t StartScan(const std::string scannerId, const bool &batchMode) override; + int32_t GetSingleFrameFD(const std::string scannerId, uint32_t &size, uint32_t fd) override; + int32_t CancelScan(const std::string scannerId) override; + int32_t SetScanIOMode(const std::string scannerId, const bool isNonBlocking) override; + int32_t GetScanSelectFd(const std::string scannerId, int32_t &fd) override; + int32_t On(const std::string taskId, const std::string &type, const sptr &listener) override; + int32_t Off(const std::string taskId, const std::string &type) override; + int32_t GetScannerState(int32_t &scannerState) override; + int32_t GetScanProgress(const std::string scannerId, ScanProgress &prog) override; + int32_t AddScanner(const std::string& serialNumber, const std::string& discoverMode) override; + int32_t DeleteScanner(const std::string& serialNumber, const std::string& discoverMode) override; + int32_t GetAddedScanner(std::vector& allAddedScanner) override; + int32_t UpdateScannerName(const std::string& serialNumber, + const std::string& discoverMode, const std::string& deviceName) override; + int32_t AddPrinter(const std::string& serialNumber, const std::string& discoverMode) override; + int32_t OnStartScan(const std::string scannerId, const bool &batchMode); + void DisConnectUsbScanner(std::string serialNumber, std::string newDeviceId); // public + void UpdateUsbScannerId(std::string serialNumber, std::string newDeviceId); // public + +private: +#ifdef SANE_ENABLE + int32_t ActionSetAuto(SANE_Handle &scannerHandle, const int32_t &optionIndex); + int32_t ActionGetValue(SANE_Handle &scannerHandle, ScanOptionValue &value, const int32_t &optionIndex); + int32_t ActionSetValue(SANE_Handle &scannerHandle, ScanOptionValue &value, + const int32_t &optionIndex, int32_t &info); + int32_t SelectScanOptionDesc(const SANE_Option_Descriptor* &optionDesc, ScanOptionDescriptor &desc); +#endif + int32_t DoScanTask(const std::string scannerId, ScanProgress* scanProPtr); + void StartScanTask(const std::string scannerId); + void SendDeviceInfoTCP(const ScanDeviceInfoTCP &info, std::string event); + void SendDeviceInfo(const ScanDeviceInfo &info, std::string event); + void SendDeviceInfoSync(const ScanDeviceInfoSync &info, std::string event); + void SendInitEvent(int32_t &scanVersion, std::string event); + void SendDeviceSearchEnd(std::string &info, std::string event); + void SetScannerSerialNumber(ScanDeviceInfo &info); + void SaneGetScanner(); + void SyncScannerInfo(ScanDeviceInfo &info); +public: + static std::map scanDeviceInfoTCPMap_; + static std::map saneGetUsbDeviceInfoMap; + static std::map saneGetTcpDeviceInfoMap; + static std::map usbSnMap; + void UnloadSystemAbility(); + static int32_t appCount_; +protected: + void OnStart() override; + void OnStop() override; + +private: + int32_t ServiceInit(); + void InitServiceHandler(); + void ManualStart(); + int32_t ReInitScan(int32_t &scanVersion); + bool CheckPermission(const std::string &permissionName); + void SendGetFrameResEvent(const bool isGetSucc, const int32_t sizeRead); +#ifdef SANE_ENABLE + void SetScanOptionDescriptor(ScanOptionDescriptor &desc, const SANE_Option_Descriptor *optionDesc); + SANE_Handle GetScanHandle(const std::string &scannerId); +#endif + int32_t WriteJpegHeader(ScanParameters &parm, struct jpeg_error_mgr* jerr); + void GeneratePicture(const std::string &scannerId, std::string &file_name, + std::string &output_file, int32_t &status, ScanProgress* &scanProPtr); + void GetPicFrame(const std::string scannerId, ScanProgress *scanProPtr, + int32_t &scanStatus, ScanParameters &parm); + bool WritePicData(int &jpegrow, int32_t curReadSize, ScanParameters &parm, ScanProgress *scanProPtr); + void GeneratePictureBatch(const std::string &scannerId, std::string &file_name, + std::string &output_file, int32_t &status, ScanProgress* &scanProPtr); + void GeneratePictureSingle(const std::string &scannerId, std::string &file_name, + std::string &output_file, int32_t &status, ScanProgress* &scanProPtr); + void AddFoundUsbScanner(ScanDeviceInfo &info); + void AddFoundTcpScanner(ScanDeviceInfo &info); +#ifdef SANE_ENABLE + bool SetScannerInfo(const SANE_Device** ¤tDevice, ScanDeviceInfo &info); +#endif + bool GetUsbDevicePort(const std::string &deviceId, std::string &firstId, std::string &secondId); + bool GetTcpDeviceIp(const std::string &deviceId, std::string &ip); + void CleanScanTask(const std::string &scannerId); + void SendDeviceList(std::vector &info, std::string event); +#ifdef SANE_ENABLE + std::map scannerHandleList_; +#endif + ServiceRunningState state_; + std::mutex lock_; + static std::mutex instanceLock_; + static sptr instance_; + static std::shared_ptr serviceHandler_; + static std::map> registeredListeners_; + std::recursive_mutex apiMutex_; + std::recursive_mutex scanMutex_; + uint64_t currentJobId_; +#ifdef SANE_ENABLE + std::function getSingleFrameFDExe; +#endif + std::function cyclicCallExe; + std::queue scanQueue; + std::map scanTaskMap; + std::vector deviceInfos; + int32_t nextPicId = 1; + int32_t buffer_size; + bool batchMode_ = false; + uint8_t *saneReadBuf; + struct jpeg_compress_struct cinfo; + FILE *ofp = NULL; + bool isCancel = false; + int32_t dpi = 0; + JSAMPLE *jpegbuf = NULL; +}; +} // namespace OHOS::Scan +#endif // SCAN_SYSTEM_ABILITY_H \ No newline at end of file diff --git a/services/scan_service/include/scan_service_stub.h b/services/scan_service/include/scan_service_stub.h new file mode 100644 index 0000000..b6d86cd --- /dev/null +++ b/services/scan_service/include/scan_service_stub.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_SERVICE_STUB_H +#define SCAN_SERVICE_STUB_H + +#include "iscan_service.h" +#include "iremote_stub.h" + +namespace OHOS::Scan { +class ScanServiceStub : public IRemoteStub { +public: + explicit ScanServiceStub(); + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + bool OnInitScan(MessageParcel &data, MessageParcel &reply); + bool OnExitScan(MessageParcel &data, MessageParcel &reply); + bool OnGetScannerList(MessageParcel &data, MessageParcel &reply); + bool OnStopDiscover(MessageParcel &data, MessageParcel &reply); + bool OnOpenScanner(MessageParcel &data, MessageParcel &reply); + bool OnCloseScanner(MessageParcel &data, MessageParcel &reply); + bool OnGetScanOptionDesc(MessageParcel &data, MessageParcel &reply); + bool OnOpScanOptionValue(MessageParcel &data, MessageParcel &reply); + bool OnGetScanParameters(MessageParcel &data, MessageParcel &reply); + bool OnStartScan(MessageParcel &data, MessageParcel &reply); + bool OnGetSingleFrameFD(MessageParcel &data, MessageParcel &reply); + bool OnCancelScan(MessageParcel &data, MessageParcel &reply); + bool OnSetScanIOMode(MessageParcel &data, MessageParcel &reply); + bool OnGetScanSelectFd(MessageParcel &data, MessageParcel &reply); + bool OnGetScannerState(MessageParcel &data, MessageParcel &reply); + bool OnGetScanProgress(MessageParcel &data, MessageParcel &reply); + bool OnConnectScanner(MessageParcel &data, MessageParcel &reply); + bool OnDisConnectScanner(MessageParcel &data, MessageParcel &reply); + bool OnGetConnectedScanner(MessageParcel &data, MessageParcel &reply); + bool OnUpdateScannerName(MessageParcel &data, MessageParcel &reply); + bool OnAddPrinter(MessageParcel &data, MessageParcel &reply); + + bool OnEventOn(MessageParcel &data, MessageParcel &reply); + bool OnEventOff(MessageParcel &data, MessageParcel &reply); + +private: + using ScanCmdHandler = bool (ScanServiceStub::*)(MessageParcel &, MessageParcel &); + std::map cmdMap_; + bool isSaneInit_ = false; + std::mutex lock_; +}; +} // namespace OHOS::Scan +#endif // SCAN_SERVICE_STUB_H diff --git a/services/scan_service/include/scan_system_data.h b/services/scan_service/include/scan_system_data.h new file mode 100644 index 0000000..31cf705 --- /dev/null +++ b/services/scan_service/include/scan_system_data.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_SYSTEM_DATA_H +#define SCAN_SYSTEM_DATA_H + +#include +#include +#include +#include "scanner_info.h" + +namespace OHOS { +namespace Scan { + +class ScanSystemData { +public: + static ScanSystemData& GetInstance() + { + static ScanSystemData instance; + return instance; + } + bool Init(); + void InsertScannerInfo(const std::string &uniqueId, const ScanDeviceInfo &scannerInfo); + bool DeleteScannerInfo(const std::string &uniqueId); + bool UpdateScannerNameByUniqueId(const std::string &uniqueId, const std::string &deviceName); + bool UpdateScannerInfoByUniqueId(const std::string &uniqueId, const ScanDeviceInfo &scannerInfo); + bool QueryScannerNameByUniqueId(const std::string &uniqueId, std::string &deviceName); + bool QueryScannerInfoByUniqueId(const std::string &uniqueId, ScanDeviceInfo &scannerInfo); + void GetAddedScannerInfoList(std::vector &infoList); + bool SaveScannerMap(); + +private: + std::map> addedScannerMap_; + bool ParseScannerListJsonV1(nlohmann::json& jsonObject); + bool CheckJsonObjectValue(const nlohmann::json& object); + std::mutex addedScannerMapLock_; +}; + +} // namespace Scan +} // namespace OHOS +#endif // SCAN_SYSTEM_DATA_H diff --git a/services/scan_service/include/scan_usb_manager.h b/services/scan_service/include/scan_usb_manager.h new file mode 100644 index 0000000..2833be7 --- /dev/null +++ b/services/scan_service/include/scan_usb_manager.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_USB_MANAGER_H_ +#define SCAN_USB_MANAGER_H_ + +#include +#include +#include +#include "usb_srv_client.h" +#include "singleton.h" +#include "scan_event_subscriber.h" + +namespace OHOS::Scan { + +class ScanUsbManager final : public DelayedSingleton { +public: + ScanUsbManager(); + ~ScanUsbManager(); + void RefreshUsbDevice(); + std::string GetSerialNumber(USB::UsbDevice &usbDevice); + void DealUsbDevStatusChange(const std::string &devStr, bool isAttach); + void Init(); +private: + std::string GetDeviceSerialNumber(USB::USBDevicePipe &usbDevicePipe); + void formatUsbPort(std::string &port); + std::string getNewDeviceId(std::string oldDeviceId, std::string usbDeviceName); + void UpdateUsbScannerId(std::string serialNumber, std::string usbDeviceName); + void DisConnectUsbScanner(std::string usbDeviceName); + std::shared_ptr usbDevStatusListener; + bool isInit = false; +}; + +} + +#endif // SCAN_USB_MANAGER_H_ \ No newline at end of file diff --git a/services/scan_service/src/scan_callback_proxy.cpp b/services/scan_service/src/scan_callback_proxy.cpp new file mode 100644 index 0000000..d5a0c20 --- /dev/null +++ b/services/scan_service/src/scan_callback_proxy.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "scan_callback_proxy.h" + +#include "message_parcel.h" +#include "scan_log.h" + +namespace OHOS::Scan { +ScanCallbackProxy::ScanCallbackProxy(const sptr &impl) : IRemoteProxy(impl) {} + + +bool ScanCallbackProxy::OnCallback(uint32_t state, const ScanDeviceInfoTCP &info) +{ + SCAN_HILOGD("GetScannerList ScanCallbackProxy::OnCallback"); + SCAN_HILOGD("ScanCallbackProxy::OnCallback Start"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + SCAN_HILOGE("write descriptor failed"); + return false; + } + + data.WriteUint32(state); + info.Marshalling(data); + + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanCallbackProxy::OnCallback remote is null"); + return false; + } + + int error = remote->SendRequest(SCAN_CALLBACK_DEVICE_TCP, data, reply, option); + if (error != 0) { + SCAN_HILOGE("SendRequest failed, error %{public}d", error); + return false; + } + + SCAN_HILOGD("ScanCallbackProxy::OnCallback End"); + return true; +} + +bool ScanCallbackProxy::OnCallback(uint32_t state, const ScanDeviceInfo &info) +{ + SCAN_HILOGD("GetScannerList ScanCallbackProxy::OnCallback"); + SCAN_HILOGD("ScanCallbackProxy::OnCallback Start"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + SCAN_HILOGE("write descriptor failed"); + return false; + } + + data.WriteUint32(state); + info.Marshalling(data); + + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanCallbackProxy::OnCallback remote is null"); + return false; + } + + int error = remote->SendRequest(SCAN_CALLBACK_DEVICE, data, reply, option); + if (error != 0) { + SCAN_HILOGE("SendRequest failed, error %{public}d", error); + return false; + } + + SCAN_HILOGD("ScanCallbackProxy::OnCallback End"); + return true; +} + +bool ScanCallbackProxy::OnCallbackSync(uint32_t state, const ScanDeviceInfoSync &info) +{ + SCAN_HILOGD("ScanCallbackProxy::OnCallback Start"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + SCAN_HILOGE("write descriptor failed"); + return false; + } + data.WriteUint32(state); + info.Marshalling(data); + + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanCallbackProxy::OnCallbackSync remote is null"); + return false; + } + + int error = remote->SendRequest(SCAN_CALLBACK_DEVICE_SYNC, data, reply, option); + if (error != 0) { + SCAN_HILOGE("SendRequest failed, error %{public}d", error); + return false; + } + + SCAN_HILOGD("ScanCallbackProxy::OnCallbackSync End"); + return true; +} + +bool ScanCallbackProxy::OnGetFrameResCallback(bool isGetSucc, int32_t sizeRead) +{ + SCAN_HILOGD("ScanCallbackProxy::OnGetFrameResCallback Start"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + SCAN_HILOGE("write descriptor failed"); + return false; + } + + data.WriteBool(isGetSucc); + data.WriteInt32(sizeRead); + + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanCallbackProxy::OnGetFrameResCallback remote is null"); + return false; + } + + int error = remote->SendRequest(SCAN_CALLBACK_GET_FRAME_RES, data, reply, option); + if (error != 0) { + SCAN_HILOGE("SendRequest failed, error %{public}d", error); + return false; + } + SCAN_HILOGD("ScanCallbackProxy::OnGetFrameResCallback End"); + return true; +} + +bool ScanCallbackProxy::OnScanInitCallback(int32_t &scanVersion) +{ + SCAN_HILOGE("Enter OnScanInitCallback"); + SCAN_HILOGD("ScanCallbackProxy::OnCallback Start"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + SCAN_HILOGE("write descriptor failed"); + return false; + } + + data.WriteUint32(scanVersion); + + auto remote = Remote(); + if (remote == nullptr) { + SCAN_HILOGE("ScanCallbackProxy::OnScanInitCallback remote is null"); + return false; + } + + int error = remote->SendRequest(SCAN_CALLBACK_SCAN_INIT, data, reply, option); + if (error != 0) { + SCAN_HILOGE("SendRequest failed, error %{public}d", error); + return false; + } + + SCAN_HILOGD("ScanCallbackProxy::OnCallback End"); + return true; +} + +bool ScanCallbackProxy::OnSendSearchMessage(std::string &message) +{ + SCAN_HILOGD("Enter OnSendSearchMessage"); + SCAN_HILOGD("ScanCallbackProxy::OnSendSearchMessage Start"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + SCAN_HILOGE("write descriptor failed"); + return false; + } + + data.WriteString(message); + auto remotePtr = Remote(); + if (!remotePtr) { + SCAN_HILOGE("Remote() nullptr failed"); + return false; + } + int error = remotePtr->SendRequest(SCAN_CALLBACK_SEND_MESSAGE, data, reply, option); + if (error != 0) { + SCAN_HILOGE("SendRequest failed, error %{public}d", error); + return false; + } + SCAN_HILOGD("ScanCallbackProxy::OnSendSearchMessage End"); + return true; +} + +bool ScanCallbackProxy::OnGetDevicesList(std::vector &infos) +{ + SCAN_HILOGI("Enter OnGetDevicesList"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + SCAN_HILOGE("write descriptor failed"); + return false; + } + data.WriteInt32(infos.size()); + for (size_t i = 0; i < infos.size(); i++) { + infos[i].Marshalling(data); + } + int error = Remote()->SendRequest(SCAN_CALLBACK_DEVICE_LIST, data, reply, option); + if (error != 0) { + SCAN_HILOGE("SendRequest failed, error %{public}d", error); + return false; + } + + SCAN_HILOGI("ScanCallbackProxy::OnCallback End"); + return true; +} +} // namespace OHOS::Scan diff --git a/services/scan_service/src/scan_event_subscriber.cpp b/services/scan_service/src/scan_event_subscriber.cpp new file mode 100644 index 0000000..dcf309d --- /dev/null +++ b/services/scan_service/src/scan_event_subscriber.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_event_subscriber.h" +#include "common_event_manager.h" +#include "common_event_support.h" +#include "scan_usb_manager.h" +#include "scan_log.h" + +namespace OHOS { +namespace Scan { +ScanEventSubscriber::ScanEventSubscriber( + const EventFwk::CommonEventSubscribeInfo &subscribeInfo) : EventFwk::CommonEventSubscriber(subscribeInfo) +{} + +ScanEventSubscriber::~ScanEventSubscriber() +{} + +void ScanEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &data) +{ + std::string action = data.GetWant().GetAction(); + if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USB_DEVICE_ATTACHED) { + SCAN_HILOGI("OnReceiveEvent attached start"); + std::string devStr = data.GetData(); + SCAN_HILOGD("OnReceiveEvent attached devStr = %{public}s", devStr.c_str()); + DelayedSingleton::GetInstance()->DealUsbDevStatusChange(devStr, true); + } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USB_DEVICE_DETACHED) { + SCAN_HILOGI("OnReceiveEvent detached start"); + std::string devStr = data.GetData(); + DelayedSingleton::GetInstance()->DealUsbDevStatusChange(devStr, false); + SCAN_HILOGD("OnReceiveEvent detached devStr = %{public}s end", devStr.c_str()); + } +} + +} // namespace Scan +} // namespace OHOS \ No newline at end of file diff --git a/services/scan_service/src/scan_mdns_service.cpp b/services/scan_service/src/scan_mdns_service.cpp new file mode 100644 index 0000000..48cea2b --- /dev/null +++ b/services/scan_service/src/scan_mdns_service.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_mdns_service.h" +#include "mdns_common.h" + +#define SCAN_MDNS_PORT 5353 + +namespace OHOS::Scan { +using namespace OHOS::NetManagerStandard; + +void ScanMdnsService::SetServiceType(std::string stype) +{ + _serviceInfo.type = stype; + _serviceInfo.port = SCAN_MDNS_PORT; + _scanMDnsDiscoveryCallBack = new (std::nothrow) ScanMDnsDiscoveryObserver(_serviceInfo); + _scanMDnsResolveCallBack = new (std::nothrow) ScanMDnsResolveObserver(_serviceInfo); +} + +MDnsServiceInfo &ScanMdnsService::GetServiceInfo() +{ + return _serviceInfo; +} + +void ScanMdnsService::SetServiceInfo(const MDnsServiceInfo &info) +{ + _serviceInfo = info; +} + +sptr ScanMdnsService::GetMDnsDiscoveryCallBack() +{ + return _scanMDnsDiscoveryCallBack; +} + +void ScanMdnsService::SetMDnsDiscoveryCallBack(sptr &cb) +{ + _scanMDnsDiscoveryCallBack = cb; +} + +sptr ScanMdnsService::GetMDnsResolveCallBack() +{ + return _scanMDnsResolveCallBack; +} + +void ScanMdnsService::SetMDnsResolveCallBack(sptr &cb) +{ + _scanMDnsResolveCallBack = cb; +} + +bool ScanMdnsService::onStartDiscoverService() +{ + if (_scanMDnsDiscoveryCallBack == nullptr) { + SCAN_HILOGE("GetScannerList onStartDiscoverService1 nullptr"); + return false; + } + SCAN_HILOGI("GetScannerList onStartDiscoverService begin"); + int32_t ret = DelayedSingleton::GetInstance()->StartDiscoverService( + _serviceInfo.type, _scanMDnsDiscoveryCallBack); + if (ret != NETMANAGER_EXT_SUCCESS) { + return false; + } + SCAN_HILOGI("GetScannerList onStartDiscoverService end"); + return true; +} + +bool ScanMdnsService::onResolveService(MDnsServiceInfo &serviceInfo) +{ + SCAN_HILOGI("GetScannerList onResolveService"); + if (_scanMDnsResolveCallBack == nullptr) { + SCAN_HILOGE("GetScannerList _scanMDnsResolveCallBack null fail"); + return false; + } + int32_t ret = DelayedSingleton::GetInstance()->ResolveService(serviceInfo, _scanMDnsResolveCallBack); + if (ret != NETMANAGER_EXT_SUCCESS) { + SCAN_HILOGE("GetScannerList onResolveService false"); + return false; + } + SCAN_HILOGI("GetScannerList onResolveService1 success"); + return true; +} + +bool ScanMdnsService::onStopDiscoverService() +{ + SCAN_HILOGI("GetScannerList onStopDiscoverService"); + if (_scanMDnsDiscoveryCallBack == nullptr) { + SCAN_HILOGE("GetScannerList _scanMDnsDiscoveryCallBack null fail"); + return false; + } + int32_t ret = DelayedSingleton::GetInstance()->StopDiscoverService(_scanMDnsDiscoveryCallBack); + if (ret != NETMANAGER_EXT_SUCCESS) { + SCAN_HILOGE("GetScannerList onStopDiscoverService false"); + return false; + } + SCAN_HILOGI("GetScannerList onStopDiscoverService success"); + return true; +} + +void ScanMDnsDiscoveryObserver::HandleServiceFound(const MDnsServiceInfo &info, int32_t retCode) +{ + MDnsServiceInfo tempInfo = info; + SCAN_HILOGD("GetScannerList HandleServiceFound [%{public}s][%{public}s][%{public}d][%{public}s]", + info.name.c_str(), + info.type.c_str(), + info.port, + info.addr.c_str()); + ScanMdnsService::GetInstance().onResolveService(tempInfo); +} + +void ScanMDnsResolveObserver::HandleResolveResult(const MDnsServiceInfo &info, int32_t retCode) +{ + _serviceInfo = info; + SCAN_HILOGD("GetScannerList HandleResolveResult [%{public}s][%{public}s][%{public}d][%{public}s]", + info.name.c_str(), + info.type.c_str(), + info.port, + info.addr.c_str()); + MDnsServiceInfo tempInfo = info; + auto texRecord = tempInfo.GetAttrMap(); + auto textIt = texRecord.begin(); + for (; textIt != texRecord.end(); textIt++) { + SCAN_HILOGD("GetScannerList startHandleServiceResolve keys [%{public}s]", textIt->first.c_str()); + } + + ScanMdnsService::GetInstance().ToMDnsScaner(tempInfo); +} + +void ScanMDnsDiscoveryObserver::HandleStopDiscover(const MDnsServiceInfo &serviceInfo, int32_t retCode) +{ + MDnsServiceInfo info = serviceInfo; + SCAN_HILOGD("GetScannerList HandleStopDiscover [%{public}s][%{public}s][%{public}d][%{public}s]", + info.name.c_str(), + info.type.c_str(), + info.port, + info.addr.c_str()); +} + +void ScanMdnsService::ToMDnsScaner(MDnsServiceInfo &serviceInfo) +{ + std::unique_ptr scannerInfo = std::make_unique(); + scannerInfo->addr = serviceInfo.addr; + scannerInfo->deviceName = serviceInfo.name; + scannerInfo->port = std::to_string(serviceInfo.port); + std::vector keys = {"UUID", "adminur", "button", "feeder", "mdl", "mfg", "mote", "txtvers", "ty"}; + for (auto key : keys) { + std::string value = ScanMdnsService::GetServiceAttribute(serviceInfo, key); + if (value.empty()) { + SCAN_HILOGW("GetScannerList key [%{public}s] is empty", key.c_str()); + continue; + } + SCAN_HILOGD("GetScannerList key:[%{public}s] value:[%{public}s]", key.c_str(), value.c_str()); + if (key == "UUID") { + scannerInfo->uuid = value; + } else if (key == "mdl") { + scannerInfo->model = value; + } else if (key == "mfg") { + scannerInfo->manufacturer = value; + } else if (key == "ty") { + scannerInfo->deviceType = value; + } else if (key == "port") { + scannerInfo->port = value; + } else if (key == "button") { + scannerInfo->button = value; + } else if (key == "feeder") { + scannerInfo->feeder = value; + } + } + SCAN_HILOGI("mdns scanner's deviceName:[%{public}s]", scannerInfo->deviceName.c_str()); + SCAN_HILOGD("mdns scanner's addr:[%{public}s]", scannerInfo->addr.c_str()); + SCAN_HILOGD("mdns scanner's port:[%{public}s]", scannerInfo->port.c_str()); + ScanServiceAbility::scanDeviceInfoTCPMap_[scannerInfo->addr] = *scannerInfo; +} + +std::string ScanMdnsService::GetServiceAttribute(MDnsServiceInfo &serviceInfo, std::string keyStr) +{ + SCAN_HILOGD("GetScannerList GetServiceAttribute keyStr [%{public}s]", keyStr.c_str()); + TxtRecord attrMap = serviceInfo.GetAttrMap(); + auto attrArrSize = attrMap.size(); + if (attrArrSize < 1) { + SCAN_HILOGE("can not get attr"); + return ""; + } + auto attrIt = attrMap.find(keyStr); + if (attrIt == attrMap.end()) { + SCAN_HILOGE("can not find key"); + return ""; + } + std::string value = ""; + if (!attrMap[keyStr].empty()) { + value += std::accumulate(attrMap[keyStr].begin(), attrMap[keyStr].end(), ""); + } + + return value; +} + + +} // namespace OHOS::Scan diff --git a/services/scan_service/src/scan_service_ability.cpp b/services/scan_service/src/scan_service_ability.cpp new file mode 100644 index 0000000..a7a0827 --- /dev/null +++ b/services/scan_service/src/scan_service_ability.cpp @@ -0,0 +1,1888 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "scan_service_ability.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "accesstoken_kit.h" +#include "array_wrapper.h" +#include "int_wrapper.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "napi_scan_utils.h" +#include "scan_constant.h" +#include "scan_log.h" +#include "scan_util.h" +#include "scanner_info.h" +#include "string_wrapper.h" +#include "system_ability.h" +#include "system_ability_definition.h" +#include "want_params_wrapper.h" +#include "scan_usb_manager.h" +#include "common_event_data.h" +#include "common_event_manager.h" +#include "common_event_support.h" +#include "scan_system_data.h" + +namespace OHOS::Scan { +using namespace std; +using namespace OHOS::HiviewDFX; +using namespace Security::AccessToken; +using SteadyTimePoint = std::chrono::steady_clock::time_point; + +constexpr int ONE_MB = 1024 * 1024; // default buffersize 1MB +constexpr int SCAN_PROGRESS_100 = 100; +#ifdef SANE_ENABLE +constexpr int SCAN_PROGRESS_10 = 10; +constexpr int SCAN_PROGRESS_19 = 19; +constexpr int SCAN_PROGRESS_80 = 80; +#endif +constexpr int JPEG_QUALITY_SEVENTY_FIVE = 75; +constexpr int CHANNEL_ONE = 1; +constexpr int CHANNEL_THREE = 3; +#ifdef SANE_ENABLE +constexpr int MAX_PICTURE_DPI = 3000; +#endif +const int64_t INIT_INTERVAL = 5000L; +const uint32_t ASYNC_CMD_DELAY = 10; +const int64_t UNLOAD_SYSTEMABILITY_DELAY = 1000 * 30; + +static int32_t g_scannerState = SCANNER_READY; +#ifdef SANE_ENABLE +static bool g_hasOpenScannerFaild = false; +#endif +static bool g_hasIoFaild = false; +static bool g_isJpegWriteSuccess = false; +static const std::string PERMISSION_NAME_SCAN = "ohos.permission.SCAN"; +static const std::string PERMISSION_NAME_SCAN_JOB = "ohos.permission.MANAGE_SCAN_JOB"; +static const std::string PERMISSION_NAME_PRINT = "ohos.permission.PRINT"; +static const std::string PERMISSION_NAME_PRINT_JOB = "ohos.permission.MANAGE_PRINT_JOB"; +static const std::string SCAN_DEVICE_FOUND_TCP = "scanDeviceFoundTCP"; +static const std::string SCAN_DEVICE_FOUND = "scanDeviceFound"; +static const std::string SCAN_DEVICE_SYNC = "scanDeviceSync"; +static const std::string SCAN_DEVICE_ADD = "scanDeviceAdd"; +static const std::string SCAN_DEVICE_DEL = "scanDeviceDel"; +static const std::string SCAN_INIT_EVENT = "scanInitEvent"; + +static const std::string DEVICE_EVENT_TYPE = "deviceStateChange"; +static const std::string GET_FRAME_RES_EVENT_TYPE = "getFrameResult"; +static const std::string GET_SCANNER_DEVICE_LIST = "GET_SCANNER_DEVICE_LIST"; + +std::map> OHOS::Scan::ScanServiceAbility::registeredListeners_; + +REGISTER_SYSTEM_ABILITY_BY_ID(ScanServiceAbility, SCAN_SERVICE_ID, true); + +int32_t ScanServiceAbility::appCount_ = 0; +std::mutex ScanServiceAbility::instanceLock_; +sptr ScanServiceAbility::instance_; +std::shared_ptr ScanServiceAbility::serviceHandler_; +std::map ScanServiceAbility::scanDeviceInfoTCPMap_; +std::map ScanServiceAbility::saneGetUsbDeviceInfoMap; +std::map ScanServiceAbility::saneGetTcpDeviceInfoMap; +std::map ScanServiceAbility::usbSnMap; + +ScanServiceAbility::ScanServiceAbility(int32_t systemAbilityId, bool runOnCreate) + : SystemAbility(systemAbilityId, runOnCreate), state_(ServiceRunningState::STATE_NOT_START), + currentJobId_(SCAN_CONSTRAINT_NONE) +{ + buffer_size = ONE_MB; + saneReadBuf = static_cast(malloc(buffer_size)); +#ifdef SANE_ENABLE + getSingleFrameFDExe = [=](SANE_Handle scannerHandle, uint32_t fd) { + int32_t totalReadSize = 0; + int32_t curReadSize = 0; + uint8_t *buffer = static_cast(malloc(buffer_size)); + if (!buffer) { + SCAN_HILOGE("malloc memory for buffer failed!!!"); + SendGetFrameResEvent(false, totalReadSize); + return; + } + SANE_Status status = SANE_STATUS_GOOD; + while (true) { + status = sane_read(scannerHandle, buffer, buffer_size, &curReadSize); + if (status == SANE_STATUS_EOF) { + SCAN_HILOGD("Totally read %{public}d bytes of frame data", totalReadSize); + SendGetFrameResEvent(true, totalReadSize); + break; + } + if (status != SANE_STATUS_GOOD) { + SCAN_HILOGE("sane_read failed, reason: [%{public}s]", sane_strstatus(status)); + g_scannerState = SCANNER_READY; + SendGetFrameResEvent(false, totalReadSize); + break; + } + write(fd, buffer, curReadSize); + totalReadSize += curReadSize; + SCAN_HILOGD("sane_read success, current read: %{public}d Bytes, already read %{public}d Bytes", + curReadSize, totalReadSize); + } + free(buffer); + buffer = nullptr; + }; +#endif + + cinfo.comps_in_scan = 0; +} + +ScanServiceAbility::~ScanServiceAbility() +{ + free(saneReadBuf); + FREE_AND_NULLPTR(jpegbuf) + SCAN_HILOGD("~ScanServiceAbility state_ is %{public}d.", static_cast(state_)); +} + +sptr ScanServiceAbility::GetInstance() +{ + if (instance_ == nullptr) { + std::lock_guard autoLock(instanceLock_); + if (instance_ == nullptr) { + instance_ = new ScanServiceAbility(SCAN_SERVICE_ID, true); + } + } + return instance_; +} + +int32_t ScanServiceAbility::ServiceInit() +{ + bool ret = Publish(ScanServiceAbility::GetInstance()); + if (!ret) { + SCAN_HILOGE("ScanServiceAbility Publish failed."); + return E_SCAN_SERVER_FAILURE; + } + state_ = ServiceRunningState::STATE_RUNNING; + SCAN_HILOGD("state_ is %{public}d.", static_cast(state_)); + SCAN_HILOGI("Init ScanServiceAbility success."); + return ERR_OK; +} + +void ScanServiceAbility::OnStart() +{ + SCAN_HILOGI("ScanServiceAbility::Enter OnStart."); + if (instance_ == nullptr) { + instance_ = this; + } + if (state_ == ServiceRunningState::STATE_RUNNING) { + SCAN_HILOGI("ScanServiceAbility is already running."); + return; + } + + InitServiceHandler(); + int32_t ret = ServiceInit(); + if (ret != ERR_OK) { + auto callback = [=]() { ServiceInit(); }; + serviceHandler_->PostTask(callback, INIT_INTERVAL); + SCAN_HILOGE("ScanServiceAbility Init failed. Try again 5s later"); + return; + } + state_ = ServiceRunningState::STATE_RUNNING; + return; +} + +void ScanServiceAbility::InitServiceHandler() +{ + SCAN_HILOGI("InitServiceHandler started."); + if (serviceHandler_ != nullptr) { + SCAN_HILOGI("InitServiceHandler already init."); + return; + } + std::shared_ptr runner = AppExecFwk::EventRunner::Create("ScanServiceAbility"); + serviceHandler_ = std::make_shared(runner); + SCAN_HILOGI("InitServiceHandler succeeded."); +} + +void ScanServiceAbility::ManualStart() +{ + if (state_ != ServiceRunningState::STATE_RUNNING) { + SCAN_HILOGI("ScanServiceAbility restart."); + OnStart(); + } +} + +void ScanServiceAbility::OnStop() +{ + SCAN_HILOGI("OnStop started."); + if (state_ != ServiceRunningState::STATE_RUNNING) { + return; + } + serviceHandler_ = nullptr; + state_ = ServiceRunningState::STATE_NOT_START; + SCAN_HILOGI("OnStop end."); +} +void ScanServiceAbility::UnloadSystemAbility() +{ + SCAN_HILOGI("appCount_= %{public}d", appCount_); + auto unloadTask = [this]() { + if (ScanServiceAbility::appCount_ != 0) { + SCAN_HILOGW("appCount is not equal to zerro"); + return; + } + auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgrProxy == nullptr) { + SCAN_HILOGE("get samgr failed"); + return; + } + int32_t ret = samgrProxy->UnloadSystemAbility(SCAN_SERVICE_ID); + if (ret != ERR_OK) { + SCAN_HILOGE("unload system ability failed"); + return; + } + this->ExitScan(); + SCAN_HILOGI("unload system ability successfully"); + }; + serviceHandler_->PostTask(unloadTask, UNLOAD_SYSTEMABILITY_DELAY); +} + +#ifdef SANE_ENABLE +SANE_Handle ScanServiceAbility::GetScanHandle(const std::string &scannerId) +{ + auto scannerIt = scannerHandleList_.find(scannerId); + if (scannerIt == scannerHandleList_.end()) { + SCAN_HILOGE("ScannerId: [%{public}s] is not openned!!!", scannerId.c_str()); + return nullptr; + } + + return scannerHandleList_[scannerId]; +} +#endif + +int32_t ScanServiceAbility::InitScan(int32_t &scanVersion) +{ + ManualStart(); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + ExitScan(); + SCAN_HILOGI("ScanServiceAbility InitScan start"); +#ifdef SANE_ENABLE + SANE_Status status = sane_init(&scanVersion, nullptr); + if (status != SANE_STATUS_GOOD) { + SCAN_HILOGE("sane_init failed, reason: [%{public}s]", sane_strstatus(status)); + return ScanUtil::ConvertErro(status); + } +#endif + DelayedSingleton::GetInstance()->Init(); + ScanSystemData::GetInstance().Init(); + SCAN_HILOGI("ScanServiceAbility InitScan end, scanVersion = [%{public}d]", scanVersion); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::ExitScan() +{ + ManualStart(); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGI("ScanServiceAbility ExitScan start"); + std::lock_guard autoLock(lock_); +#ifdef SANE_ENABLE + sane_exit(); + scannerHandleList_.clear(); +#endif + g_scannerState = SCANNER_READY; + std::queue empty; + scanQueue.swap(empty); + scanTaskMap.clear(); + SCAN_HILOGI("ScanServiceAbility ExitScan end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::ReInitScan(int32_t &scanVersion) +{ + ManualStart(); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGD("ScanServiceAbility ReInitScan start"); +#ifdef SANE_ENABLE + sane_exit(); + scannerHandleList_.clear(); + g_scannerState = SCANNER_READY; + std::queue empty; + scanQueue.swap(empty); + scanTaskMap.clear(); + + SANE_Status status = sane_init(&scanVersion, nullptr); + if (status != SANE_STATUS_GOOD) { + SCAN_HILOGE("ReInitScan sane_init failed, reason: [%{public}s]", sane_strstatus(status)); + return ScanUtil::ConvertErro(status); + } +#endif + DelayedSingleton::GetInstance()->Init(); + SCAN_HILOGD("ScanServiceAbility ReInitScan end, scanVersion = [%{public}d]", scanVersion); + return E_SCAN_NONE; +} + +bool ScanServiceAbility::GetUsbDevicePort(const std::string &deviceId, std::string &firstId, std::string &secondId) +{ + std::regex pattern(R"(([a-zA-Z0-9_]+):(libusb):([0-9]{3}):([0-9]{3}))"); + std::smatch match; + if (std::regex_match(deviceId, match, pattern)) { + constexpr size_t STRING_POS_THREE = 3; + constexpr size_t STRING_POS_FOUR = 4; + firstId = std::to_string(std::stoi(match[STRING_POS_THREE])); + secondId = std::to_string(std::stoi(match[STRING_POS_FOUR])); + return true; + } else { + SCAN_HILOGE("In USB mode, the deviceId string format does not match"); + return false; + } +} + +bool ScanServiceAbility::GetTcpDeviceIp(const std::string &deviceId, std::string &ip) +{ + std::regex pattern(R"(([^ ]+) (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) ([^ ]+))"); + std::smatch match; + if (std::regex_match(deviceId, match, pattern)) { + constexpr size_t STRING_POS_TWO = 2; + ip = match[STRING_POS_TWO]; + return true; + } else { + SCAN_HILOGE("In TCP mode, the deviceId string format does not match"); + return false; + } +} + +void ScanServiceAbility::SetScannerSerialNumber(ScanDeviceInfo &info) +{ + info.model = info.model.substr(0, info.model.find("(") - 1); + if (info.deviceId.find(":tcp") != info.deviceId.npos) { + info.discoverMode = "TCP"; + SCAN_HILOGI("SetScannerSerialNumber discoverMode:[%{public}s]", info.discoverMode.c_str()); + std::string ip; + if (!GetTcpDeviceIp(info.deviceId, ip)) { + SCAN_HILOGE("cannot get device's ip"); + return; + } + auto it = scanDeviceInfoTCPMap_.find(ip); + if (it != scanDeviceInfoTCPMap_.end()) { + info.serialNumber = it->second.deviceName.substr( + it->second.deviceName.find_last_of(" ") + 1, it->second.deviceName.size() - 1); + SCAN_HILOGI("Set mdns ScannerSerialNumber :[%{public}s]", info.serialNumber.c_str()); + } + } else if (info.deviceId.find(":libusb") != info.deviceId.npos) { + info.discoverMode = "USB"; + SCAN_HILOGI("SetScannerSerialNumber discoverMode:[%{public}s]", info.discoverMode.c_str()); + std::string firstId; + std::string secondId; + if (!GetUsbDevicePort(info.deviceId, firstId, secondId)) { + SCAN_HILOGE("cannot get usb's port"); + return; + } + std::string usbScannerPort = firstId + "-" + secondId; + SCAN_HILOGI("usbScannerPort: firstId-secondId [%{public}s]", usbScannerPort.c_str()); + DelayedSingleton::GetInstance()->RefreshUsbDevice(); + auto it = usbSnMap.find(usbScannerPort); + if (it != usbSnMap.end() && it->second != "") { + SCAN_HILOGI("set serialNumber [%{public}s]", usbSnMap[usbScannerPort].c_str()); + info.serialNumber = usbSnMap[usbScannerPort]; + } else { + SCAN_HILOGE("usb %{public}s can't find serialNumber", usbScannerPort.c_str()); + } + } + info.deviceName = info.manufacturer + "-" + info.model + "-" + info.serialNumber; +} + +void ScanServiceAbility::SyncScannerInfo(ScanDeviceInfo &info) +{ + std::string uniqueId = info.discoverMode + info.serialNumber; + std::string deviceName = ""; + if (ScanSystemData::GetInstance().QueryScannerNameByUniqueId(uniqueId, deviceName)) { + info.deviceName = deviceName; + } else { + SCAN_HILOGW("ScanServiceAbility SyncScannerInfo deviceName not need upadate"); + } + if (ScanSystemData::GetInstance().UpdateScannerInfoByUniqueId(uniqueId, info)) { + ScanSystemData::GetInstance().SaveScannerMap(); + } +} + +void ScanServiceAbility::AddFoundUsbScanner(ScanDeviceInfo &info) +{ + SCAN_HILOGI("AddFoundUsbScanner start model:[%{public}s]", info.model.c_str()); + SyncScannerInfo(info); +#ifdef DEBUG_ENABLE + auto it = saneGetUsbDeviceInfoMap.find(info.serialNumber); + if (it != saneGetUsbDeviceInfoMap.end()) { + SCAN_HILOGD("AddFoundUsbScanner usbScanner deviceId:[%{public}s] of serialNumber:[%{public}s] has change", + saneGetUsbDeviceInfoMap[info.serialNumber].deviceId.c_str(), info.serialNumber.c_str()); + } +#endif + saneGetUsbDeviceInfoMap[info.serialNumber] = info; +#ifdef DEBUG_ENABLE + SCAN_HILOGD("AddFoundUsbScanner usbScanner deviceId:[%{public}s] of serialNumber:[%{public}s]", + saneGetUsbDeviceInfoMap[info.serialNumber].deviceId.c_str(), info.serialNumber.c_str()); +#endif + SCAN_HILOGI("AddFoundUsbScanner end model:[%{public}s]", info.model.c_str()); +} + +void ScanServiceAbility::AddFoundTcpScanner(ScanDeviceInfo &info) +{ + SCAN_HILOGI("AddFoundTcpScanner start: model:[%{public}s]", info.model.c_str()); + SyncScannerInfo(info); +#ifdef DEBUG_ENABLE + auto it = saneGetTcpDeviceInfoMap.find(info.serialNumber); + if (it != saneGetTcpDeviceInfoMap.end()) { + SCAN_HILOGD("AddFoundTcpScanner tcpScanner deviceId:[%{public}s] of serialNumber:[%{public}s] has change", + saneGetTcpDeviceInfoMap[info.serialNumber].deviceId.c_str(), info.serialNumber.c_str()); + } +#endif + saneGetTcpDeviceInfoMap[info.serialNumber] = info; +#ifdef DEBUG_ENABLE + SCAN_HILOGD("AddFoundTcpScanner tcpScanner deviceId:[%{public}s] of serialNumber:[%{public}s]", + saneGetTcpDeviceInfoMap[info.serialNumber].deviceId.c_str(), info.serialNumber.c_str()); +#endif + SCAN_HILOGI("AddFoundTcpScanner end: model:[%{public}s]", info.model.c_str()); +} + +#ifdef SANE_ENABLE +bool ScanServiceAbility::SetScannerInfo(const SANE_Device** ¤tDevice, ScanDeviceInfo &info) +{ + SCAN_HILOGI("SetScannerInfo start."); + const std::string nullString = ""; + if ((*currentDevice)->name != nullptr && (*currentDevice)->name != nullString) { + info.deviceId = (*currentDevice)->name; + } else { + SCAN_HILOGE("SaneGetScanner current_device's name is null."); + return false; + } + if ((*currentDevice)->vendor != nullptr) { + info.manufacturer = (*currentDevice)->vendor; + } + if ((*currentDevice)->model != nullptr) { + info.model = (*currentDevice)->model; + } + if ((*currentDevice)->type != nullptr) { + info.deviceType = (*currentDevice)->type; + } +#ifdef DEBUG_ENABLE + SCAN_HILOGD("SetScannerInfo deviceId:[%{public}s] manufacturer:[%{public}s]" + "model:[%{public}s] deviceType:[%{public}s]", + info.deviceId.c_str(), info.manufacturer.c_str(), info.model.c_str(), info.deviceType.c_str()); +#endif + SCAN_HILOGI("SetScannerInfo end."); + return true; +} +#endif + +#ifdef SANE_ENABLE +void ScanServiceAbility::SaneGetScanner() +{ + const SANE_Device **deviceList; + SANE_Status devicesStatus = SANE_STATUS_GOOD; + std::lock_guard autoLock(lock_); + g_scannerState = SCANNER_SEARCHING; + saneGetTcpDeviceInfoMap.clear(); + saneGetUsbDeviceInfoMap.clear(); + devicesStatus = sane_get_devices(&deviceList, SANE_FALSE); + if (devicesStatus != SANE_STATUS_GOOD) { + SCAN_HILOGE("sane_get_devices failed, reason: [%{public}s]", sane_strstatus(devicesStatus)); + g_scannerState = SCANNER_READY; + return; + } + for (const SANE_Device **currentDevice = deviceList; *currentDevice != nullptr; ++currentDevice) { + ScanDeviceInfo info; + if (!SetScannerInfo(currentDevice, info)) { + SCAN_HILOGE("SaneGetScanner SetScannerInfo failed"); + continue; + } + SetScannerSerialNumber(info); +#ifdef DEBUG_ENABLE + SCAN_HILOGD("SaneGetScanner serialNumber:[%{public}s] discoverMode:[%{public}s", + info.serialNumber.c_str(), info.discoverMode.c_str()); +#endif + if (info.serialNumber != "" && info.discoverMode == "USB") { + SCAN_HILOGI("SaneGetScanner AddFoundUsbScanner model:[%{public}s]", info.model.c_str()); + AddFoundUsbScanner(info); + } else if (info.serialNumber != "" && info.discoverMode == "TCP") { + SCAN_HILOGI("SaneGetScanner AddFoundTcpScanner model:[%{public}s]", info.model.c_str()); + AddFoundTcpScanner(info); + } else { + SCAN_HILOGE("SaneGetScanner SetScannerSerialNumber failed, model:[%{public}s]", info.model.c_str()); + } + } + for (auto &t : saneGetUsbDeviceInfoMap) { + SendDeviceInfo(t.second, SCAN_DEVICE_FOUND); + deviceInfos.emplace_back(t.second); + } + for (auto &t : saneGetTcpDeviceInfoMap) { + SendDeviceInfo(t.second, SCAN_DEVICE_FOUND); + deviceInfos.emplace_back(t.second); + } + g_scannerState = SCANNER_READY; +} +#endif + +int32_t ScanServiceAbility::GetScannerList() +{ + ManualStart(); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + return E_SCAN_NO_PERMISSION; + } + if (g_scannerState != SCANNER_READY) { + SCAN_HILOGW("is working"); + return E_SCAN_DEVICE_BUSY; + } + int32_t version = 0; + InitScan(version); + SCAN_HILOGD("ScanServiceAbility GetScannerList start"); + std::lock_guard autoLock(lock_); + // tcp + auto exec_tcp = [=]() { + ScanMdnsService::GetInstance().SetServiceType("_scanner._tcp"); + ScanMdnsService::GetInstance().onStartDiscoverService(); + }; + auto exec_sane_getscaner = [=]() { + deviceInfos.clear(); +#ifdef SANE_ENABLE + SaneGetScanner(); +#endif + std::string message = "EOF"; + SendDeviceSearchEnd(message, SCAN_DEVICE_FOUND); + SendDeviceList(deviceInfos, GET_SCANNER_DEVICE_LIST); + }; + serviceHandler_->PostTask(exec_tcp, ASYNC_CMD_DELAY); + serviceHandler_->PostTask(exec_sane_getscaner, ASYNC_CMD_DELAY); + SCAN_HILOGD("ScanServiceAbility GetScannerList end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::StopDiscover() +{ + ManualStart(); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGD("ScanServiceAbility StopDiscover start"); + + ScanMdnsService::GetInstance().onStopDiscoverService(); + + SCAN_HILOGD("ScanServiceAbility StopDiscover end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::OpenScanner(const std::string scannerId) +{ + ManualStart(); + std::lock_guard autoLock(lock_); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGI("ScanServiceAbility OpenScanner start"); + if (scannerId.empty()) { + SCAN_HILOGE("OpenScanner scannerId is empty"); + return E_SCAN_INVALID_PARAMETER; + } + if (g_scannerState != SCANNER_READY) { + SCAN_HILOGE("OpenScanner scannerState not ready"); + return E_SCAN_DEVICE_BUSY; + } +#ifdef SANE_ENABLE + SANE_Handle scannerHandle = 0; + SANE_String_Const scannerIdCstr = scannerId.c_str(); + SANE_Status status = sane_open(scannerIdCstr, &scannerHandle); + if (status != SANE_STATUS_GOOD) { + SCAN_HILOGE("sane_open failed, reason: [%{public}s], retry one times", sane_strstatus(status)); + g_hasOpenScannerFaild = true; + } + if (g_hasOpenScannerFaild == true) { + int32_t scanVersion = 0; + int32_t ret = ReInitScan(scanVersion); + if (ret != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceAbility OpenScanner ReInitScan failed !!!"); + return ret; + } + status = sane_open(scannerIdCstr, &scannerHandle); + g_hasOpenScannerFaild = false; + } + + if (status != SANE_STATUS_GOOD) { + SCAN_HILOGE("sane_open failed, reason: [%{public}s]", sane_strstatus(status)); + return ScanUtil::ConvertErro(status); + } + + scannerHandleList_[scannerId] = scannerHandle; +#endif + SCAN_HILOGI("ScanServiceAbility OpenScanner end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::CloseScanner(const std::string scannerId) +{ + ManualStart(); + std::lock_guard autoLock(lock_); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGI("ScanServiceAbility CloseScanner start"); + +#ifdef SANE_ENABLE + + auto scannerHandle = GetScanHandle(scannerId); + if (scannerHandle == nullptr) { + SCAN_HILOGE("ScanServiceAbility CloseScanner error exit"); + return E_SCAN_INVALID_PARAMETER; + } + scanTaskMap.clear(); + std::queue emptyQueue; + scanQueue.swap(emptyQueue); + sane_close(scannerHandle); + scannerHandleList_.erase(scannerId); +#endif + SCAN_HILOGI("ScanServiceAbility CloseScanner end"); + return E_SCAN_NONE; +} + +#ifdef SANE_ENABLE +void ScanServiceAbility::SetScanOptionDescriptor(ScanOptionDescriptor &desc, const SANE_Option_Descriptor *optionDesc) +{ + if (optionDesc->name != nullptr) { + desc.SetOptionName(std::string(optionDesc->name)); + } + if (optionDesc->title != nullptr) { + desc.SetOptionTitle(std::string(optionDesc->title)); + } + if (optionDesc->desc != nullptr) { + desc.SetOptionDesc(std::string(optionDesc->desc)); + } + desc.SetOptionType(optionDesc->type); + desc.SetOptionUnit(optionDesc->unit); + desc.SetOptionSize(optionDesc->size); + desc.SetOptionCap(optionDesc->cap); + desc.SetOptionConstraintType(optionDesc->constraint_type); +} +#endif + +#ifdef SANE_ENABLE +int32_t ScanServiceAbility::SelectScanOptionDesc( + const SANE_Option_Descriptor* &optionDesc, ScanOptionDescriptor &desc) +{ + if (optionDesc->constraint_type == SANE_CONSTRAINT_RANGE && optionDesc->constraint.range != nullptr) { + ScanRange scanRange; + scanRange.SetMinValue(optionDesc->constraint.range->min); + scanRange.SetMaxValue(optionDesc->constraint.range->max); + scanRange.SetQuantValue(optionDesc->constraint.range->quant); + desc.SetOptionConstraintRange(scanRange); + } else if (optionDesc->constraint_type == SANE_CONSTRAINT_WORD_LIST + && optionDesc->constraint.word_list != nullptr) { + std::vector optionConstraintNumber; + int sizeNumber = *(optionDesc->constraint.word_list) + 1; + for (int i = 0; i < sizeNumber; i++) { + SCAN_HILOGD("SANE_CONSTRAINT_WORD_LIST: %d", *(optionDesc->constraint.word_list + i)); + optionConstraintNumber.push_back(*(optionDesc->constraint.word_list + i)); + } + desc.SetOptionConstraintNumber(optionConstraintNumber); + } else if (optionDesc->constraint_type == SANE_CONSTRAINT_STRING_LIST + && optionDesc->constraint.string_list != nullptr) { + std::vector optionConstraintString; + const SANE_String_Const* stringList = optionDesc->constraint.string_list; + if (stringList == nullptr) { + SCAN_HILOGE("sane_get_option_descriptor stringList nullptr"); + return E_SCAN_INVALID_PARAMETER; + } + for (int i = 0; stringList[i] != NULL; i++) { + SCAN_HILOGD("SANE_CONSTRAINT_STRING_LIST: %s", stringList[i]); + optionConstraintString.push_back(std::string(stringList[i])); + } + optionConstraintString.push_back(string("null")); + desc.SetOptionConstraintString(optionConstraintString); + } + return E_SCAN_NONE; +} +#endif + +int32_t ScanServiceAbility::GetScanOptionDesc( + const std::string scannerId, const int32_t optionIndex, ScanOptionDescriptor &desc) +{ + ManualStart(); + std::lock_guard autoLock(lock_); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGD("ScanServiceAbility GetScanOptionDesc start"); + SCAN_HILOGI("optionIndex [%{public}d]", optionIndex); + +#ifdef SANE_ENABLE + auto scannerHandle = GetScanHandle(scannerId); + if (scannerHandle == nullptr) { + SCAN_HILOGE("ScanServiceAbility GetScanOptionDesc error exit"); + return E_SCAN_INVALID_PARAMETER; + } + const SANE_Option_Descriptor *optionDesc = sane_get_option_descriptor(scannerHandle, optionIndex); + if (optionDesc == nullptr) { + SCAN_HILOGE("sane_get_option_descriptor failed, ScannerId: [%{public}s]", scannerId.c_str()); + return E_SCAN_INVALID_PARAMETER; + } + SetScanOptionDescriptor(desc, optionDesc); + int32_t state = SelectScanOptionDesc(optionDesc, desc); + if (state != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceAbility GetScanOptionDesc error exit"); + return state; + } + +#endif + SCAN_HILOGD("ScanServiceAbility GetScanOptionDesc end"); + return E_SCAN_NONE; +} + +#ifdef SANE_ENABLE +int32_t ScanServiceAbility::ActionSetAuto(SANE_Handle &scannerHandle, const int32_t &optionIndex) +{ + SCAN_HILOGD("Set OpScanOptionValue SCAN_ACTION_SET_AUTO"); + SANE_Status status = SANE_STATUS_GOOD; + status = sane_control_option(scannerHandle, optionIndex, SANE_ACTION_SET_AUTO, 0, 0); + if (status != SANE_STATUS_GOOD) { + SCAN_HILOGE("sane_control_option failed, reason: [%{public}s]", sane_strstatus(status)); + return ScanUtil::ConvertErro(status); + } + return E_SCAN_NONE; +} +#endif + +#ifdef SANE_ENABLE +int32_t ScanServiceAbility::ActionGetValue(SANE_Handle &scannerHandle, ScanOptionValue &value, + const int32_t &optionIndex) +{ + SCAN_HILOGD("Set OpScanOptionValue SCAN_ACTION_GET_VALUE"); + SANE_Status status = SANE_STATUS_GOOD; + int32_t valueSize = value.GetValueSize() / sizeof(SANE_Word); + uint32_t bufSize = (value.GetStrValue().size() + 1) + > sizeof(int) ? (value.GetStrValue().size() + 1) : sizeof(int); + + void* saneValueBuf = malloc(bufSize); + ScanOptionValueType valueType = value.GetScanOptionValueType(); + if (!saneValueBuf) { + SCAN_HILOGE("malloc value buffer failed"); + return E_SCAN_GENERIC_FAILURE; + } + if (memset_s(saneValueBuf, bufSize, 0, bufSize) != 0) { + SCAN_HILOGE("memset_s failed"); + free(saneValueBuf); + saneValueBuf = nullptr; + return E_SCAN_GENERIC_FAILURE; + } + + status = sane_control_option(scannerHandle, optionIndex, SANE_ACTION_GET_VALUE, saneValueBuf, 0); + if (status != SANE_STATUS_GOOD) { + SCAN_HILOGE("sane_control_option failed, reason: [%{public}s]", sane_strstatus(status)); + return ScanUtil::ConvertErro(status); + } + + if (valueType == SCAN_VALUE_NUM) { + value.SetNumValue(*static_cast(saneValueBuf)); + } else if (valueType == SCAN_VALUE_NUM_LIST) { + std::vector numListValue; + for (int i = 0; i < valueSize; i++) { + numListValue.emplace_back(*(static_cast(saneValueBuf) + i)); + } + value.SetNumListValue(numListValue); + } else if (valueType == SCAN_VALUE_STR) { + value.SetStrValue(*static_cast(saneValueBuf)); + } else if (valueType == SCAN_VALUE_BOOL) { + value.SetBoolValue(*static_cast(saneValueBuf) > 0 ? true : false); + } + + free(saneValueBuf); + saneValueBuf = nullptr; + return E_SCAN_NONE; +} +#endif + +#ifdef SANE_ENABLE +int32_t ScanServiceAbility::ActionSetValue(SANE_Handle &scannerHandle, ScanOptionValue &value, + const int32_t &optionIndex, int32_t &info) +{ + SCAN_HILOGD("Set OpScanOptionValue SCAN_ACTION_SET_VALUE"); + SANE_Status status = SANE_STATUS_GOOD; + int32_t valueSize = value.GetValueSize() / sizeof(SANE_Word); + uint32_t bufSize = (value.GetStrValue().size() + 1) + > sizeof(int) ? (value.GetStrValue().size() + 1) : sizeof(int); + void* saneValueBuf = malloc(bufSize); + if (!saneValueBuf) { + SCAN_HILOGE("malloc value buffer failed"); + return E_SCAN_GENERIC_FAILURE; + } + if (memset_s(saneValueBuf, bufSize, 0, bufSize) != 0) { + SCAN_HILOGE("memset_s failed"); + free(saneValueBuf); + saneValueBuf = nullptr; + return E_SCAN_GENERIC_FAILURE; + } + ScanOptionValueType valueType = value.GetScanOptionValueType(); + if (valueType == SCAN_VALUE_NUM) { + int32_t numValue = value.GetNumValue(); + dpi = numValue > 0 && numValue < MAX_PICTURE_DPI ? numValue : 0; + *static_cast(saneValueBuf) = value.GetNumValue(); // + } else if (valueType == SCAN_VALUE_NUM_LIST) { + std::vector numListValue; + value.GetNumListValue(numListValue); + for (int i = 0; i < valueSize; i++) { + *(static_cast(saneValueBuf) + i) = numListValue[i]; + } + } else if (valueType == SCAN_VALUE_STR) { + SCAN_HILOGE("Set scanner mode:[%{public}s]", value.GetStrValue().c_str()); + strncpy_s(static_cast(saneValueBuf), bufSize, + value.GetStrValue().c_str(), value.GetStrValue().size()); + } else if (valueType == SCAN_VALUE_BOOL) { + *static_cast(saneValueBuf) = value.GetBoolValue() > 0 ? true : false; + } + status = sane_control_option(scannerHandle, optionIndex, + SANE_ACTION_SET_VALUE, saneValueBuf, &info); + if (status != SANE_STATUS_GOOD) { + SCAN_HILOGE("sane_control_option failed, reason: [%{public}s]", sane_strstatus(status)); + return ScanUtil::ConvertErro(status); + } + + free(saneValueBuf); + saneValueBuf = nullptr; + + return E_SCAN_NONE; +} +#endif + +int32_t ScanServiceAbility::OpScanOptionValue(const std::string scannerId, const int32_t optionIndex, + const ScanOptionOpType op, ScanOptionValue &value, int32_t &info) +{ + SCAN_HILOGD("ScanServiceAbility OpScanOptionValue start"); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGI("optionIndex [%{public}d]", optionIndex); + int32_t state = E_SCAN_NONE; +#ifdef SANE_ENABLE + if (g_hasIoFaild) { + SCAN_HILOGI("OpScanOptionValue try to reOpenScanner start"); + int32_t openRet = OpenScanner(scannerId); + if (openRet != E_SCAN_NONE) { + SCAN_HILOGE("OpScanOptionValue try to reOpenScanner failed"); + return E_SCAN_DEVICE_BUSY; + } + g_hasIoFaild = false; + } + + std::lock_guard autoLock(lock_); + + auto scannerHandle = GetScanHandle(scannerId); + if (scannerHandle == nullptr) { + SCAN_HILOGE("ScanServiceAbility OpScanOptionValue error exit"); + return E_SCAN_INVALID_PARAMETER; + } + SCAN_HILOGD("ScanServiceAbility OpScanOptionValue start to dump value"); + value.Dump(); + switch (op) { + case SCAN_ACTION_SET_AUTO: + state = ActionSetAuto(scannerHandle, optionIndex); + break; + case SCAN_ACTION_GET_VALUE: + state = ActionGetValue(scannerHandle, value, optionIndex); + break; + case SCAN_ACTION_SET_VALUE: + state = ActionSetValue(scannerHandle, value, optionIndex, info); + break; + default: + SCAN_HILOGE("ScanServiceAbility OpScanOptionValue not find ScanOptionOpType"); + break; + } + + if (state != E_SCAN_NONE) { + SCAN_HILOGE("ScanServiceAbility::OpScanOptionValue error exit"); + } + + SCAN_HILOGD("ScanServiceAbility OpScanOptionValue start to dump value"); + value.Dump(); +#endif + SCAN_HILOGD("ScanServiceAbility OpScanOptionValue end"); + return state; +} + + +int32_t ScanServiceAbility::GetScanParameters(const std::string scannerId, ScanParameters ¶) +{ + ManualStart(); + std::lock_guard autoLock(lock_); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGD("ScanServiceAbility GetScanParameters start"); + +#ifdef SANE_ENABLE + auto scannerHandle = GetScanHandle(scannerId); + if (scannerHandle == nullptr) { + SCAN_HILOGE("ScanServiceAbility GetScanParameters error exit"); + return E_SCAN_INVALID_PARAMETER; + } + SANE_Parameters parameters; + SANE_Status status = sane_get_parameters(scannerHandle, ¶meters); + if (status != SANE_STATUS_GOOD) { + SCAN_HILOGE("sane_get_parameters failed, reason: [%{public}s]", sane_strstatus(status)); + return ScanUtil::ConvertErro(status); + } + para.SetFormat((ScanFrame)parameters.format); + para.SetLastFrame((bool)parameters.last_frame); + para.SetBytesPerLine(parameters.bytes_per_line); + para.SetPixelsPerLine(parameters.pixels_per_line); + para.SetLines(parameters.lines); + para.SetDepth(parameters.depth); + para.Dump(); +#endif + SCAN_HILOGD("ScanServiceAbility GetScanParameters end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::GetSingleFrameFD(const std::string scannerId, uint32_t &size, uint32_t fd) +{ + ManualStart(); + std::lock_guard autoLock(lock_); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGD("ScanServiceAbility GetSingleFrameFD start"); + +#ifdef SANE_ENABLE + auto scannerHandle = GetScanHandle(scannerId); + if (scannerHandle == nullptr) { + SCAN_HILOGE("ScanServiceAbility GetSingleFrameFD error exit"); + return E_SCAN_INVALID_PARAMETER; + } +#ifdef SANE_ENABLE + auto exeFrameFD = this->getSingleFrameFDExe; + auto exe = [=]() { + exeFrameFD(scannerHandle, fd); + }; +#endif + serviceHandler_->PostTask(exe, ASYNC_CMD_DELAY); + +#endif + SCAN_HILOGD("ScanServiceAbility GetSingleFrameFD end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::CancelScan(const std::string scannerId) +{ + ManualStart(); + std::lock_guard autoLock(lock_); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGI("ScanServiceAbility CancelScan start"); +#ifdef SANE_ENABLE + auto scannerHandle = GetScanHandle(scannerId); + if (scannerHandle != nullptr) { + SCAN_HILOGW("start sane_cancel"); + sane_cancel(scannerHandle); + } + std::queue emptyQueue; + scanQueue.swap(emptyQueue); + if (g_scannerState == SCANNER_SCANING) { + SCAN_HILOGW("ScannerState change to SCANNER_CANCELING"); + g_scannerState = SCANNER_CANCELING; + } +#endif + SCAN_HILOGI("ScanServiceAbility CancelScan end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::SetScanIOMode(const std::string scannerId, const bool isNonBlocking) +{ + ManualStart(); + std::lock_guard autoLock(lock_); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGD("ScanServiceAbility SetScanIOMode start"); + +#ifdef SANE_ENABLE + auto scannerHandle = GetScanHandle(scannerId); + if (scannerHandle == nullptr) { + SCAN_HILOGE("ScanServiceAbility SetScanIOMode error exit"); + return E_SCAN_INVALID_PARAMETER; + } + SANE_Status status = sane_set_io_mode(scannerHandle, isNonBlocking); + if (status != SANE_STATUS_GOOD) { + SCAN_HILOGE("sane_set_io_mode failed, reason: [%{public}s]", sane_strstatus(status)); + return ScanUtil::ConvertErro(status); + } +#endif + SCAN_HILOGE("ScanServiceAbility SetScanIOMode end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::GetScanSelectFd(const std::string scannerId, int32_t &fd) +{ + ManualStart(); + std::lock_guard autoLock(lock_); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGD("ScanServiceAbility GetScanSelectFd start"); + +#ifdef SANE_ENABLE + auto scannerHandle = GetScanHandle(scannerId); + if (scannerHandle == nullptr) { + SCAN_HILOGE("ScanServiceAbility GetScanSelectFd error exit"); + return E_SCAN_INVALID_PARAMETER; + } + SANE_Status status = sane_get_select_fd(scannerHandle, &fd); + if (status != SANE_STATUS_GOOD) { + SCAN_HILOGE("sane_set_io_mode failed, reason: [%{public}s]", sane_strstatus(status)); + return ScanUtil::ConvertErro(status); + } +#endif + SCAN_HILOGE("ScanServiceAbility GetScanSelectFd end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::On(const std::string taskId, const std::string &type, const sptr &listener) +{ + std::string eventType = type; + if (taskId != "") { + eventType = NapiScanUtils::GetTaskEventId(taskId, type); + } + if (!CheckPermission(PERMISSION_NAME_PRINT)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + + SCAN_HILOGD("ScanServiceAbility::On started. type=%{public}s", eventType.c_str()); + std::lock_guard lock(apiMutex_); + if (registeredListeners_.find(eventType) == registeredListeners_.end()) { + const auto temp = registeredListeners_.insert(std::make_pair(eventType, listener)); + if (!temp.second) { + SCAN_HILOGE("ScanServiceAbility::On insert type=%{public}s object fail.", eventType.c_str()); + return E_SCAN_SERVER_FAILURE; + } + } else { + SCAN_HILOGD("ScanServiceAbility::On Replace listener."); + registeredListeners_[eventType] = listener; + } + SCAN_HILOGD("ScanServiceAbility::On end."); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::Off(const std::string taskId, const std::string &type) +{ + std::string eventType = type; + if (taskId != "") { + eventType = NapiScanUtils::GetTaskEventId(taskId, type); + } + if (!CheckPermission(PERMISSION_NAME_PRINT)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + + SCAN_HILOGD("ScanServiceAbility::Off started."); + std::lock_guard lock(apiMutex_); + auto iter = registeredListeners_.find(eventType); + if (iter != registeredListeners_.end()) { + SCAN_HILOGD("ScanServiceAbility::Off delete type=%{public}s object message.", eventType.c_str()); + registeredListeners_.erase(iter); + return E_SCAN_NONE; + } + return E_SCAN_INVALID_PARAMETER; +} + +void ScanServiceAbility::SendGetFrameResEvent(const bool isGetSucc, const int32_t sizeRead) +{ + std::lock_guard lock(apiMutex_); + SCAN_HILOGE("ScanServiceAbility::SendGetFrameSuccEvent SizeRead %{public}d", sizeRead); + auto eventIt = registeredListeners_.find(GET_FRAME_RES_EVENT_TYPE); + if (eventIt != registeredListeners_.end()) { + eventIt->second->OnGetFrameResCallback(isGetSucc, sizeRead); + } else { + SCAN_HILOGE("%{public}s event not register", GET_FRAME_RES_EVENT_TYPE.c_str()); + } +} + +void ScanServiceAbility::SendDeviceInfoTCP(const ScanDeviceInfoTCP &info, std::string event) +{ + std::lock_guard lock(apiMutex_); + + if (event.empty()) { + SCAN_HILOGE("SendDeviceInfoTCP parm has nullptr"); + return; + } + + auto eventIt = registeredListeners_.find(event); + if (eventIt != registeredListeners_.end()) { + SCAN_HILOGI("GetScannerListSendDeviceInfoTCP event has registered"); + eventIt->second->OnCallback(info.GetDeviceState(), info); + } else { + SCAN_HILOGE("GetScannerList SendDeviceInfoTCP event not register"); + } +} + +void ScanServiceAbility::SendDeviceInfo(const ScanDeviceInfo &info, std::string event) +{ + std::lock_guard lock(apiMutex_); + + if (event.empty()) { + SCAN_HILOGE("SendDeviceInfo parm has nullptr"); + return; + } + + auto eventIt = registeredListeners_.find(event); + if (eventIt != registeredListeners_.end()) { + SCAN_HILOGI("GetScannerList SendDeviceInfo event has registered"); + eventIt->second->OnCallback(info.GetDeviceState(), info); + } else { + SCAN_HILOGE("GetScannerList SendDeviceInfo event not register"); + } +} + +void ScanServiceAbility::SendDeviceList(std::vector &infos, std::string event) +{ + std::lock_guard lock(apiMutex_); + + if (event.empty()) { + SCAN_HILOGE("SendDeviceInfo parm has nullptr"); + return; + } + + auto eventIt = registeredListeners_.find(event); + if (eventIt != registeredListeners_.end()) { + SCAN_HILOGE("GetScannerList SendDeviceList event has registered"); + eventIt->second->OnGetDevicesList(infos); + } else { + SCAN_HILOGE("GetScannerList SendDeviceList event not register"); + } +} + +void ScanServiceAbility::SendDeviceInfoSync(const ScanDeviceInfoSync &info, std::string event) +{ + std::lock_guard lock(apiMutex_); + + if (event.empty()) { + SCAN_HILOGE("SendDeviceInfoSync parm has nullptr"); + return; + } + + auto eventIt = registeredListeners_.find(event); + if (eventIt != registeredListeners_.end()) { + SCAN_HILOGI("DealUsbDevStatusChange SendDeviceInfoSync event has registered"); + eventIt->second->OnCallbackSync(info.GetDeviceState(), info); + } else { + SCAN_HILOGE("DealUsbDevStatusChange SendDeviceInfoSync event not register"); + } +} + +void ScanServiceAbility::DisConnectUsbScanner(std::string serialNumber, std::string deviceId) +{ + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return; + } + SCAN_HILOGD("DisConnectUsbScanner start deviceId:%{public}s", deviceId.c_str()); + ScanDeviceInfoSync scanDeviceInfoSync; + scanDeviceInfoSync.serialNumber = serialNumber; + scanDeviceInfoSync.deviceId = deviceId; + scanDeviceInfoSync.discoverMode = "USB"; + scanDeviceInfoSync.syncMode = "delete"; + scanDeviceInfoSync.deviceState = 0; + SendDeviceInfoSync(scanDeviceInfoSync, SCAN_DEVICE_SYNC); +#ifdef DEBUG_ENABLE + SCAN_HILOGD("GetScannerList delete end serialNumber:%{public}s newDeviceId:%{public}s", + serialNumber.c_str(), deviceId.c_str()); +#endif +} + +void ScanServiceAbility::UpdateUsbScannerId(std::string serialNumber, std::string newDeviceId) +{ + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return; + } + SCAN_HILOGD("UpdateUsbScannerId start newDeviceId:%{public}s", newDeviceId.c_str()); + ScanDeviceInfoSync scanDeviceInfoSync; + scanDeviceInfoSync.serialNumber = serialNumber; + scanDeviceInfoSync.deviceId = newDeviceId; + scanDeviceInfoSync.discoverMode = "USB"; + scanDeviceInfoSync.syncMode = "update"; + scanDeviceInfoSync.deviceState = 0; + auto it = saneGetUsbDeviceInfoMap.find(serialNumber); + if (it != saneGetUsbDeviceInfoMap.end()) { + saneGetUsbDeviceInfoMap[serialNumber].deviceId = newDeviceId; + SendDeviceInfoSync(scanDeviceInfoSync, SCAN_DEVICE_SYNC); + } +#ifdef DEBUG_ENABLE + SCAN_HILOGD("GetScannerList UpdateUsbScannerId serialNumber:%{public}s newDeviceId:%{public}s", + serialNumber.c_str(), newDeviceId.c_str()); +#endif +} + +void ScanServiceAbility::SendInitEvent(int32_t &scanVersion, std::string event) +{ + std::lock_guard lock(apiMutex_); + + if (event.empty()) { + SCAN_HILOGE("SendInitEvent parm has nullptr"); + return; + } + + auto eventIt = registeredListeners_.find(event); + if (eventIt != registeredListeners_.end()) { + SCAN_HILOGE("InitScan SendInitEvent event has registered"); + eventIt->second->OnScanInitCallback(scanVersion); + } else { + SCAN_HILOGE("InitScan SendInitEvent event not register"); + } +} + +void ScanServiceAbility::SendDeviceSearchEnd(std::string &message, std::string event) +{ + std::lock_guard lock(apiMutex_); + + if (message.empty() || event.empty()) { + SCAN_HILOGE("SendDeviceSearchEnd parm has nullptr"); + return; + } + + auto eventIt = registeredListeners_.find(event); + if (eventIt != registeredListeners_.end()) { + SCAN_HILOGD("SCAN_DEVICE_FOUND event has registered"); + if (!(eventIt->second)) { + SCAN_HILOGE("eventIt null ptr error"); + return; + } + eventIt->second->OnSendSearchMessage(message); + } else { + SCAN_HILOGE("SCAN_DEVICE_FOUND event not register"); + } +} + +bool ScanServiceAbility::CheckPermission(const std::string &permissionName) +{ + AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); + TypeATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId); + if (tokenType == TOKEN_INVALID) { + SCAN_HILOGE("invalid token id %{public}d", tokenId); + return false; + } + int result = AccessTokenKit::VerifyAccessToken(tokenId, permissionName); + if (result != PERMISSION_GRANTED) { + if (permissionName == PERMISSION_NAME_PRINT) { + result = AccessTokenKit::VerifyAccessToken(tokenId, PERMISSION_NAME_PRINT_JOB); + } + SCAN_HILOGE("Current tokenId permission is %{public}d", result); + } + return result == PERMISSION_GRANTED; +} + +int32_t ScanServiceAbility::GetScannerState(int32_t &scannerState) +{ + ManualStart(); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGD("ScanServiceAbility GetScannerState start"); + scannerState = g_scannerState; + SCAN_HILOGD("ScanServiceAbility GetScannerState end, scannerState = [%{public}d]", scannerState); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::GetScanProgress(const std::string scannerId, ScanProgress &prog) +{ + ManualStart(); + std::lock_guard autoLock(lock_); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGI("ScanServiceAbility GetScanProgress start"); + +#ifdef SANE_ENABLE + if (scanQueue.empty()) { + SCAN_HILOGE("Not exist scan progress"); + if (g_hasIoFaild) { + return E_SCAN_INVALID_PARAMETER; + } + return E_SCAN_GENERIC_FAILURE; + } + int32_t frontPicId = scanQueue.front(); + SCAN_HILOGD("frontPicId : [%{public}d]", frontPicId); + auto frontProg = scanTaskMap[frontPicId]; + auto taskCode = frontProg.GetTaskCode(); + if (taskCode != E_SCAN_GOOD) { + SCAN_HILOGE("scanprogress exception occurred:[%{public}u]", taskCode); + scanQueue.pop(); + return taskCode; + } + auto scanProgress = frontProg.GetScanProgress(); + if (scanProgress == SCAN_PROGRESS_100) { + SCAN_HILOGE("get scan picture successfully!"); + prog = frontProg; + prog.Dump(); + scanQueue.pop(); + return E_SCAN_NONE; + } + auto nowTime = std::chrono::steady_clock::now(); + auto preTime = scanTaskMap[frontPicId].GetScanTime(); + auto elapsedTime = std::chrono::duration_cast(nowTime - preTime); + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(SCAN_PROGRESS_10, SCAN_PROGRESS_19); + int32_t randomNumber = dis(gen); + if (elapsedTime.count() >= 1 && scanProgress < SCAN_PROGRESS_80) { + scanTaskMap[frontPicId].SetScanProgress(scanProgress + randomNumber); + scanTaskMap[frontPicId].SetScanTime(nowTime); + } + prog = scanTaskMap[frontPicId]; + prog.Dump(); +#endif + SCAN_HILOGI("ScanServiceAbility GetScanProgress end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::AddScanner(const std::string& serialNumber, const std::string& discoverMode) +{ + ManualStart(); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGI("ScanServiceAbility AddScanner start"); + +#ifdef SANE_ENABLE + std::string uniqueId = discoverMode + serialNumber; + if (discoverMode == "USB") { + auto usbIt = saneGetUsbDeviceInfoMap.find(serialNumber); + if (usbIt != saneGetUsbDeviceInfoMap.end()) { + ScanSystemData::GetInstance().InsertScannerInfo(uniqueId, usbIt->second); + if (!ScanSystemData::GetInstance().SaveScannerMap()) { + SCAN_HILOGE("ScanServiceAbility AddScanner SaveScannerMap fail"); + return E_SCAN_GENERIC_FAILURE; + } + SendDeviceInfo(usbIt->second, SCAN_DEVICE_ADD); + } else { + SCAN_HILOGE("ScanServiceAbility AddScanner not found the USB scanner"); + } + } else if (discoverMode == "TCP") { + auto tcpIt = saneGetTcpDeviceInfoMap.find(serialNumber); + if (tcpIt != saneGetTcpDeviceInfoMap.end()) { + ScanSystemData::GetInstance().InsertScannerInfo(uniqueId, tcpIt->second); + if (!ScanSystemData::GetInstance().SaveScannerMap()) { + SCAN_HILOGE("ScanServiceAbility AddScanner SaveScannerMap fail"); + return E_SCAN_GENERIC_FAILURE; + } + SendDeviceInfo(tcpIt->second, SCAN_DEVICE_ADD); + } else { + SCAN_HILOGE("ScanServiceAbility AddScanner not found the TCP scanner"); + } + } else { + SCAN_HILOGE("ScanServiceAbility AddScanner invalid parameter"); + return E_SCAN_INVALID_PARAMETER; + } +#endif + SCAN_HILOGI("ScanServiceAbility AddScanner end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::DeleteScanner(const std::string& serialNumber, const std::string& discoverMode) +{ + ManualStart(); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGI("ScanServiceAbility DeleteScanner start"); + +#ifdef SANE_ENABLE + std::string uniqueId = discoverMode + serialNumber; + ScanDeviceInfo scannerInfo; + if (!ScanSystemData::GetInstance().QueryScannerInfoByUniqueId(uniqueId, scannerInfo)) { + SCAN_HILOGE("ScanServiceAbility DeleteScanner QueryScannerInfoByUniqueId fail"); + return E_SCAN_INVALID_PARAMETER; + } + if (!ScanSystemData::GetInstance().DeleteScannerInfo(uniqueId)) { + SCAN_HILOGE("ScanServiceAbility DeleteScanner DeleteScannerInfo fail"); + return E_SCAN_INVALID_PARAMETER; + } + if (!ScanSystemData::GetInstance().SaveScannerMap()) { + SCAN_HILOGE("ScanServiceAbility DeleteScanner SaveScannerMap fail"); + return E_SCAN_GENERIC_FAILURE; + } + SendDeviceInfo(scannerInfo, SCAN_DEVICE_DEL); +#endif + SCAN_HILOGI("ScanServiceAbility DeleteScanner end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::GetAddedScanner(std::vector& allAddedScanner) +{ + ManualStart(); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGI("ScanServiceAbility GetAddedScanner start"); +#ifdef SANE_ENABLE + ScanSystemData::GetInstance().GetAddedScannerInfoList(allAddedScanner); +#endif + SCAN_HILOGI("ScanServiceAbility GetAddedScanner end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::UpdateScannerName(const std::string& serialNumber, + const std::string& discoverMode, const std::string& deviceName) +{ + ManualStart(); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGI("ScanServiceAbility UpdateScannerName start"); + +#ifdef SANE_ENABLE + std::string uniqueId = discoverMode + serialNumber; + if (!ScanSystemData::GetInstance().UpdateScannerNameByUniqueId(uniqueId, deviceName)) { + SCAN_HILOGE("ScanServiceAbility UpdateScannerNameByUniqueId fail"); + return E_SCAN_INVALID_PARAMETER; + } + if (!ScanSystemData::GetInstance().SaveScannerMap()) { + SCAN_HILOGE("ScanServiceAbility UpdateScannerName SaveScannerMap fail"); + return E_SCAN_GENERIC_FAILURE; + } +#endif + SCAN_HILOGI("ScanServiceAbility UpdateScannerName end"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::AddPrinter(const std::string& serialNumber, const std::string& discoverMode) +{ + ManualStart(); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + auto exe = [=]() { + AddScanner(serialNumber, discoverMode); + }; + serviceHandler_->PostTask(exe, ASYNC_CMD_DELAY); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::OnStartScan(const std::string scannerId, const bool &batchMode) +{ + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + std::queue emptyQueue; + scanQueue.swap(emptyQueue); + int32_t status = StartScan(scannerId, batchMode_); + if (status != E_SCAN_NONE) { + SCAN_HILOGE("Start Scan error"); + return status; + } + batchMode_ = batchMode; + g_scannerState = SCANNER_SCANING; + auto exe = [=]() { + StartScanTask(scannerId); + }; + serviceHandler_->PostTask(exe, ASYNC_CMD_DELAY); + SCAN_HILOGI("StartScan successfully"); + return E_SCAN_NONE; +} + +int32_t ScanServiceAbility::StartScan(const std::string scannerId, const bool &batchMode) +{ + ManualStart(); + std::lock_guard autoLock(lock_); + if (!CheckPermission(PERMISSION_NAME_PRINT_JOB)) { + SCAN_HILOGE("no permission to access scan service"); + return E_SCAN_NO_PERMISSION; + } + SCAN_HILOGI("ScanServiceAbility StartScan start"); + +#ifdef SANE_ENABLE + if (g_scannerState == SCANNER_CANCELING) { + SCAN_HILOGE("scan task is canceling"); + return E_SCAN_DEVICE_BUSY; + } + auto scannerHandle = GetScanHandle(scannerId); + if (scannerHandle == nullptr) { + SCAN_HILOGE("ScanServiceAbility StartScan error exit"); + return E_SCAN_INVALID_PARAMETER; + } + SANE_Status saneStatus = sane_start(scannerHandle); + if (saneStatus != SANE_STATUS_GOOD) { + SCAN_HILOGE("sane_start failed, reason: [%{public}s], sane sane_cancel start", sane_strstatus(saneStatus)); + sane_cancel(scannerHandle); + auto it = scanTaskMap.find(nextPicId); + if (it != scanTaskMap.end() && it != scanTaskMap.begin()) { + it--; + (it->second).SetScanProgress(SCAN_PROGRESS_100); + } + return ScanUtil::ConvertErro(saneStatus); + } + ScanProgress prog; + scanTaskMap[nextPicId] = prog; + scanQueue.push(nextPicId); + scanTaskMap[nextPicId].SetPictureId(nextPicId); + auto nowTime = std::chrono::steady_clock::now(); + scanTaskMap[nextPicId].SetScanTime(nowTime); + nextPicId++; +#endif + SCAN_HILOGI("ScanServiceAbility StartScan end"); + return E_SCAN_NONE; +} + +void ScanServiceAbility::StartScanTask(const std::string scannerId) +{ + SCAN_HILOGI("ScanServiceAbility StartScanTask start, batchMode_ = [%{public}d]", batchMode_); + int32_t status = E_SCAN_NONE; + std::string file_name; + std::string output_file; + ScanProgress* scanProPtr = nullptr; + if (batchMode_) { + SCAN_HILOGI("start batch mode scan"); + GeneratePictureBatch(scannerId, file_name, output_file, status, scanProPtr); + } else { + SCAN_HILOGI("start single mode scan"); + GeneratePictureSingle(scannerId, file_name, output_file, status, scanProPtr); + } + if (status != E_SCAN_NONE) { + SCAN_HILOGI("ScanServiceAbility StartScanTask error, errorcode = [%{public}d]", status); + } + g_scannerState = SCANNER_READY; + SCAN_HILOGI("ScanServiceAbility StartScanTask end"); +} + +void ScanServiceAbility::GeneratePictureBatch(const std::string &scannerId, std::string &file_name, + std::string &output_file, int32_t &status, ScanProgress* &scanProPtr) +{ + bool firstScan = true; + do { + if (!firstScan) { + SCAN_HILOGE("not first scan"); + status = StartScan(scannerId, batchMode_); + if (status != E_SCAN_NONE) { + SCAN_HILOGE("ScanTask restart fail"); + break; + } + auto it = scanTaskMap.find(nextPicId - 2); // nextPicId - 2 is to find a PicId before nowScanId. + (it->second).SetIsFinal(false); + it->second.SetScanProgress(SCAN_PROGRESS_100); + SCAN_HILOGE("ScanTask restart success, status:[%{public}d]", status); + } + auto it = scanTaskMap.find(nextPicId - 1); + int32_t nowScanId = it->first; + SCAN_HILOGI("scanQueue.size:[%{public}lu], scanTaskMap.size:[%{public}lu]", + static_cast(scanQueue.size()), static_cast(scanTaskMap.size())); + SCAN_HILOGI("nowScanId :[%{public}d], nextPicId: [%{public}d]", nowScanId, nextPicId); + file_name = "scan_tmp"+ std::to_string(nowScanId) +".jpg"; + std::string outputDir = "/data/service/el1/public/print_service/sane/tmp/"; + output_file = outputDir.append(file_name); + ofp = fopen(output_file.c_str(), "w"); + if (ofp == nullptr) { + SCAN_HILOGE("file [%{public}s] open fail", output_file.c_str()); + return ; + } + SCAN_HILOGI("create picture file [%{public}s] open", output_file.c_str()); + scanProPtr = &(scanTaskMap[nowScanId]); +#ifdef SANE_ENABLE + status = DoScanTask(scannerId, scanProPtr); +#endif + SCAN_HILOGE("ScanTask status:[%{public}d]", status); + auto fd = open(output_file.c_str(), O_RDONLY); + scanProPtr->SetScanPictureFd(fd); + firstScan = false; + } while (status == E_SCAN_EOF); + if (status == E_SCAN_NO_DOCS) { + auto it = scanTaskMap.find(nextPicId - 1); + it->second.SetScanProgress(SCAN_PROGRESS_100); + SCAN_HILOGI("ScanTask batch mode exit successfully [%{public}d]", status); + } else { + SCAN_HILOGE("ScanTask error exit[%{public}d]", status); + } +} + +void ScanServiceAbility::GeneratePictureSingle(const std::string &scannerId, std::string &file_name, + std::string &output_file, int32_t &status, ScanProgress* &scanProPtr) +{ + auto it = scanTaskMap.find(nextPicId - 1); + int32_t nowScanId = it->first; + SCAN_HILOGI("scanQueue.size:[%{public}lu], scanTaskMap.size:[%{public}lu]", + static_cast(scanQueue.size()), static_cast(scanTaskMap.size())); + SCAN_HILOGI("nowScanId :[%{public}d], nextPicId: [%{public}d]", nowScanId, nextPicId); + file_name = "scan_tmp"+ std::to_string(nowScanId) +".jpg"; + std::string outputDir = "/data/service/el1/public/print_service/sane/tmp/"; + output_file = outputDir.append(file_name); + ofp = fopen(output_file.c_str(), "w"); + if (ofp == nullptr) { + SCAN_HILOGE("file [%{public}s] open fail", output_file.c_str()); + return ; + } + SCAN_HILOGI("create picture file [%{public}s] open", output_file.c_str()); + scanProPtr = &(scanTaskMap[nowScanId]); +#ifdef SANE_ENABLE + status = DoScanTask(scannerId, scanProPtr); +#endif + SCAN_HILOGE("ScanTask status:[%{public}d]", status); + if (status == E_SCAN_EOF) { + auto fd = open(output_file.c_str(), O_RDONLY); + scanProPtr->SetScanPictureFd(fd); + scanProPtr->SetScanProgress(SCAN_PROGRESS_100); + } else { + SCAN_HILOGE("ScanTask error exit[%{public}d]", status); + } + if (ofp) { + fclose(ofp); + ofp = NULL; + } + { + std::lock_guard autoLock(lock_); +#ifdef SANE_ENABLE + SANE_Handle scannerHandle = GetScanHandle(scannerId); + if (scannerHandle != nullptr) { + SCAN_HILOGI("GeneratePictureSingle finished, doing sane_cancel"); + sane_cancel(scannerHandle); + } +#endif + } +} + +#ifdef SANE_ENABLE +int32_t ScanServiceAbility::DoScanTask(const std::string scannerId, ScanProgress* scanProPtr) +{ + int32_t first_frame = 1; + int32_t scanStatus = E_SCAN_NONE; + ScanParameters parm; + struct jpeg_error_mgr jerr; + do { + SCAN_HILOGI("start DoScanTask"); + if (!first_frame) { + scanStatus = StartScan(scannerId, batchMode_); + if (scanStatus != E_SCAN_NONE) { + SCAN_HILOGE("StartScanTask error exit after StartScan"); + return scanStatus; + } + } + scanStatus = GetScanParameters(scannerId, parm); + if (scanStatus != E_SCAN_NONE) { + SCAN_HILOGE("cyclicCallExe error exit after GetScanParameters"); + return scanStatus; + } + if (first_frame) { + scanStatus = WriteJpegHeader(parm, &jerr); + if (scanStatus != E_SCAN_NONE) { + SCAN_HILOGE("StartScanTask error exit after WriteJpegHeader"); + return scanStatus; + } + jpegbuf = (JSAMPLE*)malloc(parm.GetBytesPerLine()); + if (jpegbuf == nullptr) { + SCAN_HILOGE("jpegbuf malloc fail"); + return E_SCAN_GENERIC_FAILURE; + } + } + GetPicFrame(scannerId, scanProPtr, scanStatus, parm); + if (g_scannerState == SCANNER_CANCELING) { + SCAN_HILOGE("DoScanTask cancel"); + FREE_AND_NULLPTR(jpegbuf) + return E_SCAN_NONE; + } + if (scanStatus != E_SCAN_GOOD && scanStatus != E_SCAN_EOF) { + SCAN_HILOGE("get scanframe fail"); + FREE_AND_NULLPTR(jpegbuf) + return E_SCAN_NONE; + } + first_frame = 0; + } while (!(parm.GetLastFrame())); + jpeg_finish_compress(&cinfo); + fflush(ofp); + FREE_AND_NULLPTR(jpegbuf) + SCAN_HILOGI("end DoScanTask"); + return scanStatus; +} +#endif + +int32_t ScanServiceAbility::WriteJpegHeader(ScanParameters &parm, struct jpeg_error_mgr* jerr) +{ + ScanFrame format = parm.GetFormat(); + int32_t width = parm.GetPixelsPerLine(); + int32_t height = parm.GetLines(); + struct jpeg_compress_struct* cinfoPtr = &cinfo; + cinfoPtr->err = jpeg_std_error(jerr); + cinfoPtr->err->error_exit = [](j_common_ptr cinfo) { + g_isJpegWriteSuccess = false; + }; + g_isJpegWriteSuccess = true; + jpeg_create_compress(cinfoPtr); + jpeg_stdio_dest(cinfoPtr, ofp); + + cinfoPtr->image_width = (JDIMENSION)width; + cinfoPtr->image_height = (JDIMENSION)height; + if (format == SCAN_FRAME_RGB) { + cinfoPtr->in_color_space = JCS_RGB; + cinfoPtr->input_components = CHANNEL_THREE; + SCAN_HILOGI("generate RGB picture"); + } else if (format == SCAN_FRAME_GRAY) { + cinfoPtr->in_color_space = JCS_GRAYSCALE; + cinfoPtr->input_components = CHANNEL_ONE; + SCAN_HILOGI("generate gray picture"); + } else { + SCAN_HILOGE("not support this color"); + return E_SCAN_INVALID_PARAMETER; + } + jpeg_set_defaults(cinfoPtr); + cinfoPtr->density_unit = 1; + cinfoPtr->X_density = dpi; + cinfoPtr->Y_density = dpi; + cinfoPtr->write_JFIF_header = TRUE; + SCAN_HILOGI("width:[%{public}d],height:[%{public}d],dpi:[%{public}d]", width, height, dpi); + jpeg_set_quality(cinfoPtr, JPEG_QUALITY_SEVENTY_FIVE, TRUE); + jpeg_start_compress(cinfoPtr, TRUE); + cinfoPtr = nullptr; + SCAN_HILOGI("finish write jpegHeader"); + return E_SCAN_NONE; +} + +void ScanServiceAbility::CleanScanTask(const std::string &scannerId) +{ + CancelScan(scannerId); + scanTaskMap.clear(); + g_hasIoFaild = true; +} + +#ifdef SANE_ENABLE +void ScanServiceAbility::GetPicFrame(const std::string scannerId, ScanProgress *scanProPtr, + int32_t &scanStatus, ScanParameters &parm) +{ + int32_t curReadSize = 0; + int64_t totalBytes = 0; + int jpegrow = 0; + SANE_Handle scannerHandle = GetScanHandle(scannerId); + int64_t hundred_percent = ((int64_t)parm.GetBytesPerLine()) * parm.GetLines() * (((SANE_Frame)parm.GetFormat() + == SANE_FRAME_RGB || (SANE_Frame)parm.GetFormat() == SANE_FRAME_GRAY) ? CHANNEL_ONE : CHANNEL_THREE); + if (hundred_percent == 0) { + scanStatus = E_SCAN_INVAL; + return; + } + while (true) { + SANE_Status saneStatus = sane_read(scannerHandle, saneReadBuf, buffer_size, &curReadSize); + scanStatus = ScanUtil::ConvertErro(saneStatus); + totalBytes += (uint64_t)curReadSize; + int64_t progr = ((totalBytes * SCAN_PROGRESS_100) / hundred_percent); + if (progr >= SCAN_PROGRESS_100) + progr = SCAN_PROGRESS_100 - 1; + if (progr > (scanProPtr->GetScanProgress())) { + scanProPtr->SetScanProgress((int32_t)progr); + } + SCAN_HILOGI(" %{public}ld bytes ; scan progr:%{public}lu", totalBytes, progr); + if (g_scannerState == SCANNER_CANCELING) { + std::queue emptyQueue; + scanQueue.swap(emptyQueue); + nextPicId--; + scanTaskMap.erase(nextPicId); + scanStatus = E_SCAN_NONE; + SCAN_HILOGE("scan task is canceled"); + return; + } + if (saneStatus == SANE_STATUS_EOF) { + SCAN_HILOGI("Totally read %{public}ld bytes of frame data", totalBytes); + break; + } + if (saneStatus != SANE_STATUS_GOOD) { + SCAN_HILOGE("sane_read failed, reason: [%{public}s]", sane_strstatus(saneStatus)); + ScanErrorCode taskCode = ScanUtil::ConvertErro(saneStatus); + scanProPtr->SetTaskCode(taskCode); + if (taskCode == E_SCAN_IO_ERROR) { + CleanScanTask(scannerId); + } + break; + } + + if (!WritePicData(jpegrow, curReadSize, parm, scanProPtr)) { + SCAN_HILOGI("WritePicData fail"); + return; + } + } +} +#endif + +bool ScanServiceAbility::WritePicData(int &jpegrow, int32_t curReadSize, ScanParameters &parm, ScanProgress *scanProPtr) +{ + SCAN_HILOGI("start write jpeg picture data"); + constexpr int bit = 1; + int i = 0; + int left = curReadSize; + while (jpegrow + left >= parm.GetBytesPerLine()) { + if (!g_isJpegWriteSuccess) { + scanProPtr->SetTaskCode(E_SCAN_NO_MEM); + return false; + } + int ret = memcpy_s(jpegbuf + jpegrow, parm.GetBytesPerLine(), + saneReadBuf + i, parm.GetBytesPerLine() - jpegrow); + if (ret != ERR_OK) { + scanProPtr->SetTaskCode(E_SCAN_GENERIC_FAILURE); + SCAN_HILOGE("memcpy_s failed"); + return false; + } + if (parm.GetDepth() != 1) { + jpeg_write_scanlines(&cinfo, &jpegbuf, bit); + i += parm.GetBytesPerLine() - jpegrow; + left -= parm.GetBytesPerLine() - jpegrow; + jpegrow = 0; + continue; + } + constexpr int byteBits = 8; + JSAMPLE *buf8 = (JSAMPLE *)malloc(parm.GetBytesPerLine() * byteBits); + if (buf8 == nullptr) { + scanProPtr->SetTaskCode(E_SCAN_GENERIC_FAILURE); + SCAN_HILOGE("pic buffer malloc fail"); + return false; + } + for (int col1 = 0; col1 < parm.GetBytesPerLine(); col1++) { + for (int col8 = 0; col8 < byteBits; col8++) { + buf8[col1 * byteBits + col8] = jpegbuf[col1] & (1 << (byteBits - col8 - 1)) ? 0 : 0xff; + jpeg_write_scanlines(&cinfo, &buf8, byteBits); + } + } + free(buf8); + i += parm.GetBytesPerLine() - jpegrow; + left -= parm.GetBytesPerLine() - jpegrow; + jpegrow = 0; + } + memcpy_s(jpegbuf + jpegrow, parm.GetBytesPerLine(), saneReadBuf + i, left); + jpegrow += left; + SCAN_HILOGI("finish write jpeg picture data"); + return true; +} +} // namespace OHOS::Scan \ No newline at end of file diff --git a/services/scan_service/src/scan_service_stub.cpp b/services/scan_service/src/scan_service_stub.cpp new file mode 100644 index 0000000..9ddd29a --- /dev/null +++ b/services/scan_service/src/scan_service_stub.cpp @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_service_stub.h" +#include "ipc_skeleton.h" +#include "iscan_service.h" +#include "message_parcel.h" +#include "scan_constant.h" +#include "scan_log.h" +#include "scanner_info.h" +#include "scan_service_ability.h" + +namespace OHOS::Scan { +using namespace OHOS::HiviewDFX; + +ScanServiceStub::ScanServiceStub() +{ + cmdMap_[CMD_INIT_SCAN] = &ScanServiceStub::OnInitScan; + cmdMap_[CMD_EXIT_SCAN] = &ScanServiceStub::OnExitScan; + cmdMap_[CMD_GET_SCANNER_LIST] = &ScanServiceStub::OnGetScannerList; + cmdMap_[CMD_STOP_DISCOVER] = &ScanServiceStub::OnStopDiscover; + cmdMap_[CMD_OPEN_SCANNER] = &ScanServiceStub::OnOpenScanner; + cmdMap_[CMD_CLOSE_SCANNER] = &ScanServiceStub::OnCloseScanner; + cmdMap_[CMD_GET_SCAN_OPTION_DESC] = &ScanServiceStub::OnGetScanOptionDesc; + cmdMap_[CMD_OP_SCAN_OPTION_VALUE] = &ScanServiceStub::OnOpScanOptionValue; + cmdMap_[CMD_GET_SCAN_PARAMETERS] = &ScanServiceStub::OnGetScanParameters; + cmdMap_[CMD_START_SCAN] = &ScanServiceStub::OnStartScan; + cmdMap_[CMD_GET_SINGLE_FRAME_FD] = &ScanServiceStub::OnGetSingleFrameFD; + cmdMap_[CMD_CANCEL_SCAN] = &ScanServiceStub::OnCancelScan; + cmdMap_[CMD_SET_SCAN_IO_MODE] = &ScanServiceStub::OnSetScanIOMode; + cmdMap_[CMD_GET_SCAN_SELECT_FD] = &ScanServiceStub::OnGetScanSelectFd; + cmdMap_[CMD_GET_SCANNER_STATE] = &ScanServiceStub::OnGetScannerState; + cmdMap_[CMD_GET_SCAN_PROGRESS] = &ScanServiceStub::OnGetScanProgress; + cmdMap_[CMD_CONNECT_SCANNER] = &ScanServiceStub::OnConnectScanner; + cmdMap_[CMD_DISCONNECT_SCANNER] = &ScanServiceStub::OnDisConnectScanner; + cmdMap_[CMD_GET_CONNECTED_SCANNER] = &ScanServiceStub::OnGetConnectedScanner; + cmdMap_[CMD_UPDATE_SCANNER_NAME] = &ScanServiceStub::OnUpdateScannerName; + cmdMap_[CMD_ADD_PRINTER] = &ScanServiceStub::OnAddPrinter; + cmdMap_[CMD_ON] = &ScanServiceStub::OnEventOn; + cmdMap_[CMD_OFF] = &ScanServiceStub::OnEventOff; +} + +int32_t ScanServiceStub::OnRemoteRequest( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + SCAN_HILOGD("OnRemoteRequest started, code = %{public}d", code); + auto descriptorToken = data.ReadInterfaceToken(); + if (descriptorToken != GetDescriptor()) { + SCAN_HILOGE("Remote descriptor not the same as local descriptor."); + return E_SCAN_RPC_FAILURE; + } + + auto itFunc = cmdMap_.find(code); + if (itFunc != cmdMap_.end()) { + auto requestFunc = itFunc->second; + if (requestFunc != nullptr) { + return (this->*requestFunc)(data, reply); + } + } + SCAN_HILOGW("default case, need check."); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} + +bool ScanServiceStub::OnInitScan(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGI("ScanServiceStub::OnInitScan start"); + int32_t ret = E_SCAN_RPC_FAILURE; + int32_t scanVersion = 0; + { + std::lock_guard autoLock(lock_); + ScanServiceAbility::appCount_++; + SCAN_HILOGI("ScanServiceAbility::appCount_= %{public}d", ScanServiceAbility::appCount_); + } + if (isSaneInit_) { + SCAN_HILOGW("is isSaneInit_ed"); + return E_SCAN_NONE; + } + ret = InitScan(scanVersion); + isSaneInit_ = true; + reply.WriteInt32(ret); + reply.WriteInt32(scanVersion); + SCAN_HILOGI("ScanServiceStub::OnInitScan end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnExitScan(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGI("ScanServiceStub::OnExitScan start"); + auto scanServiceAbilityPtr = ScanServiceAbility::GetInstance(); + if (scanServiceAbilityPtr == nullptr) { + SCAN_HILOGE("scanServiceAbilityPtr is a nullptr"); + reply.WriteInt32(E_SCAN_GENERIC_FAILURE); + return false; + } + { + std::lock_guard autoLock(lock_); + ScanServiceAbility::appCount_ = ScanServiceAbility::appCount_-1 >= 0 ? ScanServiceAbility::appCount_-1 : 0; + SCAN_HILOGI("appCount = %{public}d", ScanServiceAbility::appCount_); + if (ScanServiceAbility::appCount_ == 0) { + SCAN_HILOGI("connected app number = 0, start unloadSA"); + scanServiceAbilityPtr->UnloadSystemAbility(); + } + } + reply.WriteInt32(E_SCAN_NONE); + SCAN_HILOGI("ScanServiceStub::OnExitScan end"); + return true; +} + +bool ScanServiceStub::OnGetScannerList(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGI("ScanServiceStub::OnGetScannerList start"); + int32_t ret = GetScannerList(); + reply.WriteInt32(ret); + SCAN_HILOGI("ScanServiceStub::OnGetScannerList end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnStopDiscover(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnStopDiscover start"); + int32_t ret = StopDiscover(); + reply.WriteInt32(ret); + SCAN_HILOGD("ScanServiceStub::OnStopDiscover end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnOpenScanner(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGI("ScanServiceStub::OnOpenScanner start"); + std::string scannerId = data.ReadString(); + int32_t ret = OpenScanner(scannerId); + reply.WriteInt32(ret); + SCAN_HILOGI("ScanServiceStub::OnOpenScanner end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnCloseScanner(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGI("ScanServiceStub::OnCloseScanner start"); + std::string scannerId = data.ReadString(); + int32_t ret = CloseScanner(scannerId); + reply.WriteInt32(ret); + SCAN_HILOGI("ScanServiceStub::OnCloseScanner end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnGetScanOptionDesc(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGI("ScanServiceStub::OnGetScanOptionDesc start"); + std::string scannerId = data.ReadString(); + int32_t optionIndex = data.ReadInt32(); + ScanOptionDescriptor desc; + int32_t ret = GetScanOptionDesc(scannerId, optionIndex, desc); + reply.WriteInt32(ret); + if (ret == E_SCAN_NONE) { + desc.Marshalling(reply); + } + SCAN_HILOGI("ScanServiceStub::OnGetScanOptionDesc end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnOpScanOptionValue(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnOpScanOptionValue start"); + std::string scannerId = data.ReadString(); + int32_t optionIndex = data.ReadInt32(); + ScanOptionOpType op = (ScanOptionOpType) data.ReadUint32(); + ScanOptionValue value; + auto scanOptionValue = ScanOptionValue::Unmarshalling(data); + value = *scanOptionValue; + int32_t info; + int32_t ret = OpScanOptionValue(scannerId, optionIndex, op, value, info); + reply.WriteInt32(ret); + if (ret == E_SCAN_NONE) { + value.Marshalling(reply); + if (op == SCAN_ACTION_GET_VALUE) { + reply.WriteInt32(info); + } + } + SCAN_HILOGD("ScanServiceStub::OnOpScanOptionValue end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnGetScanParameters(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnGetScanParameters start"); + std::string scannerId = data.ReadString(); + ScanParameters para; + int32_t ret = GetScanParameters(scannerId, para); + reply.WriteInt32(ret); + if (ret == E_SCAN_NONE) { + para.Marshalling(reply); + } + SCAN_HILOGD("ScanServiceStub::OnGetScanParameters end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnStartScan(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGI("ScanServiceStub::OnStartScan start"); + std::string scannerId = data.ReadString(); + bool batchMode = data.ReadBool(); + int32_t ret = ScanServiceAbility::GetInstance()->OnStartScan(scannerId, batchMode); + reply.WriteInt32(ret); + SCAN_HILOGI("ScanServiceStub::OnStartScan end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnGetSingleFrameFD(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnGetSingleFrameFD start"); + std::string scannerId = data.ReadString(); + int32_t fd = data.ReadFileDescriptor(); + uint32_t frameSize = 0; + int32_t ret = GetSingleFrameFD(scannerId, frameSize, fd); + reply.WriteInt32(ret); + if (ret == E_SCAN_NONE) { + reply.WriteInt32(frameSize); + } + SCAN_HILOGD("ScanServiceStub::OnGetSingleFrameFD end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnCancelScan(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGI("ScanServiceStub::OnCancelScan start"); + std::string scannerId = data.ReadString(); + int32_t ret = CancelScan(scannerId); + reply.WriteInt32(ret); + SCAN_HILOGI("ScanServiceStub::OnCancelScan end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnSetScanIOMode(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnSetScanIOMode start"); + std::string scannerId = data.ReadString(); + bool isNonBlocking = data.ReadBool(); + int32_t ret = SetScanIOMode(scannerId, isNonBlocking); + reply.WriteInt32(ret); + SCAN_HILOGD("ScanServiceStub::OnSetScanIOMode end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnGetScanSelectFd(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnGetScanSelectFd start"); + std::string scannerId = data.ReadString(); + int32_t fd = 0; + int32_t ret = GetScanSelectFd(scannerId, fd); + reply.WriteInt32(ret); + reply.WriteInt32(fd); + SCAN_HILOGD("ScanServiceStub::OnGetScanSelectFd end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnEventOn(MessageParcel &data, MessageParcel &reply) +{ + std::string taskId = data.ReadString(); + std::string type = data.ReadString(); + SCAN_HILOGD("ScanServiceStub::OnEventOn type=%{public}s ", type.c_str()); + if (type.empty()) { + SCAN_HILOGE("ScanServiceStub::OnEventOn type is null."); + reply.WriteInt32(E_SCAN_RPC_FAILURE); + return false; + } + sptr remote = data.ReadRemoteObject(); + if (remote == nullptr) { + SCAN_HILOGE("ScanServiceStub::OnEventOn remote is nullptr"); + reply.WriteInt32(E_SCAN_RPC_FAILURE); + return false; + } + sptr listener = iface_cast(remote); + if (listener.GetRefPtr() == nullptr) { + SCAN_HILOGE("ScanServiceStub::OnEventOn listener is null"); + reply.WriteInt32(E_SCAN_RPC_FAILURE); + return false; + } + int32_t ret = On(taskId, type, listener); + reply.WriteInt32(ret); + SCAN_HILOGD("ScanServiceStub::OnEventOn out"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnEventOff(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnEventOff in"); + std::string taskId = data.ReadString(); + std::string type = data.ReadString(); + SCAN_HILOGD("ScanServiceStub::OnEventOff type=%{public}s ", type.c_str()); + int32_t ret = Off(taskId, type); + reply.WriteInt32(ret); + SCAN_HILOGD("ScanServiceStub::OnEventOff out"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnGetScannerState(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnGetScannerState start"); + int32_t ret = E_SCAN_RPC_FAILURE; + int32_t scannerState = 0; + ret = GetScannerState(scannerState); + reply.WriteInt32(ret); + reply.WriteInt32(scannerState); + SCAN_HILOGD("ScanServiceStub::OnGetScannerState end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnGetScanProgress(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnGetScanProgress start"); + std::string scannerId = data.ReadString(); + ScanProgress prog; + int32_t ret = GetScanProgress(scannerId, prog); + reply.WriteInt32(ret); + if (ret == E_SCAN_NONE) { + prog.Marshalling(reply); + } + SCAN_HILOGD("ScanServiceStub::OnGetScanProgress end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnConnectScanner(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnConnectScanner start"); + std::string serialNumber = data.ReadString(); + std::string discoverMode = data.ReadString(); + int32_t ret = AddScanner(serialNumber, discoverMode); + reply.WriteInt32(ret); + SCAN_HILOGD("ScanServiceStub::OnConnectScanner end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnDisConnectScanner(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnDisConnectScanner start"); + std::string serialNumber = data.ReadString(); + std::string discoverMode = data.ReadString(); + int32_t ret = DeleteScanner(serialNumber, discoverMode); + reply.WriteInt32(ret); + SCAN_HILOGD("ScanServiceStub::OnDisConnectScanner end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnGetConnectedScanner(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnGetConnectedScanner start"); + std::vector allAddedScanner; + allAddedScanner.clear(); + int32_t ret = GetAddedScanner(allAddedScanner); + reply.WriteInt32(ret); + if (ret == E_SCAN_NONE) { + uint32_t size = static_cast(allAddedScanner.size()); + reply.WriteUint32(size); + for (uint32_t index = 0; index < size; index++) { + allAddedScanner[index].Marshalling(reply); + } + } + SCAN_HILOGD("ScanServiceStub::OnGetConnectedScanner end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnUpdateScannerName(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnUpdateScannerName start"); + std::string serialNumber = data.ReadString(); + std::string discoverMode = data.ReadString(); + std::string deviceName = data.ReadString(); + int32_t ret = UpdateScannerName(serialNumber, discoverMode, deviceName); + reply.WriteInt32(ret); + SCAN_HILOGD("ScanServiceStub::OnUpdateScannerName end"); + return ret == E_SCAN_NONE; +} + +bool ScanServiceStub::OnAddPrinter(MessageParcel &data, MessageParcel &reply) +{ + SCAN_HILOGD("ScanServiceStub::OnAddPrinter start"); + std::string serialNumber = data.ReadString(); + std::string discoverMode = data.ReadString(); + int32_t ret = AddPrinter(serialNumber, discoverMode); + reply.WriteInt32(ret); + SCAN_HILOGD("ScanServiceStub::OnAddPrinter end"); + return ret == E_SCAN_NONE; +} + +} // namespace OHOS::Scan diff --git a/services/scan_service/src/scan_system_data.cpp b/services/scan_service/src/scan_system_data.cpp new file mode 100644 index 0000000..3a4607b --- /dev/null +++ b/services/scan_service/src/scan_system_data.cpp @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include "scan_system_data.h" +#include "scan_log.h" + +namespace { +const std::string SCANNER_LIST_FILE = "/data/service/el1/public/print_service/sane/tmp/scanner_list.json"; +const std::string SCANNER_LIST_VERSION = "v1"; +} // namespace + +namespace OHOS { +namespace Scan { +bool ScanSystemData::CheckJsonObjectValue(const nlohmann::json& object) +{ + const std::vector keyList = {"deviceId", "manufacturer", "model", "deviceType", + "discoverMode", "serialNumber", "deviceName"}; + for (auto key : keyList) { + if (!object.contains(key) || !object[key].is_string()) { + SCAN_HILOGW("can not find %{public}s", key.c_str()); + return false; + } + } + return true; +} + +bool ScanSystemData::ParseScannerListJsonV1(nlohmann::json& jsonObject) +{ + if (!jsonObject.contains("scaner_list") || !jsonObject["scaner_list"].is_array()) { + SCAN_HILOGW("can not find scaner_list"); + return false; + } + for (auto &element : jsonObject["scaner_list"].items()) { + nlohmann::json object = element.value(); + if (!CheckJsonObjectValue(object)) { + continue; + } + ScanDeviceInfo scanDeviceInfo; + scanDeviceInfo.deviceId = object["deviceId"]; + scanDeviceInfo.manufacturer = object["manufacturer"]; + scanDeviceInfo.model = object["model"]; + scanDeviceInfo.deviceType = object["deviceType"]; + scanDeviceInfo.discoverMode = object["discoverMode"]; + scanDeviceInfo.serialNumber = object["serialNumber"]; + scanDeviceInfo.deviceName = object["deviceName"]; + std::string uniqueId = scanDeviceInfo.discoverMode + scanDeviceInfo.serialNumber; + InsertScannerInfo(uniqueId, scanDeviceInfo); + } + return true; +} + +bool ScanSystemData::Init() +{ + addedScannerMap_.clear(); + std::ifstream ifs(SCANNER_LIST_FILE.c_str(), std::ios::in | std::ios::binary); + if (!ifs.is_open()) { + SCAN_HILOGW("open scanner list file fail"); + return false; + } + std::string fileData((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); + ifs.close(); + if (!nlohmann::json::accept(fileData)) { + SCAN_HILOGW("json accept fail"); + return false; + } + nlohmann::json jsonObject = nlohmann::json::parse(fileData); + if (!jsonObject.contains("version") || !jsonObject["version"].is_string()) { + SCAN_HILOGW("can not find version"); + return false; + } + std::string version = jsonObject["version"].get(); + SCAN_HILOGI("json version: %{public}s", version.c_str()); + if (version == SCANNER_LIST_VERSION) { + return ParseScannerListJsonV1(jsonObject); + } + return false; +} + +void ScanSystemData::InsertScannerInfo(const std::string &uniqueId, const ScanDeviceInfo &scannerInfo) +{ + std::lock_guard autoLock(addedScannerMapLock_); + auto iter = addedScannerMap_.find(uniqueId); + if (iter == addedScannerMap_.end() || iter->second == nullptr) { + SCAN_HILOGI("insert new scanner"); + addedScannerMap_[uniqueId] = std::make_shared(scannerInfo); + } else { + SCAN_HILOGI("update exist scanner"); + iter->second->deviceId = scannerInfo.deviceId; + iter->second->manufacturer = scannerInfo.manufacturer; + iter->second->model = scannerInfo.model; + iter->second->deviceType = scannerInfo.deviceType; + iter->second->serialNumber = scannerInfo.serialNumber; + iter->second->deviceName = scannerInfo.deviceName; + } +} + +bool ScanSystemData::DeleteScannerInfo(const std::string &uniqueId) +{ + std::lock_guard autoLock(addedScannerMapLock_); + auto iter = addedScannerMap_.find(uniqueId); + if (iter != addedScannerMap_.end()) { + addedScannerMap_.erase(uniqueId); + } else { + SCAN_HILOGE("ScanSystemData delete connected scanner fail"); + return false; + } + return true; +} + +bool ScanSystemData::UpdateScannerNameByUniqueId(const std::string &uniqueId, const std::string &deviceName) +{ + std::lock_guard autoLock(addedScannerMapLock_); + auto iter = addedScannerMap_.find(uniqueId); + if (iter != addedScannerMap_.end()) { + iter->second->deviceName = deviceName; + } else { + SCAN_HILOGE("ScanSystemData UpdateScannerNameByUniqueId fail"); + return false; + } + return true; +} + +bool ScanSystemData::UpdateScannerInfoByUniqueId(const std::string &uniqueId, const ScanDeviceInfo &scannerInfo) +{ + std::lock_guard autoLock(addedScannerMapLock_); + auto iter = addedScannerMap_.find(uniqueId); + if (iter != addedScannerMap_.end()) { + iter->second->deviceId = scannerInfo.deviceId; + iter->second->model = scannerInfo.model; + iter->second->deviceType = scannerInfo.deviceType; + iter->second->serialNumber = scannerInfo.serialNumber; + iter->second->deviceName = scannerInfo.deviceName; + return true; + } + SCAN_HILOGE("ScanSystemData UpdateScannerInfoByUniqueId not found scannerInfo"); + return false; +} + +bool ScanSystemData::QueryScannerNameByUniqueId(const std::string &uniqueId, std::string &deviceName) +{ + std::lock_guard autoLock(addedScannerMapLock_); + auto iter = addedScannerMap_.find(uniqueId); + if (iter != addedScannerMap_.end()) { + deviceName = iter->second->deviceName; + return true; + } + SCAN_HILOGW("QueryScannerNameByUniqueId fail"); + return false; +} + +bool ScanSystemData::QueryScannerInfoByUniqueId(const std::string &uniqueId, ScanDeviceInfo &scannerInfo) +{ + std::lock_guard autoLock(addedScannerMapLock_); + for (auto iter = addedScannerMap_.begin(); iter != addedScannerMap_.end(); ++iter) { + auto info = iter->second; + if (info == nullptr) { + continue; + } + std::string iterUniqueId = info->discoverMode + info->serialNumber; + if (uniqueId == iterUniqueId) { + scannerInfo.deviceId = info->deviceId; + scannerInfo.manufacturer = info->manufacturer; + scannerInfo.model = info->model; + scannerInfo.deviceType = info->deviceType; + scannerInfo.discoverMode = info->discoverMode; + scannerInfo.serialNumber = info->serialNumber; + scannerInfo.deviceName = info->deviceName; + return true; + } + } + return false; +} + +void ScanSystemData::GetAddedScannerInfoList(std::vector &infoList) +{ + std::lock_guard autoLock(addedScannerMapLock_); + for (auto iter = addedScannerMap_.begin(); iter != addedScannerMap_.end(); ++iter) { + if (iter->second != nullptr) { + infoList.push_back(*(iter->second)); + } + } +} + +bool ScanSystemData::SaveScannerMap() +{ + int32_t fd = open(SCANNER_LIST_FILE.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0740); + SCAN_HILOGD("SaveScannerMap fd: %{public}d", fd); + if (fd < 0) { + SCAN_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str()); + close(fd); + return false; + } + nlohmann::json scannerMapJson = nlohmann::json::array(); + { + std::lock_guard autoLock(addedScannerMapLock_); + for (auto iter = addedScannerMap_.begin(); iter != addedScannerMap_.end(); ++iter) { + auto info = iter->second; + if (info == nullptr) { + continue; + } + nlohmann::json scannerJson = nlohmann::json::object(); + scannerJson["deviceId"] = info->deviceId; + scannerJson["manufacturer"] = info->manufacturer; + scannerJson["model"] = info->model; + scannerJson["deviceType"] = info->deviceType; + scannerJson["discoverMode"] = info->discoverMode; + scannerJson["serialNumber"] = info->serialNumber; + scannerJson["deviceName"] = info->deviceName; + scannerMapJson.push_back(scannerJson); + } + } + nlohmann::json jsonObject; + jsonObject["version"] = SCANNER_LIST_VERSION; + jsonObject["scaner_list"] = scannerMapJson; + std::string jsonString = jsonObject.dump(); + size_t jsonLength = jsonString.length(); + auto writeLength = write(fd, jsonString.c_str(), jsonLength); + close(fd); + SCAN_HILOGI("SaveScannerMap finished"); + if (writeLength < 0) { + return false; + } + return (size_t)writeLength == jsonLength; +} +} // namespace Scan +} // namespace OHOS \ No newline at end of file diff --git a/services/scan_service/src/scan_usb_manager.cpp b/services/scan_service/src/scan_usb_manager.cpp new file mode 100644 index 0000000..4cac2ab --- /dev/null +++ b/services/scan_service/src/scan_usb_manager.cpp @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scan_usb_manager.h" +#include "scan_log.h" +#include "usb_errors.h" +#include "scan_constant.h" +#include "scan_service_ability.h" +#include "cJSON.h" +#include "common_event_data.h" +#include "common_event_manager.h" +#include "common_event_support.h" + +namespace OHOS::Scan { +using namespace std; +using namespace OHOS; +using namespace OHOS::USB; + +ScanUsbManager::ScanUsbManager() +{} + +ScanUsbManager::~ScanUsbManager() +{} + +void ScanUsbManager::Init() +{ + if (isInit) { + return; + } + SCAN_HILOGI("listen usb device attach detach"); + EventFwk::MatchingSkills matchingSkills; + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USB_DEVICE_ATTACHED); + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USB_DEVICE_DETACHED); + EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills); + subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON); + + usbDevStatusListener = std::make_shared(subscribeInfo); + if (!EventFwk::CommonEventManager::SubscribeCommonEvent(usbDevStatusListener)) { + SCAN_HILOGE("subscribe common event failed"); + return; + } + isInit = true; +} + +void ScanUsbManager::RefreshUsbDevice() +{ + SCAN_HILOGI("RefreshDeviceList start"); + vector devlist; + auto &UsbSrvClient = UsbSrvClient::GetInstance(); + auto ret = UsbSrvClient.GetDevices(devlist); + if (ret != ERR_OK) { + SCAN_HILOGE("RefreshDeviceList GetDevices failed with ret = %{public}d.", ret); + return; + } + SCAN_HILOGI("RefreshDeviceList DeviceList size = %{public}u.", devlist.size()); + for (auto dev : devlist) { + SCAN_HILOGI("RefreshDeviceList dev.GetName() %{public}s ", dev.GetName().c_str()); + std::string serialNumber = GetSerialNumber(dev); + SCAN_HILOGI("RefreshDeviceList serialNumber = %{public}s.", serialNumber.c_str()); + ScanServiceAbility::usbSnMap[dev.GetName()] = serialNumber; + } +} + +std::string ScanUsbManager::GetSerialNumber(UsbDevice &usbDevice) +{ + auto &UsbSrvClient = UsbSrvClient::GetInstance(); + SCAN_HILOGI("getSerialNumber dev.GetName() = %{public}s.", usbDevice.GetName().c_str()); + USBDevicePipe usbDevicePipe; + int32_t openDeviceRet = UsbSrvClient.OpenDevice(usbDevice, usbDevicePipe); + if (openDeviceRet != UEC_OK) { + SCAN_HILOGE("openDevice fail with ret = %{public}d", openDeviceRet); + return ""; + } + SCAN_HILOGI("openDevice ret = %{public}d", openDeviceRet); + std::string serialNumber = GetDeviceSerialNumber(usbDevicePipe); + return serialNumber; +} + +std::string ScanUsbManager::GetDeviceSerialNumber(USBDevicePipe &usbDevicePipe) +{ + auto &UsbSrvClient = UsbSrvClient::GetInstance(); + SCAN_HILOGI("Enter GetDeviceSerialNumber"); + uint16_t indexInStringDescriptor = USB_VALUE_DESCRIPTOR_INDEX_SERIAL_NUMBER; + uint8_t requestType = USB_REQUESTTYPE_DEVICE_TO_HOST; + uint8_t request = USB_REQUEST_GET_DESCRIPTOR; + uint16_t value = (USB_VALUE_DESCRIPTOR_TYPE_STRING << HTTP_COMMON_CONST_VALUE_8) | indexInStringDescriptor; + uint16_t index = USB_INDEX_LANGUAGE_ID_ENGLISH; + int32_t timeOut = HTTP_COMMON_CONST_VALUE_500; + const HDI::Usb::V1_0::UsbCtrlTransfer tctrl = {requestType, request, value, index, timeOut}; + std::vector bufferData(HTTP_COMMON_CONST_VALUE_100, 0); + int32_t ret = UsbSrvClient.ControlTransfer(usbDevicePipe, tctrl, bufferData); + if (ret != 0 || bufferData[0] == 0) { + SCAN_HILOGE("ControlTransfer failed ret = %{public}d, buffer length = %{public}d", ret, bufferData[0]); + return ""; + } + + std::vector arr((bufferData[0] - HTTP_COMMON_CONST_VALUE_2) / HTTP_COMMON_CONST_VALUE_2); + int arrIndex = 0; + for (int i = 2; i < bufferData[0];) { + arr[arrIndex++] = bufferData[i]; + i += HTTP_COMMON_CONST_VALUE_2; + } + std::string scannerInfo(arr.begin(), arr.end()); + SCAN_HILOGI("bufferData scanerInfo: %{public}s\n", scannerInfo.c_str()); + return scannerInfo; +} + +void ScanUsbManager::formatUsbPort(std::string &port) +{ + for (int size = port.size(); size < USB_DEVICEID_FIRSTID_LEN_3; size++) { + std::string newString = "0"; + newString.append(port); + port = newString; + } +} + +std::string ScanUsbManager::getNewDeviceId(std::string oldDeviceId, std::string usbDeviceName) +{ + std::string deviceIdHead = oldDeviceId.substr(0, oldDeviceId.find_last_of(":") + - USB_DEVICEID_FIRSTID_LEN_3); + std::string firstPort = usbDeviceName.substr(0, usbDeviceName.find("-")); + std::string secondPort = usbDeviceName.substr(usbDeviceName.find("-") + 1, usbDeviceName.size() - 1); + SCAN_HILOGI("firstPort = %{public}s, secondPort = %{public}s.", + firstPort.c_str(), secondPort.c_str()); + formatUsbPort(firstPort); + formatUsbPort(secondPort); + return deviceIdHead + firstPort + ":" + secondPort; +} + +void ScanUsbManager::UpdateUsbScannerId(std::string serialNumber, std::string usbDeviceName) +{ + if (serialNumber.empty() || usbDeviceName.empty()) { + SCAN_HILOGE("UpdateUsbScannerId serialNumber or usbDeviceName is null."); + return; + } + auto it = ScanServiceAbility::saneGetUsbDeviceInfoMap.find(serialNumber); + if (it != ScanServiceAbility::saneGetUsbDeviceInfoMap.end()) { +#ifdef DEBUG_ENABLE + SCAN_HILOGD("DealUsbDevStatusChange attached find out usbDeviceName = %{public}s, serialNumber = %{public}s " + "deviceId = %{public}s.", + usbDeviceName.c_str(), serialNumber.c_str(), it->second.deviceId.c_str()); +#endif + std::string newDeviceId = getNewDeviceId(it->second.deviceId, usbDeviceName); + ScanServiceAbility::GetInstance()->UpdateUsbScannerId(serialNumber, newDeviceId); + for (auto &t : ScanServiceAbility::usbSnMap) { + if (t.second == serialNumber) { + SCAN_HILOGD("UpdateUsbScannerId usbSnMap erase %{public}s.", t.first.c_str()); + ScanServiceAbility::usbSnMap.erase(t.first); + break; + } + } + ScanServiceAbility::usbSnMap[usbDeviceName] = serialNumber; + } +} + +void ScanUsbManager::DisConnectUsbScanner(std::string usbDeviceName) +{ + if (usbDeviceName.empty()) { + SCAN_HILOGE("DisConnectUsbScanner usbDeviceName is null."); + return; + } + auto usbSnMapit = ScanServiceAbility::usbSnMap.find(usbDeviceName); + if (usbSnMapit != ScanServiceAbility::usbSnMap.end()) { + std::string serialNumber = usbSnMapit->second; + if (!serialNumber.empty()) { + auto it = ScanServiceAbility::saneGetUsbDeviceInfoMap.find(serialNumber); + if (it != ScanServiceAbility::saneGetUsbDeviceInfoMap.end()) { + ScanServiceAbility::GetInstance()->DisConnectUsbScanner(serialNumber, it->second.deviceId); + ScanServiceAbility::usbSnMap.erase(usbDeviceName); + } + } +#ifdef DEBUG_ENABLE + SCAN_HILOGD("DealUsbDevStatusChange detached usbDeviceName = %{public}s, serialNumber = %{public}s. end", + usbDeviceName.c_str(), serialNumber.c_str()); +#endif + } +} + +void ScanUsbManager::DealUsbDevStatusChange(const std::string &devStr, bool isAttach) +{ + SCAN_HILOGD("DealUsbDevStatusChange isAttach = %{public}d, devStr = %{public}s.", + isAttach, devStr.c_str()); + cJSON *devJson = cJSON_Parse(devStr.c_str()); + if (!devJson) { + SCAN_HILOGE("Create devJson error"); + return; + } + UsbDevice *dev = new UsbDevice(devJson); + std::string usbDeviceName = dev->GetName(); + if (!isAttach) { + DisConnectUsbScanner(usbDeviceName); + } else { + std::string serialNumber = GetSerialNumber(*dev); + if (!serialNumber.empty()) { + UpdateUsbScannerId(serialNumber, usbDeviceName); + } + } + cJSON_Delete(devJson); + delete dev; + dev = nullptr; +} + +} \ No newline at end of file diff --git a/utils/include/scan_constant.h b/utils/include/scan_constant.h new file mode 100644 index 0000000..0b1cc7b --- /dev/null +++ b/utils/include/scan_constant.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_CONSTANT_H +#define SCAN_CONSTANT_H + +#include + +namespace OHOS::Scan { + +#define SCAN_RET_NONE +#define SCAN_MAX_COUNT 1000 + +#define SCAN_ASSERT_BASE(env, assertion, message, retVal) \ + do { \ + if (!(assertion)) { \ + SCAN_HILOGE(message); \ + return retVal; \ + } \ + } while (0) + +#define SCAN_ASSERT(env, assertion, message) SCAN_ASSERT_BASE(env, assertion, message, nullptr) + +#define SCAN_ASSERT_RETURN_VOID(env, assertion, message) SCAN_ASSERT_BASE(env, assertion, message, SCAN_RET_NONE) + +#define SCAN_CALL_BASE(env, theCall, retVal) \ + do { \ + if ((theCall) != napi_ok) { \ + return retVal; \ + } \ + } while (0) + +#define SCAN_CALL(env, theCall) SCAN_CALL_BASE(env, theCall, nullptr) + +#define SCAN_CALL_RETURN_VOID(env, theCall) SCAN_CALL_BASE(env, theCall, SCAN_RET_NONE) + +#define DELETE_AND_NULLIFY(ptr) \ + if ((ptr) != nullptr) { \ + delete (ptr); \ + (ptr) = nullptr; \ + } + +#define DELETE_ARRAY_AND_NULLIFY(ptr) \ + if ((ptr) != nullptr) { \ + delete[] (ptr); \ + (ptr) = nullptr; \ + } + +#define FREE_AND_NULLPTR(ptr) \ + if ((ptr) != nullptr) { \ + free (ptr); \ + (ptr) = nullptr; \ + } + +#define INIT_CALLBACK_PARAMS \ + uv_loop_s *loop = nullptr; \ + bool flag = true; \ + napi_get_uv_event_loop(env_, &loop); \ + CHECK_AND_CREATE(loop, "Failed to get uv event loop", flag); \ + uv_work_t *work = nullptr; \ + CallbackParam *param = nullptr; \ + CallbackContext *context = nullptr; \ + CreateCallbackParam(work, param, context, flag) \ + +#define CHECK_AND_CREATE(pointer, error_message, flag) \ + if ((pointer) == nullptr) { \ + SCAN_HILOGE(error_message); \ + (flag) = false; \ + } + +#define CREATE_PRC_MESSAGE \ + MessageParcel data; \ + MessageParcel reply; \ + MessageOption option; \ + data.WriteInterfaceToken(GetDescriptor()) \ + +#define CHECK_IS_EXCEED_SCAN_RANGE_BASE(count, retVal) \ + do { \ + if ((count) > SCAN_MAX_COUNT) { \ + SCAN_HILOGW("input val is exceed scan max range:%{public}d", SCAN_MAX_COUNT); \ + return retVal; \ + } \ + } while (0) + +#define CHECK_IS_EXCEED_SCAN_RANGE(count) CHECK_IS_EXCEED_SCAN_RANGE_BASE(count, nullptr) +#define CHECK_IS_EXCEED_SCAN_RANGE_BOOL(count) CHECK_IS_EXCEED_SCAN_RANGE_BASE(count, false) +#define CHECK_IS_EXCEED_SCAN_RANGE_VOID(count) CHECK_IS_EXCEED_SCAN_RANGE_BASE(count, E_SCAN_NONE) +#define CHECK_IS_EXCEED_SCAN_RANGE_INT(count) CHECK_IS_EXCEED_SCAN_RANGE_BASE(count, E_SCAN_INVALID_PARAMETER) + +enum ScanErrorCode { + // FWK ERROR + E_SCAN_NONE = 0, // no error + E_SCAN_NO_PERMISSION = 201, // no permission + E_SCAN_INVALID_PARAMETER = 401, // invalid parameter + E_SCAN_GENERIC_FAILURE = 13100001, // generic failure of scan + E_SCAN_RPC_FAILURE = 13100002, // RPC failure + E_SCAN_SERVER_FAILURE = 13100003, // failure of scan service + + // DEVICE ERROR + E_SCAN_GOOD = 13200000, /* everything A-OK */ + E_SCAN_UNSUPPORTED = 13200001, /* operation is not supported */ + E_SCAN_CANCELLED = 13200002, /* operation was cancelled */ + E_SCAN_DEVICE_BUSY = 13200003, /* device is busy; try again later */ + E_SCAN_INVAL = 13200004, /* data is invalid (includes no dev at open) */ + E_SCAN_EOF = 13200005, /* no more data available (end-of-file) */ + E_SCAN_JAMMED = 13200006, /* document feeder jammed */ + E_SCAN_NO_DOCS = 13200007, /* document feeder out of documents */ + E_SCAN_COVER_OPEN = 13200008, /* scanner cover is open */ + E_SCAN_IO_ERROR = 13200009, /* error during device I/O */ + E_SCAN_NO_MEM = 13200010, /* out of memory */ + E_SCAN_ACCESS_DENIED = 13200011, /* access to resource has been denied */ +}; + +const uint32_t SCAN_INVALID_ID = 0xFFFFFFFF; // -1 +const uint16_t USB_VALUE_DESCRIPTOR_INDEX_SERIAL_NUMBER = 0X03; +const uint8_t USB_REQUESTTYPE_DEVICE_TO_HOST = 0X80; +const uint8_t USB_REQUEST_GET_DESCRIPTOR = 0X06; +const uint16_t USB_VALUE_DESCRIPTOR_TYPE_STRING = 0X03; +const int HTTP_COMMON_CONST_VALUE_8 = 8; +const uint16_t USB_INDEX_LANGUAGE_ID_ENGLISH = 0X409; +const int HTTP_COMMON_CONST_VALUE_500 = 500; +const int HTTP_COMMON_CONST_VALUE_100 = 100; +const int HTTP_COMMON_CONST_VALUE_2 = 2; +const int USB_DEVICEID_FIRSTID_LEN_3 = 3; + +enum ScanFrame { + SCAN_FRAME_GRAY = 0, /* band covering human visual range */ + SCAN_FRAME_RGB = 1, /* pixel-interleaved red/green/blue bands */ + SCAN_FRAME_RED = 2, /* red band only */ + SCAN_FRAME_GREEN = 3, /* green band only */ + SCAN_FRAME_BLUE = 4, /* blue band only */ +}; + +enum ScanExtensionState { + SCAN_EXTENSION_UNLOAD, + SCAN_EXTENSION_LOADING, + SCAN_EXTENSION_LOADED, +}; + +enum ScanParamStatus { + SCAN_PARAM_NOT_SET, + SCAN_PARAM_OPT, + SCAN_PARAM_SET, +}; + +enum ScanOptionOpType { + SCAN_ACTION_GET_VALUE = 0, + SCAN_ACTION_SET_VALUE, + SCAN_ACTION_SET_AUTO +}; + +enum ScanOptionValueType { + SCAN_VALUE_NONE, + SCAN_VALUE_NUM, + SCAN_VALUE_NUM_LIST, + SCAN_VALUE_STR, + SCAN_VALUE_BOOL, +}; + +enum ScanConstraintType { + SCAN_CONSTRAINT_NONE = 0, + SCAN_CONSTRAINT_RANGE = 1, + SCAN_CONSTRAINT_WORD_LIST = 2, + SCAN_CONSTRAINT_STRING_LIST = 3, +}; + +enum ScannerState { + SCANNER_READY = 0, + SCANNER_SCANING = 1, + SCANNER_SEARCHING = 2, + SCANNER_CANCELING = 3, +}; +} // namespace OHOS::Scan +#endif // SCAN_CONSTANT_H diff --git a/utils/include/scan_log.h b/utils/include/scan_log.h new file mode 100644 index 0000000..f2846c3 --- /dev/null +++ b/utils/include/scan_log.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_LOG +#define SCAN_LOG + +#define CONFIG_SCAN_LOG +#ifdef CONFIG_SCAN_LOG +#include "hilog/log.h" + +#ifdef SCAN_HILOGF +#undef SCAN_HILOGF +#endif + +#ifdef SCAN_HILOGE +#undef SCAN_HILOGE +#endif + +#ifdef SCAN_HILOGW +#undef SCAN_HILOGW +#endif + +#ifdef SCAN_HILOGD +#undef SCAN_HILOGD +#endif + +#ifdef SCAN_HILOGI +#undef SCAN_HILOGI +#endif + +#define SCAN_LOG_TAG "scankit" +#define SCAN_LOG_DOMAIN 0xD001C00 + +#define SCAN_MAKE_FILE_NAME (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) + +#define SCAN_HILOGF(fmt, ...) \ + (void)HILOG_IMPL(LOG_CORE, LOG_FATAL, SCAN_LOG_DOMAIN, SCAN_LOG_TAG, "[%{public}s %{public}s %{public}d] " fmt, \ + SCAN_MAKE_FILE_NAME, __FUNCTION__, __LINE__, ##__VA_ARGS__) + +#define SCAN_HILOGE(fmt, ...) \ + (void)HILOG_IMPL(LOG_CORE, LOG_ERROR, SCAN_LOG_DOMAIN, SCAN_LOG_TAG, "[%{public}s %{public}s %{public}d] " fmt, \ + SCAN_MAKE_FILE_NAME, __FUNCTION__, __LINE__, ##__VA_ARGS__) + +#define SCAN_HILOGW(fmt, ...) \ + (void)HILOG_IMPL(LOG_CORE, LOG_WARN, SCAN_LOG_DOMAIN, SCAN_LOG_TAG, "[%{public}s %{public}s %{public}d] " fmt, \ + SCAN_MAKE_FILE_NAME, __FUNCTION__, __LINE__, ##__VA_ARGS__) + +#define SCAN_HILOGD(fmt, ...) \ + (void)HILOG_IMPL(LOG_CORE, LOG_DEBUG, SCAN_LOG_DOMAIN, SCAN_LOG_TAG, "[%{public}s %{public}s %{public}d] " fmt, \ + SCAN_MAKE_FILE_NAME, __FUNCTION__, __LINE__, ##__VA_ARGS__) + +#define SCAN_HILOGI(fmt, ...) \ + (void)HILOG_IMPL(LOG_CORE, LOG_INFO, SCAN_LOG_DOMAIN, SCAN_LOG_TAG, "[%{public}s %{public}s %{public}d] " fmt, \ + SCAN_MAKE_FILE_NAME, __FUNCTION__, __LINE__, ##__VA_ARGS__) + +#else + +#define SCAN_HILOGF(fmt, ...) +#define SCAN_HILOGE(fmt, ...) +#define SCAN_HILOGW(fmt, ...) +#define SCAN_HILOGD(fmt, ...) +#define SCAN_HILOGI(fmt, ...) +#endif // CONFIG_SCAN_LOG + +#endif /* SCAN_LOG */ diff --git a/utils/include/scan_util.h b/utils/include/scan_util.h new file mode 100644 index 0000000..3cbe2fa --- /dev/null +++ b/utils/include/scan_util.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCAN_UTIL_H +#define SCAN_UTIL_H + +#include +#include +#include +#include +#include +#include + +#include "scan_log.h" + +namespace OHOS::Scan { +class ScanUtil { +public: + #ifdef SANE_ENABLE + static ScanErrorCode ConvertErro(const SANE_Status status); + #endif +}; +#ifdef SANE_ENABLE +inline ScanErrorCode ScanUtil::ConvertErro(const SANE_Status status) +{ + return static_cast (status + E_SCAN_GOOD); +} +#endif +} // namespace OHOS::Scan + +#endif // SCAN_UTIL_H