1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ohprint.h"
17 
18 #include <algorithm>
19 #include <map>
20 #include <memory>
21 #include <mutex>
22 #include <vector>
23 
24 #include "ability_context.h"
25 #include "iprint_adapter.h"
26 #include "print_attributes.h"
27 #include "print_manager_client.h"
28 #include "print_constant.h"
29 #include "print_log.h"
30 #include "ability_manager_client.h"
31 #include "print_util.h"
32 #include "print_callback.h"
33 #include "print_converter.h"
34 #include "print_helper.h"
35 #include "refbase.h"
36 #include "ui_extension_context.h"
37 
38 using namespace OHOS::Print;
39 
40 static Print_PrinterDiscoveryCallback printerDiscoverCallback = nullptr;
41 static Print_PrinterChangeCallback printerInfoCallback = nullptr;
42 
NativePrinterDiscoverFunction(uint32_t event,const PrinterInfo & info)43 static bool NativePrinterDiscoverFunction(uint32_t event, const PrinterInfo &info)
44 {
45     PRINT_HILOGD("NativePrinterDiscoverFunction event: %{public}d, printerId: [%{public}s]",
46         event, info.GetPrinterId().c_str());
47     if (printerDiscoverCallback == nullptr) {
48         PRINT_HILOGW("printerDiscoverCallback is null");
49         return false;
50     }
51     Print_PrinterInfo *nativePrinterInfo = ConvertToNativePrinterInfo(info);
52     if (nativePrinterInfo == nullptr) {
53         PRINT_HILOGW("nativePrinterInfo is null.");
54         return false;
55     }
56     printerDiscoverCallback(static_cast<Print_DiscoveryEvent>(event), nativePrinterInfo);
57     OH_Print_ReleasePrinterInfo(nativePrinterInfo);
58     return true;
59 }
60 
NativePrinterInfoFunction(uint32_t event,const PrinterInfo & info)61 static bool NativePrinterInfoFunction(uint32_t event, const PrinterInfo &info)
62 {
63     PRINT_HILOGD("NativePrinterInfoFunction event: [%{public}d, printerId: [%{public}s]",
64         event, info.GetPrinterId().c_str());
65     if (printerInfoCallback == nullptr) {
66         PRINT_HILOGW("printerInfoCallback is null");
67         return false;
68     }
69     Print_PrinterInfo *nativePrinterInfo = ConvertToNativePrinterInfo(info);
70     if (nativePrinterInfo == nullptr) {
71         PRINT_HILOGW("nativePrinterInfo is null.");
72         return false;
73     }
74     printerInfoCallback(static_cast<Print_PrinterEvent>(event), nativePrinterInfo);
75     OH_Print_ReleasePrinterInfo(nativePrinterInfo);
76     nativePrinterInfo = nullptr;
77     return true;
78 }
79 
GetUIContent(void * context)80 static OHOS::Ace::UIContent *GetUIContent(void *context)
81 {
82     if (context == nullptr) {
83         PRINT_HILOGE("input context is null.");
84         return nullptr;
85     }
86 
87     auto weakContext = static_cast<std::weak_ptr<OHOS::AbilityRuntime::Context>*>(context);
88     if (weakContext == nullptr) {
89         PRINT_HILOGE("cast context to weak is null.");
90         return nullptr;
91     }
92     auto sharedContext = weakContext->lock();
93     auto abilityContext =
94         OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(sharedContext);
95     if (abilityContext != nullptr) {
96         PRINT_HILOGD("get ability ui content.");
97         return abilityContext->GetUIContent();
98     }
99     auto uiExtensionContext =
100         OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::UIExtensionContext>(sharedContext);
101     if (uiExtensionContext != nullptr) {
102         PRINT_HILOGD("get ui extension ui content.");
103         return uiExtensionContext->GetUIContent();
104     }
105     PRINT_HILOGE("get ui content failed.");
106     return nullptr;
107 }
108 
NewPrintAttributes(void)109 static Print_PrintAttributes *NewPrintAttributes(void)
110 {
111     auto attributes = new (std::nothrow) Print_PrintAttributes;
112     if (attributes == nullptr) {
113         PRINT_HILOGE("OH_Print new attributes failed.");
114         return nullptr;
115     }
116     if (memset_s(attributes, sizeof(Print_PrintAttributes), 0, sizeof(Print_PrintAttributes)) != 0) {
117         PRINT_HILOGE("OH_Print attributes memset failed.");
118         delete attributes;
119         return nullptr;
120     }
121     return attributes;
122 }
123 
ReleasePrintAttributes(Print_PrintAttributes * attr)124 static void ReleasePrintAttributes(Print_PrintAttributes *attr)
125 {
126     if (attr == nullptr) {
127         PRINT_HILOGE("OH_Print release attr is null.");
128         return;
129     }
130     if (attr->pageRange.pagesArray != nullptr) {
131         delete [] attr->pageRange.pagesArray;
132         attr->pageRange.pagesArray = nullptr;
133     }
134     delete attr;
135 }
136 
137 // 初始化
OH_Print_Init()138 Print_ErrorCode OH_Print_Init()
139 {
140     int32_t ret = PrintManagerClient::GetInstance()->Init();
141     PRINT_HILOGI("OH_Print_Init ret = [%{public}d]", ret);
142     return ConvertToNativeErrorCode(ret);
143 }
144 
145 // 反初始化
OH_Print_Release()146 Print_ErrorCode OH_Print_Release()
147 {
148     int32_t ret = PrintManagerClient::GetInstance()->Release();
149     PRINT_HILOGI("OH_Print_Release ret = [%{public}d]", ret);
150     return ConvertToNativeErrorCode(ret);
151 }
152 
OH_Print_StartPrinterDiscovery(Print_PrinterDiscoveryCallback callback)153 Print_ErrorCode OH_Print_StartPrinterDiscovery(Print_PrinterDiscoveryCallback callback)
154 {
155     printerDiscoverCallback = callback;
156     std::vector<PrintExtensionInfo> extensionInfos;
157     int32_t ret = PrintManagerClient::GetInstance()->QueryAllExtension(extensionInfos);
158     PRINT_HILOGI("QueryAllExtension ret = [%{public}d]", ret);
159     if (ret == PRINT_ERROR_NONE) {
160         std::vector<std::string> extensionIds;
161         for (auto &extensionInfo : extensionInfos) {
162             extensionIds.emplace_back(extensionInfo.GetExtensionId());
163         }
164         PRINT_HILOGI("extensionIds size = [%{public}zu]", extensionIds.size());
165         PrintManagerClient::GetInstance()->SetNativePrinterChangeCallback(
166             PRINTER_DISCOVER_EVENT_TYPE, NativePrinterDiscoverFunction);
167         ret = PrintManagerClient::GetInstance()->StartDiscoverPrinter(extensionIds);
168         PRINT_HILOGI("StartDiscoverPrinter ret = [%{public}d]", ret);
169     }
170     return ConvertToNativeErrorCode(ret);
171 }
172 
OH_Print_StopPrinterDiscovery()173 Print_ErrorCode OH_Print_StopPrinterDiscovery()
174 {
175     PrintManagerClient::GetInstance()->SetNativePrinterChangeCallback(PRINTER_DISCOVER_EVENT_TYPE, nullptr);
176     printerDiscoverCallback = nullptr;
177     int32_t ret = PrintManagerClient::GetInstance()->StopDiscoverPrinter();
178     PRINT_HILOGI("StopDiscoverPrinter ret = [%{public}d]", ret);
179     return ConvertToNativeErrorCode(ret);
180 }
181 
OH_Print_ConnectPrinter(const char * printerId)182 Print_ErrorCode OH_Print_ConnectPrinter(const char *printerId)
183 {
184     if (printerId == nullptr) {
185         PRINT_HILOGW("printerId is null.");
186         return PRINT_ERROR_INVALID_PRINTER;
187     }
188     std::string nativePrinterId = printerId;
189     int32_t ret = PrintManagerClient::GetInstance()->ConnectPrinter(nativePrinterId);
190     PRINT_HILOGI("ConnectPrinter ret = [%{public}d]", ret);
191     return ConvertToNativeErrorCode(ret);
192 }
193 
OH_Print_StartPrintJob(const Print_PrintJob * printJob)194 Print_ErrorCode OH_Print_StartPrintJob(const Print_PrintJob *printJob)
195 {
196     if (printJob == nullptr) {
197         PRINT_HILOGI("printJob is null.");
198         return PRINT_ERROR_INVALID_PRINT_JOB;
199     }
200     PrintJob curPrintJob;
201     int32_t ret = ConvertNativeJobToPrintJob(*printJob, curPrintJob);
202     if (ret != 0) {
203         PRINT_HILOGW("ConvertNativeJobToPrintJob fail.");
204         return PRINT_ERROR_INVALID_PRINT_JOB;
205     }
206     ret = PrintManagerClient::GetInstance()->StartNativePrintJob(curPrintJob);
207     PRINT_HILOGI("StartNativePrintJob ret = [%{public}d]", ret);
208     return ConvertToNativeErrorCode(ret);
209 }
210 
OH_Print_RegisterPrinterChangeListener(Print_PrinterChangeCallback callback)211 Print_ErrorCode OH_Print_RegisterPrinterChangeListener(Print_PrinterChangeCallback callback)
212 {
213     printerInfoCallback = callback;
214     PrintManagerClient::GetInstance()->SetNativePrinterChangeCallback(
215         PRINTER_CHANGE_EVENT_TYPE, NativePrinterInfoFunction);
216     return PRINT_ERROR_NONE;
217 }
218 
OH_Print_UnregisterPrinterChangeListener()219 void OH_Print_UnregisterPrinterChangeListener()
220 {
221     PrintManagerClient::GetInstance()->SetNativePrinterChangeCallback(PRINTER_CHANGE_EVENT_TYPE, nullptr);
222     printerInfoCallback = nullptr;
223 }
224 
OH_Print_QueryPrinterList(Print_StringList * printerIdList)225 Print_ErrorCode OH_Print_QueryPrinterList(Print_StringList *printerIdList)
226 {
227     if (printerIdList == nullptr) {
228         PRINT_HILOGW("printerIdList is null.");
229         return PRINT_ERROR_INVALID_PARAMETER;
230     }
231     std::vector<std::string> printerNameList;
232     int32_t ret = PrintManagerClient::GetInstance()->QueryAddedPrinter(printerNameList);
233     size_t count = printerNameList.size();
234     PRINT_HILOGI("OH_Print_QueryPrinterList ret = %{public}d, count = %{public}zu.", ret, count);
235     if (ret != 0 || count == 0) {
236         return PRINT_ERROR_INVALID_PRINTER;
237     }
238     printerIdList->list = new (std::nothrow) char *[count];
239     if (printerIdList->list == nullptr) {
240         PRINT_HILOGW("printerIdList->list is null");
241         return PRINT_ERROR_GENERIC_FAILURE;
242     }
243     if (memset_s(printerIdList->list, count * sizeof(char *), 0, count * sizeof(char *)) != 0) {
244         delete[] printerIdList->list;
245         printerIdList->list = nullptr;
246         PRINT_HILOGW("memset_s fail");
247         return PRINT_ERROR_GENERIC_FAILURE;
248     }
249     for (size_t i = 0; i < count; ++i) {
250         printerIdList->list[i] = CopyString(printerNameList[i]);
251     }
252     printerIdList->count = count;
253     return PRINT_ERROR_NONE;
254 }
255 
OH_Print_ReleasePrinterList(Print_StringList * printerIdList)256 void OH_Print_ReleasePrinterList(Print_StringList *printerIdList)
257 {
258     if (printerIdList == nullptr) {
259         PRINT_HILOGW("printerIdList is null.");
260         return;
261     }
262     if (printerIdList->list != nullptr) {
263         for (uint32_t i = 0; i < printerIdList->count; i++) {
264             SAFE_DELETE_ARRAY(printerIdList->list[i]);
265         }
266         SAFE_DELETE_ARRAY(printerIdList->list);
267     }
268     printerIdList->count = 0;
269 }
270 
OH_Print_QueryPrinterInfo(const char * printerId,Print_PrinterInfo ** printerInfo)271 Print_ErrorCode OH_Print_QueryPrinterInfo(const char *printerId, Print_PrinterInfo **printerInfo)
272 {
273     if (printerId == nullptr || printerInfo == nullptr) {
274         PRINT_HILOGW("Invalid parameter.");
275         return PRINT_ERROR_INVALID_PARAMETER;
276     }
277     std::string id(printerId);
278     PrinterInfo info;
279     int32_t ret = PrintManagerClient::GetInstance()->QueryPrinterInfoByPrinterId(id, info);
280     PRINT_HILOGI("QueryPrinterInfoByPrinterId ret = %{public}d", ret);
281     if (info.GetPrinterId() != id || info.GetPrinterName().empty()) {
282         PRINT_HILOGI("QueryPrinterInfoByPrinterId invalid printer");
283         return PRINT_ERROR_INVALID_PRINTER;
284     }
285     Print_PrinterInfo *nativePrinterInfo = ConvertToNativePrinterInfo(info);
286     if (nativePrinterInfo != nullptr) {
287         if (ret != 0) {
288             nativePrinterInfo->printerState = PRINTER_UNAVAILABLE;
289         }
290         *printerInfo = nativePrinterInfo;
291     }
292     return ConvertToNativeErrorCode(ret);
293 }
294 
OH_Print_ReleasePrinterInfo(Print_PrinterInfo * printerInfo)295 void OH_Print_ReleasePrinterInfo(Print_PrinterInfo *printerInfo)
296 {
297     if (printerInfo == nullptr) {
298         PRINT_HILOGW("printerInfo is null.");
299         return;
300     }
301     ReleasePrinterInfo(*printerInfo);
302     delete printerInfo;
303     printerInfo = nullptr;
304 }
305 
OH_Print_LaunchPrinterManager()306 Print_ErrorCode OH_Print_LaunchPrinterManager()
307 {
308     PRINT_HILOGW("Ability context is needed to start ability");
309     return PRINT_ERROR_GENERIC_FAILURE;
310 }
311 
OH_Print_QueryPrinterProperties(const char * printerId,const Print_StringList * propertyKeyList,Print_PropertyList * propertyList)312 Print_ErrorCode OH_Print_QueryPrinterProperties(
313     const char *printerId, const Print_StringList *propertyKeyList, Print_PropertyList *propertyList)
314 {
315     if (printerId == nullptr || propertyKeyList == nullptr || propertyKeyList->list == nullptr ||
316         propertyList == nullptr) {
317         PRINT_HILOGW("OH_Print_QueryPrinterProperties invalid parameter.");
318         return PRINT_ERROR_INVALID_PRINTER;
319     }
320     std::vector<std::string> keyList;
321     for (uint32_t i = 0; i < propertyKeyList->count; i++) {
322         if (propertyKeyList->list[i] == nullptr) {
323             continue;
324         }
325         std::string key(propertyKeyList->list[i]);
326         if (key.empty()) {
327             continue;
328         }
329         keyList.emplace_back(key);
330     }
331     if (keyList.size() == 0) {
332         PRINT_HILOGW("empty keyList");
333         return PRINT_ERROR_INVALID_PARAMETER;
334     }
335     std::vector<std::string> valueList;
336     int32_t ret = PrintManagerClient::GetInstance()->QueryPrinterProperties(printerId, keyList, valueList);
337     PRINT_HILOGI("QueryPrinterProperties ret = %{public}d", ret);
338     if (ret != 0) {
339         PRINT_HILOGW("QueryPrinterProperties fail");
340         return PRINT_ERROR_INVALID_PRINTER;
341     }
342     return ConvertStringVectorToPropertyList(valueList, propertyList);
343 }
344 
OH_Print_ReleasePrinterProperties(Print_PropertyList * propertyList)345 void OH_Print_ReleasePrinterProperties(Print_PropertyList *propertyList)
346 {
347     if (propertyList == nullptr) {
348         PRINT_HILOGW("propertyList is null");
349         return;
350     }
351     if (propertyList->list != nullptr) {
352         for (uint32_t i = 0; i < propertyList->count; ++i) {
353             SAFE_DELETE_ARRAY(propertyList->list[i].key);
354             SAFE_DELETE_ARRAY(propertyList->list[i].value);
355         }
356         SAFE_DELETE_ARRAY(propertyList->list);
357     }
358     propertyList->count = 0;
359 }
360 
OH_Print_UpdatePrinterProperties(const char * printerId,const Print_PropertyList * propertyList)361 Print_ErrorCode OH_Print_UpdatePrinterProperties(const char *printerId, const Print_PropertyList *propertyList)
362 {
363     if (printerId == nullptr || propertyList->list == nullptr || propertyList->count <= 0) {
364         PRINT_HILOGW("OH_Print_UpdatePrinterProperties invalid parameter.");
365         return PRINT_ERROR_INVALID_PRINTER;
366     }
367     nlohmann::json settingJson;
368     for (uint32_t i = 0; i < propertyList->count; i++) {
369         settingJson[propertyList->list[i].key] = propertyList->list[i].value;
370     }
371     PRINT_HILOGW("OH_Print_UpdatePrinterProperties setting : %{public}s.", settingJson.dump().c_str());
372     int32_t ret = PrintManagerClient::GetInstance()->SetPrinterPreference(printerId, settingJson.dump());
373     if (ret != 0) {
374         PRINT_HILOGW("SetPrinterPreference fail");
375         return PRINT_ERROR_INVALID_PRINTER;
376     }
377     return PRINT_ERROR_NONE;
378 }
379 
OH_Print_RestorePrinterProperties(const char * printerId,const Print_StringList * propertyKeyList)380 Print_ErrorCode OH_Print_RestorePrinterProperties(const char *printerId, const Print_StringList *propertyKeyList)
381 {
382     return PRINT_ERROR_NONE;
383 }
384 
385 namespace {
386 class PrintDocumentAdapterWrapper : public PrintDocumentAdapter {
387 public:
388     explicit PrintDocumentAdapterWrapper(Print_PrintDocCallback PrintCallback);
389     void onStartLayoutWrite(const std::string &jobId,
390                             const PrintAttributes &oldAttrs,
391                             const PrintAttributes &newAttrs,
392                             uint32_t fd,
393                             std::function<void(std::string, uint32_t)> writeResultCallback) override;
394     void onJobStateChanged(const std::string &jobId, uint32_t state) override;
395     void OnWriteResultCallback(const std::string &jobId, uint32_t code);
396     static void WriteResultCallback(const char *jobId, uint32_t code);
397 
398 private:
399     Print_PrintAttributes *BuildPrintAttributes(const PrintAttributes &attrs);
400 
401     Print_PrintDocCallback printCb_;
402     std::function<void(std::string, uint32_t)> writeResultCb_;
403     static std::mutex printDocMutex_;
404     static std::map<std::string, PrintDocumentAdapterWrapper*> printDocAdapterMap_;
405 };
406 
407 std::mutex PrintDocumentAdapterWrapper::printDocMutex_;
408 std::map<std::string, PrintDocumentAdapterWrapper*> PrintDocumentAdapterWrapper::printDocAdapterMap_;
409 
PrintDocumentAdapterWrapper(Print_PrintDocCallback PrintCallback)410 PrintDocumentAdapterWrapper::PrintDocumentAdapterWrapper(Print_PrintDocCallback PrintCallback)
411 {
412     printCb_ = PrintCallback;
413 }
414 
onStartLayoutWrite(const std::string & jobId,const PrintAttributes & oldAttrs,const PrintAttributes & newAttrs,uint32_t fd,std::function<void (std::string,uint32_t)> writeResultCallback)415 void PrintDocumentAdapterWrapper::onStartLayoutWrite(const std::string &jobId,
416                                                      const PrintAttributes &oldAttrs,
417                                                      const PrintAttributes &newAttrs,
418                                                      uint32_t fd,
419                                                      std::function<void(std::string, uint32_t)> writeResultCallback)
420 {
421     if (printCb_.startLayoutWriteCb == nullptr) {
422         PRINT_HILOGE("OH_Print start layout callback is null.");
423         return;
424     }
425     {
426         std::lock_guard<std::mutex> lock(printDocMutex_);
427         if (printDocAdapterMap_.find(jobId) == printDocAdapterMap_.end()) {
428             printDocAdapterMap_.insert({ jobId, this });
429         }
430     }
431     writeResultCb_ = writeResultCallback;
432     auto oldAttrsPtr = BuildPrintAttributes(oldAttrs);
433     auto newAttrsPtr = BuildPrintAttributes(newAttrs);
434     printCb_.startLayoutWriteCb(jobId.c_str(),
435                                 fd,
436                                 oldAttrsPtr,
437                                 newAttrsPtr,
438                                 PrintDocumentAdapterWrapper::WriteResultCallback);
439     ReleasePrintAttributes(oldAttrsPtr);
440     ReleasePrintAttributes(newAttrsPtr);
441     oldAttrsPtr = nullptr;
442     newAttrsPtr = nullptr;
443 }
444 
onJobStateChanged(const std::string & jobId,uint32_t state)445 void PrintDocumentAdapterWrapper::onJobStateChanged(const std::string &jobId, uint32_t state)
446 {
447     if (printCb_.jobStateChangedCb == nullptr) {
448         PRINT_HILOGE("OH_Print job state callback is null.");
449         return;
450     }
451     if (state == PRINT_DOC_ADAPTER_PREVIEW_ABILITY_DESTROY_FOR_CANCELED
452         || state == PRINT_DOC_ADAPTER_PREVIEW_ABILITY_DESTROY_FOR_STARTED) {
453         std::lock_guard<std::mutex> lock(printDocMutex_);
454         printDocAdapterMap_.erase(jobId);
455     }
456     printCb_.jobStateChangedCb(jobId.c_str(), state);
457 }
458 
WriteResultCallback(const char * jobId,uint32_t code)459 void PrintDocumentAdapterWrapper::WriteResultCallback(const char *jobId, uint32_t code)
460 {
461     if (jobId == nullptr) {
462         PRINT_HILOGE("OH_Print write result callback param is null.");
463         return;
464     }
465     std::string jobIdStr = jobId;
466     PrintDocumentAdapterWrapper* wrapper = nullptr;
467     {
468         std::lock_guard<std::mutex> lock(printDocMutex_);
469         auto iter = printDocAdapterMap_.find(jobId);
470         if (iter != printDocAdapterMap_.end()) {
471             wrapper = iter->second;
472         }
473     }
474     if (wrapper == nullptr) {
475         PRINT_HILOGE("OH_Print get wrapper failed.");
476         return;
477     }
478     wrapper->OnWriteResultCallback(jobIdStr, code);
479 }
480 
OnWriteResultCallback(const std::string & jobId,uint32_t code)481 void PrintDocumentAdapterWrapper::OnWriteResultCallback(const std::string &jobId, uint32_t code)
482 {
483     if (writeResultCb_ == nullptr) {
484         PRINT_HILOGE("OH_Print write callback is null.");
485         return;
486     }
487     writeResultCb_(jobId, code);
488 }
489 
BuildPrintAttributes(const PrintAttributes & attrs)490 Print_PrintAttributes *PrintDocumentAdapterWrapper::BuildPrintAttributes(const PrintAttributes &attrs)
491 {
492     auto attributesRaw = NewPrintAttributes();
493     if (attributesRaw == nullptr) {
494         PRINT_HILOGE("OH_Print attribute raw is null.");
495         return nullptr;
496     }
497     std::unique_ptr<Print_PrintAttributes> attributes(attributesRaw);
498     attributes->copyNumber = attrs.GetCopyNumber();
499     Print_Range printRange;
500     PrintRange range;
501     attrs.GetPageRange(range);
502     printRange.startPage = range.GetStartPage();
503     printRange.endPage = range.GetEndPage();
504     std::vector<uint32_t> pages;
505     range.GetPages(pages);
506     auto pageArray = new (std::nothrow) uint32_t[pages.size()];
507     if (pageArray == nullptr) {
508         PRINT_HILOGE("OH_Print pages array is null.");
509         return nullptr;
510     }
511     std::copy(pages.begin(), pages.end(), pageArray);
512     printRange.pagesArray = pageArray;
513     printRange.pagesArrayLen = pages.size();
514     attributes->pageRange = printRange;
515     attributes->isSequential = attrs.GetIsSequential();
516     Print_PageSize printPageSize;
517     PrintPageSize pageSize;
518     attrs.GetPageSize(pageSize);
519     printPageSize.width = pageSize.GetWidth();
520     printPageSize.height = pageSize.GetHeight();
521     attributes->pageSize = printPageSize;
522     attributes->isLandscape = attrs.GetIsLandscape();
523     attributes->colorMode = attrs.GetColorMode();
524     attributes->duplexMode = attrs.GetDuplexMode();
525     Print_Margin printMargin;
526     PrintMargin margin;
527     attrs.GetMargin(margin);
528     printMargin.topMargin = margin.GetTop();
529     printMargin.bottomMargin = margin.GetBottom();
530     printMargin.leftMargin = margin.GetLeft();
531     printMargin.rightMargin = margin.GetRight();
532     attributes->pageMargin = printMargin;
533     return attributes.release();
534 }
535 }
536 
OH_Print_StartPrintByNative(const char * printJobName,Print_PrintDocCallback printDocCallback,void * context)537 Print_ErrorCode OH_Print_StartPrintByNative(const char *printJobName,
538                                             Print_PrintDocCallback printDocCallback,
539                                             void *context)
540 {
541     if (printJobName == nullptr) {
542         PRINT_HILOGE("OH_Print start print native print job name is null.");
543         return PRINT_ERROR_INVALID_PARAMETER;
544     }
545 
546     auto uiContent = GetUIContent(context);
547     if (uiContent == nullptr) {
548         PRINT_HILOGE("OH_Print start print native ui content is null.");
549         return PRINT_ERROR_INVALID_PARAMETER;
550     }
551     auto wrapper = new (std::nothrow) PrintDocumentAdapterWrapper(printDocCallback);
552     if (wrapper == nullptr) {
553         PRINT_HILOGE("OH_Print start print print doc adapter is null.");
554         return PRINT_ERROR_GENERIC_FAILURE;
555     }
556     OHOS::sptr<IPrintCallback> printCb = new (std::nothrow) PrintCallback(wrapper);
557     if (printCb == nullptr) {
558         PRINT_HILOGE("OH_Print start print print callback is null.");
559         delete wrapper;
560         return PRINT_ERROR_GENERIC_FAILURE;
561     }
562     auto attributes = std::make_shared<PrintAttributes>();
563     std::string printJobNameStr = printJobName;
564     int32_t ret =
565         PrintManagerClient::GetInstance()->Print(printJobNameStr, printCb, attributes, uiContent);
566     if (ret != PRINT_ERROR_NONE) {
567         PRINT_HILOGE("OH_Print start print start failed, error code : %{public}d.", ret);
568         return ConvertToNativeErrorCode(ret);
569     }
570     return PRINT_ERROR_NONE;
571 }
572