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