• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "napi/native_common.h"
17 #include "accesstoken_kit.h"
18 
19 #include "print_task.h"
20 #include "napi_print_utils.h"
21 #include "print_callback.h"
22 #include "print_log.h"
23 #include "print_manager_client.h"
24 #include "print_constant.h"
25 
26 namespace OHOS::Print {
27 
28 using namespace std;
29 using namespace Security::AccessToken;
30 
31 const std::string EVENT_BLOCK = "block";
32 const std::string EVENT_SUCCESS = "succeed";
33 const std::string EVENT_FAIL = "fail";
34 const std::string EVENT_CANCEL = "cancel";
35 
36 static const std::string SPOOLER_BUNDLE_NAME = "com.ohos.spooler";
37 static const std::string SPOOLER_PREVIEW_ABILITY_NAME = "PrintServiceExtAbility";
38 static const std::string LAUNCH_PARAMETER_JOB_ID = "jobId";
39 static const std::string LAUNCH_PARAMETER_FILE_LIST = "fileList";
40 static const std::string TOKEN_KEY = "ohos.ability.params.token";
41 static const std::string UI_EXTENSION_TYPE_NAME = "ability.want.params.uiExtensionType";
42 static const std::string PRINT_UI_EXTENSION_TYPE = "sysDialog/print";
43 static const std::string CALLER_PKG_NAME = "caller.pkgName";
44 static const std::string ABILITY_PARAMS_STREAM = "ability.params.stream";
45 static const std::string LAUNCH_PARAMETER_FILE_LIST_SIZE = "fileListSize";
46 static const int32_t MAX_FILE_LIST_SIZE = 100;
47 
PrintTask(const std::vector<std::string> & innerList,const sptr<IRemoteObject> & innerCallerToken_)48 PrintTask::PrintTask(const std::vector<std::string> &innerList, const sptr<IRemoteObject> &innerCallerToken_)
49     : taskId_("")
50 {
51     if (!innerList.empty()) {
52         if (innerList.begin()->find("fd://") == 0) {
53             PRINT_HILOGD("list type: fdlist");
54             for (auto fdPath : innerList) {
55                 pathType_ = FD_PATH;
56                 uint32_t fd = PrintUtils::GetIdFromFdPath(fdPath);
57                 fdList_.emplace_back(fd);
58             }
59         } else {
60             PRINT_HILOGD("list type: filelist");
61             fileList_.assign(innerList.begin(), innerList.end());
62             pathType_ = FILE_PATH_ABSOLUTED;
63             if (!fileList_.empty() && fileList_.begin()->find("file://") == 0) {
64                 pathType_ = FILE_PATH;
65             }
66         }
67     }
68 
69     supportEvents_[EVENT_BLOCK] = true;
70     supportEvents_[EVENT_SUCCESS] = true;
71     supportEvents_[EVENT_FAIL] = true;
72     supportEvents_[EVENT_CANCEL] = true;
73     callerToken_ = innerCallerToken_;
74 }
75 
PrintTask(const std::string & innerPrintJobName_,const sptr<IPrintCallback> & innerPrintAdapterCallback_,const std::shared_ptr<PrintAttributes> & innerPrintAttributes_,const sptr<IRemoteObject> & innerCallerToken_)76 PrintTask::PrintTask(const std::string &innerPrintJobName_, const sptr<IPrintCallback> &innerPrintAdapterCallback_,
77     const std::shared_ptr<PrintAttributes> &innerPrintAttributes_, const sptr<IRemoteObject> &innerCallerToken_)
78     : taskId_("")
79 {
80     supportEvents_[EVENT_BLOCK] = true;
81     supportEvents_[EVENT_SUCCESS] = true;
82     supportEvents_[EVENT_FAIL] = true;
83     supportEvents_[EVENT_CANCEL] = true;
84     printJobName_ = innerPrintJobName_;
85     printAdapterCallback_ = innerPrintAdapterCallback_;
86     printAttributes_ = innerPrintAttributes_;
87     callerToken_ = innerCallerToken_;
88 }
89 
~PrintTask()90 PrintTask::~PrintTask()
91 {
92     supportEvents_.clear();
93     Stop();
94 }
95 
Start(napi_env env,napi_callback_info info)96 uint32_t PrintTask::Start(napi_env env, napi_callback_info info)
97 {
98     if (fileList_.empty() && fdList_.empty()) {
99         PRINT_HILOGE("fileList and fdList are both empty");
100         return E_PRINT_INVALID_PARAMETER;
101     }
102     if (pathType_ == FILE_PATH_ABSOLUTED) {
103         for (auto file : fileList_) {
104             int32_t fd = PrintUtils::OpenFile(file);
105             if (fd >= 0) {
106                 fdList_.emplace_back(fd);
107                 continue;
108             }
109             PRINT_HILOGE("file[%{private}s] is invalid", file.c_str());
110             for (auto fd : fdList_) {
111                 fdsan_close_with_tag(fd, PRINT_LOG_DOMAIN);
112             }
113             fdList_.clear();
114             fileList_.clear();
115             return E_PRINT_INVALID_PARAMETER;
116         }
117     }
118 
119     PRINT_HILOGI("call client's StartPrint interface.");
120     std::shared_ptr<AdapterParam> adapterParam = std::make_shared<AdapterParam>();
121     CreateDefaultAdapterParam(adapterParam);
122     std::string jobId = PrintUtils::GetPrintJobId();
123     adapterParam->jobId = jobId;
124     taskId_ = jobId;
125     uint32_t ret = CallSpooler(env, info, adapterParam, false);
126     if (ret != E_PRINT_NONE) {
127         PRINT_HILOGE("CallSpooler failed.");
128         for (auto fd : fdList_) {
129             fdsan_close_with_tag(fd, PRINT_LOG_DOMAIN);
130         }
131         fdList_.clear();
132         fileList_.clear();
133         return ret;
134     }
135     return PrintManagerClient::GetInstance()->StartPrint(fileList_, fdList_, taskId_);
136 }
137 
StartPrintAdapter(napi_env env,napi_callback_info info)138 uint32_t PrintTask::StartPrintAdapter(napi_env env, napi_callback_info info)
139 {
140     if (printAdapterCallback_ != nullptr && printAttributes_ != nullptr) {
141         PRINT_HILOGI("call client's StartPrintAdapter interface.");
142         if (callerToken_ == nullptr) {
143             PRINT_HILOGE("callerToken is null.");
144             return E_PRINT_INVALID_PARAMETER;
145         }
146         std::shared_ptr<AdapterParam> adapterParam = std::make_shared<AdapterParam>();
147         if (adapterParam == nullptr) {
148             PRINT_HILOGE("create adapterParam failed.");
149             return E_PRINT_SERVER_FAILURE;
150         }
151         adapterParam->documentName = printJobName_;
152         adapterParam->isCheckFdList = false;
153         adapterParam->printAttributes = *printAttributes_;
154         std::string jobId = PrintUtils::GetPrintJobId();
155         adapterParam->jobId = jobId;
156         taskId_ = jobId;
157         uint32_t ret = CallSpooler(env, info, adapterParam, true);
158         if (ret != E_PRINT_NONE) {
159             PRINT_HILOGE("CallSpooler failed.");
160             return ret;
161         }
162         return PrintManagerClient::GetInstance()->Print(
163             printJobName_, printAdapterCallback_, *printAttributes_, taskId_, callerToken_);
164     }
165     return E_PRINT_INVALID_PARAMETER;
166 }
167 
CallSpooler(napi_env env,napi_callback_info info,const std::shared_ptr<AdapterParam> & adapterParam,bool isPrintByAdapter)168 uint32_t PrintTask::CallSpooler(
169     napi_env env, napi_callback_info info, const std::shared_ptr<AdapterParam> &adapterParam, bool isPrintByAdapter)
170 {
171     PRINT_HILOGI("enter CallSpooler.");
172     if (!CheckPermission(PERMISSION_NAME_PRINT)) {
173         PRINT_HILOGE("no permission to access print service, ErrorCode:[%{public}d]", E_PRINT_NO_PERMISSION);
174         return E_PRINT_NO_PERMISSION;
175     }
176     size_t argc = NapiPrintUtils::MAX_ARGC;
177     size_t contextIndex = isPrintByAdapter ? NapiPrintUtils::INDEX_THREE : NapiPrintUtils::INDEX_ONE;
178     size_t callBackIndex = isPrintByAdapter ? NapiPrintUtils::INDEX_FOUR : NapiPrintUtils::INDEX_TWO;
179     size_t argMaxNum = isPrintByAdapter ? NapiPrintUtils::ARGC_FIVE : NapiPrintUtils::ARGC_THREE;
180     napi_value argv[NapiPrintUtils::MAX_ARGC] = { nullptr };
181     napi_value thisArg = nullptr;
182     void *data = nullptr;
183     napi_value result = nullptr;
184 
185     PRINT_CALL_BASE(env, napi_get_undefined(env, &result), E_PRINT_INVALID_PARAMETER);
186     PRINT_CALL_BASE(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data), E_PRINT_INVALID_PARAMETER);
187     PRINT_HILOGI("CallSpooler params size: %{public}zu", argc);
188     if (argc < argMaxNum - 1) {
189         PRINT_HILOGE("invalid parameters.");
190         return E_PRINT_INVALID_PARAMETER;
191     }
192 
193     auto asyncContext = std::make_shared<BaseContext>();
194     asyncContext->env = env;
195     asyncContext->requestType = PrintRequestType::REQUEST_TYPE_START;
196     if (!ParseAbilityContextReq(env, argv[contextIndex], asyncContext->context, asyncContext->uiExtensionContext)) {
197         PRINT_HILOGE("invalid parameters.");
198         return E_PRINT_INVALID_PARAMETER;
199     }
200 
201     if (argc == argMaxNum) {
202         napi_valuetype valueType = napi_undefined;
203         PRINT_CALL_BASE(env, napi_typeof(env, argv[callBackIndex], &valueType), napi_undefined);
204         if (valueType == napi_function) {
205             PRINT_CALL_BASE(env, napi_create_reference(env, argv[callBackIndex], 1, &asyncContext->callback),
206                 E_PRINT_INVALID_PARAMETER);
207             PRINT_HILOGD("is a callback api");
208         }
209     } else {
210         PRINT_CALL_BASE(env, napi_create_promise(env, &asyncContext->deferred, &result), E_PRINT_INVALID_PARAMETER);
211         PRINT_HILOGD("is a promise api");
212     }
213     uint32_t ret = StartUIExtensionAbility(asyncContext, adapterParam);
214     PRINT_HILOGI("end CallSpooler");
215     return ret;
216 }
217 
ParseAbilityContextReq(napi_env env,const napi_value & obj,std::shared_ptr<OHOS::AbilityRuntime::AbilityContext> & abilityContext,std::shared_ptr<OHOS::AbilityRuntime::UIExtensionContext> & uiExtensionContext)218 bool PrintTask::ParseAbilityContextReq(napi_env env, const napi_value &obj,
219     std::shared_ptr<OHOS::AbilityRuntime::AbilityContext> &abilityContext,
220     std::shared_ptr<OHOS::AbilityRuntime::UIExtensionContext> &uiExtensionContext)
221 {
222     PRINT_HILOGD("begin ParseAbilityContextReq");
223     bool stageMode = false;
224     napi_status status = OHOS::AbilityRuntime::IsStageContext(env, obj, stageMode);
225     if (status != napi_ok || !stageMode) {
226         PRINT_HILOGE("it is not a stage mode");
227         return false;
228     }
229 
230     auto context = OHOS::AbilityRuntime::GetStageModeContext(env, obj);
231     if (context == nullptr) {
232         PRINT_HILOGE("get context failed");
233         return false;
234     }
235 
236     abilityContext = OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(context);
237     if (abilityContext == nullptr) {
238         PRINT_HILOGE("get abilityContext failed");
239         uiExtensionContext =
240             OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::UIExtensionContext>(context);
241         if (uiExtensionContext == nullptr) {
242             PRINT_HILOGE("get uiExtensionContext failed");
243             return false;
244         }
245     }
246 
247     PRINT_HILOGD("end ParseAbilityContextReq");
248     return true;
249 }
250 
StartUIExtensionAbility(std::shared_ptr<BaseContext> asyncContext,const std::shared_ptr<AdapterParam> & adapterParam)251 uint32_t PrintTask::StartUIExtensionAbility(
252     std::shared_ptr<BaseContext> asyncContext, const std::shared_ptr<AdapterParam> &adapterParam)
253 {
254     PRINT_HILOGD("begin StartUIExtensionAbility");
255 
256     if (adapterParam == nullptr) {
257         PRINT_HILOGE("adapterParam is nullptr.");
258         return E_PRINT_INVALID_PARAMETER;
259     }
260     if ((adapterParam->isCheckFdList && fileList_.empty() && fdList_.empty())) {
261         PRINT_HILOGE("to be printed filelist and fdlist are empty.");
262         return E_PRINT_INVALID_PARAMETER;
263     }
264     AAFwk::Want want;
265     want.SetElementName(SPOOLER_BUNDLE_NAME, SPOOLER_PREVIEW_ABILITY_NAME);
266     want.SetParam(LAUNCH_PARAMETER_JOB_ID, adapterParam->jobId);
267     if (fileList_.size() <= MAX_FILE_LIST_SIZE) {
268         want.SetParam(LAUNCH_PARAMETER_FILE_LIST, fileList_);
269     } else {
270         PRINT_HILOGW("fileList exceeds the maximum length.");
271     }
272     want.SetParam(LAUNCH_PARAMETER_FILE_LIST_SIZE, static_cast<int>(fileList_.size()));
273     PrintUtils::BuildAdapterParam(adapterParam, want);
274     int32_t callerTokenId = static_cast<int32_t>(IPCSkeleton::GetCallingTokenID());
275     int32_t callerUid = IPCSkeleton::GetCallingUid();
276     int32_t callerPid = IPCSkeleton::GetCallingPid();
277     std::string callerPkg = PrintUtils::GetBundleNameForUid(callerUid);
278     want.SetParam(AAFwk::Want::PARAM_RESV_CALLER_TOKEN, callerTokenId);
279     want.SetParam(AAFwk::Want::PARAM_RESV_CALLER_UID, callerUid);
280     want.SetParam(AAFwk::Want::PARAM_RESV_CALLER_PID, callerPid);
281     want.SetParam(CALLER_PKG_NAME, callerPkg);
282     want.SetParam(UI_EXTENSION_TYPE_NAME, PRINT_UI_EXTENSION_TYPE);
283     want.SetParam(ABILITY_PARAMS_STREAM, fileList_);
284     want.SetFlags(AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION);
285 
286     uint32_t ret = StartUIExtensionAbility(want, asyncContext);
287     if (ret != E_PRINT_NONE) {
288         PRINT_HILOGE("StartUIExtensionAbility fail");
289     }
290     PRINT_HILOGD("end StartUIExtensionAbility");
291     return ret;
292 }
293 
StartUIExtensionAbility(OHOS::AAFwk::Want & want,std::shared_ptr<BaseContext> asyncContext)294 uint32_t PrintTask::StartUIExtensionAbility(OHOS::AAFwk::Want &want, std::shared_ptr<BaseContext> asyncContext)
295 {
296     PRINT_HILOGI("begin StartUIExtensionAbility");
297     if (asyncContext == nullptr) {
298         PRINT_HILOGE("asyncContext is nullptr");
299         return E_PRINT_INVALID_PARAMETER;
300     }
301 
302     if (asyncContext->context == nullptr && asyncContext->uiExtensionContext == nullptr) {
303         PRINT_HILOGE("asyncContext is nullptr");
304         return E_PRINT_INVALID_PARAMETER;
305     }
306 
307     auto uiContent = GetUIContent(asyncContext.get());
308     if (uiContent == nullptr) {
309         PRINT_HILOGE("UIContent is nullptr");
310         return E_PRINT_INVALID_PARAMETER;
311     }
312 
313     std::string info = uiContent->GetContentInfo();
314     auto callback = std::make_shared<PrintModalUICallback>(asyncContext);
315     if (callback == nullptr) {
316         PRINT_HILOGE("create callback failed.");
317         return E_PRINT_SERVER_FAILURE;
318     }
319     OHOS::Ace::ModalUIExtensionCallbacks extensionCallbacks = {
320         [callback](int32_t releaseCode) { callback->OnRelease(releaseCode); },
321         [callback](int32_t resultCode, const OHOS::AAFwk::Want& result) {
322             callback->OnResultForModal(resultCode, result);
323         },
324         [callback](const OHOS::AAFwk::WantParams& request) { callback->OnReceive(request); },
325         [callback](int32_t code, const std::string& name, const std::string& message) {
326             callback->OnError(code, name, message);
327         }
328     };
329 
330     OHOS::Ace::ModalUIExtensionConfig config;
331     config.isProhibitBack = true;
332     int32_t sessionId = uiContent->CreateModalUIExtension(want, extensionCallbacks, config);
333     PRINT_HILOGI("StartUIExtensionAbility sessionId %{public}d", sessionId);
334     callback->SetSessionId(sessionId);
335 
336     PRINT_HILOGI("end StartUIExtensionAbility");
337     return E_PRINT_NONE;
338 }
339 
GetUIContent(const BaseContext * asyncContext)340 OHOS::Ace::UIContent *PrintTask::GetUIContent(const BaseContext *asyncContext)
341 {
342     if (asyncContext == nullptr) {
343         PRINT_HILOGE("asyncContext is nullptr.");
344         return nullptr;
345     }
346     OHOS::Ace::UIContent *uiContent = nullptr;
347     if (asyncContext->context != nullptr) {
348         PRINT_HILOGI("get uiContext by ability context");
349         uiContent = asyncContext->context->GetUIContent();
350     } else if (asyncContext->uiExtensionContext != nullptr) {
351         PRINT_HILOGI("get uiContext by ui extension ability context");
352         uiContent = asyncContext->uiExtensionContext->GetUIContent();
353     } else {
354         PRINT_HILOGE("get uiContext failed.");
355     }
356 
357     return uiContent;
358 }
359 
CreateDefaultAdapterParam(const std::shared_ptr<AdapterParam> & adapterParam)360 void PrintTask::CreateDefaultAdapterParam(const std::shared_ptr<AdapterParam> &adapterParam)
361 {
362     adapterParam->documentName = "";
363     adapterParam->isCheckFdList = true;
364 }
365 
Stop()366 void PrintTask::Stop()
367 {
368     PrintManagerClient::GetInstance()->StopPrint(taskId_);
369     taskId_ = "";
370 }
371 
GetId() const372 const std::string &PrintTask::GetId() const
373 {
374     return taskId_;
375 }
376 
On(napi_env env,napi_callback_info info)377 napi_value PrintTask::On(napi_env env, napi_callback_info info)
378 {
379     PRINT_HILOGD("Enter ---->");
380     size_t argc = NapiPrintUtils::MAX_ARGC;
381     napi_value argv[NapiPrintUtils::MAX_ARGC] = { nullptr };
382     napi_value thisVal = nullptr;
383     void *data = nullptr;
384     PRINT_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, &data));
385     PRINT_ASSERT(env, argc == NapiPrintUtils::ARGC_TWO, "need 2 parameter!");
386 
387     napi_valuetype valuetype;
388     PRINT_CALL(env, napi_typeof(env, argv[0], &valuetype));
389     PRINT_ASSERT(env, valuetype == napi_string, "type is not a string");
390     std::string type = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ZERO]);
391     PRINT_HILOGD("type : %{public}s", type.c_str());
392 
393     valuetype = napi_undefined;
394     napi_typeof(env, argv[1], &valuetype);
395     PRINT_ASSERT(env, valuetype == napi_function, "callback is not a function");
396 
397     PrintTask *task;
398     PRINT_CALL(env, napi_unwrap(env, thisVal, reinterpret_cast<void **>(&task)));
399     if (task == nullptr || !task->IsSupportType(type)) {
400         PRINT_HILOGE("Event On type : %{public}s not support", type.c_str());
401         return nullptr;
402     }
403 
404     napi_ref callbackRef = NapiPrintUtils::CreateReference(env, argv[1]);
405     sptr<IPrintCallback> callback = new (std::nothrow) PrintCallback(env, callbackRef);
406     if (callback == nullptr) {
407         PRINT_HILOGE("create print callback object fail");
408         return nullptr;
409     }
410     int32_t ret = PrintManagerClient::GetInstance()->On(task->taskId_, type, callback);
411     if (ret != E_PRINT_NONE) {
412         PRINT_HILOGE("Failed to register event");
413         return nullptr;
414     }
415     return nullptr;
416 }
417 
Off(napi_env env,napi_callback_info info)418 napi_value PrintTask::Off(napi_env env, napi_callback_info info)
419 {
420     PRINT_HILOGD("Enter ---->");
421     auto context = std::make_shared<TaskEventContext>();
422     if (context == nullptr) {
423         PRINT_HILOGE("create context failed.");
424         return nullptr;
425     }
426     auto input =
427         [context](
428             napi_env env, size_t argc, napi_value *argv, napi_value self, napi_callback_info info) -> napi_status {
429         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, "need 1 parameter!", napi_invalid_arg);
430         napi_valuetype valuetype;
431         PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype), napi_invalid_arg);
432         PRINT_ASSERT_BASE(env, valuetype == napi_string, "type is not a string", napi_string_expected);
433         std::string type = NapiPrintUtils::GetStringFromValueUtf8(env, argv[0]);
434         PrintTask *task;
435         PRINT_CALL_BASE(env, napi_unwrap(env, self, reinterpret_cast<void **>(&task)), napi_invalid_arg);
436         if (task == nullptr || !task->IsSupportType(type)) {
437             PRINT_HILOGE("Event On type : %{public}s not support", type.c_str());
438             context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
439             return napi_invalid_arg;
440         }
441 
442         context->type = type;
443         context->taskId = task->taskId_;
444         PRINT_HILOGD("event type : %{public}s", context->type.c_str());
445         return napi_ok;
446     };
447     auto output = [context](napi_env env, napi_value *result) -> napi_status {
448         napi_status status = napi_get_boolean(env, context->result, result);
449         PRINT_HILOGD("context->result = %{public}d", context->result);
450         return status;
451     };
452     auto exec = [context](PrintAsyncCall::Context *ctx) {
453         int32_t ret = PrintManagerClient::GetInstance()->Off(context->taskId, context->type);
454         context->result = ret == E_PRINT_NONE;
455         if (ret != E_PRINT_NONE) {
456             PRINT_HILOGE("Failed to unregistered event");
457             context->SetErrorIndex(ret);
458         }
459     };
460     context->SetAction(std::move(input), std::move(output));
461     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
462     return asyncCall.Call(env, exec);
463 }
464 
IsSupportType(const std::string & type) const465 bool PrintTask::IsSupportType(const std::string &type) const
466 {
467     return supportEvents_.find(type) != supportEvents_.end();
468 }
469 
CheckPermission(const std::string & name)470 bool PrintTask::CheckPermission(const std::string &name)
471 {
472     AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
473     TypeATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
474     if (tokenType == TOKEN_INVALID) {
475         PRINT_HILOGE("invalid token id %{public}d", tokenId);
476         return false;
477     }
478     int result = AccessTokenKit::VerifyAccessToken(tokenId, name);
479     if (result != PERMISSION_GRANTED) {
480         PRINT_HILOGE("Current tokenId permission is %{public}d", result);
481     }
482     return result == PERMISSION_GRANTED;
483 }
484 } // namespace OHOS::Print
485