Signed-off-by: 张余 <1459392684@qq.com>
Change-Id: I771dceeeb486157be850c3c4b59e3a9498de8877
This commit is contained in:
张余 2024-09-26 15:11:49 +08:00
parent 15b99fa1de
commit ad72622003
8 changed files with 494 additions and 92 deletions

View File

@ -159,6 +159,9 @@ enum CMDialogErrorCode {
CMR_DIALOG_ERROR = -1,
CMR_DIALOG_ERROR_INVALID_ARGUMENT = -2,
CMR_DIALOG_ERROR_INTERNAL = -3,
CMR_DIALOG_ERROR_OPERATION_CANCELS = -4,
CMR_DIALOG_ERROR_INSTALL_FAILED = -5,
CMR_DIALOG_ERROR_NOT_SUPPORTED = -6,
CMR_DIALOG_ERROR_PERMISSION_DENIED = 1011,
};

View File

@ -94,6 +94,7 @@ ohos_shared_library("certmanagerdialog") {
"src/dialog/cm_napi_dialog.cpp",
"src/dialog/cm_napi_dialog_common.cpp",
"src/dialog/cm_napi_open_dialog.cpp",
"src/dialog/cm_napi_open_install_dialog.cpp",
]
external_deps = [

View File

@ -21,6 +21,7 @@
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cm_napi_open_dialog.h"
#include "cm_mem.h"
#include "cm_type.h"
@ -30,9 +31,14 @@ static const std::string BUSINESS_ERROR_PROPERTY_CODE = "code";
static const std::string BUSINESS_ERROR_PROPERTY_MESSAGE = "message";
static const int32_t RESULT_NUMBER = 2;
void StartUIExtensionAbility(std::shared_ptr<CmUIExtensionRequestContext> asyncContext,
OHOS::AAFwk::Want want, std::shared_ptr<CmUIExtensionCallback> uiExtCallback);
bool ParseCmUIAbilityContextReq(
napi_env env, const napi_value& obj, std::shared_ptr<OHOS::AbilityRuntime::AbilityContext>& abilityContext);
napi_value ParseUint32(napi_env env, napi_value object, uint32_t &store);
napi_value ParseBoolean(napi_env env, napi_value object, bool &status);
napi_value ParseString(napi_env env, napi_value object, CmBlob *&blob);
napi_value GetUint8ArrayToBase64Str(napi_env env, napi_value object, std::string &certArray);
void ThrowError(napi_env env, int32_t errorCode, const std::string errMsg);
napi_value GenerateBusinessError(napi_env env, int32_t errorCode);
@ -51,7 +57,16 @@ enum CmDialogPageType {
PAGE_MAIN = 1,
PAGE_CA_CERTIFICATE = 2,
PAGE_CREDENTIAL = 3,
PAGE_INSTALL_CERTIFICATE = 4
PAGE_INSTALL_CERTIFICATE = 4,
PAGE_INSTALL_CA_GUIDE = 5
};
enum CmCertificateType {
CA_CERT = 1
};
enum CertificateScope {
CURRENT_USER = 1
};
enum ErrorCode {
@ -61,6 +76,8 @@ enum ErrorCode {
PARAM_ERROR = 401,
DIALOG_ERROR_GENERIC = 29700001,
DIALOG_ERROR_OPERATION_CANCELED = 29700002,
DIALOG_ERROR_INSTALL_FAILED = 29700003,
DIALOG_ERROR_NOT_SUPPORTED = 29700004,
};
} // namespace CertManagerNapi

View File

@ -24,7 +24,24 @@
#include "ui_content.h"
namespace CMNapi {
const std::string PARAM_UI_EXTENSION_TYPE = "ability.want.params.uiExtensionType";
const std::string SYS_COMMON_UI = "sys/commonUI";
const std::string CERT_MANAGER_BUNDLENAME = "com.ohos.certmanager";
const std::string CERT_MANAGER_ABILITYNAME = "CertPickerUIExtAbility";
const std::string CERT_MANAGER_PAGE_TYPE = "pageType";
const std::string CERT_MANAGER_CERTSCOPE_TYPE = "certScope";
const std::string CERT_MANAGER_CERTIFICATE_DATA = "cert";
const std::string CERT_MANAGER_CALLER_BUNDLENAME = "bundleName";
constexpr int32_t PARAM0 = 0;
constexpr int32_t PARAM1 = 1;
constexpr int32_t PARAM2 = 2;
constexpr int32_t PARAM3 = 3;
constexpr int32_t PARAM_SIZE_TWO = 2;
constexpr int32_t PARAM_SIZE_FOUR = 4;
constexpr int32_t ERROR_STR_LEN = 256;
napi_value CMNapiOpenCertManagerDialog(napi_env env, napi_callback_info info);
napi_value CMNapiOpenInstallCertManagerDialog(napi_env env, napi_callback_info info);
struct CommonAsyncContext {
explicit CommonAsyncContext(napi_env env);
@ -33,25 +50,31 @@ struct CommonAsyncContext {
napi_status status = napi_invalid_arg;
int32_t errCode = 0;
napi_deferred deferred = nullptr; // promise handle
std::string uri = "";
};
struct CmUIExtensionRequestContext : public CommonAsyncContext {
explicit CmUIExtensionRequestContext(napi_env env) : CommonAsyncContext(env) {};
std::shared_ptr<OHOS::AbilityRuntime::AbilityContext> context = nullptr;
uint32_t pageType = 0;
uint32_t certificateType = 0;
uint32_t certificateScope = 0;
std::string certStr = "";
};
class CmUIExtensionCallback {
public:
explicit CmUIExtensionCallback(std::shared_ptr<CmUIExtensionRequestContext>& reqContext);
void SetSessionId(const int32_t sessionId);
void OnRelease(const int32_t releaseCode);
void OnResult(const int32_t resultCode, const OHOS::AAFwk::Want& result);
void OnReceive(const OHOS::AAFwk::WantParams& request);
void OnError(const int32_t code, const std::string& name, const std::string& message);
void OnRemoteReady(const std::shared_ptr<OHOS::Ace::ModalUIExtensionProxy>& uiProxy);
void OnDestroy();
void SendMessageBack();
virtual ~CmUIExtensionCallback();
virtual void SetSessionId(const int32_t sessionId);
virtual void OnRelease(const int32_t releaseCode);
virtual void OnResult(const int32_t resultCode, const OHOS::AAFwk::Want& result);
virtual void OnReceive(const OHOS::AAFwk::WantParams& request);
virtual void OnError(const int32_t code, const std::string& name, const std::string& message);
virtual void OnRemoteReady(const std::shared_ptr<OHOS::Ace::ModalUIExtensionProxy>& uiProxy);
virtual void OnDestroy();
virtual void SendMessageBack();
virtual void ProcessCallback(napi_env env, const CommonAsyncContext* asyncContext);
private:
bool SetErrorCode(int32_t errCode);

View File

@ -35,6 +35,8 @@ static napi_value CreateCmErrorCode(napi_env env)
AddInt32Property(env, dialogErrorCode, "ERROR_GENERIC", DIALOG_ERROR_GENERIC);
AddInt32Property(env, dialogErrorCode, "ERROR_OPERATION_CANCELED", DIALOG_ERROR_OPERATION_CANCELED);
AddInt32Property(env, dialogErrorCode, "ERROR_INSTALL_FAILED", DIALOG_ERROR_INSTALL_FAILED);
AddInt32Property(env, dialogErrorCode, "ERROR_NOT_SUPPORTED", DIALOG_ERROR_NOT_SUPPORTED);
return dialogErrorCode;
}
@ -51,6 +53,26 @@ static napi_value CreateCmDialogPageType(napi_env env)
return dialogPageType;
}
static napi_value CreateCmCertificateType(napi_env env)
{
napi_value certificateType = nullptr;
NAPI_CALL(env, napi_create_object(env, &certificateType));
AddInt32Property(env, certificateType, "CA_CERT", CA_CERT);
return certificateType;
}
static napi_value CreateCmCertificateScope(napi_env env)
{
napi_value certificateScope = nullptr;
NAPI_CALL(env, napi_create_object(env, &certificateScope));
AddInt32Property(env, certificateScope, "CURRENT_USER", CURRENT_USER);
return certificateScope;
}
} // namespace CertManagerNapi
using namespace CMNapi;
@ -61,9 +83,12 @@ static napi_value CMDialogNapiRegister(napi_env env, napi_value exports)
napi_property_descriptor desc[] = {
DECLARE_NAPI_PROPERTY("CertificateDialogErrorCode", CreateCmErrorCode(env)),
DECLARE_NAPI_PROPERTY("CertificateDialogPageType", CreateCmDialogPageType(env)),
DECLARE_NAPI_PROPERTY("CertificateType", CreateCmCertificateType(env)),
DECLARE_NAPI_PROPERTY("CertificateScope", CreateCmCertificateScope(env)),
/* dialog */
DECLARE_NAPI_FUNCTION("openCertificateManagerDialog", CMNapiOpenCertManagerDialog),
DECLARE_NAPI_FUNCTION("openInstallCertificateDialog", CMNapiOpenInstallCertManagerDialog),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
return exports;

View File

@ -21,6 +21,20 @@
#include "cm_log.h"
#include "cm_type.h"
#define BYTE_SHIFT_10 0x10
#define BYTE_SHIFT_8 0x08
#define BYTE_SHIFT_6 6
#define BASE64_URL_TABLE_SIZE 0x3F
#define BASE64_GROUP_NUM 3
#define BYTE_INDEX_ZONE 0
#define BYTE_INDEX_ONE 1
#define BYTE_INDEX_TWO 2
#define BYTE_INDEX_THREE 3
#define BASE64_PADDING "="
#define BYTE_END_ONE 1
#define BYTE_END_TWO 2
static const char g_base64Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
namespace CMNapi {
namespace {
constexpr int CM_MAX_DATA_LEN = 0x6400000; // The maximum length is 100M
@ -28,6 +42,10 @@ constexpr int CM_MAX_DATA_LEN = 0x6400000; // The maximum length is 100M
static const std::string DIALOG_NO_PERMISSION_MSG = "the caller has no permission";
static const std::string DIALOG_INVALID_PARAMS_MSG = "the input parameters is invalid";
static const std::string DIALOG_GENERIC_MSG = "there is an internal error";
static const std::string DIALOG_OPERATION_CANCELS_MSG = "the user cancels the installation operation";
static const std::string DIALOG_INSTALL_FAILED_MSG = "the user install certificate failed"
" in the certificate manager dialog";
static const std::string DIALOG_NOT_SUPPORTED_MSG = "the API is not supported on this device";
static const std::unordered_map<int32_t, int32_t> DIALOG_CODE_TO_JS_CODE_MAP = {
// invalid params
@ -36,15 +54,125 @@ static const std::unordered_map<int32_t, int32_t> DIALOG_CODE_TO_JS_CODE_MAP = {
{ CMR_DIALOG_ERROR_PERMISSION_DENIED, HAS_NO_PERMISSION },
// internal error
{ CMR_DIALOG_ERROR_INTERNAL, DIALOG_ERROR_GENERIC },
// the user cancels the installation operation
{ CMR_DIALOG_ERROR_OPERATION_CANCELS, DIALOG_ERROR_OPERATION_CANCELED },
// the user install certificate failed in the certificate manager dialog
{ CMR_DIALOG_ERROR_INSTALL_FAILED, DIALOG_ERROR_INSTALL_FAILED },
// the API is not supported on this device
{ CMR_DIALOG_ERROR_NOT_SUPPORTED, DIALOG_ERROR_NOT_SUPPORTED },
};
static const std::unordered_map<int32_t, std::string> DIALOG_CODE_TO_MSG_MAP = {
{ CMR_DIALOG_ERROR_INVALID_ARGUMENT, DIALOG_INVALID_PARAMS_MSG },
{ CMR_DIALOG_ERROR_PERMISSION_DENIED, DIALOG_NO_PERMISSION_MSG },
{ CMR_DIALOG_ERROR_INTERNAL, DIALOG_GENERIC_MSG },
{ CMR_DIALOG_ERROR_OPERATION_CANCELS, DIALOG_OPERATION_CANCELS_MSG },
{ CMR_DIALOG_ERROR_INSTALL_FAILED, DIALOG_INSTALL_FAILED_MSG },
{ CMR_DIALOG_ERROR_NOT_SUPPORTED, DIALOG_NOT_SUPPORTED_MSG },
};
} // namespace
void StartUIExtensionAbility(std::shared_ptr<CmUIExtensionRequestContext> asyncContext,
OHOS::AAFwk::Want want, std::shared_ptr<CmUIExtensionCallback> uiExtCallback)
{
CM_LOG_D("begin StartUIExtensionAbility");
auto abilityContext = asyncContext->context;
if (abilityContext == nullptr) {
CM_LOG_E("abilityContext is null");
ThrowError(asyncContext->env, PARAM_ERROR, "abilityContext is null");
return;
}
auto uiContent = abilityContext->GetUIContent();
if (uiContent == nullptr) {
CM_LOG_E("uiContent is null");
ThrowError(asyncContext->env, PARAM_ERROR, "uiContent is null");
return;
}
OHOS::Ace::ModalUIExtensionCallbacks extensionCallbacks = {
[uiExtCallback](int32_t releaseCode) { uiExtCallback->OnRelease(releaseCode); },
[uiExtCallback](int32_t resultCode, const OHOS::AAFwk::Want& result) {
uiExtCallback->OnResult(resultCode, result); },
[uiExtCallback](const OHOS::AAFwk::WantParams& request) { uiExtCallback->OnReceive(request); },
[uiExtCallback](int32_t errorCode, const std::string& name, const std::string& message) {
uiExtCallback->OnError(errorCode, name, message); },
[uiExtCallback](const std::shared_ptr<OHOS::Ace::ModalUIExtensionProxy>& uiProxy) {
uiExtCallback->OnRemoteReady(uiProxy); },
[uiExtCallback]() { uiExtCallback->OnDestroy(); }
};
OHOS::Ace::ModalUIExtensionConfig uiExtConfig;
uiExtConfig.isProhibitBack = false;
int32_t sessionId = uiContent->CreateModalUIExtension(want, extensionCallbacks, uiExtConfig);
CM_LOG_I("end CreateModalUIExtension");
if (sessionId == 0) {
CM_LOG_E("CreateModalUIExtension failed");
ThrowError(asyncContext->env, PARAM_ERROR, "CreateModalUIExtension failed");
}
uiExtCallback->SetSessionId(sessionId);
return;
}
static std::string Base64Encode(const uint8_t *indata, const uint32_t length)
{
std::string encodeStr("");
if (indata == nullptr) {
CM_LOG_E("input param is invalid");
return encodeStr;
}
int i = 0;
while (i < (int)length) {
unsigned int octeta = i < (int)length ? *(indata + (i++)) : 0;
unsigned int octetb = i < (int)length ? *(indata + (i++)) : 0;
unsigned int octetc = i < (int)length ? *(indata + (i++)) : 0;
unsigned int triple = (octeta << BYTE_SHIFT_10) + (octetb << BYTE_SHIFT_8) + octetc;
encodeStr += g_base64Table[(triple >> BYTE_INDEX_THREE * BYTE_SHIFT_6) & BASE64_URL_TABLE_SIZE];
encodeStr += g_base64Table[(triple >> BYTE_INDEX_TWO * BYTE_SHIFT_6) & BASE64_URL_TABLE_SIZE];
encodeStr += g_base64Table[(triple >> BYTE_INDEX_ONE * BYTE_SHIFT_6) & BASE64_URL_TABLE_SIZE];
encodeStr += g_base64Table[(triple >> BYTE_INDEX_ZONE * BYTE_SHIFT_6) & BASE64_URL_TABLE_SIZE];
}
switch (BASE64_GROUP_NUM - (i % BASE64_GROUP_NUM)) {
case BYTE_END_TWO:
encodeStr.replace(encodeStr.length() - BYTE_END_TWO, 1, BASE64_PADDING);
encodeStr.replace(encodeStr.length() - BYTE_END_ONE, 1, BASE64_PADDING);
break;
case BYTE_END_ONE:
encodeStr.replace(encodeStr.length() - BYTE_END_ONE, 1, BASE64_PADDING);
break;
default:
break;
}
return encodeStr;
}
bool ParseCmUIAbilityContextReq(
napi_env env, const napi_value& obj, std::shared_ptr<OHOS::AbilityRuntime::AbilityContext>& abilityContext)
{
bool stageMode = false;
napi_status status = OHOS::AbilityRuntime::IsStageContext(env, obj, stageMode);
if (status != napi_ok || !stageMode) {
CM_LOG_E("not stage mode");
return false;
}
auto context = OHOS::AbilityRuntime::GetStageModeContext(env, obj);
if (context == nullptr) {
CM_LOG_E("get context failed");
return false;
}
abilityContext = OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(context);
if (abilityContext == nullptr) {
CM_LOG_E("get abilityContext failed");
return false;
}
CM_LOG_I("end ParseUIAbilityContextReq");
return true;
}
napi_value ParseUint32(napi_env env, napi_value object, uint32_t &store)
{
napi_valuetype type;
@ -89,7 +217,6 @@ napi_value ParseString(napi_env env, napi_value obj, CmBlob *&blob)
return nullptr;
}
// add 0 length check
if ((length == 0) || (length > CM_MAX_DATA_LEN)) {
CM_LOG_E("input string length is 0 or too large, length: %d", length);
return nullptr;
@ -125,6 +252,49 @@ napi_value ParseString(napi_env env, napi_value obj, CmBlob *&blob)
return GetInt32(env, 0);
}
napi_value GetUint8ArrayToBase64Str(napi_env env, napi_value object, std::string &certArray)
{
napi_typedarray_type arrayType;
napi_value arrayBuffer = nullptr;
size_t length = 0;
size_t offset = 0;
void *certData = nullptr;
napi_status status = napi_get_typedarray_info(
env, object, &arrayType, &length, static_cast<void **>(&certData), &arrayBuffer, &offset);
if (arrayType != napi_uint8_array) {
return nullptr;
}
if (status != napi_ok) {
CM_LOG_E("the type of param is not uint8_array");
return nullptr;
}
if (length > CM_MAX_DATA_LEN) {
CM_LOG_E("certData is too large, length = %x", length);
return nullptr;
}
uint8_t *data = nullptr;
if (length == 0) {
CM_LOG_D("The memory length created is only 1 Byte");
// The memory length created is only 1 Byte
data = static_cast<uint8_t *>(CmMalloc(1));
} else {
data = static_cast<uint8_t *>(CmMalloc(length));
}
if (data == nullptr) {
CM_LOG_E("Malloc failed");
return nullptr;
}
(void)memset_s(data, length, 0, length);
if (memcpy_s(data, length, certData, length) != EOK) {
CM_LOG_E("memcpy_s fail, length = %x", length);
return nullptr;
}
std::string encode = Base64Encode(data, length);
certArray = encode;
return GetInt32(env, 0);
}
static const char *GetJsErrorMsg(int32_t errCode)
{
auto iter = DIALOG_CODE_TO_MSG_MAP.find(errCode);

View File

@ -25,17 +25,6 @@
#include "want_params_wrapper.h"
namespace CMNapi {
namespace {
const std::string PARAM_UI_EXTENSION_TYPE = "ability.want.params.uiExtensionType";
const std::string SYS_COMMON_UI = "sys/commonUI";
const std::string CERT_MANAGER_BUNDLENAME = "com.ohos.certmanager";
const std::string CERT_MANAGER_ABILITYNAME = "CertPickerUIExtAbility";
const std::string CERT_MANAGER_PAGE_TYPE = "pageType";
constexpr int32_t PARAM0 = 0;
constexpr int32_t PARAM1 = 1;
constexpr int32_t PARAM_SIZE_TWO = 2;
constexpr int32_t ERROR_STR_LEN = 256;
} // namespace
CommonAsyncContext::CommonAsyncContext(napi_env env)
{
@ -53,6 +42,11 @@ CmUIExtensionCallback::CmUIExtensionCallback(std::shared_ptr<CmUIExtensionReques
this->reqContext_ = reqContext;
}
CmUIExtensionCallback::~CmUIExtensionCallback()
{
CM_LOG_D("~CmUIExtensionCallback");
}
void CmUIExtensionCallback::SetSessionId(const int32_t sessionId)
{
this->sessionId_ = sessionId;
@ -128,7 +122,7 @@ void CmUIExtensionCallback::OnDestroy()
}
}
void ProcessCallback(napi_env env, const CommonAsyncContext* asyncContext)
void CmUIExtensionCallback::ProcessCallback(napi_env env, const CommonAsyncContext* asyncContext)
{
napi_value args[PARAM_SIZE_TWO] = {nullptr};
@ -166,73 +160,6 @@ void CmUIExtensionCallback::SendMessageBack()
ProcessCallback(this->reqContext_->env, this->reqContext_.get());
}
bool ParseCmUIAbilityContextReq(
napi_env env, const napi_value& obj, std::shared_ptr<OHOS::AbilityRuntime::AbilityContext>& abilityContext)
{
bool stageMode = false;
napi_status status = OHOS::AbilityRuntime::IsStageContext(env, obj, stageMode);
if (status != napi_ok || !stageMode) {
CM_LOG_E("not stage mode");
return false;
}
auto context = OHOS::AbilityRuntime::GetStageModeContext(env, obj);
if (context == nullptr) {
CM_LOG_E("get context failed");
return false;
}
abilityContext = OHOS::AbilityRuntime::Context::ConvertTo<OHOS::AbilityRuntime::AbilityContext>(context);
if (abilityContext == nullptr) {
CM_LOG_E("get abilityContext failed");
return false;
}
CM_LOG_I("end ParseUIAbilityContextReq");
return true;
}
static void StartUIExtensionAbility(std::shared_ptr<CmUIExtensionRequestContext> asyncContext,
OHOS::AAFwk::Want want)
{
CM_LOG_D("begin StartUIExtensionAbility");
auto abilityContext = asyncContext->context;
if (abilityContext == nullptr) {
CM_LOG_E("abilityContext is null");
ThrowError(asyncContext->env, PARAM_ERROR, "abilityContext is null");
return;
}
auto uiContent = abilityContext->GetUIContent();
if (uiContent == nullptr) {
CM_LOG_E("uiContent is null");
ThrowError(asyncContext->env, PARAM_ERROR, "uiContent is null");
return;
}
auto uiExtCallback = std::make_shared<CmUIExtensionCallback>(asyncContext);
OHOS::Ace::ModalUIExtensionCallbacks extensionCallbacks = {
[uiExtCallback](int32_t releaseCode) { uiExtCallback->OnRelease(releaseCode); },
[uiExtCallback](int32_t resultCode, const OHOS::AAFwk::Want& result) {
uiExtCallback->OnResult(resultCode, result); },
[uiExtCallback](const OHOS::AAFwk::WantParams& request) { uiExtCallback->OnReceive(request); },
[uiExtCallback](int32_t errorCode, const std::string& name, const std::string& message) {
uiExtCallback->OnError(errorCode, name, message); },
[uiExtCallback](const std::shared_ptr<OHOS::Ace::ModalUIExtensionProxy>& uiProxy) {
uiExtCallback->OnRemoteReady(uiProxy); },
[uiExtCallback]() { uiExtCallback->OnDestroy(); }
};
OHOS::Ace::ModalUIExtensionConfig uiExtConfig;
uiExtConfig.isProhibitBack = false;
int32_t sessionId = uiContent->CreateModalUIExtension(want, extensionCallbacks, uiExtConfig);
CM_LOG_I("end CreateModalUIExtension");
if (sessionId == 0) {
CM_LOG_E("CreateModalUIExtension failed");
ThrowError(asyncContext->env, PARAM_ERROR, "CreateModalUIExtension failed");
}
uiExtCallback->SetSessionId(sessionId);
return;
}
static bool IsCmDialogPageTypeEnum(const uint32_t value)
{
switch (static_cast<CmDialogPageType>(value)) {
@ -291,10 +218,10 @@ napi_value CMNapiOpenCertManagerDialog(napi_env env, napi_callback_info info)
want.SetParam(PARAM_UI_EXTENSION_TYPE, SYS_COMMON_UI);
NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
auto uiExtCallback = std::make_shared<CmUIExtensionCallback>(asyncContext);
// Start ui extension by context.
StartUIExtensionAbility(asyncContext, want);
StartUIExtensionAbility(asyncContext, want, uiExtCallback);
CM_LOG_D("cert manager dialog end");
return result;
}
} // namespace CMNapi
} // namespace CMNapi

View File

@ -0,0 +1,236 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cm_napi_open_dialog.h"
#include "syspara/parameters.h"
#include "securec.h"
#include "cert_manager_api.h"
#include "cm_log.h"
#include "cm_napi_dialog_common.h"
#include "want.h"
#include "want_params_wrapper.h"
namespace CMNapi {
class CmInstallUIExtensionCallback : public CmUIExtensionCallback {
public:
explicit CmInstallUIExtensionCallback(
std::shared_ptr<CmUIExtensionRequestContext>& reqContext) : CmUIExtensionCallback(reqContext)
{
this->reqContext_ = reqContext;
}
~CmInstallUIExtensionCallback() override
{
CM_LOG_D("~CmInstallUIExtensionCallback");
}
void OnRelease(const int32_t releaseCode) override
{
CM_LOG_D("InstallUIExtensionComponent OnRelease(), releaseCode = %d", releaseCode);
if (SetErrorCode(CMR_DIALOG_ERROR_OPERATION_CANCELS)) {
SendMessageBack();
}
}
void OnResult(const int32_t resultCode, const OHOS::AAFwk::Want& result) override
{
CM_LOG_D("InstallUIExtensionComponent OnResult(), resultCode = %d", resultCode);
this->resultCode_ = resultCode;
this->resultWant_ = result;
if (SetErrorCode(CMR_DIALOG_ERROR_INSTALL_FAILED)) {
SendMessageBack();
}
}
void OnReceive(const OHOS::AAFwk::WantParams& request) override
{
CM_LOG_D("InstallUIExtensionComponent OnReceive()");
this->reqContext_->uri = request.GetStringParam("uri");
if (SetErrorCode(0)) {
SendMessageBack();
}
}
void ProcessCallback(napi_env env, const CommonAsyncContext* asyncContext) override
{
napi_value args = nullptr;
if (asyncContext->errCode == CM_SUCCESS) {
NAPI_CALL_RETURN_VOID(env,
napi_create_string_utf8(env, asyncContext->uri.c_str(), NAPI_AUTO_LENGTH, &args));
} else {
args = GenerateBusinessError(env, asyncContext->errCode);
}
if (asyncContext->deferred != nullptr) {
if (asyncContext->errCode == CM_SUCCESS) {
NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, asyncContext->deferred, args));
} else {
NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncContext->deferred, args));
}
}
}
void OnDestroy() override
{
CM_LOG_D("InstallUIExtensionComponent OnDestroy()");
}
private:
bool SetErrorCode(int32_t errCode)
{
if (this->reqContext_ == nullptr) {
CM_LOG_E("OnError reqContext is nullptr");
return false;
}
if (this->alreadyCallback_) {
CM_LOG_D("alreadyCallback");
return false;
}
this->alreadyCallback_ = true;
this->reqContext_->errCode = errCode;
return true;
};
int32_t resultCode_ = 0;
OHOS::AAFwk::Want resultWant_;
std::shared_ptr<CmUIExtensionRequestContext> reqContext_ = nullptr;
bool alreadyCallback_ = false;
};
static bool IsCmCertificateScopeEnum(const uint32_t value)
{
switch (static_cast<CertificateScope>(value)) {
case CertificateScope::CURRENT_USER:
return true;
default:
return false;
}
}
static bool IsCmCertificateTypeAndConvert(const uint32_t value, uint32_t &pageType)
{
switch (static_cast<CmCertificateType>(value)) {
case CmCertificateType::CA_CERT:
pageType = CmDialogPageType::PAGE_INSTALL_CA_GUIDE;
return true;
default:
return false;
}
}
static napi_value CMCheckArgvVaild(napi_env env, std::shared_ptr<CmUIExtensionRequestContext> asyncContext,
napi_value argv[PARAM_SIZE_FOUR])
{
napi_value result = nullptr;
// Parse first argument for context.
if (!ParseCmUIAbilityContextReq(env, argv[PARAM0], asyncContext->context)) {
CM_LOG_E("ParseUIAbilityContextReq failed");
ThrowError(env, PARAM_ERROR, "Get context failed.");
return result;
}
// Parse second argument for certificate type.
uint32_t certificateType = 0;
result = ParseUint32(env, argv[PARAM1], certificateType);
if (result == nullptr) {
CM_LOG_E("parse type failed");
ThrowError(env, PARAM_ERROR, "parse type failed");
return result;
}
if (!IsCmCertificateTypeAndConvert(certificateType, asyncContext->certificateType)) {
CM_LOG_E("certificateType invalid");
ThrowError(env, PARAM_ERROR, "certificateType invalid");
return nullptr;
}
// Parse third argument for certificateScope.
result = ParseUint32(env, argv[PARAM2], asyncContext->certificateScope);
if (result == nullptr) {
CM_LOG_E("parse type failed");
ThrowError(env, PARAM_ERROR, "parse type failed");
return result;
}
if (!IsCmCertificateScopeEnum(asyncContext->certificateScope)) {
CM_LOG_E("certificateScope invalid");
ThrowError(env, PARAM_ERROR, "certificateScope invalid");
return nullptr;
}
// Parse fourth argument for cert.
result = GetUint8ArrayToBase64Str(env, argv[PARAM3], asyncContext->certStr);
if (result == nullptr) {
ThrowError(env, PARAM_ERROR, "cert is not a uint8Array or the length is 0 or too long.");
CM_LOG_E("could not get cert");
return nullptr;
}
asyncContext->env = env;
return GetInt32(env, 0);
}
napi_value CMNapiOpenInstallCertManagerDialog(napi_env env, napi_callback_info info)
{
CM_LOG_D("cert install dialog enter");
napi_value result = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &result));
if (OHOS::system::GetParameter("const.product.devicetype", "") != "2in1") {
CM_LOG_E("deviceType is not 2in1");
std::string errMsg = "DeviceType Error. deviceType is not 2in1";
ThrowError(env, DIALOG_ERROR_NOT_SUPPORTED, errMsg);
return result;
}
size_t argc = PARAM_SIZE_FOUR;
napi_value argv[PARAM_SIZE_FOUR] = { nullptr };
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
if (argc != PARAM_SIZE_FOUR) {
CM_LOG_E("params number mismatch");
std::string errMsg = "Parameter Error. Params number mismatch, need " + std::to_string(PARAM_SIZE_FOUR)
+ ", given " + std::to_string(argc);
ThrowError(env, PARAM_ERROR, errMsg);
return result;
}
auto asyncContext = std::make_shared<CmUIExtensionRequestContext>(env);
if (CMCheckArgvVaild(env, asyncContext, argv) == nullptr) {
CM_LOG_E("check argv vaild faild");
return nullptr;
}
std::string labelName;
int32_t resCode = asyncContext->context->GetResourceManager()->GetStringByName("app_name", labelName);
if (resCode != CM_SUCCESS) {
CM_LOG_E("get labelName faild, code is %d", resCode);
return nullptr;
}
OHOS::AAFwk::Want want;
want.SetElementName(CERT_MANAGER_BUNDLENAME, CERT_MANAGER_ABILITYNAME);
want.SetParam(CERT_MANAGER_PAGE_TYPE, static_cast<int32_t>(asyncContext->certificateType));
want.SetParam(CERT_MANAGER_CERTIFICATE_DATA, asyncContext->certStr);
want.SetParam(CERT_MANAGER_CERTSCOPE_TYPE, static_cast<int32_t>(asyncContext->certificateScope));
want.SetParam(CERT_MANAGER_CALLER_BUNDLENAME, labelName);
want.SetParam(PARAM_UI_EXTENSION_TYPE, SYS_COMMON_UI);
NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
auto uiExtCallback = std::make_shared<CmInstallUIExtensionCallback>(asyncContext);
StartUIExtensionAbility(asyncContext, want, uiExtCallback);
CM_LOG_D("cert install dialog end");
return result;
}
} // namespace CMNapi