!296 提供并开放拉起证书管理界面的API接口

Merge pull request !296 from 张余/master
This commit is contained in:
openharmony_ci 2024-07-28 15:39:41 +00:00 committed by Gitee
commit 977828e1cd
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 503 additions and 1 deletions

View File

@ -27,7 +27,10 @@ group("cert_manager_sdk_test") {
group("cert_manager_napi") {
if (os_level == "standard") {
if (support_jsapi) {
deps = [ "./interfaces/kits/napi:certmanager" ]
deps = [
"./interfaces/kits/napi:certmanager",
"./interfaces/kits/napi:certmanagerdialog",
]
}
}
}

View File

@ -35,6 +35,8 @@
"deps": {
"components": [
"ability_base",
"ace_engine",
"ability_runtime",
"access_token",
"bounds_checking_function",
"bundle_framework",

View File

@ -68,3 +68,55 @@ ohos_shared_library("certmanager") {
subsystem_name = "security"
part_name = "certificate_manager"
}
ohos_shared_library("certmanagerdialog") {
branch_protector_ret = "pac_ret"
sanitize = {
cfi = true
cfi_cross_dso = true
boundary_sanitize = true
debug = false
integer_overflow = true
ubsan = true
}
defines = [
"L2_STANDARD",
"_HARDWARE_ROOT_KEY_",
"_CM_LOG_ENABLE_",
]
include_dirs = [
"../../../frameworks/cert_manager_standard/main/common/include",
"include",
"include/dialog",
]
sources = [
"src/cm_napi_common.cpp",
"src/dialog/cm_napi_dialog.cpp",
"src/dialog/cm_napi_open_dialog.cpp",
]
external_deps = [
"ability_base:base",
"ability_base:want",
"ability_runtime:ability_context_native",
"ability_runtime:ability_manager",
"ability_runtime:abilitykit_native",
"ability_runtime:app_context",
"ability_runtime:napi_base_context",
"ability_runtime:napi_common",
"ace_engine:ace_uicontent",
"c_utils:utils",
"napi:ace_napi",
]
cflags_cc = [
"-Wall",
"-Werror",
]
deps = [ "../../innerkits/cert_manager_standard/main:cert_manager_sdk" ]
relative_install_dir = "module/security"
subsystem_name = "security"
part_name = "certificate_manager"
}

View File

@ -0,0 +1,81 @@
/*
* 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.
*/
#ifndef CM_NAPI_OPEN_DIALOG_H
#define CM_NAPI_OPEN_DIALOG_H
#include "ability_context.h"
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "napi_base_context.h"
#include "napi_common_want.h"
#include "ui_content.h"
#include "cm_napi_common.h"
namespace CMNapi {
napi_value CMNapiOpenCertManagerDialog(napi_env env, napi_callback_info info);
enum CmDialogErrorCode {
DIALOG_ERROR_GENERIC = 29700001,
DIALOG_ERROR_OPERATION_CANCELED = 29700002,
};
enum CmDialogPageType {
PAGE_MAIN = 1,
PAGE_CA_CERTIFICATE = 2,
PAGE_CREDENTIAL = 3,
PAGE_INSTALL_CERTIFICATE = 4
};
struct CommonAsyncContext {
explicit CommonAsyncContext(napi_env env);
virtual ~CommonAsyncContext();
napi_env env = nullptr;
napi_status status = napi_invalid_arg;
int32_t errCode = 0;
napi_deferred deferred = nullptr; // promise handle
};
struct CmUIExtensionRequestContext : public CommonAsyncContext {
explicit CmUIExtensionRequestContext(napi_env env) : CommonAsyncContext(env) {};
std::shared_ptr<OHOS::AbilityRuntime::AbilityContext> context = nullptr;
OHOS::AAFwk::Want want;
uint32_t pageType;
};
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();
private:
bool SetErrorCode(int32_t errCode);
int32_t sessionId_ = 0;
int32_t resultCode_ = 0;
OHOS::AAFwk::Want resultWant_;
std::shared_ptr<CmUIExtensionRequestContext> reqContext_ = nullptr;
bool alreadyCallback_ = false;
};
} // namespace CertManagerNapi
#endif // CM_NAPI_OPEN_DIALOG_H

View File

@ -0,0 +1,86 @@
/*
* 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 "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cm_napi_common.h"
#include "cm_napi_open_dialog.h"
namespace CMNapi {
inline void AddInt32Property(napi_env env, napi_value object, const char *name, int32_t value)
{
napi_value property = nullptr;
NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, value, &property));
NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, name, property));
}
static napi_value CreateCmErrorCode(napi_env env)
{
napi_value dialogErrorCode = nullptr;
NAPI_CALL(env, napi_create_object(env, &dialogErrorCode));
AddInt32Property(env, dialogErrorCode, "ERROR_GENERIC", DIALOG_ERROR_GENERIC);
AddInt32Property(env, dialogErrorCode, "ERROR_OPERATION_CANCELED", DIALOG_ERROR_OPERATION_CANCELED);
return dialogErrorCode;
}
static napi_value CreateCmDialogPageType(napi_env env)
{
napi_value dialogPageType = nullptr;
NAPI_CALL(env, napi_create_object(env, &dialogPageType));
AddInt32Property(env, dialogPageType, "PAGE_MAIN", PAGE_MAIN);
AddInt32Property(env, dialogPageType, "PAGE_CA_CERTIFICATE", PAGE_CA_CERTIFICATE);
AddInt32Property(env, dialogPageType, "PAGE_CREDENTIAL", PAGE_CREDENTIAL);
AddInt32Property(env, dialogPageType, "PAGE_INSTALL_CERTIFICATE", PAGE_INSTALL_CERTIFICATE);
return dialogPageType;
}
} // namespace CertManagerNapi
using namespace CMNapi;
extern "C" {
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)),
/* dialog */
DECLARE_NAPI_FUNCTION("openCertificateManagerDialog", CMNapiOpenCertManagerDialog),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
return exports;
}
static napi_module g_module = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = CMDialogNapiRegister,
.nm_modname = "security.certManagerDialog",
.nm_priv = nullptr,
.reserved = { nullptr },
};
__attribute__((constructor)) void CMDialogNapiRegister(void)
{
napi_module_register(&g_module);
}
}

View File

@ -0,0 +1,278 @@
/*
* 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 "securec.h"
#include "cert_manager_api.h"
#include "cm_log.h"
#include "cm_napi_common.h"
#include "want.h"
#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;
} // namespace
CommonAsyncContext::CommonAsyncContext(napi_env env)
{
CM_LOG_D("CommonAsyncContext");
this->env = env;
}
CommonAsyncContext::~CommonAsyncContext()
{
CM_LOG_D("~CommonAsyncContext");
}
CmUIExtensionCallback::CmUIExtensionCallback(std::shared_ptr<CmUIExtensionRequestContext>& reqContext)
{
this->reqContext_ = reqContext;
}
void CmUIExtensionCallback::SetSessionId(const int32_t sessionId)
{
this->sessionId_ = sessionId;
}
bool CmUIExtensionCallback::SetErrorCode(int32_t code)
{
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 = code;
return true;
}
void CmUIExtensionCallback::OnRelease(const int32_t releaseCode)
{
CM_LOG_D("UIExtensionComponent OnRelease(), releaseCode = %d", releaseCode);
if (SetErrorCode(releaseCode)) {
SendMessageBack();
}
}
void CmUIExtensionCallback::OnResult(const int32_t resultCode, const OHOS::AAFwk::Want& result)
{
CM_LOG_D("UIExtensionComponent OnResult(), resultCode = %d", resultCode);
this->resultCode_ = resultCode;
this->resultWant_ = result;
if (SetErrorCode(0)) {
SendMessageBack();
}
}
void CmUIExtensionCallback::OnReceive(const OHOS::AAFwk::WantParams& request)
{
CM_LOG_D("UIExtensionComponent OnReceive()");
if (SetErrorCode(0)) {
SendMessageBack();
}
}
void CmUIExtensionCallback::OnError(const int32_t errorCode, const std::string& name, const std::string& message)
{
CM_LOG_E("UIExtensionComponent OnError(), errorCode = %d, name = %s, message = %s",
errorCode, name.c_str(), message.c_str());
if (SetErrorCode(errorCode)) {
SendMessageBack();
}
}
void CmUIExtensionCallback::OnRemoteReady(const std::shared_ptr<OHOS::Ace::ModalUIExtensionProxy>& uiProxy)
{
CM_LOG_D("UIExtensionComponent OnRemoteReady()");
}
void CmUIExtensionCallback::OnDestroy()
{
CM_LOG_D("UIExtensionComponent OnDestroy()");
if (SetErrorCode(0)) {
SendMessageBack();
}
}
void ProcessCallback(napi_env env, const CommonAsyncContext* asyncContext)
{
napi_value args[PARAM_SIZE_TWO] = {nullptr};
if (asyncContext->errCode == CM_SUCCESS) {
NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, 0, &args[PARAM0]));
NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, true, &args[PARAM1]));
} else {
args[PARAM0] = GenerateBusinessError(env, asyncContext->errCode);
NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &args[PARAM1]));
}
if (asyncContext->deferred != nullptr) {
GeneratePromise(env, asyncContext->deferred, asyncContext->errCode, args, CM_ARRAY_SIZE(args));
}
}
void CmUIExtensionCallback::SendMessageBack()
{
CM_LOG_I("start SendMessageBack");
if (this->reqContext_ == nullptr) {
CM_LOG_E("reqContext is nullptr");
return;
}
auto abilityContext = this->reqContext_->context;
if (abilityContext != nullptr) {
auto uiContent = abilityContext->GetUIContent();
if (uiContent != nullptr) {
CM_LOG_D("CloseModalUIExtension");
uiContent->CloseModalUIExtension(this->sessionId_);
}
}
CM_LOG_D("ProcessCallback");
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)
{
CM_LOG_D("begin StartUIExtensionAbility");
if (asyncContext == nullptr) {
CM_LOG_E("asyncContext is null");
ThrowError(asyncContext->env, PARAM_ERROR, "asyncContext is null");
return;
}
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(asyncContext->want, extensionCallbacks, uiExtConfig);
CM_LOG_I("end CreateModalUIExtension sessionId = %d", sessionId);
if (sessionId == 0) {
CM_LOG_E("CreateModalUIExtension failed, sessionId is %d", sessionId);
ThrowError(asyncContext->env, PARAM_ERROR, "CreateModalUIExtension failed");
}
uiExtCallback->SetSessionId(sessionId);
return;
}
napi_value CMNapiOpenCertManagerDialog(napi_env env, napi_callback_info info)
{
CM_LOG_I("cert manager dialog enter");
size_t argc = PARAM_SIZE_TWO;
napi_value argv[PARAM_SIZE_TWO] = { nullptr };
napi_value result = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &result));
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
if (argc != PARAM_SIZE_TWO) {
CM_LOG_E("params number mismatch");
std::string errMsg = "Parameter Error. Params number mismatch, need " + std::to_string(PARAM_SIZE_TWO)
+ ", given " + std::to_string(argc);
ThrowError(env, PARAM_ERROR, errMsg);
return result;
}
// Parse first argument for context.
auto asyncContext = std::make_shared<CmUIExtensionRequestContext>(env);
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 page type.
result = ParseUint32(env, argv[PARAM1], asyncContext->pageType);
if (result == nullptr) {
CM_LOG_E("parse type failed");
ThrowError(env, PARAM_ERROR, "parse type failed");
return result;
}
asyncContext->env = env;
OHOS::AAFwk::Want want;
want.SetElementName(CERT_MANAGER_BUNDLENAME, CERT_MANAGER_ABILITYNAME);
want.SetParam(CERT_MANAGER_PAGE_TYPE, static_cast<int32_t>(asyncContext->pageType));
want.SetParam(PARAM_UI_EXTENSION_TYPE, SYS_COMMON_UI);
asyncContext->want = want;
NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result));
// Start ui extension by context.
StartUIExtensionAbility(asyncContext);
CM_LOG_D("cert manager dialog end");
return result;
}
} // namespace CMNapi