1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "ani_print_task.h"
16 #include "print_log.h"
17 #include "print_manager_client.h"
18
19 namespace OHOS::Print {
20 static const std::string SPOOLER_BUNDLE_NAME = "com.ohos.spooler";
21 static const std::string SPOOLER_PREVIEW_ABILITY_NAME = "PrintServiceExtAbility";
22 static const std::string LAUNCH_PARAMETER_JOB_ID = "jobId";
23 static const std::string LAUNCH_PARAMETER_FILE_LIST = "fileList";
24 static const std::string UI_EXTENSION_TYPE_NAME = "ability.want.params.uiExtensionType";
25 static const std::string PRINT_UI_EXTENSION_TYPE = "sysDialog/print";
26 static const std::string CALLER_PKG_NAME = "caller.pkgName";
27 static const std::string ABILITY_PARAMS_STREAM = "ability.params.stream";
28 static const int32_t MAX_FILE_LIST_SIZE = 100;
AniPrintTask(ani_env * env)29 AniPrintTask::AniPrintTask(ani_env *env)
30 {
31 if (env == nullptr) {
32 PRINT_HILOGE("env is a nullptr");
33 return;
34 }
35 ani_vm *vm = nullptr;
36 env->GetVM(&vm);
37 aniVm_ = vm;
38 jobId_ = PrintUtils::GetPrintJobId();
39 }
40
~AniPrintTask()41 AniPrintTask::~AniPrintTask()
42 {
43 aniVm_ = nullptr;
44 }
45
StartPrintWithContext(const std::vector<std::string> & files,std::shared_ptr<AbilityRuntime::Context> ctx)46 int32_t AniPrintTask::StartPrintWithContext(const std::vector<std::string>& files,
47 std::shared_ptr<AbilityRuntime::Context> ctx)
48 {
49 if (files.empty()) {
50 PRINT_HILOGE("fileList and fdList are both empty");
51 return E_PRINT_INVALID_PARAMETER;
52 }
53 FdListWrapper fdList;
54 if (files.begin()->find("fd://") == 0) {
55 PRINT_HILOGD("list type: fdlist");
56 for (auto fdPath : files) {
57 uint32_t fd = PrintUtils::GetIdFromFdPath(fdPath);
58 fdList.Add(fd);
59 }
60 } else {
61 PRINT_HILOGD("list type: filelist");
62 for (auto file : files) {
63 int32_t fd = PrintUtils::OpenFile(file);
64 if (fd < 0) {
65 PRINT_HILOGE("file[%{private}s] is invalid", file.c_str());
66 return E_PRINT_INVALID_PARAMETER;
67 }
68 fdList.Add(fd);
69 }
70 }
71 std::shared_ptr<AdapterParam> adapterParam = std::make_shared<AdapterParam>();
72 adapterParam->jobId = jobId_;
73 adapterParam->documentName = "";
74 adapterParam->isCheckFdList = true;
75 uint32_t ret = CallSpooler(adapterParam, files, ctx);
76 if (ret != E_PRINT_NONE) {
77 PRINT_HILOGE("CallSpooler fail");
78 return ret;
79 }
80 return PrintManagerClient::GetInstance()->StartPrint(files, fdList.Get(), jobId_);
81 }
82
StartPrintWithAttributes(const std::string & jobName,std::shared_ptr<AbilityRuntime::Context> ctx,const PrintAttributes & attributes,const sptr<IPrintCallback> & listener)83 int32_t AniPrintTask::StartPrintWithAttributes(const std::string& jobName, std::shared_ptr<AbilityRuntime::Context> ctx,
84 const PrintAttributes& attributes, const sptr<IPrintCallback> &listener)
85 {
86 std::shared_ptr<OHOS::AbilityRuntime::AbilityContext> abilityContext =
87 OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(ctx);
88 sptr<IRemoteObject> callerToken = abilityContext->GetToken();
89 std::shared_ptr<AdapterParam> adapterParam = std::make_shared<AdapterParam>();
90 adapterParam->documentName = jobName;
91 adapterParam->isCheckFdList = false;
92 adapterParam->printAttributes = attributes;
93 adapterParam->jobId = jobId_;
94 uint32_t ret = CallSpooler(adapterParam, {}, ctx);
95 if (ret != E_PRINT_NONE) {
96 PRINT_HILOGE("CallSpooler fail");
97 return ret;
98 }
99 return PrintManagerClient::GetInstance()->Print(
100 jobName, listener, attributes, jobId_, callerToken);
101 }
102
CallSpooler(const std::shared_ptr<AdapterParam> & adapterParam,const std::vector<std::string> & files,std::shared_ptr<AbilityRuntime::Context> ctx)103 uint32_t AniPrintTask::CallSpooler(const std::shared_ptr<AdapterParam>& adapterParam,
104 const std::vector<std::string>& files, std::shared_ptr<AbilityRuntime::Context> ctx)
105 {
106 if (adapterParam == nullptr || ctx == nullptr) {
107 PRINT_HILOGE("Invalid parameters");
108 return E_PRINT_INVALID_PARAMETER;
109 }
110 AAFwk::Want want;
111 want.SetElementName(SPOOLER_BUNDLE_NAME, SPOOLER_PREVIEW_ABILITY_NAME);
112 want.SetParam(LAUNCH_PARAMETER_JOB_ID, adapterParam->jobId);
113 want.SetParam(LAUNCH_PARAMETER_FILE_LIST, files);
114 if (!files.empty() && files.size() <= MAX_FILE_LIST_SIZE) {
115 want.SetParam(LAUNCH_PARAMETER_FILE_LIST, files);
116 want.SetParam(ABILITY_PARAMS_STREAM, files);
117 }
118 PrintUtils::BuildAdapterParam(adapterParam, want);
119 int32_t callerTokenId = static_cast<int32_t>(IPCSkeleton::GetCallingTokenID());
120 want.SetParam(AAFwk::Want::PARAM_RESV_CALLER_TOKEN, callerTokenId);
121 want.SetParam(CALLER_PKG_NAME, PrintUtils::GetBundleNameForUid(IPCSkeleton::GetCallingUid()));
122 want.SetParam(UI_EXTENSION_TYPE_NAME, PRINT_UI_EXTENSION_TYPE);
123 want.SetFlags(AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION);
124 OHOS::Ace::ModalUIExtensionConfig config;
125 config.isProhibitBack = true;
126 auto uiContent = GetUIContent(ctx);
127 if (uiContent == nullptr) {
128 PRINT_HILOGE("GetUIContent failed");
129 return E_PRINT_GENERIC_FAILURE;
130 }
131 auto callback = std::make_shared<PrintEtsUICallback>(uiContent);
132 OHOS::Ace::ModalUIExtensionCallbacks extensionCallbacks = {
133 [callback](int32_t releaseCode) { callback->OnRelease(releaseCode); },
134 [callback](int32_t resultCode, const OHOS::AAFwk::Want& result) {
135 callback->OnResultForModal(resultCode, result);
136 },
137 [callback](const OHOS::AAFwk::WantParams& request) { callback->OnReceive(request); },
138 [callback](int32_t code, const std::string& name, const std::string& message) {
139 callback->OnError(code, name, message);
140 }
141 };
142 int32_t sessionId = uiContent->CreateModalUIExtension(want, extensionCallbacks, config);
143 callback->SetSessionId(sessionId);
144 PRINT_HILOGD("Created session: %{public}d", sessionId);
145
146 return E_PRINT_NONE;
147 }
148
GetUIContent(std::shared_ptr<OHOS::AbilityRuntime::Context> ctx)149 OHOS::Ace::UIContent* AniPrintTask::GetUIContent(std::shared_ptr<OHOS::AbilityRuntime::Context> ctx)
150 {
151 std::shared_ptr<OHOS::AbilityRuntime::AbilityContext> abilityContext =
152 OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(ctx);
153 if (abilityContext != nullptr) {
154 return abilityContext->GetUIContent();
155 }
156 std::shared_ptr<OHOS::AbilityRuntime::UIExtensionContext> uiExtensionContext =
157 OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::UIExtensionContext>(ctx);
158 if (uiExtensionContext != nullptr) {
159 return uiExtensionContext->GetUIContent();
160 }
161 return nullptr;
162 }
163
On(std::string type,sptr<IPrintCallback> callback)164 int32_t AniPrintTask::On(std::string type, sptr<IPrintCallback> callback)
165 {
166 int32_t ret = PrintManagerClient::GetInstance()->On(jobId_, type, callback);
167 return ret;
168 }
169
Off(std::string type,sptr<IPrintCallback> callback)170 int32_t AniPrintTask::Off(std::string type, sptr<IPrintCallback> callback)
171 {
172 int32_t ret = PrintManagerClient::GetInstance()->Off(jobId_, type);
173 return ret;
174 }
175 } // namespace OHOS::Print