fix bugs Signed-off-by:zoumeiguang@huawei.com

Signed-off-by: guang <zoumeiguang@huawei.com>
This commit is contained in:
guang 2023-08-01 12:34:12 +08:00
parent 0775bfc15e
commit 1e393bb110
18 changed files with 273 additions and 31 deletions

View File

@ -33,6 +33,8 @@ public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Print.IPrintService");
virtual int32_t StartPrint(const std::vector<std::string> &fileList,
const std::vector<uint32_t> &fdList, std::string &taskId) = 0;
virtual int32_t StartPrint(const std::vector<std::string> &fileList,const std::vector<uint32_t> &fdList,
std::string &taskId, const sptr<IRemoteObject> &token) = 0;
virtual int32_t StopPrint(const std::string &taskId) = 0;
virtual int32_t ConnectPrinter(const std::string &printerId) = 0;
virtual int32_t DisconnectPrinter(const std::string &printerId) = 0;

View File

@ -42,6 +42,8 @@ public:
int32_t StartPrint(const std::vector<std::string> &fileList,
const std::vector<uint32_t> &fdList, std::string &taskId);
int32_t StopPrint(const std::string &taskId);
int32_t StartPrint(const std::vector<std::string> &fileList, const std::vector<uint32_t> &fdList,
std::string &taskId, const sptr<IRemoteObject> &token);
int32_t QueryAllExtension(std::vector<PrintExtensionInfo> &extensionInfos);
int32_t StartDiscoverPrinter(const std::vector<std::string> &extensionList);
int32_t StopDiscoverPrinter();

View File

@ -28,6 +28,8 @@ public:
int32_t StartPrint(const std::vector<std::string> &fileList,
const std::vector<uint32_t> &fdList, std::string &taskId) override;
int32_t StopPrint(const std::string &taskId) override;
int32_t StartPrint(const std::vector<std::string> &fileList, const std::vector<uint32_t> &fdList,
std::string &taskId, const sptr<IRemoteObject> &token);
int32_t ConnectPrinter(const std::string &printerId) override;
int32_t DisconnectPrinter(const std::string &printerId) override;
int32_t StartDiscoverPrinter(const std::vector<std::string> &extensionList) override;

View File

@ -99,6 +99,18 @@ int32_t PrintManagerClient::StartPrint(const std::vector<std::string> &fileList,
return ret;
}
int32_t PrintManagerClient::StartPrint(const std::vector<std::string> &fileList, const std::vector<uint32_t> &fdList,
std::string &taskId, const sptr<IRemoteObject> &token)
{
PRINT_HILOGD("PrintManagerClient StartPrint start.");
int32_t ret = E_PRINT_RPC_FAILURE;
if (LoadServer() && GetPrintServiceProxy()) {
ret = printServiceProxy_->StartPrint(fileList, fdList, taskId, token);
PRINT_HILOGD("PrintManagerClient StartPrint out ret = [%{public}d].", ret);
}
return ret;
}
int32_t PrintManagerClient::StopPrint(const std::string &taskId)
{
PRINT_HILOGD("PrintManagerClient StopPrint start.");

View File

@ -68,6 +68,42 @@ int32_t PrintServiceProxy::StartPrint(const std::vector<std::string> &fileList,
return ret;
}
int32_t PrintServiceProxy::StartPrint(const std::vector<std::string> &fileList, const std::vector<uint32_t> &fdList,
std::string &taskId, const sptr<IRemoteObject> &token)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
PRINT_HILOGD("Current file is %{public}zd", fileList.size());
for (auto file : fileList) {
PRINT_HILOGD("file is %{private}s", file.c_str());
}
data.WriteBool(fileList.size() > 0);
if (!fileList.empty()) {
data.WriteStringVector(fileList);
}
data.WriteBool(fdList.size() > 0);
if (!fdList.empty()) {
data.WriteInt32(fdList.size());
for (auto fd : fdList) {
data.WriteFileDescriptor(fd);
}
}
if (token == nullptr || !data.WriteRemoteObject(token)) {
PRINT_HILOGE("StartPrint, Failed to write remote object.");
return E_PRINT_INVALID_PARAMETER;
}
PRINT_HILOGD("PrintServiceProxy StartPrint started.");
int32_t ret = Remote()->SendRequest(OHOS::Print::IPrintInterfaceCode::CMD_START_PRINT, data, reply, option);
ret = GetResult(ret, reply);
taskId = reply.ReadString();
PRINT_HILOGD("PrintServiceProxy StartPrint ret = [%{public}d] TaskId = %{public}s", ret, taskId.c_str());
return ret;
}
int32_t PrintServiceProxy::StopPrint(const std::string &taskId)
{
MessageParcel data, reply;

View File

@ -13,6 +13,7 @@
* limitations under the License.
*/
import type { AsyncCallback } from './@ohos.base';
import type Context from '/application/Context';
/**
* System print
@ -61,6 +62,18 @@ declare namespace print {
function print(files: Array<string>, callback: AsyncCallback<PrintTask>): void;
function print(files: Array<string>): Promise<PrintTask>;
/**
* Start new print task for App.
* @since 10
* @param files Indicates the filepath list to be printed. Only pdf and picture filetype are supported.
* @paramv { Context } context - The ability context that initiates the call print request.
* @param callback The callback function for print task.
* @permission {@code ohos.permission.PRINT}
* @return -
*/
function print(files: Array<string>, context: Context, callback: AsyncCallback<PrintTask>): void;
function print(files: Array<string>, context: Context): Promise<PrintTask>;
interface PrintMargin {
top?: number; // top margin
bottom?: number; // bottom margin

View File

@ -45,6 +45,7 @@ ohos_shared_library("print_napi") {
external_deps = [
"ability_base:want",
"ability_base:zuri",
"ability_runtime:ability_context_native",
"ability_runtime:ability_manager",
"ability_runtime:abilitykit_native",
"ability_runtime:data_ability_helper",

View File

@ -17,10 +17,18 @@
#define NAPI_PRINT_TASK_H
#include <string>
#include "ability.h"
#include "ability_context.h"
#include "napi/native_api.h"
#include "napi/native_common.h"
namespace OHOS::Print {
struct PrintTaskContext : public PrintAsyncCall::Context {
napi_ref ref = nullptr;
PrintTaskContext() : Context(nullptr, nullptr) {}
PrintTaskContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)) {};
virtual ~PrintTaskContext() {}
};
class NapiPrintTask {
public:
static napi_value Print(napi_env env, napi_callback_info info);
@ -29,6 +37,11 @@ private:
static napi_value GetCtor(napi_env env);
static napi_value Initialize(napi_env env, napi_callback_info info);
static bool IsValidFile(const std::string &fileName);
static napi_value GetAbilityContext(
napi_env env, napi_value value, std::shard_ptr<OHOS::AbilityRuntime::AbilityContext> &abilityContext);
static napi_value WrapVoidToJS(napi_env env);
static napi_status VerifyParameters(napi_env env, size_t argc, napi_value *argv,
const std::shared_ptr<PrintTaskContext> context, napi_value proxy);
private:
static __thread napi_ref globalCtor;

View File

@ -21,6 +21,7 @@
#include <string>
#include <vector>
#include "iremote_object.h"
#include "iprint_callback.h"
#include "napi/native_api.h"
#include "napi/native_common.h"
@ -29,7 +30,7 @@
namespace OHOS::Print {
class PrintTask {
public:
explicit PrintTask(const std::vector<std::string> &fileList);
explicit PrintTask(const std::vector<std::string> &fileList, const sptr<IRemoteObject> &callerToken_);
~PrintTask();
uint32_t Start();
@ -57,6 +58,7 @@ private:
std::vector<uint32_t> fdList_;
std::map<std::string, bool> supportEvents_;
uint32_t pathType_ = 0;
sptr<IRemoteObject> callerToken_;
enum FilePathType {
FD_UNDEFINED,
FD_PATH,

View File

@ -14,6 +14,7 @@
*/
#include <mutex>
#include "napi_base_context.h"
#include "napi_print_utils.h"
#include "print_async_call.h"
#include "print_log.h"
@ -28,39 +29,18 @@ namespace OHOS::Print {
__thread napi_ref NapiPrintTask::globalCtor = nullptr;
std::mutex g_printTaskMutex;
struct PrintTaskContext : public PrintAsyncCall::Context {
napi_ref ref = nullptr;
PrintTaskContext() : Context(nullptr, nullptr) {}
PrintTaskContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)) {};
virtual ~PrintTaskContext() {}
};
napi_value NapiPrintTask::Print(napi_env env, napi_callback_info info)
{
PRINT_HILOGD("Enter print JsMain.");
auto context = std::make_shared<PrintTaskContext>();
auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
PRINT_HILOGD("print parser to native params %{public}d!", static_cast<int>(argc));
PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, "need 1 parameter!", napi_invalid_arg);
bool isFileArray = false;
napi_is_array(env, argv[0], &isFileArray);
PRINT_ASSERT_BASE(env, isFileArray == true, "parameter type isn't list", napi_invalid_arg);
uint32_t len = 0;
PRINT_CALL_BASE(env, napi_get_array_length(env, argv[0], &len), napi_invalid_arg);
if (!isFileArray || len == 0) {
context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
return napi_invalid_arg;
}
PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE || argc == NapiPrintUtils::ARGC_TWO,
"need 1 or 2 parameter!", napi_invalid_arg);
napi_value proxy = nullptr;
napi_status status = napi_new_instance(env, GetCtor(env), argc, argv, &proxy);
if ((proxy == nullptr) || (status != napi_ok)) {
PRINT_HILOGE("Failed to create print task");
context->SetErrorIndex(E_PRINT_GENERIC_FAILURE);
return napi_generic_failure;
napi_status checkStatus = VerifyParameters(env, argc, argv, context, proxy);
if (checkStatus != napi_ok) {
return checkStatus;
}
PrintTask *task;
@ -91,6 +71,36 @@ napi_value NapiPrintTask::Print(napi_env env, napi_callback_info info)
return asyncCall.Call(env);
}
napi_value NapiPrintTask::GetAbilityContext(
napi_env env, napi_value value, std::shard_ptr<OHOS::AbilityRuntime::AbilityContext> &abilityContext)
{
bool stageMode = false;
napi_status status = OHOS::AbilityRuntime::IsStageContext(env, value, stageMode);
if (status != napi_ok || !stageMode) {
PRINT_HILOGE("GetAbilityContext it is not a stage mode");
return nullptr;
} else {
auto context = OHOS::AbilityRuntime::GetStageModeContext(env, value);
if (context == nullptr) {
PRINT_HILOGE("GetAbilityContext get context failed");
return nullptr;
}
abilityContext = OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(context);
if (abilityContext == nullptr) {
PRINT_HILOGE("GetAbilityContext get Stage model ability context failed.");
return nullptr;
}
return WrapVoidToJS(env);
}
}
napi_value NapiPrintTask::WrapVoidToJS(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_get_null(env, &result));
return result;
}
napi_value NapiPrintTask::GetCtor(napi_env env)
{
std::lock_guard<std::mutex> lock(g_printTaskMutex);
@ -131,7 +141,14 @@ napi_value NapiPrintTask::Initialize(napi_env env, napi_callback_info info)
}
}
auto task = new (std::nothrow) PrintTask(printfiles);
std::shard_ptr<OHOS::AbilityRuntime::AbilityContext> abilityContext;
sptr<IRemoteObject> callerToken;
if (argc == NapiPrintUtils::ARGC_TWO && GetAbilityContext(env, argv[1], abilityContext) != nullptr) {
callerToken = abilityContext->GetToken();
PRINT_HILOGI("get callerToken:%{public}s", callerToken !=nullptr ? "success" : "failed");
}
auto task = new (std::nothrow) PrintTask(printfiles, callerToken);
if (task == nullptr) {
PRINT_HILOGE("print task fail");
return nullptr;
@ -167,4 +184,36 @@ bool NapiPrintTask::IsValidFile(const std::string &fileName)
PRINT_HILOGE("invalid file name");
return false;
}
napi_status NapiPrintTask::VerifyParameters(napi_env env, size_t argc, napi_value *argv,
const std::shared_ptr<PrintTaskContext> context, napi_value proxy)
{
bool isFileArray = false;
napi_is_array(env, argv[0], &isFileArray);
PRINT_ASSERT_BASE(env, isFileArray == true, "parameter type isn't list", napi_invalid_arg);
uint32_t len = 0;
PRINT_CALL_BASE(env, napi_get_array_length(env, argv[0], &len), napi_invalid_arg);
if (!isFileArray || len == 0) {
context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
return napi_invalid_arg;
}
std::shard_ptr<OHOS::AbilityRuntime::AbilityContext> abilityContext;
if (argc == NapiPrintUtils::ARGC_TWO) {
if (GetAbilityContext(env, argv[1], abilityContext) == nullptr) {
PRINT_HILOGE("Print, Ability Context is null.");
}
}
napi_status status = napi_new_instance(env, GetCtor(env), argc, argv, &proxy);
if ((proxy == nullptr) || (status != napi_ok))
{
PRINT_HILOGE("Failed to create print task");
context->SetErrorIndex(E_PRINT_GENERIC_FAILURE);
return napi_generic_failure;
}
return napi_ok;
}
} // namespace OHOS::Print

View File

@ -27,7 +27,8 @@ const std::string EVENT_SUCCESS = "success";
const std::string EVENT_FAIL = "failed";
const std::string EVENT_CANCEL = "cancelled";
PrintTask::PrintTask(const std::vector<std::string> &innerList) : taskId_("")
PrintTask::PrintTask(const std::vector<std::string> &innerList, const sptr<IRemoteObject> &innerCallerToken_)
: taskId_("")
{
if (innerList.begin()->find("fd://") == 0) {
PRINT_HILOGD("list type: fdlist");
@ -51,6 +52,7 @@ PrintTask::PrintTask(const std::vector<std::string> &innerList) : taskId_("")
supportEvents_[EVENT_SUCCESS] = true;
supportEvents_[EVENT_FAIL] = true;
supportEvents_[EVENT_CANCEL] = true;
callerToken_ = innerCallerToken_;
}
PrintTask::~PrintTask()
@ -75,7 +77,13 @@ uint32_t PrintTask::Start()
fdList_.emplace_back(fd);
}
}
return PrintManagerClient::GetInstance()->StartPrint(fileList_, fdList_, taskId_);
if (callToken_ == nullptr) {
PRINT_HILOGI("call client's old StartPrint interface.");
return PrintManagerClient::GetInstance()->StartPrint(fileList_, fdList_, taskId_);
} else {
PRINT_HILOGI("call client's new StartPrint interface.");
return PrintManagerClient::GetInstance()->StartPrint(fileList_, fdList_, taskId_, callToken_);
}
}
void PrintTask::Stop()

View File

@ -33,6 +33,7 @@
namespace OHOS::Print {
enum class ServiceRunningState { STATE_NOT_START, STATE_RUNNING };
static int32_t curRequestCode_ = 0;
class IKeyguardStateCallback;
class PrintServiceAbility : public SystemAbility, public PrintServiceStub {
@ -46,6 +47,8 @@ public:
static sptr<PrintServiceAbility> GetInstance();
int32_t StartPrint(const std::vector<std::string> &fileList,
const std::vector<uint32_t> &fdList, std::string &taskId) override;
int32_t StartPrint(const std::vector<std::string> &fileList, const std::vector<uint32_t> &fdList,
std::string &taskId, const sptr<IRemoteObject> &token) override;
int32_t StopPrint(const std::string &taskId) override;
int32_t ConnectPrinter(const std::string &printerId) override;
int32_t DisconnectPrinter(const std::string &printerId) override;
@ -82,6 +85,7 @@ private:
void ManualStart();
std::string GetPrintJobId();
bool StartAbility(const AAFwk::Want &want);
bool StartPrintServiceExtension(const AAFwk::Want &want, int32_t curRequestCode_);
PrintExtensionInfo ConvertToPrintExtensionInfo(const AppExecFwk::ExtensionAbilityInfo &extInfo);
bool DelayStartDiscovery(const std::string &extensionId);
void SendPrinterEvent(const PrinterInfo &info);

View File

@ -28,6 +28,7 @@ public:
virtual ~PrintServiceHelper();
virtual bool CheckPermission(const std::string &name);
virtual bool StartAbility(const AAFwk::Want &want);
virtual bool StartPrintServiceExtension(const AAFwk::Want &want, int32_t requestCode_);
virtual sptr<IRemoteObject> GetBundleMgr();
virtual bool QueryAccounts(std::vector<int> &accountList);
virtual bool QueryExtension(sptr<AppExecFwk::IBundleMgr> mgr, int userId,

View File

@ -76,6 +76,8 @@ static const std::string QUEUE_JOB_LIST_PRINTING = "printing";
static const std::string QUEUE_JOB_LIST_COMPLETED = "completed";
static const std::string QUEUE_JOB_LIST_BLOCKED = "blocked";
static const std::string QUEUE_JOB_LIST_CLEAR_BLOCKED = "clear_blocked";
static const std::string SPOOLER_PREVIEW_ABILITY_NAME = "PrintServiceExtAbility";
static const std::string TOKEN_KEY = "ohos.ability.params.token";
static bool publishState = false;
@ -260,6 +262,57 @@ int32_t PrintServiceAbility::StartPrint(const std::vector<std::string> &fileList
return E_PRINT_NONE;
}
int32_t PrintServiceAbility::StartPrint(const std::vector<std::string> &fileList, const std::vector<uint32_t> &fdList,
std::string &taskId, const sptr<IRemoteObject> &token)
{
ManualStart();
if (!CheckPermission(PERMISSION_NAME_PRINT)) {
PRINT_HILOGD("no permission to access print service, ErrorCode:[%{public}d]", E_PRINT_NO_PERMISSION);
return E_PRINT_NO_PERMISSION;
}
PRINT_HILOGD("PrintServiceAbility StartPrint started.");
std::lock_guard<std::recursive_mutex> lock(apiMutex_);
if (fileList.empty() && fdList.empty() && token == nullptr) {
PRINT_HILOGE("to be printed filelist and fdlist are empty, or token is null.");
return E_PRINT_INVALID_PARAMETER;
}
std::string jobId = GetPrintJobId();
auto printJob = std::make_shared<PrintJob>();
if (printJob == nullptr) {
return E_PRINT_GENERIC_FAILURE;
}
printJob->SetFdList(fdList);
printJob->SetJobId(jobId);
printJob->SetJobState(PRINT_JOB_PREPARED);
AAFwk::Want want;
want.SetElementName(SPOOLER_BUNDLE_NAME, SPOOLER_ABILITY_NAME);
want.SetParam(LAUNCH_PARAMETER_JOB_ID, jobId);
want.SetParam(LAUNCH_PARAMETER_FILE_LIST, fileList);
BuildFDParam(fdList, want);
int32_t callerTokenId = static_cast<int32_t>(IPCSkeleton::GetCallingTokenID());
std::string callerPkg = DelayedSingleton<PrintBMSHelper>::GetInstance()->QueryCallerBundleName();
ingressPackage = callerPkg;
int32_t callerUid = IPCSkeleton::GetCallingUid();
int32_t callerPid = IPCSkeleton::GetCallingPid();
want.SetParam(AAFwk::Want::PARAM_RESV_CALLER_TOKEN, callerTokenId);
want.SetParam(AAFwk::Want::PARAM_RESV_CALLER_UID, callerUid);
want.SetParam(AAFwk::Want::PARAM_RESV_CALLER_PID, callerPid);
want.SetParam(CALLER_PKG_NAME, callerPkg);
want.SetParam(TOKEN_KEY, token);
curRequestCode_ = (curRequestCode_ == INT_MAX) ? 0 : (curRequestCode_ + 1);
if (!StartPrintServiceExtension(want, curRequestCode_)) {
PRINT_HILOGE("Failed to start spooler ability");
return E_PRINT_SERVER_FAILURE;
}
printJobList_.insert(std::make_pair(jobId, printJob));
taskId = jobId;
SendPrintJobEvent(*printJob);
// save securityGuard base info
securityGuardManager_.receiveBaseInfo(jobId, callerPkg, fileList);
return E_PRINT_NONE;
}
int32_t PrintServiceAbility::StopPrint(const std::string &taskId)
{
ManualStart();
@ -1250,6 +1303,15 @@ bool PrintServiceAbility::StartAbility(const AAFwk::Want &want)
return helper_->StartAbility(want);
}
bool PrintServiceAbility::StartPrintServiceExtension(const AAFwk::Want &want, int32_t curRequestCode_)
{
if (helper_ == nullptr) {
return false;
}
PRINT_HILOGI("StartPrintServiceExtension curRequestCode_ [%{public}d]", curRequestCode_);
return helper_->StartPrintServiceExtension(want, curRequestCode_);
}
PrintExtensionInfo PrintServiceAbility::ConvertToPrintExtensionInfo(const AppExecFwk::ExtensionAbilityInfo &extInfo)
{
PrintExtensionInfo printExtInfo;

View File

@ -69,6 +69,28 @@ bool PrintServiceHelper::StartAbility(const AAFwk::Want &want)
return true;
}
bool PrintServiceHelper::StartPrintServiceExtension(const AAFwk::Want &want, int32_t requestCode_)
{
AppExecFwk::ElementName element = want.GetElement();
AAFwk::AbilityManagerClient::GetInstance()->Connect();
uint32_t retry = 0;
while (retry++ < MAX_RETRY_TIMES) {
PRINT_HILOGD("PrintServiceHelper::StartAbility %{public}s %{public}s",
element.GetBundleName().c_str(), element.GetAbilityName().c_str());
if (AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, requestCode_) == 0) {
break;
}
break;
std::this_thread::sleep_for(std::chrono::seconds(START_ABILITY_INTERVAL));
PRINT_HILOGD("PrintServiceHelper::StartAbility %{public}d", retry);
}
if (retry > MAX_RETRY_TIMES) {
PRINT_HILOGE("PrintServiceHelper::StartAbility --> failed ");
return false;
}
return true;
}
sptr<IRemoteObject> PrintServiceHelper::GetBundleMgr()
{
auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();

View File

@ -100,7 +100,14 @@ bool PrintServiceStub::OnStartPrint(MessageParcel &data, MessageParcel &reply)
}
}
int32_t ret = StartPrint(fileList, fdList, result);
sptr<IRemoteObject> token = data.ReadRemoteObject();
PRINT_HILOGI("OnStartPrint read token %{public}s", token != nullptr ? "success" : "failed");
int32_t ret = E_PRINT_NONE;
if (token == nullptr) {
ret = StartPrint(fileList, fdList, result);
} else {
ret = StartPrint(fileList, fdList, result, token);
}
reply.WriteInt32(ret);
reply.WriteString(result);
PRINT_HILOGD("PrintServiceStub::OnStartPrint out");

View File

@ -28,6 +28,11 @@ public:
{
return E_PRINT_NONE;
}
int32_t StartPrint(const std::vector<std::string> &fileList,
const std::vector<uint32_t> &fdList, std::string &taskId, const sptr<IRemoteObject> &token) override
{
return E_PRINT_NONE;
}
int32_t StopPrint(const std::string &taskId) override
{
return E_PRINT_NONE;

View File

@ -25,6 +25,7 @@ class MockPrintServiceHelper final : public PrintServiceHelper {
public:
MOCK_METHOD1(CheckPermission, bool(const std::string&));
MOCK_METHOD1(StartAbility, bool(const AAFwk::Want&));
MOCK_METHOD2(StartPrintServiceExtension, bool(const AAFwk::Want&, int32_t));
MOCK_METHOD0(GetBundleMgr, sptr<IRemoteObject>());
MOCK_METHOD1(QueryAccounts, bool(std::vector<int>&));
MOCK_METHOD3(QueryExtension, bool(sptr<AppExecFwk::IBundleMgr>, int,