!12261 添加仓颉extensionAbility适配

Merge pull request !12261 from 罗明/master
This commit is contained in:
openharmony_ci
2025-01-07 03:02:01 +00:00
committed by Gitee
46 changed files with 3587 additions and 169 deletions
+1
View File
@@ -39,6 +39,7 @@ ohos_shared_library("cj_ability_ffi") {
"${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context",
"${ability_runtime_path}/tools/aa/include",
"${ability_runtime_path}/frameworks/cj/ffi",
"${ability_runtime_path}/frameworks/cj/ffi/context",
"${ability_runtime_services_path}/common/include",
]
@@ -23,6 +23,7 @@
#include "cj_ability_lifecycle_callback_impl.h"
#include "cj_application_state_change_callback.h"
#include "cj_environment_callback.h"
#include "cj_context.h"
#include "ffi_remote_data.h"
#include "running_process_info.h"
#include "want.h"
@@ -40,10 +41,10 @@ enum CjAppProcessState {
STATE_DESTROY
};
class CJApplicationContext : public FFI::FFIData {
class CJApplicationContext : public FfiContext::CJContext {
public:
explicit CJApplicationContext(std::weak_ptr<AbilityRuntime::ApplicationContext> &&applicationContext)
: applicationContext_(std::move(applicationContext)) {};
: FfiContext::CJContext(applicationContext.lock()), applicationContext_(std::move(applicationContext)) {};
int GetArea();
std::shared_ptr<AppExecFwk::ApplicationInfo> GetApplicationInfo();
+11 -2
View File
@@ -15,6 +15,14 @@ import("//build/ohos.gni")
import("//foundation/ability/ability_runtime/ability_runtime.gni")
import("//foundation/ability/ability_runtime/cj_environment/cj_environment.gni")
config("cj_context_ffi_public_config") {
visibility = [
":*",
"${ability_runtime_native_path}/ability/*",
]
include_dirs = [ "${ability_runtime_path}/frameworks/cj/ffi/context" ]
}
ohos_shared_library("cj_context_ffi") {
defines = [
"AMS_LOG_TAG = \"CJ_ABILITY_FFI\"",
@@ -30,13 +38,14 @@ ohos_shared_library("cj_context_ffi") {
"${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context",
"${ability_runtime_path}/frameworks/cj/ffi",
"${ability_runtime_path}/frameworks/cj/ffi/context",
"${ability_runtime_path}/frameworks/cj/ffi/application_context/include",
"${ability_runtime_services_path}/common/include",
]
public_configs = [ ":cj_context_ffi_public_config" ]
deps = [
"${ability_runtime_innerkits_path}/ability_manager:ability_manager",
"${ability_runtime_native_path}/ability:ability_context_native",
"${ability_runtime_native_path}/ability/native:abilitykit_native",
"${ability_runtime_native_path}/appkit:app_context",
"${ability_runtime_path}/frameworks/cj/ffi:cj_ability_ffi",
]
+52 -86
View File
@@ -15,7 +15,10 @@
#include "cj_context.h"
#include "context.h"
#include "cj_utils_ffi.h"
#include "cj_macro.h"
#include "cj_application_context.h"
#include "cj_ability_runtime_error.h"
#include "bundle_manager_convert.h"
#include "hilog_tag_wrapper.h"
@@ -26,83 +29,34 @@ using namespace OHOS::FFI;
using namespace OHOS::AbilityRuntime;
using namespace OHOS::CJSystemapi::BundleManager;
static constexpr int32_t ABILITY_CONTEXT = 0;
static constexpr int32_t APPLICATION_CONTEXT = 1;
static constexpr int32_t ABILITY_STAGE_CONTEXT = 2;
static constexpr int32_t CJ_CONTEXT = 3;
std::shared_ptr<AbilityRuntime::Context> GetCJContextFromCJ(int64_t id)
std::shared_ptr<AbilityRuntime::Context> GetContextFromCJ(int64_t id)
{
auto cjContext = FFI::FFIData::GetData<CJContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null cj AbilityContext");
TAG_LOGE(AAFwkTag::CONTEXT, "null cjContext");
return nullptr;
}
auto context = cjContext->GetContext();
return context;
return cjContext->GetContext();
}
std::shared_ptr<AbilityRuntime::Context> GetAbilityContextFromCJ(int64_t id)
extern "C" {
CJ_EXPORT void* FfiContextGetContext(int64_t id, int32_t type)
{
auto cjAbilityContext = FFI::FFIData::GetData<CJAbilityContext>(id);
if (cjAbilityContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null cj AbilityContext");
return nullptr;
}
auto abilityContext = cjAbilityContext->GetAbilityContext();
return abilityContext;
}
std::shared_ptr<AbilityRuntime::Context> GetApplicationContextFromCJ(int64_t id)
{
auto cjAppContext = FFI::FFIData::GetData<ApplicationContextCJ::CJApplicationContext>(id);
if (cjAppContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null cj ApplicationContext");
return nullptr;
}
auto appContext = cjAppContext->GetApplicationContext();
return appContext;
}
std::shared_ptr<AbilityRuntime::Context> GetAbilityStageContextFromCJ(int64_t id)
{
auto cjAbilityStageContext = FFI::FFIData::GetData<CJAbilityStageContext>(id);
if (cjAbilityStageContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null cj AbilityContext");
return nullptr;
}
auto abilityStageContext = cjAbilityStageContext->GetContext();
return abilityStageContext;
}
std::shared_ptr<AbilityRuntime::Context> GetContextFromCJ(int64_t id, int32_t type)
{
if (type == ABILITY_CONTEXT) {
return GetAbilityContextFromCJ(id);
} else if (type == APPLICATION_CONTEXT) {
return GetApplicationContextFromCJ(id);
} else if (type == ABILITY_STAGE_CONTEXT) {
return GetAbilityStageContextFromCJ(id);
} else if (type == CJ_CONTEXT) {
return GetCJContextFromCJ(id);
}
return nullptr;
}
void* FfiContextGetContext(int64_t id, int32_t type)
{
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
(void)type;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return nullptr;
}
// return shared_ptr.get() is not safe!
return nativeContext.get();
}
RetApplicationInfo FfiContextGetApplicationInfo(int64_t id, int32_t type)
CJ_EXPORT RetApplicationInfo FfiContextGetApplicationInfo(int64_t id, int32_t type)
{
(void)type;
RetApplicationInfo appInfo;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return appInfo;
@@ -115,9 +69,10 @@ RetApplicationInfo FfiContextGetApplicationInfo(int64_t id, int32_t type)
return Convert::ConvertApplicationInfo(*applicationInfo);
}
char* FfiContextGetFilesDir(int64_t id, int32_t type)
CJ_EXPORT char* FfiContextGetFilesDir(int64_t id, int32_t type)
{
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
(void)type;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return nullptr;
@@ -126,9 +81,10 @@ char* FfiContextGetFilesDir(int64_t id, int32_t type)
return CreateCStringFromString(filesDir);
}
char* FfiContextGetCacheDir(int64_t id, int32_t type)
CJ_EXPORT char* FfiContextGetCacheDir(int64_t id, int32_t type)
{
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
(void)type;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return nullptr;
@@ -137,9 +93,10 @@ char* FfiContextGetCacheDir(int64_t id, int32_t type)
return CreateCStringFromString(cacheDir);
}
char* FfiContextGetTempDir(int64_t id, int32_t type)
CJ_EXPORT char* FfiContextGetTempDir(int64_t id, int32_t type)
{
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
(void)type;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return nullptr;
@@ -148,9 +105,10 @@ char* FfiContextGetTempDir(int64_t id, int32_t type)
return CreateCStringFromString(tempDir);
}
char* FfiContextGetResourceDir(int64_t id, int32_t type)
CJ_EXPORT char* FfiContextGetResourceDir(int64_t id, int32_t type)
{
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
(void)type;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return nullptr;
@@ -159,9 +117,10 @@ char* FfiContextGetResourceDir(int64_t id, int32_t type)
return CreateCStringFromString(resourceDir);
}
char* FfiContextGetDatabaseDir(int64_t id, int32_t type)
CJ_EXPORT char* FfiContextGetDatabaseDir(int64_t id, int32_t type)
{
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
(void)type;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return nullptr;
@@ -170,9 +129,10 @@ char* FfiContextGetDatabaseDir(int64_t id, int32_t type)
return CreateCStringFromString(databaseDir);
}
char* FfiContextGetPreferencesDir(int64_t id, int32_t type)
CJ_EXPORT char* FfiContextGetPreferencesDir(int64_t id, int32_t type)
{
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
(void)type;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return nullptr;
@@ -181,9 +141,10 @@ char* FfiContextGetPreferencesDir(int64_t id, int32_t type)
return CreateCStringFromString(preferencesDir);
}
char* FfiContextGetBundleCodeDir(int64_t id, int32_t type)
CJ_EXPORT char* FfiContextGetBundleCodeDir(int64_t id, int32_t type)
{
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
(void)type;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return nullptr;
@@ -192,9 +153,10 @@ char* FfiContextGetBundleCodeDir(int64_t id, int32_t type)
return CreateCStringFromString(bundleCodeDir);
}
char* FfiContextGetDistributedFilesDir(int64_t id, int32_t type)
CJ_EXPORT char* FfiContextGetDistributedFilesDir(int64_t id, int32_t type)
{
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
(void)type;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return nullptr;
@@ -203,9 +165,10 @@ char* FfiContextGetDistributedFilesDir(int64_t id, int32_t type)
return CreateCStringFromString(distributedFilesDir);
}
char* FfiContextGetCloudFileDir(int64_t id, int32_t type)
CJ_EXPORT char* FfiContextGetCloudFileDir(int64_t id, int32_t type)
{
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
(void)type;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return nullptr;
@@ -214,9 +177,10 @@ char* FfiContextGetCloudFileDir(int64_t id, int32_t type)
return CreateCStringFromString(cloudFileDir);
}
int32_t FfiContextGetArea(int64_t id, int32_t type)
CJ_EXPORT int32_t FfiContextGetArea(int64_t id, int32_t type)
{
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
(void)type;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return -1;
@@ -224,7 +188,7 @@ int32_t FfiContextGetArea(int64_t id, int32_t type)
return nativeContext->GetArea();
}
int64_t FfiContextGetApplicationContext()
CJ_EXPORT int64_t FfiContextGetApplicationContext()
{
auto appContext = ApplicationContextCJ::CJApplicationContext::GetCJApplicationContext(
AbilityRuntime::Context::GetApplicationContext());
@@ -235,9 +199,10 @@ int64_t FfiContextGetApplicationContext()
return appContext->GetID();
}
char* FfiContextGetGroupDir(int64_t id, int32_t type, char* groupId)
CJ_EXPORT char* FfiContextGetGroupDir(int64_t id, int32_t type, char* groupId)
{
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
(void)type;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return nullptr;
@@ -246,9 +211,10 @@ char* FfiContextGetGroupDir(int64_t id, int32_t type, char* groupId)
return CreateCStringFromString(groupDir);
}
int64_t FfiContextCreateModuleContext(int64_t id, int32_t type, char* moduleName)
CJ_EXPORT int64_t FfiContextCreateModuleContext(int64_t id, int32_t type, char* moduleName)
{
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id, type);
(void)type;
std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
if (nativeContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null context");
return -1;
@@ -265,6 +231,6 @@ int64_t FfiContextCreateModuleContext(int64_t id, int32_t type, char* moduleName
}
return cjContext->GetID();
}
}
}
}
+4 -24
View File
@@ -18,16 +18,14 @@
#include <memory>
#include "bundle_manager_convert.h"
#include "cj_macro.h"
#include "cj_ability_stage_context.h"
#include "cj_application_context.h"
#include "ability_runtime/cj_ability_context.h"
#include "ffi_remote_data.h"
namespace OHOS {
namespace AbilityRuntime {
class Context;
}
namespace FfiContext {
using namespace OHOS::AbilityRuntime;
using namespace OHOS::CJSystemapi::BundleManager;
class CJContext : public FFI::FFIData {
public:
@@ -40,24 +38,6 @@ public:
private:
std::shared_ptr<AbilityRuntime::Context> context_;
};
extern "C" {
CJ_EXPORT void* FfiContextGetContext(int64_t id, int32_t type);
CJ_EXPORT RetApplicationInfo FfiContextGetApplicationInfo(int64_t id, int32_t type);
CJ_EXPORT char* FfiContextGetFilesDir(int64_t id, int32_t type);
CJ_EXPORT char* FfiContextGetCacheDir(int64_t id, int32_t type);
CJ_EXPORT char* FfiContextGetTempDir(int64_t id, int32_t type);
CJ_EXPORT char* FfiContextGetResourceDir(int64_t id, int32_t type);
CJ_EXPORT char* FfiContextGetDatabaseDir(int64_t id, int32_t type);
CJ_EXPORT char* FfiContextGetPreferencesDir(int64_t id, int32_t type);
CJ_EXPORT char* FfiContextGetBundleCodeDir(int64_t id, int32_t type);
CJ_EXPORT char* FfiContextGetDistributedFilesDir(int64_t id, int32_t type);
CJ_EXPORT char* FfiContextGetCloudFileDir(int64_t id, int32_t type);
CJ_EXPORT int32_t FfiContextGetArea(int64_t id, int32_t type);
CJ_EXPORT int64_t FfiContextGetApplicationContext();
CJ_EXPORT char* FfiContextGetGroupDir(int64_t id, int32_t type, char* groupId);
CJ_EXPORT int64_t FfiContextCreateModuleContext(int64_t id, int32_t type, char* moduleName);
};
}
}
#endif // OHOS_ABILITY_RUNTIME_CJ_CONTEXT_H
+17
View File
@@ -109,6 +109,23 @@ ohos_shared_library("ability_context_native") {
external_deps += [ "hichecker:libhichecker" ]
}
if (cj_frontend) {
sources += [ "ability_runtime/cj_extension_context.cpp" ]
include_dirs += [ "${ability_runtime_path}/frameworks/cj/ffi" ]
deps += [
"${ability_runtime_path}/frameworks/cj/ffi:cj_ability_ffi",
"${ability_runtime_path}/frameworks/cj/ffi/context:cj_context_ffi",
]
external_deps += [
"bundle_framework:cj_bundle_manager_ffi",
"napi:cj_bind_ffi",
"napi:cj_bind_native",
]
}
innerapi_tags = [ "platformsdk" ]
subsystem_name = "ability"
part_name = "ability_runtime"
@@ -0,0 +1,154 @@
/*
* 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 "cj_extension_context.h"
#include "cj_macro.h"
#include "cj_common_ffi.h"
#include "cj_utils_ffi.h"
#include "bundle_manager_convert.h"
#include "hilog_tag_wrapper.h"
namespace OHOS {
namespace AbilityRuntime {
using namespace CJSystemapi::BundleManager;
class CJExtensionContextImpl {
public:
CJExtensionContextImpl(const std::shared_ptr<ExtensionContext> &context,
std::shared_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo)
: context_(context), abilityInfo_(abilityInfo) {}
int32_t GetConfiguration(CConfiguration* cConfig);
int32_t GetCurrentHapModuleInfo(RetHapModuleInfo* hapInfo);
int32_t GetExtAbilityInfo(RetExtensionAbilityInfo* retInfo);
std::weak_ptr<ExtensionContext> context_;
std::weak_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo_;
};
CJExtensionContext::CJExtensionContext(const std::shared_ptr<ExtensionContext> &context,
std::shared_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo)
: FfiContext::CJContext(context)
{
impl_ = std::make_shared<CJExtensionContextImpl>(context, abilityInfo);
}
int32_t CJExtensionContextImpl::GetConfiguration(CConfiguration* cConfig)
{
auto context = context_.lock();
if (context == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto configuration = context->GetConfiguration();
if (configuration == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "GetConfiguration return nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
*cConfig = CreateCConfiguration(*configuration);
return SUCCESS_CODE;
}
int32_t CJExtensionContextImpl::GetExtAbilityInfo(RetExtensionAbilityInfo* retInfo)
{
auto context = context_.lock();
if (context == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto abilityInfo = abilityInfo_.lock();
if (abilityInfo == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "GetAbilityInfo return nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto hapModuleInfo = context->GetHapModuleInfo();
if (hapModuleInfo == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "GetCurrentHapModuleInfo return nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto isExist = [&abilityInfo](const AppExecFwk::ExtensionAbilityInfo& info) {
TAG_LOGD(AAFwkTag::CONTEXT, "%{public}s, %{public}s", info.bundleName.c_str(), info.name.c_str());
return info.bundleName == abilityInfo->bundleName && info.name == abilityInfo->name;
};
auto infoIter = std::find_if(
hapModuleInfo->extensionInfos.begin(), hapModuleInfo->extensionInfos.end(), isExist);
if (infoIter == hapModuleInfo->extensionInfos.end()) {
TAG_LOGE(AAFwkTag::CONTEXT, "get extensionAbilityInfo fail");
return ERR_INVALID_INSTANCE_CODE;
}
*retInfo = Convert::ConvertExtensionAbilityInfo(*infoIter);
return SUCCESS_CODE;
}
int32_t CJExtensionContextImpl::GetCurrentHapModuleInfo(RetHapModuleInfo* hapInfo)
{
auto context = context_.lock();
if (context == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto hapModuleInfo = context->GetHapModuleInfo();
if (hapModuleInfo == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "GetCurrentHapModuleInfo return nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
*hapInfo = Convert::ConvertHapModuleInfo(*hapModuleInfo);
return SUCCESS_CODE;
}
extern "C" {
CJ_EXPORT int32_t FFICJExtCtxGetConfig(int64_t id, void* paramConfig)
{
if (paramConfig == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "input param paramConfig is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::GetData<CJExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "GetCJExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
return cjContext->impl_->GetConfiguration(static_cast<CConfiguration*>(paramConfig));
}
CJ_EXPORT int32_t FFICJExtCtxGetExtAbilityInfo(int64_t id, void* retInfo)
{
if (retInfo == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "input param retInfo is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::GetData<CJExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "GetCJExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
return cjContext->impl_->GetExtAbilityInfo(static_cast<RetExtensionAbilityInfo*>(retInfo));
}
CJ_EXPORT int32_t FFICJExtCtxGetCurrentHapModuleInfo(int64_t id, void* hapInfo)
{
if (hapInfo == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "input param hapInfo is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::GetData<CJExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "GetCJExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
return cjContext->impl_->GetCurrentHapModuleInfo(static_cast<RetHapModuleInfo*>(hapInfo));
}
}
} // namespace AbilityRuntime
} // namespace OHOS
+81 -1
View File
@@ -391,7 +391,11 @@ ohos_shared_library("abilitykit_native") {
"${ability_runtime_path}/frameworks/cj/ffi",
"${ability_runtime_path}/frameworks/cj/ffi/application_context/include",
]
deps += [ "${ability_runtime_path}/frameworks/cj/ffi:cj_ability_ffi" ]
public_configs += [ "${ability_runtime_path}/frameworks/cj/ffi/context:cj_context_ffi_public_config" ]
deps += [
"${ability_runtime_path}/frameworks/cj/ffi:cj_ability_ffi",
"${ability_runtime_path}/frameworks/cj/ffi/context:cj_context_ffi",
]
external_deps += [
"ace_engine:ace_uicontent",
"bundle_framework:cj_bundle_manager_ffi",
@@ -514,6 +518,22 @@ ohos_shared_library("extensionkit_native") {
"jsoncpp:jsoncpp",
]
if (cj_frontend) {
sources += [
"${ability_runtime_native_path}/ability/native/cj_extension_common.cpp",
"${ability_runtime_native_path}/ability/native/cj_ui_extension_object.cpp",
]
include_dirs +=
[ "${ability_runtime_path}/cj_environment/interfaces/inner_api" ]
deps += [ "${ability_runtime_path}/frameworks/cj/ffi:cj_ability_ffi" ]
external_deps += [
"napi:cj_bind_ffi",
"napi:cj_bind_native",
]
}
if (ability_runtime_graphics) {
external_deps += [ "ability_base:session_info" ]
public_external_deps += [
@@ -1456,6 +1476,29 @@ ohos_shared_library("ui_extension") {
"window_manager:windowstage_kit",
]
if (cj_frontend) {
sources += [
"${ability_runtime_native_path}/ability/native/ui_extension_base/cj_ui_extension_base.cpp",
"${ability_runtime_native_path}/ability/native/ui_extension_base/cj_ui_extension_content_session.cpp",
"${ability_runtime_native_path}/ability/native/ui_extension_base/cj_ui_extension_context.cpp",
]
include_dirs += [
"${ability_runtime_path}/cj_environment/interfaces/inner_api",
"${ability_runtime_path}/frameworks/cj/ffi",
]
deps += [
":extensionkit_native",
"${ability_runtime_path}/frameworks/cj/ffi:cj_ability_ffi",
]
external_deps += [
"napi:cj_bind_ffi",
"napi:cj_bind_native",
]
}
if (ability_runtime_graphics) {
defines = [ "SUPPORT_SCREEN" ]
external_deps += [
@@ -1549,6 +1592,11 @@ ohos_shared_library("share_extension") {
"napi:ace_napi",
]
if (cj_frontend) {
sources += [ "${ability_runtime_native_path}/ability/native/share_extension_ability/cj_share_extension.cpp" ]
external_deps += [ "napi:cj_bind_native" ]
}
if (ability_runtime_graphics) {
external_deps += [ "window_manager:libwm" ]
}
@@ -1600,6 +1648,11 @@ ohos_shared_library("action_extension") {
"napi:ace_napi",
]
if (cj_frontend) {
sources += [ "${ability_runtime_native_path}/ability/native/action_extension_ability/cj_action_extension.cpp" ]
external_deps += [ "napi:cj_bind_native" ]
}
if (ability_runtime_graphics) {
external_deps += [ "window_manager:libwm" ]
}
@@ -1815,6 +1868,17 @@ ohos_shared_library("embedded_ui_extension") {
"napi:ace_napi",
]
if (cj_frontend) {
sources += [ "${ability_runtime_native_path}/ability/native/embedded_ui_extension_ability/cj_embedded_ui_extension.cpp" ]
deps += [ "${ability_runtime_path}/frameworks/cj/ffi:cj_ability_ffi" ]
external_deps += [
"napi:cj_bind_ffi",
"napi:cj_bind_native",
]
}
if (ability_runtime_graphics) {
external_deps += [ "window_manager:libwm" ]
}
@@ -2029,6 +2093,22 @@ ohos_shared_library("photo_editor_extension") {
"napi:ace_napi",
]
if (cj_frontend) {
sources += [
"${ability_runtime_native_path}/ability/native/photo_editor_extension_ability/cj_photo_editor_extension.cpp",
"${ability_runtime_native_path}/ability/native/photo_editor_extension_ability/cj_photo_editor_extension_context.cpp",
"${ability_runtime_native_path}/ability/native/photo_editor_extension_ability/cj_photo_editor_extension_impl.cpp",
]
deps += [ "${ability_runtime_path}/frameworks/cj/ffi:cj_ability_ffi" ]
external_deps += [
"image_framework:cj_image_ffi",
"napi:cj_bind_ffi",
"napi:cj_bind_native",
]
}
if (ability_runtime_graphics) {
external_deps += [ "window_manager:libwm" ]
}
@@ -16,12 +16,31 @@
#include "cj_ability_connect_callback_object.h"
#include "cj_remote_object_ffi.h"
#include "cj_macro.h"
#include "hilog_tag_wrapper.h"
using namespace OHOS::AbilityRuntime;
namespace OHOS {
namespace AbilityRuntime {
struct CJUIExtensionConnectionKey {
AAFwk::Want want;
int64_t id;
};
struct KeyCompare {
bool operator()(const CJUIExtensionConnectionKey &key1, const CJUIExtensionConnectionKey &key2) const
{
if (key1.id < key2.id) {
return true;
}
return false;
}
};
namespace {
CJAbilityConnectCallbackFuncs* g_cjAbilityConnectCallbackFuncs = nullptr;
static CJAbilityConnectCallbackFuncs* g_cjAbilityConnectCallbackFuncs = nullptr;
static std::map<CJUIExtensionConnectionKey, sptr<CJAbilityConnectCallback>, KeyCompare> g_connects;
static int64_t g_serialNumber = 0;
static std::mutex g_connectMtx;
}
void RegisterCJAbilityConnectCallbackFuncs(void (*registerFunc)(CJAbilityConnectCallbackFuncs* result))
@@ -36,6 +55,56 @@ void RegisterCJAbilityConnectCallbackFuncs(void (*registerFunc)(CJAbilityConnect
registerFunc(g_cjAbilityConnectCallbackFuncs);
}
sptr<CJAbilityConnectCallback> CJAbilityConnectCallback::Create(int64_t id, AAFwk::Want& want)
{
auto connection = sptr<CJAbilityConnectCallback>::MakeSptr(id);
CJUIExtensionConnectionKey key;
{
std::unique_lock<std::mutex> lock(g_connectMtx);
key.id = g_serialNumber;
key.want = want;
g_serialNumber = (g_serialNumber + 1) % INT32_MAX;
g_connects.emplace(key, connection);
}
connection->SetConnectionId(key.id);
return connection;
}
void CJAbilityConnectCallback::Remove(int64_t connectId)
{
std::unique_lock<std::mutex> lock(g_connectMtx);
auto item = std::find_if(g_connects.begin(), g_connects.end(), [&connectId](const auto &obj) {
return connectId == obj.first.id;
});
if (item != g_connects.end()) {
TAG_LOGD(AAFwkTag::UI_EXT, "conn ability exists");
g_connects.erase(item);
} else {
TAG_LOGD(AAFwkTag::UI_EXT, "conn ability not exists");
}
}
void CJAbilityConnectCallback::FindConnection(AAFwk::Want& want, sptr<CJAbilityConnectCallback>& connection,
int64_t connectId)
{
std::unique_lock<std::mutex> lock(g_connectMtx);
TAG_LOGD(AAFwkTag::UI_EXT, "Disconnect ability enter, connection:%{public}" PRId64, connectId);
auto item = std::find_if(g_connects.begin(), g_connects.end(), [connectId](const auto &obj) {
return connectId == obj.first.id;
});
if (item != g_connects.end()) {
// match id
want = item->first.want;
connection = item->second;
TAG_LOGD(AAFwkTag::UI_EXT, "find conn ability exist");
}
}
CJAbilityConnectCallback::~CJAbilityConnectCallback()
{
if (g_cjAbilityConnectCallbackFuncs == nullptr) {
@@ -74,4 +143,18 @@ void CJAbilityConnectCallback::OnAbilityDisconnectDone(const AppExecFwk::Element
ElementNameHandle elementNameHandle = const_cast<AppExecFwk::ElementName*>(&element);
g_cjAbilityConnectCallbackFuncs->onDisconnect(callbackId_, elementNameHandle, resultCode);
Remove(connectId_);
}
void CJAbilityConnectCallback::OnFailed(int32_t resultCode)
{
TAG_LOGD(AAFwkTag::CONTEXT, "called, resultCode:%{public}d", resultCode);
if (g_cjAbilityConnectCallbackFuncs == nullptr) {
TAG_LOGE(AAFwkTag::CONTEXT, "null cangjie callback");
return;
}
g_cjAbilityConnectCallbackFuncs->onFailed(callbackId_, resultCode);
}
} // AbilityRuntime
} // OHOS
@@ -17,6 +17,7 @@
#include "hilog_tag_wrapper.h"
#include "js_action_extension.h"
#include "cj_action_extension.h"
#include "runtime.h"
#include "ui_extension_context.h"
@@ -31,6 +32,8 @@ ActionExtension *ActionExtension::Create(const std::unique_ptr<Runtime> &runtime
switch (runtime->GetLanguage()) {
case Runtime::Language::JS:
return JsActionExtension::Create(runtime);
case Runtime::Language::CJ:
return CJActionExtension::Create(runtime);
default:
return new ActionExtension();
}
@@ -0,0 +1,41 @@
/*
* 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 "cj_action_extension.h"
#include "hilog_tag_wrapper.h"
#include "hitrace_meter.h"
#include "cj_ui_extension_base.h"
namespace OHOS {
namespace AbilityRuntime {
CJActionExtension *CJActionExtension::Create(const std::unique_ptr<Runtime> &runtime)
{
return new CJActionExtension(runtime);
}
CJActionExtension::CJActionExtension(const std::unique_ptr<Runtime> &runtime)
{
auto uiExtensionBaseImpl = std::make_shared<CJUIExtensionBase>(runtime);
uiExtensionBaseImpl->SetExtType(CJExtensionAbilityType::ACTION);
SetUIExtensionBaseImpl(uiExtensionBaseImpl);
}
CJActionExtension::~CJActionExtension()
{
TAG_LOGD(AAFwkTag::ACTION_EXT, "destructor");
}
} // namespace AbilityRuntime
} // namespace OHOS
@@ -0,0 +1,50 @@
/*
* 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 "cj_extension_common.h"
#include "hilog_tag_wrapper.h"
#include "cj_runtime.h"
namespace OHOS {
namespace AbilityRuntime {
using namespace OHOS::AppExecFwk;
std::shared_ptr<CJExtensionCommon> CJExtensionCommon::Create(CJUIExtensionObject cjObj)
{
return std::make_shared<CJExtensionCommon>(cjObj);
}
CJExtensionCommon::CJExtensionCommon(CJUIExtensionObject cjObj)
: cjObj_(cjObj) {}
void CJExtensionCommon::OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration> &fullConfig)
{
TAG_LOGI(AAFwkTag::EXT, "called");
if (!fullConfig) {
TAG_LOGE(AAFwkTag::EXT, "invalid config");
return;
}
cjObj_.OnConfigurationUpdate(fullConfig);
}
void CJExtensionCommon::OnMemoryLevel(int level)
{
TAG_LOGD(AAFwkTag::EXT, "called");
cjObj_.OnMemoryLevel(level);
}
} // namespace AbilityRuntime
} // namespace OHOS
@@ -0,0 +1,224 @@
/*
* 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 "cj_ui_extension_object.h"
#include "configuration_utils.h"
#include "hilog_tag_wrapper.h"
#include "hitrace_meter.h"
#include "int_wrapper.h"
#include "cj_utils_ffi.h"
namespace OHOS {
namespace AbilityRuntime {
struct CJLaunchParam {
int32_t launchReason;
int32_t lastExitReason;
char* lastExitMessage;
};
struct CJExtAbilityFuncs {
int64_t (*createCjExtAbility)(const char* name, int32_t type);
void (*releaseCjExtAbility)(int64_t id, int32_t type);
void (*cjExtAbilityInit)(int64_t id, int32_t type, ExtAbilityHandle extAbility);
void (*cjExtAbilityOnCreate)(int64_t id, int32_t type, WantHandle want, CJLaunchParam launchParam);
void (*cjExtAbilityOnDestroy)(int64_t id, int32_t type);
void (*cjExtAbilityOnSessionCreate)(int64_t id, int32_t type, WantHandle want, int64_t sessionId);
void (*cjExtAbilityOnSessionDestroy)(int64_t id, int32_t type, int64_t sessionId);
void (*cjExtAbilityOnForeground)(int64_t id, int32_t type);
void (*cjExtAbilityOnBackground)(int64_t id, int32_t type);
void (*cjExtAbilityOnConfigurationUpdate)(int64_t id, int32_t type, CConfiguration configuration);
void (*cjExtAbilityOnMemoryLevel)(int64_t id, int32_t type, int32_t level);
void (*cjExtAbilityOnStartContentEditing)(int64_t id, int32_t type, const char* imageUri, WantHandle want,
int64_t sessionId);
};
} // namespace AbilityRuntime
} // namespace OHOS
namespace {
static OHOS::AbilityRuntime::CJExtAbilityFuncs g_cjFuncs {};
static const int32_t CJ_OBJECT_ERR_CODE = -1;
} // namespace
namespace OHOS {
namespace AbilityRuntime {
void CJUIExtensionObject::Destroy()
{
TAG_LOGD(AAFwkTag::UI_EXT, "Destroy");
if (cjID_ != 0) {
if (g_cjFuncs.releaseCjExtAbility == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "releaseCjExtAbility is not registered");
return;
}
g_cjFuncs.releaseCjExtAbility(cjID_, GetType());
cjID_ = 0;
}
}
int32_t CJUIExtensionObject::Init(const std::string& abilityName, CJExtensionAbilityType type,
ExtAbilityHandle extAbility)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::UI_EXT, "called");
type_ = type;
if (g_cjFuncs.createCjExtAbility == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "createCjExtAbility is not registered");
return CJ_OBJECT_ERR_CODE;
}
cjID_ = g_cjFuncs.createCjExtAbility(abilityName.c_str(), GetType());
if (cjID_ == 0) {
TAG_LOGE(AAFwkTag::UI_EXT,
"Failed to Init CJUIExtensionObject. CJExtAbility: %{public}s is not registered", abilityName.c_str());
return CJ_OBJECT_ERR_CODE;
}
if (g_cjFuncs.cjExtAbilityInit == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "cjExtAbilityInit is not registered");
return CJ_OBJECT_ERR_CODE;
}
g_cjFuncs.cjExtAbilityInit(cjID_, GetType(), extAbility);
return 0;
}
void CJUIExtensionObject::OnCreate(const AAFwk::Want &want, AAFwk::LaunchParam &launchParam)
{
if (g_cjFuncs.cjExtAbilityOnCreate == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "cjExtAbilityOnCreate is not registered");
return;
}
WantHandle wantHandle = const_cast<AAFwk::Want*>(&want);
CJLaunchParam param;
param.launchReason = launchParam.launchReason;
param.lastExitReason = launchParam.lastExitReason;
param.lastExitMessage = CreateCStringFromString(launchParam.lastExitMessage);
g_cjFuncs.cjExtAbilityOnCreate(cjID_, GetType(), wantHandle, param);
}
void CJUIExtensionObject::OnDestroy()
{
if (g_cjFuncs.cjExtAbilityOnDestroy == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "cjExtAbilityOnDestroy is not registered");
return;
}
g_cjFuncs.cjExtAbilityOnDestroy(cjID_, GetType());
}
void CJUIExtensionObject::OnSessionCreate(const AAFwk::Want &want, int64_t sessionId)
{
if (g_cjFuncs.cjExtAbilityOnSessionCreate == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "cjExtAbilityOnSessionCreate is not registered");
return;
}
WantHandle wantHandle = const_cast<AAFwk::Want*>(&want);
g_cjFuncs.cjExtAbilityOnSessionCreate(cjID_, GetType(), wantHandle, sessionId);
}
void CJUIExtensionObject::OnSessionDestroy(int64_t sessionId)
{
if (g_cjFuncs.cjExtAbilityOnSessionDestroy == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "cjExtAbilityOnSessionDestroy is not registered");
return;
}
g_cjFuncs.cjExtAbilityOnSessionDestroy(cjID_, GetType(), sessionId);
}
void CJUIExtensionObject::OnForeground()
{
if (g_cjFuncs.cjExtAbilityOnForeground == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "cjExtAbilityOnForeground is not registered");
return;
}
g_cjFuncs.cjExtAbilityOnForeground(cjID_, GetType());
}
void CJUIExtensionObject::OnBackground()
{
if (g_cjFuncs.cjExtAbilityOnBackground == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "cjExtAbilityOnBackground is not registered");
return;
}
g_cjFuncs.cjExtAbilityOnBackground(cjID_, GetType());
}
void CJUIExtensionObject::OnConfigurationUpdate(std::shared_ptr<AppExecFwk::Configuration> fullConfig)
{
if (g_cjFuncs.cjExtAbilityOnConfigurationUpdate == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "cjExtAbilityOnConfigurationUpdate is not registered");
return;
}
auto cfg = CreateCConfiguration(*fullConfig);
g_cjFuncs.cjExtAbilityOnConfigurationUpdate(cjID_, GetType(), cfg);
}
void CJUIExtensionObject::OnMemoryLevel(int level)
{
if (g_cjFuncs.cjExtAbilityOnMemoryLevel == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "cjExtAbilityOnMemoryLevel is not registered");
return;
}
g_cjFuncs.cjExtAbilityOnMemoryLevel(cjID_, GetType(), level);
}
void CJUIExtensionObject::OnStartContentEditing(const std::string& imageUri, const AAFwk::Want &want, int64_t sessionId)
{
if (g_cjFuncs.cjExtAbilityOnStartContentEditing == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "cjExtAbilityOnStartContentEditing is not registered");
return;
}
WantHandle wantHandle = const_cast<AAFwk::Want*>(&want);
char* cstr = CreateCStringFromString(imageUri);
if (cstr == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "OnStartContentEditing failed");
return;
}
g_cjFuncs.cjExtAbilityOnStartContentEditing(cjID_, GetType(), cstr, wantHandle, sessionId);
}
extern "C" {
CJ_EXPORT void FFIRegisterCJExtAbilityFuncs(void (*registerFunc)(CJExtAbilityFuncs*))
{
TAG_LOGD(AAFwkTag::UI_EXT, "FFIRegisterCJExtAbilityFuncs start");
if (g_cjFuncs.createCjExtAbility != nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "Repeated registration for cj functions of CJExtAbility");
return;
}
if (registerFunc == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "FFIRegisterCJExtAbilityFuncs failed, registerFunc is nullptr");
return;
}
registerFunc(&g_cjFuncs);
TAG_LOGD(AAFwkTag::UI_EXT, "FFIRegisterCJExtAbilityFuncs end");
}
} // extern "C"
} // namespace AbilityRuntime
} // namespace OHOS
@@ -0,0 +1,41 @@
/*
* 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 "cj_embedded_ui_extension.h"
#include "hilog_tag_wrapper.h"
#include "hitrace_meter.h"
#include "cj_ui_extension_base.h"
namespace OHOS {
namespace AbilityRuntime {
CJEmbeddedUIExtension *CJEmbeddedUIExtension::Create(const std::unique_ptr<Runtime> &runtime)
{
return new CJEmbeddedUIExtension(runtime);
}
CJEmbeddedUIExtension::CJEmbeddedUIExtension(const std::unique_ptr<Runtime> &runtime)
{
auto uiExtensionBaseImpl = std::make_shared<CJUIExtensionBase>(runtime);
uiExtensionBaseImpl->SetExtType(CJExtensionAbilityType::EMBEDDED);
SetUIExtensionBaseImpl(uiExtensionBaseImpl);
}
CJEmbeddedUIExtension::~CJEmbeddedUIExtension()
{
TAG_LOGD(AAFwkTag::EMBEDDED_EXT, "destructor");
}
} // namespace AbilityRuntime
} // namespace OHOS
@@ -17,6 +17,7 @@
#include "hilog_tag_wrapper.h"
#include "js_embedded_ui_extension.h"
#include "cj_embedded_ui_extension.h"
#include "runtime.h"
#include "ui_extension_context.h"
@@ -31,6 +32,8 @@ EmbeddedUIExtension *EmbeddedUIExtension::Create(const std::unique_ptr<Runtime>
switch (runtime->GetLanguage()) {
case Runtime::Language::JS:
return JsEmbeddedUIExtension::Create(runtime);
case Runtime::Language::CJ:
return CJEmbeddedUIExtension::Create(runtime);
default:
return new (std::nothrow) EmbeddedUIExtension();
}
@@ -0,0 +1,77 @@
/*
* 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 "cj_photo_editor_extension.h"
#include "cj_photo_editor_extension_impl.h"
#include "hilog_tag_wrapper.h"
namespace OHOS {
namespace AbilityRuntime {
CJPhotoEditorExtension *CJPhotoEditorExtension::Create(const std::unique_ptr<Runtime> &runtime)
{
return new (std::nothrow) CJPhotoEditorExtension(runtime);
}
CJPhotoEditorExtension::CJPhotoEditorExtension(const std::unique_ptr<Runtime> &runtime)
{
impl_ = std::make_shared<CJPhotoEditorExtensionImpl>(runtime);
impl_->SetExtType(CJExtensionAbilityType::PHOTO_EDITOR);
SetUIExtensionBaseImpl(impl_);
}
void CJPhotoEditorExtension::Init(const std::shared_ptr<AppExecFwk::AbilityLocalRecord> &record,
const std::shared_ptr<AppExecFwk::OHOSApplication> &application,
std::shared_ptr<AppExecFwk::AbilityHandler> &handler,
const sptr<IRemoteObject> &token)
{
TAG_LOGD(AAFwkTag::UI_EXT, "Begin init photo editor extension");
std::shared_ptr<PhotoEditorExtensionContext> context = std::make_shared<PhotoEditorExtensionContext>();
context->SetToken(token);
auto appContext = Context::GetApplicationContext();
if (appContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null appContext");
return;
}
context->SetApplicationInfo(appContext->GetApplicationInfo());
context->SetResourceManager(appContext->GetResourceManager());
context->SetParentContext(appContext);
if (record == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null record");
return;
}
TAG_LOGD(AAFwkTag::UI_EXT, "Begin init abilityInfo");
auto abilityInfo = record->GetAbilityInfo();
context->SetAbilityInfo(abilityInfo);
context->InitHapModuleInfo(abilityInfo);
context->SetConfiguration(appContext->GetConfiguration());
if (abilityInfo->applicationInfo.multiProjects) {
std::shared_ptr<Context> moduleContext = context->CreateModuleContext(abilityInfo->moduleName);
if (moduleContext != nullptr) {
auto rm = moduleContext->GetResourceManager();
context->SetResourceManager(rm);
}
}
Extension::Init(record, application, handler, token);
impl_->SetContext(context);
impl_->SetAbilityInfo(Extension::abilityInfo_);
auto extensionCommon = impl_->Init(record, application, handler, token);
ExtensionBase<PhotoEditorExtensionContext>::SetExtensionCommon(extensionCommon);
}
} // namespace AbilityRuntime
} // namespace OHOS
@@ -0,0 +1,145 @@
/*
* 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 "cj_photo_editor_extension_context.h"
#include "cj_ui_extension_object.h"
#include "cj_photo_editor_extension_impl.h"
#include "cj_common_ffi.h"
#include "pixel_map_impl.h"
#include "image_ffi.h"
#include "hilog_tag_wrapper.h"
namespace OHOS {
namespace AbilityRuntime {
int32_t CJPhotoEditorExtensionContext::SaveEditedContentWithUri(const std::string& uri, AAFwk::Want& want)
{
TAG_LOGD(AAFwkTag::UI_EXT, "SaveEditedContentWithUri begin");
auto context = context_.lock();
if (context == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "Context is released");
return static_cast<int32_t>(PhotoEditorErrorCode::ERROR_CODE_INTERNAL_ERROR);
}
if (want_.lock() == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "PhotoEditorExtensionContext does not call SetWant");
return static_cast<int32_t>(PhotoEditorErrorCode::ERROR_CODE_INTERNAL_ERROR);
}
PhotoEditorErrorCode errCode = context->SaveEditedContent(uri, want);
return static_cast<int32_t>(errCode);
}
int32_t CJPhotoEditorExtensionContext::SaveEditedContentWithImage(std::shared_ptr<Media::PixelMap> image,
const Media::PackOption& packOption, AAFwk::Want& want)
{
auto context = context_.lock();
if (context == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "Context is released");
return static_cast<int32_t>(PhotoEditorErrorCode::ERROR_CODE_INTERNAL_ERROR);
}
if (want_.lock() == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "PhotoEditorExtensionContext does not call SetWant");
return static_cast<int32_t>(PhotoEditorErrorCode::ERROR_CODE_INTERNAL_ERROR);
}
PhotoEditorErrorCode errCode = context->SaveEditedContent(image, packOption, want);
return static_cast<int32_t>(errCode);
}
extern "C" {
CJ_EXPORT int32_t FFIPhotoExtAbilityGetContext(ExtAbilityHandle extAbility, int64_t* id)
{
auto ability = static_cast<CJPhotoEditorExtensionImpl*>(extAbility);
if (ability == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJPhotoEditorExtensionContext failed, extAbility is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (id == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJPhotoEditorExtensionContext failed, param id is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto context = ability->GetContext();
if (context == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJPhotoEditorExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::Create<CJPhotoEditorExtensionContext>(context);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJPhotoEditorExtensionContext failed, extAbilityContext is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
ability->SetCjContext(cjContext);
*id = cjContext->GetID();
return SUCCESS_CODE;
}
CJ_EXPORT int32_t FFIPhotoExtCtxSaveEditedContentWithUri(int64_t id, const char* uri, WantHandle want)
{
if (uri == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param uri is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (want == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param want is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::GetData<CJPhotoEditorExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJPhotoEditorExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
return cjContext->SaveEditedContentWithUri(std::string(uri), *actualWant);
}
static Media::PackOption ParseCPackOption(const CPackingOption& option)
{
return Media::PackOption {
.format = option.format,
.quality = option.quality,
.desiredDynamicRange = Media::EncodeDynamicRange(option.desiredDynamicRange),
.needsPackProperties = option.needsPackProperties,
};
}
CJ_EXPORT int32_t FFIPhotoExtCtxSaveEditedContentWithImage(int64_t id, int64_t imageId, CPackingOption option,
WantHandle want)
{
if (want == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param want is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::GetData<CJPhotoEditorExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJPhotoEditorExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto pixelMapImpl = OHOS::FFI::FFIData::GetData<Media::PixelMapImpl>(imageId);
if (pixelMapImpl == nullptr || pixelMapImpl->GetRealPixelMap() == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetPixelMapImpl result is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
return cjContext->SaveEditedContentWithImage(pixelMapImpl->GetRealPixelMap(), ParseCPackOption(option),
*actualWant);
}
}
} // namespace AbilityRuntime
} // namespace OHOS
@@ -0,0 +1,61 @@
/*
* 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 "cj_photo_editor_extension_impl.h"
#include "hilog_tag_wrapper.h"
#include "cj_ui_extension_content_session.h"
namespace OHOS {
namespace AbilityRuntime {
CJPhotoEditorExtensionImpl::CJPhotoEditorExtensionImpl(const std::unique_ptr<Runtime> &runtime)
: CJUIExtensionBase(runtime)
{}
void CJPhotoEditorExtensionImpl::OnForeground(const Want &want, sptr<AAFwk::SessionInfo> sessionInfo)
{
CJUIExtensionBase::OnForeground(want, sessionInfo);
auto componentId = sessionInfo->uiExtensionComponentId;
if (uiExtensionComponentIdSet_.find(componentId) == uiExtensionComponentIdSet_.end()) {
OnStartContentEditing(want, sessionInfo);
uiExtensionComponentIdSet_.emplace(componentId);
}
}
void CJPhotoEditorExtensionImpl::OnStartContentEditing(const AAFwk::Want &want,
const sptr<AAFwk::SessionInfo> &sessionInfo)
{
TAG_LOGD(AAFwkTag::UI_EXT, "CJPhotoEditorExtensionImpl want: (%{public}s), begin", want.ToUri().c_str());
std::string imageUri = want.GetStringParam("ability.params.stream");
if (imageUri.empty()) {
TAG_LOGE(AAFwkTag::UI_EXT, "empty imageUri");
return;
}
TAG_LOGD(AAFwkTag::UI_EXT, "CJPhotoEditorExtensionImpl imageUri: (%{public}s), begin", imageUri.c_str());
if (context_ == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return;
}
auto newWant = std::make_shared<AAFwk::Want>(want);
context_->SetWant(newWant);
if (cjContext_ != nullptr) {
cjContext_->SetWant(newWant);
}
cjObj.OnStartContentEditing(imageUri, want, contentSessions_[sessionInfo->uiExtensionComponentId]->GetID());
}
} // namespace AbilityRuntime
} // namespace OHOS
@@ -16,6 +16,7 @@
#include "photo_editor_extension.h"
#include "hilog_tag_wrapper.h"
#include "js_photo_editor_extension.h"
#include "cj_photo_editor_extension.h"
#include "runtime.h"
#include "photo_editor_extension_context.h"
@@ -30,6 +31,8 @@ PhotoEditorExtension *PhotoEditorExtension::Create(const std::unique_ptr<Runtime
switch (runtime->GetLanguage()) {
case Runtime::Language::JS:
return JsPhotoEditorExtension::Create(runtime);
case Runtime::Language::CJ:
return CJPhotoEditorExtension::Create(runtime);
default:
return new PhotoEditorExtension();
}
@@ -0,0 +1,41 @@
/*
* 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 "cj_share_extension.h"
#include "hilog_tag_wrapper.h"
#include "hitrace_meter.h"
#include "cj_ui_extension_base.h"
namespace OHOS {
namespace AbilityRuntime {
CJShareExtension *CJShareExtension::Create(const std::unique_ptr<Runtime> &runtime)
{
return new CJShareExtension(runtime);
}
CJShareExtension::CJShareExtension(const std::unique_ptr<Runtime> &runtime)
{
auto uiExtensionBaseImpl = std::make_shared<CJUIExtensionBase>(runtime);
uiExtensionBaseImpl->SetExtType(CJExtensionAbilityType::SHARE);
SetUIExtensionBaseImpl(uiExtensionBaseImpl);
}
CJShareExtension::~CJShareExtension()
{
TAG_LOGD(AAFwkTag::SHARE_EXT, "destructor");
}
} // namespace AbilityRuntime
} // namespace OHOS
@@ -17,6 +17,7 @@
#include "hilog_tag_wrapper.h"
#include "js_share_extension.h"
#include "cj_share_extension.h"
#include "runtime.h"
#include "ui_extension_context.h"
@@ -31,6 +32,8 @@ ShareExtension *ShareExtension::Create(const std::unique_ptr<Runtime> &runtime)
switch (runtime->GetLanguage()) {
case Runtime::Language::JS:
return JsShareExtension::Create(runtime);
case Runtime::Language::CJ:
return CJShareExtension::Create(runtime);
default:
return new ShareExtension();
}
@@ -0,0 +1,587 @@
/*
* 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 "cj_ui_extension_base.h"
#include <type_traits>
#include <vector>
#include "ability_info.h"
#include "ability_manager_client.h"
#include "configuration_utils.h"
#include "connection_manager.h"
#include "context.h"
#include "hilog_tag_wrapper.h"
#include "hilog_wrapper.h"
#include "hitrace_meter.h"
#include "insight_intent_executor_info.h"
#include "insight_intent_executor_mgr.h"
#include "int_wrapper.h"
#include "cj_runtime.h"
#include "cj_common_ffi.h"
#include "cj_extension_common.h"
#include "cj_application_context.h"
#include "ui_extension_window_command.h"
#include "want_params_wrapper.h"
namespace OHOS {
namespace AbilityRuntime {
CJUIExtensionBase::CJUIExtensionBase(const std::unique_ptr<Runtime> &runtime)
: cjRuntime_(static_cast<CJRuntime&>(*runtime))
{
abilityResultListeners_ = std::make_shared<AbilityResultListeners>();
}
CJUIExtensionBase::~CJUIExtensionBase()
{
TAG_LOGD(AAFwkTag::UI_EXT, "destructor");
cjObj.Destroy();
}
std::shared_ptr<ExtensionCommon> CJUIExtensionBase::Init(const std::shared_ptr<AbilityLocalRecord> &record,
const std::shared_ptr<OHOSApplication> &application, std::shared_ptr<AbilityHandler> &handler,
const sptr<IRemoteObject> &token)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::UI_EXT, "called");
if (abilityInfo_ == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null abilityInfo");
return nullptr;
}
int32_t ret = cjObj.Init(abilityInfo_->name, extType_, this);
if (ret != 0) {
TAG_LOGE(AAFwkTag::UI_EXT, "cjUIExtAbility Init failed");
return nullptr;
}
handler_ = handler;
RegisterDisplayInfoChangedListener();
return CJExtensionCommon::Create(cjObj);
}
void CJUIExtensionBase::OnStart(const AAFwk::Want &want, AAFwk::LaunchParam &launchParam,
sptr<AAFwk::SessionInfo> sessionInfo)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::UI_EXT, "called");
#ifdef SUPPORT_GRAPHICS
if (context_ != nullptr && sessionInfo != nullptr) {
auto configUtils = std::make_shared<ConfigurationUtils>();
configUtils->InitDisplayConfig(context_->GetConfiguration(), context_->GetResourceManager(),
sessionInfo->displayId, sessionInfo->density, sessionInfo->orientation);
}
#endif // SUPPORT_GRAPHICS
if (InsightIntentExecuteParam::IsInsightIntentExecute(want)) {
launchParam.launchReason = AAFwk::LaunchReason::LAUNCHREASON_INSIGHT_INTENT;
}
cjObj.OnCreate(want, launchParam);
}
void CJUIExtensionBase::OnStop()
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::UI_EXT, "called");
cjObj.OnDestroy();
#ifdef SUPPORT_GRAPHICS
UnregisterDisplayInfoChangedListener();
#endif // SUPPORT_GRAPHICS
OnStopCallBack();
}
void CJUIExtensionBase::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback)
{
(void)callbackInfo;
isAsyncCallback = false;
OnStop();
return;
}
void CJUIExtensionBase::OnStopCallBack()
{
if (context_ == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return;
}
auto ret = ConnectionManager::GetInstance().DisconnectCaller(context_->GetToken());
if (ret) {
ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid());
TAG_LOGD(AAFwkTag::UI_EXT, "service connection not disconnected");
}
auto applicationContext = Context::GetApplicationContext();
if (applicationContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null application context");
return;
}
auto appContext = ApplicationContextCJ::CJApplicationContext::GetCJApplicationContext(applicationContext);
if (appContext != nullptr) {
appContext->DispatchOnAbilityDestroy(cjObj.GetID());
}
}
void CJUIExtensionBase::OnCommand(const AAFwk::Want &want, bool restart, int32_t startId)
{
// do nothing
}
void CJUIExtensionBase::OnCommandWindow(
const AAFwk::Want &want, const sptr<AAFwk::SessionInfo> &sessionInfo, AAFwk::WindowCommand winCmd)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::UI_EXT, "called");
if (sessionInfo == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null sessionInfo");
return;
}
if (InsightIntentExecuteParam::IsInsightIntentExecute(want) && winCmd == AAFwk::WIN_CMD_FOREGROUND) {
bool finish = ForegroundWindowWithInsightIntent(want, sessionInfo, false);
if (finish) {
return;
}
}
switch (winCmd) {
case AAFwk::WIN_CMD_FOREGROUND:
ForegroundWindow(want, sessionInfo);
break;
case AAFwk::WIN_CMD_BACKGROUND:
BackgroundWindow(sessionInfo);
break;
case AAFwk::WIN_CMD_DESTROY:
DestroyWindow(sessionInfo);
break;
default:
TAG_LOGD(AAFwkTag::UI_EXT, "unsupported cmd");
break;
}
OnCommandWindowDone(sessionInfo, winCmd);
}
bool CJUIExtensionBase::ForegroundWindowWithInsightIntent(const AAFwk::Want &want,
const sptr<AAFwk::SessionInfo> &sessionInfo, bool needForeground)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::UI_EXT, "called");
if (!HandleSessionCreate(want, sessionInfo)) {
TAG_LOGE(AAFwkTag::UI_EXT, "HandleSessionCreate failed");
return false;
}
std::unique_ptr<InsightIntentExecutorAsyncCallback> executorCallback = nullptr;
executorCallback.reset(InsightIntentExecutorAsyncCallback::Create());
if (executorCallback == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null executorCallback");
return false;
}
executorCallback->Push(
[weak = weak_from_this(), sessionInfo, needForeground](AppExecFwk::InsightIntentExecuteResult result) {
TAG_LOGD(AAFwkTag::UI_EXT, "Begin UI extension transaction callback");
auto extension = weak.lock();
if (extension == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null extension");
return;
}
extension->PostInsightIntentExecuted(sessionInfo, result, needForeground);
});
InsightIntentExecutorInfo executorInfo;
std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = context_->GetAbilityInfo();
if (abilityInfo != nullptr) {
executorInfo.hapPath = abilityInfo->hapPath;
executorInfo.windowMode = abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE;
}
executorInfo.token = context_->GetToken();
executorInfo.executeParam = std::make_shared<InsightIntentExecuteParam>();
InsightIntentExecuteParam::GenerateFromWant(want, *executorInfo.executeParam);
executorInfo.executeParam->executeMode_ = UI_EXTENSION_ABILITY;
executorInfo.srcEntry = want.GetStringParam(INSIGHT_INTENT_SRC_ENTRY);
TAG_LOGD(AAFwkTag::UI_EXT, "executorInfo, insightIntentId: %{public}" PRIu64,
executorInfo.executeParam->insightIntentId_);
int32_t ret = DelayedSingleton<InsightIntentExecutorMgr>::GetInstance()->ExecuteInsightIntent(
cjRuntime_, executorInfo, std::move(executorCallback));
if (!ret) {
TAG_LOGE(AAFwkTag::UI_EXT, "Execute insight intent failed");
}
TAG_LOGD(AAFwkTag::UI_EXT, "end");
return true;
}
void CJUIExtensionBase::ForegroundWindow(const AAFwk::Want &want, const sptr<AAFwk::SessionInfo> &sessionInfo)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
if (!HandleSessionCreate(want, sessionInfo)) {
TAG_LOGE(AAFwkTag::UI_EXT, "HandleSessionCreate failed");
return;
}
TAG_LOGD(AAFwkTag::UI_EXT, "UIExtension component id: %{public}" PRId64, sessionInfo->uiExtensionComponentId);
auto componentId = sessionInfo->uiExtensionComponentId;
auto &uiWindow = uiWindowMap_[componentId];
if (uiWindow) {
HITRACE_METER_NAME(HITRACE_TAG_APP, "Rosen::Window::show");
uiWindow->Show();
foregroundWindows_.emplace(componentId);
}
}
void CJUIExtensionBase::BackgroundWindow(const sptr<AAFwk::SessionInfo> &sessionInfo)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
if (sessionInfo == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "Invalid sessionInfo");
return;
}
TAG_LOGD(AAFwkTag::UI_EXT, "UIExtension component id: %{public}" PRId64, sessionInfo->uiExtensionComponentId);
auto componentId = sessionInfo->uiExtensionComponentId;
if (uiWindowMap_.find(componentId) == uiWindowMap_.end()) {
TAG_LOGE(AAFwkTag::UI_EXT, "not find uiWindow");
return;
}
auto &uiWindow = uiWindowMap_[componentId];
if (uiWindow) {
uiWindow->Hide();
foregroundWindows_.erase(componentId);
}
}
void CJUIExtensionBase::DestroyWindow(const sptr<AAFwk::SessionInfo> &sessionInfo)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
if (sessionInfo == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "Invalid sessionInfo");
return;
}
TAG_LOGD(AAFwkTag::UI_EXT, "UIExtension component id: %{public}" PRId64, sessionInfo->uiExtensionComponentId);
auto componentId = sessionInfo->uiExtensionComponentId;
if (uiWindowMap_.find(componentId) == uiWindowMap_.end()) {
TAG_LOGE(AAFwkTag::UI_EXT, "not find uiWindow");
return;
}
if (contentSessions_.find(componentId) != contentSessions_.end() && contentSessions_[componentId] != nullptr) {
cjObj.OnSessionDestroy(contentSessions_[componentId]->GetID());
}
auto &uiWindow = uiWindowMap_[componentId];
if (uiWindow) {
uiWindow->Destroy();
}
uiWindowMap_.erase(componentId);
foregroundWindows_.erase(componentId);
contentSessions_.erase(componentId);
if (abilityResultListeners_) {
abilityResultListeners_->RemoveListener(componentId);
}
}
void CJUIExtensionBase::OnCommandWindowDone(const sptr<AAFwk::SessionInfo> &sessionInfo, AAFwk::WindowCommand winCmd)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::UI_EXT, "called");
if (context_ == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return;
}
AAFwk::AbilityCommand abilityCmd;
if (uiWindowMap_.empty()) {
abilityCmd = AAFwk::ABILITY_CMD_DESTROY;
} else if (foregroundWindows_.empty()) {
abilityCmd = AAFwk::ABILITY_CMD_BACKGROUND;
} else {
abilityCmd = AAFwk::ABILITY_CMD_FOREGROUND;
}
AAFwk::AbilityManagerClient::GetInstance()->ScheduleCommandAbilityWindowDone(
context_->GetToken(), sessionInfo, winCmd, abilityCmd);
TAG_LOGD(AAFwkTag::UI_EXT, "end");
}
bool CJUIExtensionBase::HandleSessionCreate(const AAFwk::Want &want, const sptr<AAFwk::SessionInfo> &sessionInfo)
{
if (sessionInfo == nullptr || sessionInfo->uiExtensionComponentId == 0) {
TAG_LOGE(AAFwkTag::UI_EXT, "Invalid sessionInfo");
return false;
}
TAG_LOGD(AAFwkTag::UI_EXT, "UIExtension component id: %{public}" PRId64 ", element: %{public}s",
sessionInfo->uiExtensionComponentId, want.GetElement().GetURI().c_str());
if (sessionInfo == nullptr || sessionInfo->uiExtensionComponentId == 0) {
TAG_LOGE(AAFwkTag::UI_EXT, "Invalid sessionInfo");
return false;
}
auto componentId = sessionInfo->uiExtensionComponentId;
if (uiWindowMap_.find(componentId) == uiWindowMap_.end()) {
if (context_ == nullptr || context_->GetAbilityInfo() == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return false;
}
auto option = sptr<Rosen::WindowOption>::MakeSptr();
if (option == nullptr) {
return false;
}
option->SetWindowName(context_->GetBundleName() + context_->GetAbilityInfo()->name);
option->SetWindowType(Rosen::WindowType::WINDOW_TYPE_UI_EXTENSION);
option->SetWindowSessionType(Rosen::WindowSessionType::EXTENSION_SESSION);
option->SetParentId(sessionInfo->hostWindowId);
option->SetRealParentId(sessionInfo->realHostWindowId);
option->SetParentWindowType(static_cast<Rosen::WindowType>(sessionInfo->parentWindowType));
option->SetUIExtensionUsage(static_cast<uint32_t>(sessionInfo->uiExtensionUsage));
sptr<Rosen::Window> uiWindow;
{
HITRACE_METER_NAME(HITRACE_TAG_APP, "Rosen::Window::Create");
option->SetDisplayId(sessionInfo->displayId);
uiWindow = Rosen::Window::Create(option, context_, sessionInfo->sessionToken);
}
if (uiWindow == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null uiWindow");
return false;
}
auto cjSession = CJUIExtensionContentSession::Create(sessionInfo, uiWindow, context_);
contentSessions_.emplace(sessionInfo->uiExtensionComponentId, cjSession);
cjObj.OnSessionCreate(want, cjSession->GetID());
uiWindowMap_[componentId] = uiWindow;
#ifdef SUPPORT_GRAPHICS
if (context_->GetWindow() == nullptr) {
context_->SetWindow(uiWindow);
}
#endif // SUPPORT_GRAPHICS
}
return true;
}
void CJUIExtensionBase::PostInsightIntentExecuted(const sptr<AAFwk::SessionInfo> &sessionInfo,
const AppExecFwk::InsightIntentExecuteResult &result, bool needForeground)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::UI_EXT, "Post insightintent executed");
if (needForeground) {
// If uiextensionability is started for the first time or need move background to foreground.
cjObj.OnForeground();
}
OnInsightIntentExecuteDone(sessionInfo, result);
if (needForeground) {
// If need foreground, that means triggered by onForeground.
TAG_LOGI(AAFwkTag::UI_EXT, "call abilityms");
AAFwk::PacMap restoreData;
AAFwk::AbilityManagerClient::GetInstance()->AbilityTransitionDone(token_, AAFwk::ABILITY_STATE_FOREGROUND_NEW,
restoreData);
} else {
// If uiextensionability has displayed in the foreground.
OnCommandWindowDone(sessionInfo, AAFwk::WIN_CMD_FOREGROUND);
}
}
void CJUIExtensionBase::OnInsightIntentExecuteDone(const sptr<AAFwk::SessionInfo> &sessionInfo,
const AppExecFwk::InsightIntentExecuteResult &result)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
if (sessionInfo == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "Invalid sessionInfo");
return;
}
TAG_LOGD(AAFwkTag::UI_EXT, "UIExtension component id: %{public}" PRId64, sessionInfo->uiExtensionComponentId);
auto componentId = sessionInfo->uiExtensionComponentId;
auto res = uiWindowMap_.find(componentId);
if (res != uiWindowMap_.end() && res->second != nullptr) {
WantParams params;
params.SetParam(INSIGHT_INTENT_EXECUTE_RESULT_CODE, Integer::Box(result.innerErr));
WantParams resultParams;
resultParams.SetParam("code", Integer::Box(result.code));
if (result.result != nullptr) {
sptr<AAFwk::IWantParams> pWantParams = WantParamWrapper::Box(*result.result);
if (pWantParams != nullptr) {
resultParams.SetParam("result", pWantParams);
}
}
sptr<AAFwk::IWantParams> pWantParams = WantParamWrapper::Box(resultParams);
if (pWantParams != nullptr) {
params.SetParam(INSIGHT_INTENT_EXECUTE_RESULT, pWantParams);
}
Rosen::WMError ret = res->second->TransferExtensionData(params);
if (ret == Rosen::WMError::WM_OK) {
TAG_LOGD(AAFwkTag::UI_EXT, "TransferExtensionData success");
} else {
TAG_LOGE(AAFwkTag::UI_EXT, "TransferExtensionData failed, ret=%{public}d", ret);
}
res->second->Show();
foregroundWindows_.emplace(componentId);
}
TAG_LOGD(AAFwkTag::UI_EXT, "end");
}
void CJUIExtensionBase::OnConfigurationUpdated(const AppExecFwk::Configuration &configuration)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::UI_EXT, "called");
if (context_ == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return;
}
auto configUtils = std::make_shared<ConfigurationUtils>();
configUtils->UpdateGlobalConfig(configuration, context_->GetConfiguration(), context_->GetResourceManager());
ConfigurationUpdated();
}
void CJUIExtensionBase::OnForeground(const Want &want, sptr<AAFwk::SessionInfo> sessionInfo)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::UI_EXT, "called");
if (InsightIntentExecuteParam::IsInsightIntentExecute(want)) {
bool finish = ForegroundWindowWithInsightIntent(want, sessionInfo, true);
if (finish) {
return;
}
}
ForegroundWindow(want, sessionInfo);
cjObj.OnForeground();
}
void CJUIExtensionBase::OnBackground()
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::UI_EXT, "called");
cjObj.OnBackground();
}
void CJUIExtensionBase::Dump(const std::vector<std::string> &params, std::vector<std::string> &info)
{
// do nothing
}
void CJUIExtensionBase::OnAbilityResult(int32_t requestCode, int32_t resultCode, const Want &resultData)
{
TAG_LOGD(AAFwkTag::UI_EXT, "called");
if (context_ == nullptr) {
TAG_LOGW(AAFwkTag::UI_EXT, "null context");
return;
}
context_->OnAbilityResult(requestCode, resultCode, resultData);
if (abilityResultListeners_ == nullptr) {
TAG_LOGW(AAFwkTag::UI_EXT, "null abilityResultListeners");
return;
}
abilityResultListeners_->OnAbilityResult(requestCode, resultCode, resultData);
}
void CJUIExtensionBase::SetAbilityInfo(const std::shared_ptr<AppExecFwk::AbilityInfo> &abilityInfo)
{
abilityInfo_ = abilityInfo;
}
void CJUIExtensionBase::SetContext(const std::shared_ptr<UIExtensionContext> &context)
{
context_ = context;
}
void CJUIExtensionBase::BindContext()
{
// do nothing
}
void CJUIExtensionBase::ConfigurationUpdated()
{
TAG_LOGD(AAFwkTag::UI_EXT, "begin");
// Notify extension context
if (context_ == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return;
}
auto fullConfig = context_->GetConfiguration();
if (fullConfig == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null configuration");
return;
}
cjObj.OnConfigurationUpdate(fullConfig);
}
#ifdef SUPPORT_GRAPHICS
void CJUIExtensionBase::OnDisplayInfoChange(
const sptr<IRemoteObject> &token, Rosen::DisplayId displayId, float density, Rosen::DisplayOrientation orientation)
{
TAG_LOGI(AAFwkTag::UI_EXT, "displayId: %{public}" PRIu64 "", displayId);
if (context_ == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return;
}
auto contextConfig = context_->GetConfiguration();
if (contextConfig == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null configuration");
return;
}
TAG_LOGI(AAFwkTag::UI_EXT, "Config dump: %{public}s", contextConfig->GetName().c_str());
auto configUtils = std::make_shared<ConfigurationUtils>();
auto result = configUtils->UpdateDisplayConfig(
contextConfig, context_->GetResourceManager(), displayId, density, orientation);
TAG_LOGI(AAFwkTag::UI_EXT, "Config dump after update: %{public}s", contextConfig->GetName().c_str());
if (result) {
auto cjUiExtension = std::static_pointer_cast<CJUIExtensionBase>(shared_from_this());
auto task = [cjUiExtension]() {
if (cjUiExtension) {
cjUiExtension->ConfigurationUpdated();
}
};
if (handler_ != nullptr) {
handler_->PostTask(task, "CJUIExtensionBase:OnChange");
}
}
}
void CJUIExtensionBase::RegisterDisplayInfoChangedListener()
{
// register displayid change callback
auto cjUiExtensionBase = std::static_pointer_cast<CJUIExtensionBase>(shared_from_this());
cjUIExtensionBaseDisplayListener_ = sptr<CJUIExtensionBaseDisplayListener>::MakeSptr(cjUiExtensionBase);
if (cjUIExtensionBaseDisplayListener_ == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null CJUIExtensionBaseDisplayListener");
return;
}
if (context_ == nullptr || context_->GetToken() == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return;
}
TAG_LOGI(AAFwkTag::UI_EXT, "RegisterDisplayInfoChangedListener");
Rosen::WindowManager::GetInstance().RegisterDisplayInfoChangedListener(
context_->GetToken(), cjUIExtensionBaseDisplayListener_);
}
void CJUIExtensionBase::UnregisterDisplayInfoChangedListener()
{
if (context_ == nullptr || context_->GetToken() == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return;
}
Rosen::WindowManager::GetInstance().UnregisterDisplayInfoChangedListener(
context_->GetToken(), cjUIExtensionBaseDisplayListener_);
}
#endif // SUPPORT_GRAPHICS
} // namespace AbilityRuntime
} // namespace OHOS
@@ -0,0 +1,264 @@
/*
* 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 "cj_ui_extension_content_session.h"
#include "cj_common_ffi.h"
#include "cj_ui_extension_object.h"
#include "cj_ui_extension_context.h"
#include "cj_lambda.h"
#include "ability_business_error.h"
#include "ability_manager_client.h"
#include "accesstoken_kit.h"
#include "event_handler.h"
#include "hilog_tag_wrapper.h"
#include "hitrace_meter.h"
#include "ipc_skeleton.h"
#include "string_wrapper.h"
#include "tokenid_kit.h"
#ifdef SUPPORT_SCREEN
#include "ui_content.h"
#endif // SUPPORT_SCREEN
#include "want.h"
#include "window.h"
namespace OHOS {
namespace AbilityRuntime {
namespace {
constexpr const char* PERMISSION_PRIVACY_WINDOW = "ohos.permission.PRIVACY_WINDOW";
const std::string UIEXTENSION_TARGET_TYPE_KEY = "ability.want.params.uiExtensionTargetType";
const std::string FLAG_AUTH_READ_URI_PERMISSION = "ability.want.params.uriPermissionFlag";
} // namespace
CJUIExtensionContentSession::CJUIExtensionContentSession(
sptr<AAFwk::SessionInfo> sessionInfo, sptr<Rosen::Window> uiWindow,
std::weak_ptr<AbilityRuntime::Context> context)
: sessionInfo_(sessionInfo), uiWindow_(uiWindow), context_(context)
{
}
sptr<CJUIExtensionContentSession> CJUIExtensionContentSession::Create(sptr<AAFwk::SessionInfo> sessionInfo,
sptr<Rosen::Window> uiWindow, std::weak_ptr<AbilityRuntime::Context> context)
{
return FFI::FFIData::Create<CJUIExtensionContentSession>(sessionInfo, uiWindow, context);
}
int32_t CJUIExtensionContentSession::LoadContent(const std::string& path, int storage)
{
if (sessionInfo_->isAsyncModalBinding && isFirstTriggerBindModal_) {
TAG_LOGD(AAFwkTag::UI_EXT, "Trigger binding UIExtension modal window");
uiWindow_->TriggerBindModalUIExtension();
isFirstTriggerBindModal_ = false;
}
(void)storage;
return SUCCESS_CODE;
}
int32_t CJUIExtensionContentSession::TerminateSelf()
{
return AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(sessionInfo_);
}
int32_t CJUIExtensionContentSession::TerminateSelfWithResult(AAFwk::Want* want, int32_t resultCode)
{
auto extensionContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::UIExtensionContext>(context_.lock());
if (!extensionContext) {
TAG_LOGE(AAFwkTag::UI_EXT, "extensionContext is nullptr");
} else {
auto token = extensionContext->GetToken();
AAFwk::AbilityManagerClient::GetInstance()->TransferAbilityResultForExtension(token, resultCode, *want);
}
if (uiWindow_ == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "uiWindow_ is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto ret = uiWindow_->TransferAbilityResult(resultCode, *want);
if (ret != Rosen::WMError::WM_OK) {
return ERR_INVALID_INSTANCE_CODE;
}
return AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(sessionInfo_);
}
int32_t CJUIExtensionContentSession::SetWindowPrivacyMode(bool isPrivacyMode)
{
auto selfToken = IPCSkeleton::GetSelfTokenID();
int ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(selfToken, PERMISSION_PRIVACY_WINDOW);
if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_PERMISSION_DENIED);
}
if (uiWindow_ == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null uiWindow");
return ERR_INVALID_INSTANCE_CODE;
}
auto retCode = uiWindow_->SetPrivacyMode(isPrivacyMode);
if (retCode == Rosen::WMError::WM_OK) {
return SUCCESS_CODE;
}
return ERR_INVALID_INSTANCE_CODE;
}
int32_t CJUIExtensionContentSession::StartAbilityByType(const std::string &type, AAFwk::WantParams &wantParam,
const std::shared_ptr<CjUIExtensionCallback> &uiExtensionCallbacks)
{
if (uiWindow_ == nullptr || uiWindow_->GetUIContent() == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null uiContent");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER);
}
wantParam.SetParam(UIEXTENSION_TARGET_TYPE_KEY, AAFwk::String::Box(type));
AAFwk::Want want;
want.SetParams(wantParam);
if (wantParam.HasParam(FLAG_AUTH_READ_URI_PERMISSION)) {
want.SetFlags(wantParam.GetIntParam(FLAG_AUTH_READ_URI_PERMISSION, 0));
wantParam.Remove(FLAG_AUTH_READ_URI_PERMISSION);
}
#ifdef SUPPORT_SCREEN
InitDisplayId(want);
#endif
auto uiContent = uiWindow_->GetUIContent();
Ace::ModalUIExtensionCallbacks callback;
callback.onError = [uiExtensionCallbacks](int arg, const std::string &str1, const std::string &str2) {
uiExtensionCallbacks->OnError(arg);
};
callback.onRelease = [uiExtensionCallbacks](const auto &arg) {
uiExtensionCallbacks->OnRelease(arg);
};
Ace::ModalUIExtensionConfig config;
int32_t sessionId = uiContent->CreateModalUIExtension(want, callback, config);
if (sessionId == 0) {
TAG_LOGE(AAFwkTag::UI_EXT, "createModalUIExtension failed");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER);
}
uiExtensionCallbacks->SetUIContent(uiContent);
uiExtensionCallbacks->SetSessionId(sessionId);
return static_cast<int32_t>(AbilityErrorCode::ERROR_OK);
}
#ifdef SUPPORT_SCREEN
void CJUIExtensionContentSession::InitDisplayId(AAFwk::Want &want)
{
auto context = AbilityRuntime::Context::ConvertTo<AbilityRuntime::UIExtensionContext>(context_.lock());
if (context == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return;
}
auto window = context->GetWindow();
if (window == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null window");
return;
}
TAG_LOGI(AAFwkTag::UI_EXT, "window displayId %{public}" PRIu64, window->GetDisplayId());
want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, static_cast<int32_t>(window->GetDisplayId()));
}
#endif // SUPPORT_SCREEN
extern "C" {
CJ_EXPORT int32_t FFICJExtSessionLoadContent(int64_t sessionId, const char* path, int storage)
{
if (path == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param path is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto session = FFI::FFIData::GetData<CJUIExtensionContentSession>(sessionId);
if (session == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null CJUIExtensionContentSession");
return ERR_INVALID_INSTANCE_CODE;
}
return session->LoadContent(std::string(path), storage);
}
CJ_EXPORT int32_t FFICJExtSessionTerminateSelf(int64_t sessionId)
{
auto session = FFI::FFIData::GetData<CJUIExtensionContentSession>(sessionId);
if (session == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null CJUIExtensionContentSession");
return ERR_INVALID_INSTANCE_CODE;
}
return session->TerminateSelf();
}
CJ_EXPORT int32_t FFICJExtSessionTerminateSelfWithResult(int64_t sessionId, WantHandle want, int32_t resultCode)
{
if (want == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param want is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto session = FFI::FFIData::GetData<CJUIExtensionContentSession>(sessionId);
if (session == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null CJUIExtensionContentSession");
return ERR_INVALID_INSTANCE_CODE;
}
auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
return session->TerminateSelfWithResult(actualWant, resultCode);
}
CJ_EXPORT int32_t FFICJExtSessionSetWindowPrivacyMode(int64_t sessionId, bool isPrivacyMode)
{
auto session = FFI::FFIData::GetData<CJUIExtensionContentSession>(sessionId);
if (session == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null CJUIExtensionContentSession");
return ERR_INVALID_INSTANCE_CODE;
}
return session->SetWindowPrivacyMode(isPrivacyMode);
}
CJ_EXPORT int32_t FFICJExtSessionStartAbilityByType(int64_t sessionId, char* cType, char* cWantParams,
void (*onError)(int32_t, char*, char*), void (*onResult)(CJAbilityResult))
{
if (cType == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param cType is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (cWantParams == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param cWantParams is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (onError == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param onError is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (onResult == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param onResult is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto session = FFI::FFIData::GetData<CJUIExtensionContentSession>(sessionId);
if (session == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null CJUIExtensionContentSession");
return ERR_INVALID_INSTANCE_CODE;
}
auto wantParam = AAFwk::WantParamWrapper::ParseWantParamsWithBrackets(cWantParams);
auto callback = std::make_shared<CjUIExtensionCallback>();
callback->SetCjCallbackOnResult(CJLambda::Create(onResult));
callback->SetCjCallbackOnError(CJLambda::Create(onError));
return session->StartAbilityByType(std::string(cType), wantParam, callback);
}
} // extern "C"
} // namespace AbilityRuntime
} // namespace OHOS
@@ -0,0 +1,680 @@
/*
* 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 "cj_ui_extension_context.h"
#include "ability_manager_client.h"
#include "ability_manager_errors.h"
#include "event_handler.h"
#include "hilog_tag_wrapper.h"
#include "hitrace_meter.h"
#include "open_link_options.h"
#include "start_options.h"
#include "uri.h"
#include "ui_extension_servicehost_stub_impl.h"
#include "ui_service_extension_connection_constants.h"
#include "cj_macro.h"
#include "cj_common_ffi.h"
#include "cj_utils_ffi.h"
#include "cj_ability_context_utils.h"
#include "cj_ability_connect_callback_object.h"
#include "cj_ui_extension_base.h"
#include "ability_business_error.h"
namespace OHOS {
namespace AbilityRuntime {
using CJAbilityResultCbFn = void (*)(int64_t, int32_t, CJAbilityResult*);
struct CJAbilityResultCbInfo {
int64_t lambdaId;
CJAbilityResultCbFn callback;
};
namespace {
static const std::string APP_LINKING_ONLY = "appLinkingOnly";
static const std::string ATOMIC_SERVICE_PREFIX = "com.atomicservice.";
} // namespace
class CJUIExtensionContextImpl {
public:
explicit CJUIExtensionContextImpl(const std::shared_ptr<UIExtensionContext> &context)
: context_(context) {}
int32_t StartAbility(AAFwk::Want& want);
int32_t StartAbility(AAFwk::Want& want, const AAFwk::StartOptions& option);
int32_t StartAbilityForRes(AAFwk::Want& want, int32_t requestCode, const CJAbilityResultCbInfo& cbInfo);
int32_t StartAbilityForRes(AAFwk::Want& want, const AAFwk::StartOptions& option, int32_t requestCode,
const CJAbilityResultCbInfo& cbInfo);
int32_t ConnectServiceExtensionAbility(AAFwk::Want& want, int64_t connectOptId, int64_t& connectionId);
int32_t DisconnectServiceExtensionAbility(int64_t connectionId);
int32_t TerminateSelf();
int32_t TerminateSelfWithResult(AAFwk::Want& want, int32_t resultCode);
int32_t ReportDrawnCompleted();
int32_t OpenAtomicService(const std::string& appId, AAFwk::StartOptions& options,
AAFwk::Want& want, int32_t requestCode, const CJAbilityResultCbInfo& cbInfo);
int32_t OpenLink(const std::string& link, AAFwk::OpenLinkOptions& options, AAFwk::Want& want,
int32_t requestCode, const CJAbilityResultCbInfo& cbInfo);
public:
void CheckStartAbilityInputParam(AAFwk::Want& want);
void InitDisplayId(AAFwk::Want& want);
int32_t OpenLinkInner(const AAFwk::Want& want, int requestCode, const std::string& startTime,
const std::string& link);
public:
std::weak_ptr<UIExtensionContext> context_;
};
CJUIExtensionContext::CJUIExtensionContext(const std::shared_ptr<UIExtensionContext> &context)
: CJExtensionContext(context, context->GetAbilityInfo())
{
impl = std::make_shared<CJUIExtensionContextImpl>(context);
}
void CJUIExtensionContextImpl::CheckStartAbilityInputParam(AAFwk::Want& want)
{
if (!want.HasParameter(AAFwk::Want::PARAM_BACK_TO_OTHER_MISSION_STACK)) {
want.SetParam(AAFwk::Want::PARAM_BACK_TO_OTHER_MISSION_STACK, true);
}
}
void CJUIExtensionContextImpl::InitDisplayId(AAFwk::Want& want)
{
#ifdef SUPPORT_SCREEN
auto context = context_.lock();
if (!context) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return;
}
auto window = context->GetWindow();
if (window == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null window");
return;
}
want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, static_cast<int32_t>(window->GetDisplayId()));
#endif // SUPPORT_SCREEN
}
int32_t CJUIExtensionContextImpl::StartAbility(AAFwk::Want& want)
{
CheckStartAbilityInputParam(want);
InitDisplayId(want);
auto context = context_.lock();
if (!context) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
}
return context->StartAbility(want);
}
int32_t CJUIExtensionContextImpl::StartAbility(AAFwk::Want& want, const AAFwk::StartOptions& option)
{
CheckStartAbilityInputParam(want);
InitDisplayId(want);
auto context = context_.lock();
if (!context) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
}
return context->StartAbility(want, option);
}
static RuntimeTask WrapRuntimeTask(const CJAbilityResultCbInfo& cbInfo)
{
RuntimeTask task = [cbInfo]
(int32_t resultCode, const AAFwk::Want& want, bool isInner) {
WantHandle wantHandle = const_cast<AAFwk::Want*>(&want);
CJAbilityResult abilityResult = { resultCode, wantHandle };
int32_t error;
if (isInner) {
error = static_cast<int32_t>(GetJsErrorCodeByNativeError(resultCode));
} else {
error = SUCCESS_CODE;
}
cbInfo.callback(cbInfo.lambdaId, error, &abilityResult);
TAG_LOGD(AAFwkTag::CONTEXT, "resultCode: %{public}d", resultCode);
};
return task;
}
int32_t CJUIExtensionContextImpl::StartAbilityForRes(AAFwk::Want& want, int32_t requestCode,
const CJAbilityResultCbInfo& cbInfo)
{
CheckStartAbilityInputParam(want);
InitDisplayId(want);
auto context = context_.lock();
if (!context) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
}
RuntimeTask task = WrapRuntimeTask(cbInfo);
want.SetParam(AAFwk::Want::PARAM_RESV_FOR_RESULT, true);
return context->StartAbilityForResult(want, requestCode, std::move(task));
}
int32_t CJUIExtensionContextImpl::StartAbilityForRes(AAFwk::Want& want, const AAFwk::StartOptions& option,
int32_t requestCode, const CJAbilityResultCbInfo& cbInfo)
{
CheckStartAbilityInputParam(want);
InitDisplayId(want);
auto context = context_.lock();
if (!context) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
}
RuntimeTask task = WrapRuntimeTask(cbInfo);
want.SetParam(AAFwk::Want::PARAM_RESV_FOR_RESULT, true);
return context->StartAbilityForResult(want, option, requestCode, std::move(task));
}
int32_t CJUIExtensionContextImpl::ConnectServiceExtensionAbility(AAFwk::Want& want, int64_t connectOptId,
int64_t& connectionId)
{
auto connection = CJAbilityConnectCallback::Create(connectOptId, want);
if (connection == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null connection");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER);
}
int64_t connectId = connection->GetConnectionId();
auto context = context_.lock();
if (!context) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
}
auto innerErrCode = context->ConnectAbility(want, connection);
if (innerErrCode == static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT)) {
CJAbilityConnectCallback::Remove(connectId);
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
}
int32_t errCode = static_cast<int32_t>(AbilityRuntime::GetJsErrorCodeByNativeError(innerErrCode));
if (errCode) {
connection->OnFailed(errCode);
CJAbilityConnectCallback::Remove(connectId);
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER);
}
connectionId = connectId;
return static_cast<int32_t>(AbilityErrorCode::ERROR_OK);
}
int32_t CJUIExtensionContextImpl::DisconnectServiceExtensionAbility(int64_t connectionId)
{
AAFwk::Want want;
sptr<CJAbilityConnectCallback> connection = nullptr;
CJAbilityConnectCallback::FindConnection(want, connection, connectionId);
if (!connection) {
TAG_LOGE(AAFwkTag::UI_EXT, "null connection");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER);
}
auto context = context_.lock();
if (!context) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
}
auto innerErrCode = context->DisconnectAbility(want, connection);
return static_cast<int32_t>(innerErrCode);
}
int32_t CJUIExtensionContextImpl::TerminateSelf()
{
auto context = context_.lock();
if (!context) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
}
return static_cast<int32_t>(context->TerminateSelf());
}
int32_t CJUIExtensionContextImpl::TerminateSelfWithResult(AAFwk::Want& want, int32_t resultCode)
{
auto context = context_.lock();
if (!context) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
}
auto token = context->GetToken();
AAFwk::AbilityManagerClient::GetInstance()->TransferAbilityResultForExtension(token, resultCode, want);
sptr<Rosen::Window> uiWindow = context->GetWindow();
if (!uiWindow) {
TAG_LOGE(AAFwkTag::UI_EXT, "null uiWindow");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
}
auto ret = uiWindow->TransferAbilityResult(resultCode, want);
if (ret != Rosen::WMError::WM_OK) {
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
}
return static_cast<int32_t>(GetJsErrorCodeByNativeError(context->TerminateSelf()));
}
int32_t CJUIExtensionContextImpl::ReportDrawnCompleted()
{
auto context = context_.lock();
if (!context) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
}
return static_cast<int32_t>(GetJsErrorCodeByNativeError(context->ReportDrawnCompleted()));
}
int32_t CJUIExtensionContextImpl::OpenAtomicService(const std::string& appId, AAFwk::StartOptions& options,
AAFwk::Want& want, int32_t requestCode, const CJAbilityResultCbInfo& cbInfo)
{
std::string bundleName = ATOMIC_SERVICE_PREFIX + appId;
TAG_LOGD(AAFwkTag::UI_EXT, "bundleName: %{public}s", bundleName.c_str());
want.SetBundle(bundleName);
#ifdef SUPPORT_SCREEN
InitDisplayId(want);
#endif
want.AddFlags(AAFwk::Want::FLAG_INSTALL_ON_DEMAND);
std::string startTime = std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::
system_clock::now().time_since_epoch()).count());
want.SetParam(AAFwk::Want::PARAM_RESV_START_TIME, startTime);
auto context = context_.lock();
if (context == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
}
RuntimeTask task = WrapRuntimeTask(cbInfo);
want.SetParam(AAFwk::Want::PARAM_RESV_FOR_RESULT, true);
context->OpenAtomicService(want, options, requestCode, std::move(task));
return SUCCESS_CODE;
}
static inline bool CheckUrl(const std::string &urlValue)
{
if (urlValue.empty()) {
return false;
}
Uri uri = Uri(urlValue);
if (uri.GetScheme().empty() || uri.GetHost().empty()) {
return false;
}
return true;
}
int32_t CJUIExtensionContextImpl::OpenLink(const std::string& link, AAFwk::OpenLinkOptions& options, AAFwk::Want& want,
int32_t requestCode, const CJAbilityResultCbInfo& cbInfo)
{
auto context = context_.lock();
if (!context) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
}
if (!CheckUrl(link)) {
TAG_LOGE(AAFwkTag::UI_EXT, "link parameter invalid");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
}
want.SetUri(link);
std::string startTime = std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::
system_clock::now().time_since_epoch()).count());
want.SetParam(AAFwk::Want::PARAM_RESV_START_TIME, startTime);
if (cbInfo.lambdaId > 0) {
RuntimeTask task = WrapRuntimeTask(cbInfo);
want.SetParam(AAFwk::Want::PARAM_RESV_FOR_RESULT, true);
context->InsertResultCallbackTask(requestCode, std::move(task));
}
#ifdef SUPPORT_SCREEN
InitDisplayId(want);
#endif
return OpenLinkInner(want, requestCode, startTime, link);
}
int32_t CJUIExtensionContextImpl::OpenLinkInner(const AAFwk::Want& want, int requestCode, const std::string& startTime,
const std::string& link)
{
auto context = context_.lock();
if (!context) {
TAG_LOGE(AAFwkTag::UI_EXT, "null context");
return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
}
auto innerErrCode = context->OpenLink(want, requestCode);
if (innerErrCode == 0) {
return SUCCESS_CODE;
}
if (innerErrCode == AAFwk::ERR_OPEN_LINK_START_ABILITY_DEFAULT_OK) {
TAG_LOGI(AAFwkTag::UI_EXT, "start ability by default succeeded");
return SUCCESS_CODE;
}
TAG_LOGI(AAFwkTag::UI_EXT, "OpenLink failed");
context->RemoveResultCallbackTask(requestCode);
return static_cast<int32_t>(innerErrCode);
}
extern "C" {
CJ_EXPORT int32_t FFICJUIExtAbilityGetContext(ExtAbilityHandle extAbility, int64_t* id)
{
auto ability = static_cast<CJUIExtensionBase*>(extAbility);
if (ability == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, extAbility is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (id == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, id is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto context = ability->GetContext();
if (context == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::Create<CJUIExtensionContext>(context);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, extAbilityContext is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
*id = cjContext->GetID();
return SUCCESS_CODE;
}
CJ_EXPORT int32_t FFICJUIExtCtxStartAbility(int64_t id, WantHandle want)
{
if (want == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param want is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::GetData<CJUIExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
return cjContext->impl->StartAbility(*actualWant);
}
static AAFwk::StartOptions UnWrapStartOption(CJNewStartOptions* paramOpt)
{
AAFwk::StartOptions option;
option.SetWindowMode(paramOpt->windowMode);
option.SetDisplayID(paramOpt->displayId);
option.SetWithAnimation(paramOpt->withAnimation);
option.SetWindowLeft(paramOpt->windowLeft);
option.windowLeftUsed_ = true;
option.SetWindowTop(paramOpt->windowTop);
option.windowTopUsed_ = true;
option.SetWindowWidth(paramOpt->windowWidth);
option.windowWidthUsed_ = true;
option.SetWindowHeight(paramOpt->windowHeight);
option.windowHeightUsed_ = true;
return option;
}
CJ_EXPORT int32_t FFICJUIExtCtxStartAbilityWithOpt(int64_t id, WantHandle want, CJNewStartOptions* paramOpt)
{
if (want == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param want is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (paramOpt == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param paramOpt is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::GetData<CJUIExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
AAFwk::StartOptions option = UnWrapStartOption(paramOpt);
return cjContext->impl->StartAbility(*actualWant, option);
}
CJ_EXPORT int32_t FFICJUIExtCtxStartAbilityForRes(int64_t id, WantHandle want, int32_t requestCode,
CJAbilityResultCbInfo* cbInfo)
{
if (want == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param want is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (cbInfo == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param cbInfo is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::GetData<CJUIExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
return cjContext->impl->StartAbilityForRes(*actualWant, requestCode, *cbInfo);
}
CJ_EXPORT int32_t FFICJUIExtCtxStartAbilityForResWithOpt(int64_t id, WantHandle want, CJNewStartOptions* paramOpt,
int32_t requestCode, CJAbilityResultCbInfo* cbInfo)
{
if (want == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param want is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (paramOpt == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param paramOpt is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (cbInfo == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param cbInfo is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::GetData<CJUIExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
AAFwk::StartOptions option = UnWrapStartOption(paramOpt);
return cjContext->impl->StartAbilityForRes(*actualWant, option, requestCode, *cbInfo);
}
CJ_EXPORT int32_t FFICJUIExtCtxConnectServiceExtensionAbility(int64_t id, WantHandle want, int64_t connectOptId,
int64_t* connectionId)
{
if (want == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param want is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (connectionId == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param connectionId is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::GetData<CJUIExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
return cjContext->impl->ConnectServiceExtensionAbility(*actualWant, connectOptId, *connectionId);
}
CJ_EXPORT int32_t FFICJUIExtCtxDisconnectServiceExtensionAbility(int64_t id, int64_t connectionId)
{
auto cjContext = OHOS::FFI::FFIData::GetData<CJUIExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
return cjContext->impl->DisconnectServiceExtensionAbility(connectionId);
}
CJ_EXPORT int32_t FFICJUIExtCtxTerminateSelf(int64_t id)
{
auto cjContext = OHOS::FFI::FFIData::GetData<CJUIExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
return cjContext->impl->TerminateSelf();
}
CJ_EXPORT int32_t FFICJUIExtCtxTerminateSelfWithResult(int64_t id, WantHandle want, int32_t resultCode)
{
if (want == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param want is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::GetData<CJUIExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
return cjContext->impl->TerminateSelfWithResult(*actualWant, resultCode);
}
CJ_EXPORT int32_t FFICJUIExtCtxReportDrawnCompleted(int64_t id)
{
auto cjContext = OHOS::FFI::FFIData::GetData<CJUIExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
return cjContext->impl->ReportDrawnCompleted();
}
CJ_EXPORT int32_t FFICJUIExtCtxOpenAtomicService(int64_t id, char* cAppId,
CJAtomicServiceOptions* cAtomicServiceOptions, int32_t requestCode, CJAbilityResultCbInfo* cbInfo)
{
if (cAppId == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param cAppId is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (cAtomicServiceOptions == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param cAtomicServiceOptions is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (cbInfo == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param cbInfo is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::GetData<CJUIExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
AAFwk::Want want;
AAFwk::StartOptions options;
if (cAtomicServiceOptions->hasValue) {
AAFwk::WantParams wantParams =
OHOS::AAFwk::WantParamWrapper::ParseWantParamsWithBrackets(cAtomicServiceOptions->parameters);
want.SetParams(wantParams);
if (cAtomicServiceOptions->flags != 0) {
want.SetFlags(cAtomicServiceOptions->flags);
}
options = UnWrapStartOption(&cAtomicServiceOptions->startOptions);
}
return cjContext->impl->OpenAtomicService(std::string(cAppId), options, want, requestCode, *cbInfo);
}
static AAFwk::OpenLinkOptions UnwrapOpenLinkOptions(CJOpenLinkOptions* cOpenLinkOptions, AAFwk::Want& want)
{
AAFwk::OpenLinkOptions options;
want.SetParam(APP_LINKING_ONLY, false);
if (cOpenLinkOptions->hasValue) {
if (cOpenLinkOptions->parameters != nullptr) {
AAFwk::WantParams wantParams = AAFwk::WantParamWrapper::ParseWantParamsWithBrackets(
cOpenLinkOptions->parameters);
want.SetParams(wantParams);
}
options.SetAppLinkingOnly(cOpenLinkOptions->appLinkingOnly);
want.SetParam(APP_LINKING_ONLY, cOpenLinkOptions->appLinkingOnly);
}
return options;
}
CJ_EXPORT int32_t FFICJUIExtCtxOpenLink(int64_t id, char* cLink, CJOpenLinkOptions* cOpenLinkOptions,
int32_t requestCode, CJAbilityResultCbInfo* cbInfo)
{
if (cLink == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param cLink is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (cOpenLinkOptions == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param cOpenLinkOptions is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
if (cbInfo == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "input param cbInfo is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
auto cjContext = OHOS::FFI::FFIData::GetData<CJUIExtensionContext>(id);
if (cjContext == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "GetCJUIExtensionContext failed, context is nullptr");
return ERR_INVALID_INSTANCE_CODE;
}
AAFwk::Want want;
AAFwk::OpenLinkOptions options = UnwrapOpenLinkOptions(cOpenLinkOptions, want);
return cjContext->impl->OpenLink(std::string(cLink), options, want, requestCode, *cbInfo);
}
}
} // namespace AbilityRuntime
} // namespace OHOS
+4 -1
View File
@@ -274,7 +274,10 @@ ohos_shared_library("appkit_native") {
defines += [ "CJ_FRONTEND" ]
deps += [ "${ability_runtime_path}/frameworks/cj/ffi:cj_ability_ffi" ]
deps += [
"${ability_runtime_path}/frameworks/cj/ffi:cj_ability_ffi",
"${ability_runtime_path}/frameworks/cj/ffi/context:cj_context_ffi",
]
external_deps += [
"bundle_framework:appexecfwk_base",
+10 -2
View File
@@ -1703,10 +1703,12 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con
auto helper = std::make_shared<DumpRuntimeHelper>(application_);
helper->SetAppFreezeFilterCallback();
}
#ifdef CJ_FRONTEND
}
} else {
LoadAllExtensions();
}
#endif
}
auto usertestInfo = appLaunchData.GetUserTestInfo();
if (usertestInfo) {
@@ -2079,6 +2081,12 @@ void MainThread::HandleAbilityStage(const HapModuleInfo &abilityStage)
}
void MainThread::LoadAllExtensions(NativeEngine &nativeEngine)
{
(void)nativeEngine;
return LoadAllExtensions();
}
void MainThread::LoadAllExtensions()
{
HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::APPKIT, "LoadAllExtensions");
@@ -0,0 +1,36 @@
/*
* 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 OHOS_ABILITY_RUNTIME_CJ_EXTENSION_CONTEXT_H
#define OHOS_ABILITY_RUNTIME_CJ_EXTENSION_CONTEXT_H
#include "extension_context.h"
#include "cj_context.h"
namespace OHOS {
namespace AbilityRuntime {
class CJExtensionContextImpl;
class CJExtensionContext : public FfiContext::CJContext {
public:
CJExtensionContext(const std::shared_ptr<ExtensionContext> &context,
std::shared_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo);
virtual ~CJExtensionContext() = default;
std::shared_ptr<CJExtensionContextImpl> impl_;
};
} // AbilityRuntime
} // OHOS
#endif // OHOS_ABILITY_RUNTIME_CJ_EXTENSION_CONTEXT_H
@@ -20,32 +20,48 @@
#include "ability_connect_callback.h"
#include "cj_element_name_ffi.h"
#include "want.h"
extern "C" {
namespace OHOS {
namespace AbilityRuntime {
struct CJAbilityConnectCallbackFuncs {
void (*onConnect)(int64_t id, ElementNameHandle elementNameHandle, int64_t remoteObjectId, int32_t resultCode);
void (*onDisconnect)(int64_t id, ElementNameHandle elementNameHandle, int32_t resultCode);
void (*release)(int64_t id);
void (*onFailed)(int64_t id, int32_t resultCode);
};
extern "C" {
#define EXPORT __attribute__((visibility("default")))
EXPORT void RegisterCJAbilityConnectCallbackFuncs(void (*registerFunc)(CJAbilityConnectCallbackFuncs* result));
#undef EXPORT
};
namespace OHOS {
namespace AbilityRuntime {
class CJAbilityConnectCallback : public AbilityConnectCallback {
public:
explicit CJAbilityConnectCallback(int64_t id) : callbackId_(id) {};
~CJAbilityConnectCallback() override;
static sptr<CJAbilityConnectCallback> Create(int64_t id, AAFwk::Want& want);
static void Remove(int64_t connectId);
static void FindConnection(AAFwk::Want& want, sptr<CJAbilityConnectCallback>& connection, int64_t connectId);
void OnAbilityConnectDone(
const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode) override;
void OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int resultCode) override;
void OnFailed(int32_t resultCode);
void SetConnectionId(int64_t connectId)
{
connectId_ = connectId;
}
int64_t GetConnectionId()
{
return connectId_;
}
private:
int64_t callbackId_ = 0;
int64_t connectId_;
};
} // namespace AbilityRuntime
} // namespace OHOS
@@ -20,32 +20,15 @@
#include "ability_context_impl.h"
#include "cj_ability_context_utils.h"
#include "ffi_remote_data.h"
#include "cj_ui_extension_callback.h"
#include "cj_context.h"
namespace OHOS {
namespace AbilityRuntime {
class CjUIExtensionCallback : public std::enable_shared_from_this<CjUIExtensionCallback> {
public:
explicit CjUIExtensionCallback() {}
void OnError(int32_t number);
void OnRelease(int32_t code);
void OnResult(int32_t resultCode, const AAFwk::Want &want);
void CallCjResult(int32_t resultCode, const AAFwk::Want &want);
void SetCjCallbackOnResult(std::function<void(CJAbilityResult)> onResultCallback);
void SetCjCallbackOnError(std::function<void(int32_t, char*, char*)> onErrorCallback);
void CallCjError(int32_t number);
void SetSessionId(int32_t sessionId);
void SetUIContent(Ace::UIContent* uiContent);
private:
std::function<void(CJAbilityResult)> onResultCallback_;
std::function<void(int32_t, char*, char*)> onErrorCallback_;
int32_t sessionId_ = 0;
Ace::UIContent* uiContent_ = nullptr;
};
class CJAbilityContext : public FFI::FFIData {
class CJAbilityContext : public FfiContext::CJContext {
public:
explicit CJAbilityContext(const std::shared_ptr<AbilityRuntime::AbilityContext>& abilityContext)
: context_(abilityContext) {};
: FfiContext::CJContext(abilityContext), context_(abilityContext) {};
std::shared_ptr<AbilityRuntime::AbilityContext> GetAbilityContext();
sptr<IRemoteObject> GetToken();
@@ -16,6 +16,8 @@
#ifndef OHOS_ABILITY_RUNTIME_CJ_ABILITY_CONTEXT_UTILS_H
#define OHOS_ABILITY_RUNTIME_CJ_ABILITY_CONTEXT_UTILS_H
#include <cstdint>
extern "C" {
using WantHandle = void*;
@@ -0,0 +1,50 @@
/*
* 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 OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_CALLBACK_H
#define OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_CALLBACK_H
#include "cj_ability_context_utils.h"
#include "want.h"
namespace OHOS {
namespace Ace {
class UIContent;
}
namespace AbilityRuntime {
class CjUIExtensionCallback : public std::enable_shared_from_this<CjUIExtensionCallback> {
public:
explicit CjUIExtensionCallback() {}
void OnError(int32_t number);
void OnRelease(int32_t code);
void OnResult(int32_t resultCode, const AAFwk::Want &want);
void CallCjResult(int32_t resultCode, const AAFwk::Want &want);
void SetCjCallbackOnResult(std::function<void(CJAbilityResult)> onResultCallback);
void SetCjCallbackOnError(std::function<void(int32_t, char*, char*)> onErrorCallback);
void CallCjError(int32_t number);
void SetSessionId(int32_t sessionId);
void SetUIContent(Ace::UIContent* uiContent);
private:
std::function<void(CJAbilityResult)> onResultCallback_;
std::function<void(int32_t, char*, char*)> onErrorCallback_;
int32_t sessionId_ = 0;
Ace::UIContent* uiContent_ = nullptr;
};
} // AbilityRuntime
} // OHOS
#endif // OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_CALLBACK_H
@@ -0,0 +1,42 @@
/*
* 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 OHOS_ABILITY_RUNTIME_CJ_ACTION_EXTENSION_H
#define OHOS_ABILITY_RUNTIME_CJ_ACTION_EXTENSION_H
#include "action_extension.h"
#include "configuration.h"
namespace OHOS {
namespace AbilityRuntime {
/**
* @brief Basic action extension components.
*/
class CJActionExtension : public ActionExtension, public std::enable_shared_from_this<CJActionExtension> {
public:
explicit CJActionExtension(const std::unique_ptr<Runtime> &runtime);
virtual ~CJActionExtension() override;
/**
* @brief Create CJActionExtension.
*
* @param runtime The runtime.
* @return The CJActionExtension instance.
*/
static CJActionExtension *Create(const std::unique_ptr<Runtime> &runtime);
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_CJ_ACTION_EXTENSION_H
@@ -0,0 +1,61 @@
/*
* 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 OHOS_ABILITY_RUNTIME_CJ_EXTENSION_COMMON_H
#define OHOS_ABILITY_RUNTIME_CJ_EXTENSION_COMMON_H
#include "configuration.h"
#include "service_extension.h"
#include "cj_ui_extension_object.h"
namespace OHOS {
namespace AbilityRuntime {
/**
* @brief Basic cj extension common components.
*/
class CJExtensionCommon : public ExtensionCommon,
public std::enable_shared_from_this<CJExtensionCommon> {
public:
CJExtensionCommon(CJUIExtensionObject cjObj);
virtual ~CJExtensionCommon() override = default;
/**
* @brief Create CJServiceExtension.
*
* @param cjObj The cangjie object.
* @return The CJServiceExtension instance.
*/
static std::shared_ptr<CJExtensionCommon> Create(CJUIExtensionObject cjObj);
/**
* @brief Called when the system configuration is updated.
*
* @param configuration Indicates the updated configuration information.
*/
void OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration> &fullConfig) override;
/**
* @brief Notify current memory level.
*
* @param level Current memory level.
*/
virtual void OnMemoryLevel(int level) override;
private:
CJUIExtensionObject cjObj_;
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_CJ_EXTENSION_COMMON_H
@@ -0,0 +1,83 @@
/*
* 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 OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_OBJECT_H
#define OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_OBJECT_H
#include "ability_handler.h"
#include "ability_local_record.h"
#include "configuration.h"
#include "ohos_application.h"
#include "want.h"
#include "window.h"
#ifdef WINDOWS_PLATFORM
#define CJ_EXPORT __declspec(dllexport)
#else
#define CJ_EXPORT __attribute__((visibility("default")))
#endif
enum class CJExtensionAbilityType {
ACTION = 0,
EMBEDDED,
PHOTO_EDITOR,
SHARE,
};
namespace OHOS {
namespace AbilityRuntime {
using ExtAbilityHandle = void*;
using Want = OHOS::AAFwk::Want;
class CJRuntime;
/**
* @brief cj ui extension object.
*/
class CJUIExtensionObject {
public:
CJUIExtensionObject() : cjID_(0) {}
~CJUIExtensionObject() = default;
int32_t Init(const std::string& abilityName, CJExtensionAbilityType type, ExtAbilityHandle extAbility);
int64_t GetID() const
{
return cjID_;
}
void Destroy();
void OnCreate(const AAFwk::Want &want, AAFwk::LaunchParam &launchParam);
void OnDestroy();
void OnSessionCreate(const AAFwk::Want &want, int64_t sessionId);
void OnSessionDestroy(int64_t sessionId);
void OnForeground();
void OnBackground();
void OnConfigurationUpdate(std::shared_ptr<AppExecFwk::Configuration> fullConfig);
void OnMemoryLevel(int level);
void OnStartContentEditing(const std::string& imageUri, const AAFwk::Want &want, int64_t sessionId);
protected:
int32_t GetType() const
{
return static_cast<int32_t>(type_);
}
protected:
int64_t cjID_;
CJExtensionAbilityType type_;
};
using WantHandle = void*;
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_OBJECT_H
@@ -0,0 +1,43 @@
/*
* 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 OHOS_ABILITY_RUNTIME_CJ_EMBEDDED_UI_EXTENSION_H
#define OHOS_ABILITY_RUNTIME_CJ_EMBEDDED_UI_EXTENSION_H
#include "embedded_ui_extension.h"
#include "configuration.h"
namespace OHOS {
namespace AbilityRuntime {
class EmbeddedUIExtension;
/**
* @brief Basic embedded UI extension components.
*/
class CJEmbeddedUIExtension : public EmbeddedUIExtension, public std::enable_shared_from_this<CJEmbeddedUIExtension> {
public:
explicit CJEmbeddedUIExtension(const std::unique_ptr<Runtime> &runtime);
~CJEmbeddedUIExtension() override;
/**
* @brief Create CJEmbeddedUIExtension.
*
* @param runtime The runtime.
* @return The CJEmbeddedUIExtension instance.
*/
static CJEmbeddedUIExtension *Create(const std::unique_ptr<Runtime> &runtime);
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_CJ_EMBEDDED_UI_EXTENSION_H
@@ -0,0 +1,64 @@
/*
* 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 OHOS_ABILITY_RUNTIME_CJ_PHOTO_EDITOR_EXTENSION_H
#define OHOS_ABILITY_RUNTIME_CJ_PHOTO_EDITOR_EXTENSION_H
#include "photo_editor_extension.h"
#include "configuration.h"
#include "cj_ui_extension_base.h"
namespace OHOS {
namespace AbilityRuntime {
class Runtime;
class CJPhotoEditorExtensionImpl;
/**
* @brief Basic photo editor extension components.
*/
class CJPhotoEditorExtension : public PhotoEditorExtension,
public std::enable_shared_from_this<CJPhotoEditorExtension> {
public:
explicit CJPhotoEditorExtension(const std::unique_ptr<Runtime> &runtime);
virtual ~CJPhotoEditorExtension() override = default;
/**
* @brief Init the photo editor extension.
*
* @param record the photo editor extension record.
* @param application the application info.
* @param handler the photo editor extension handler.
* @param token the remote token.
*/
virtual void Init(const std::shared_ptr<AppExecFwk::AbilityLocalRecord> &record,
const std::shared_ptr<AppExecFwk::OHOSApplication> &application,
std::shared_ptr<AppExecFwk::AbilityHandler> &handler, const sptr<IRemoteObject> &token) override;
/**
* @brief Create CJPhotoEditorExtension.
*
* @param runtime The runtime.
* @return The CJPhotoEditorExtension instance.
*/
static CJPhotoEditorExtension *Create(const std::unique_ptr<Runtime> &runtime);
private:
std::shared_ptr<CJPhotoEditorExtensionImpl> impl_ = nullptr;
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_CJ_PHOTO_EDITOR_EXTENSION_H
@@ -0,0 +1,49 @@
/*
* 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 OHOS_ABILITY_RUNTIME_CJ_PHOTO_EDITOR_EXTENSION_CONTEXT_H
#define OHOS_ABILITY_RUNTIME_CJ_PHOTO_EDITOR_EXTENSION_CONTEXT_H
#include "photo_editor_extension_context.h"
#include "cj_ui_extension_context.h"
#include "image_packer.h"
#include "cj_context.h"
namespace OHOS {
namespace AbilityRuntime {
class CJPhotoEditorExtensionContext : public CJUIExtensionContext {
public:
explicit CJPhotoEditorExtensionContext(const std::shared_ptr<PhotoEditorExtensionContext> &context)
: CJUIExtensionContext(context), context_(context)
{}
virtual ~CJPhotoEditorExtensionContext() = default;
void SetWant(const std::shared_ptr<AAFwk::Want> &want)
{
want_ = want;
}
int32_t SaveEditedContentWithUri(const std::string& uri, AAFwk::Want& want);
int32_t SaveEditedContentWithImage(std::shared_ptr<Media::PixelMap> image, const Media::PackOption& packOption,
AAFwk::Want& want);
private:
std::weak_ptr<PhotoEditorExtensionContext> context_;
std::weak_ptr<AAFwk::Want> want_;
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_CJ_PHOTO_EDITOR_EXTENSION_CONTEXT_H
@@ -0,0 +1,65 @@
/*
* 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 OHOS_ABILITY_RUNTIME_CJ_PHOTO_EDITOR_EXTENSION_IMPL_H
#define OHOS_ABILITY_RUNTIME_CJ_PHOTO_EDITOR_EXTENSION_IMPL_H
#include "cj_ui_extension_base.h"
#include "cj_photo_editor_extension_context.h"
#include <set>
namespace OHOS {
namespace AbilityRuntime {
class PhotoEditorExtensionContext;
class CJPhotoEditorExtensionImpl : public CJUIExtensionBase {
public:
explicit CJPhotoEditorExtensionImpl(const std::unique_ptr<Runtime> &runtime);
virtual ~CJPhotoEditorExtensionImpl() override = default;
void SetContext(const std::shared_ptr<PhotoEditorExtensionContext> &context)
{
context_ = context;
CJUIExtensionBase::SetContext(context);
}
std::shared_ptr<PhotoEditorExtensionContext> GetContext() const
{
return context_;
}
void SetCjContext(sptr<CJPhotoEditorExtensionContext> cjContext)
{
cjContext_ = cjContext;
}
protected:
void OnForeground(const Want &want, sptr<AAFwk::SessionInfo> sessionInfo) override;
private:
void OnStartContentEditing(const AAFwk::Want &want, const sptr<AAFwk::SessionInfo> &sessionInfo);
protected:
std::shared_ptr<PhotoEditorExtensionContext> context_ = nullptr;
sptr<CJPhotoEditorExtensionContext> cjContext_;
std::set<uint64_t> uiExtensionComponentIdSet_;
private:
using CJUIExtensionBase::SetContext;
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_CJ_PHOTO_EDITOR_EXTENSION_IMPL_H
@@ -0,0 +1,42 @@
/*
* 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 OHOS_ABILITY_RUNTIME_CJ_SHARE_EXTENSION_H
#define OHOS_ABILITY_RUNTIME_CJ_SHARE_EXTENSION_H
#include "configuration.h"
#include "share_extension.h"
namespace OHOS {
namespace AbilityRuntime {
/**
* @brief Basic share extension components.
*/
class CJShareExtension : public ShareExtension, public std::enable_shared_from_this<CJShareExtension> {
public:
explicit CJShareExtension(const std::unique_ptr<Runtime> &runtime);
virtual ~CJShareExtension() override;
/**
* @brief Create CJShareExtension.
*
* @param runtime The runtime.
* @return The CJShareExtension instance.
*/
static CJShareExtension *Create(const std::unique_ptr<Runtime> &runtime);
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_CJ_SHARE_EXTENSION_H
@@ -0,0 +1,47 @@
/*
* 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 OHOS_ABILITY_RUNTIME_ABILITY_RESULT_LISTENER_H
#define OHOS_ABILITY_RUNTIME_ABILITY_RESULT_LISTENER_H
#include <map>
#include "want.h"
namespace OHOS {
namespace AbilityRuntime {
class AbilityResultListener {
public:
AbilityResultListener() = default;
virtual ~AbilityResultListener() = default;
virtual void OnAbilityResult(int requestCode, int resultCode, const AAFwk::Want &resultData) = 0;
virtual bool IsMatch(int requestCode) = 0;
};
class AbilityResultListeners {
public:
AbilityResultListeners() = default;
virtual ~AbilityResultListeners() = default;
void AddListener(const uint64_t &uiExtensionComponentId, std::shared_ptr<AbilityResultListener> listener);
void RemoveListener(const uint64_t &uiExtensionComponentId);
void OnAbilityResult(int requestCode, int resultCode, const AAFwk::Want &resultData);
private:
std::map<uint64_t, std::shared_ptr<AbilityResultListener>> listeners_;
};
} // AbilityRuntime
} // OHOS
#endif // OHOS_ABILITY_RUNTIME_ABILITY_RESULT_LISTENER_H
@@ -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.
*/
#ifndef OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_BASE_H
#define OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_BASE_H
#include "ability_handler.h"
#include "ability_local_record.h"
#include "configuration.h"
#include "ohos_application.h"
#include "session_info.h"
#include "ui_extension_base.h"
#include "ui_extension_context.h"
#include "ui_extension_window_command.h"
#include "cj_ui_extension_object.h"
#include "cj_ui_extension_content_session.h"
#include "ability_result_listener.h"
#include "want.h"
#include "window.h"
#ifdef SUPPORT_GRAPHICS
#include "display_manager.h"
#include "window_manager.h"
#endif // SUPPORT_GRAPHICS
namespace OHOS {
namespace AbilityRuntime {
using Want = OHOS::AAFwk::Want;
class CJRuntime;
/**
* @brief cj ui extension base.
*/
class CJUIExtensionBase : public UIExtensionBaseImpl,
public std::enable_shared_from_this<CJUIExtensionBase> {
public:
explicit CJUIExtensionBase(const std::unique_ptr<Runtime> &runtime);
virtual ~CJUIExtensionBase();
/**
* @brief Init the ui extension.
*
* @param record the ui extension record.
* @param application the application info.
* @param handler the ui extension handler.
* @param token the remote token.
* @return cj extension common object.
*/
std::shared_ptr<ExtensionCommon> Init(const std::shared_ptr<AppExecFwk::AbilityLocalRecord> &record,
const std::shared_ptr<AppExecFwk::OHOSApplication> &application,
std::shared_ptr<AppExecFwk::AbilityHandler> &handler, const sptr<IRemoteObject> &token) override;
/**
* @brief Called when this ui extension is started. You must override this function if you want to perform some
* initialization operations during ui extension startup.
*
* This function can be called only once in the entire lifecycle of an ui extension.
*
* @param Want Indicates the {@link Want} structure containing startup information about the ui extension.
* @param launchParam The launch param.
* @param sessionInfo The session info of the ability.
*/
void OnStart(const AAFwk::Want &want, AAFwk::LaunchParam &launchParam,
sptr<AAFwk::SessionInfo> sessionInfo) override;
/**
* @brief Called back when ui extension is started.
*
* This method can be called only by ui extension. You can use the StartAbility(Want) method to start
* ui extension. Then the system calls back the current method to use the transferred want parameter to
* execute its own logic.
*
* @param want Indicates the want of ui extension to start.
* @param restart Indicates the startup mode. The value true indicates that ui extension is restarted after
* being destroyed, and the value false indicates a normal startup.
* @param startId Indicates the number of times the ui extension has been started. The startId is incremented
* by 1 every time the ui extension is started. For example, if the ui extension has been started for six
* times, the value of startId is 6.
*/
void OnCommand(const AAFwk::Want &want, bool restart, int32_t startId) override;
void OnCommandWindow(
const AAFwk::Want &want, const sptr<AAFwk::SessionInfo> &sessionInfo, AAFwk::WindowCommand winCmd) override;
/**
* @brief Called when this ui extension enters the <b>STATE_STOP</b> state.
*
* The ui extension in the <b>STATE_STOP</b> is being destroyed.
* You can override this function to implement your own processing logic.
*/
void OnStop() override;
void OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback) override;
/**
* @brief Called when the system configuration is updated.
*
* @param configuration Indicates the updated configuration information.
*/
void OnConfigurationUpdated(const AppExecFwk::Configuration &configuration) override;
/**
* @brief Called when this extension enters the <b>STATE_FOREGROUND</b> state.
*
*
* The extension in the <b>STATE_FOREGROUND</b> state is visible.
* You can override this function to implement your own processing logic.
*/
void OnForeground(const Want &want, sptr<AAFwk::SessionInfo> sessionInfo) override;
/**
* @brief Called when this extension enters the <b>STATE_BACKGROUND</b> state.
*
*
* The extension in the <b>STATE_BACKGROUND</b> state is invisible.
* You can override this function to implement your own processing logic.
*/
void OnBackground() override;
/**
* @brief Called when ui extension need dump info.
*
* @param params The params from ui extension.
* @param info The dump info to show.
*/
void Dump(const std::vector<std::string> &params, std::vector<std::string> &info) override;
/**
* @brief Called when startAbilityForResult(ohos.aafwk.content.Want,int32_t) is called to start an extension ability
* and the result is returned.
* @param requestCode Indicates the request code returned after the ability is started. You can define the request
* code to identify the results returned by abilities. The value ranges from 0 to 65535.
* @param resultCode Indicates the result code returned after the ability is started. You can define the result
* code to identify an error.
* @param resultData Indicates the data returned after the ability is started. You can define the data returned. The
* value can be null.
*/
void OnAbilityResult(int32_t requestCode, int32_t resultCode, const Want &resultData) override;
/**
* @brief Set ability info.
*/
void SetAbilityInfo(const std::shared_ptr<AppExecFwk::AbilityInfo> &abilityInfo) override;
/**
* @brief Set ui extension context.
*/
void SetContext(const std::shared_ptr<UIExtensionContext> &context) override;
std::shared_ptr<UIExtensionContext> GetContext()
{
return context_;
}
void BindContext() override;
void OnStopCallBack() override;
/**
* @brief Called when configuration changed, including system configuration and window configuration.
*/
void ConfigurationUpdated();
void SetExtType(CJExtensionAbilityType type)
{
extType_ = type;
}
protected:
bool ForegroundWindowWithInsightIntent(const AAFwk::Want &want, const sptr<AAFwk::SessionInfo> &sessionInfo,
bool needForeground);
void ForegroundWindow(const AAFwk::Want &want, const sptr<AAFwk::SessionInfo> &sessionInfo);
void BackgroundWindow(const sptr<AAFwk::SessionInfo> &sessionInfo);
void DestroyWindow(const sptr<AAFwk::SessionInfo> &sessionInfo);
void OnCommandWindowDone(const sptr<AAFwk::SessionInfo> &sessionInfo, AAFwk::WindowCommand winCmd);
bool HandleSessionCreate(const AAFwk::Want &want, const sptr<AAFwk::SessionInfo> &sessionInfo);
void PostInsightIntentExecuted(const sptr<AAFwk::SessionInfo> &sessionInfo,
const AppExecFwk::InsightIntentExecuteResult &result, bool needForeground);
void OnInsightIntentExecuteDone(const sptr<AAFwk::SessionInfo> &sessionInfo,
const AppExecFwk::InsightIntentExecuteResult &result);
protected:
CJRuntime &cjRuntime_;
CJUIExtensionObject cjObj;
std::shared_ptr<UIExtensionContext> context_;
std::map<uint64_t, sptr<Rosen::Window>> uiWindowMap_;
std::set<uint64_t> foregroundWindows_;
std::map<uint64_t, sptr<CJUIExtensionContentSession>> contentSessions_;
std::shared_ptr<AbilityResultListeners> abilityResultListeners_ = nullptr;
std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo_;
sptr<IRemoteObject> token_ = nullptr;
std::shared_ptr<AbilityHandler> handler_ = nullptr;
CJExtensionAbilityType extType_;
#ifdef SUPPORT_GRAPHICS
private:
class CJUIExtensionBaseDisplayListener : public OHOS::Rosen::IDisplayInfoChangedListener {
public:
explicit CJUIExtensionBaseDisplayListener(const std::weak_ptr<CJUIExtensionBase> &cjUiExtensionBase)
{
cjUiExtensionBase_ = cjUiExtensionBase;
}
void OnDisplayInfoChange(const sptr<IRemoteObject> &token, Rosen::DisplayId displayId, float density,
Rosen::DisplayOrientation orientation) override
{
auto sptr = cjUiExtensionBase_.lock();
if (sptr != nullptr) {
sptr->OnDisplayInfoChange(token, displayId, density, orientation);
}
}
private:
std::weak_ptr<CJUIExtensionBase> cjUiExtensionBase_;
};
void RegisterDisplayInfoChangedListener();
void UnregisterDisplayInfoChangedListener();
void OnDisplayInfoChange(const sptr<IRemoteObject> &token, Rosen::DisplayId displayId, float density,
Rosen::DisplayOrientation orientation);
sptr<CJUIExtensionBaseDisplayListener> cjUIExtensionBaseDisplayListener_ = nullptr;
#endif
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_BASE_H
@@ -0,0 +1,57 @@
/*
* 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 OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_CONTENT_SESSION_H
#define OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_CONTENT_SESSION_H
#include "cj_ui_extension_callback.h"
#include "ffi_remote_data.h"
#include "session_info.h"
#include "start_options.h"
#include "window.h"
namespace OHOS {
namespace AbilityRuntime {
class CJUIExtensionContentSession : public FFI::FFIData {
public:
CJUIExtensionContentSession(sptr<AAFwk::SessionInfo> sessionInfo,
sptr<Rosen::Window> uiWindow, std::weak_ptr<AbilityRuntime::Context> context);
virtual ~CJUIExtensionContentSession() = default;
static sptr<CJUIExtensionContentSession> Create(sptr<AAFwk::SessionInfo> sessionInfo,
sptr<Rosen::Window> uiWindow, std::weak_ptr<AbilityRuntime::Context> context);
int32_t LoadContent(const std::string& path, int storage);
int32_t TerminateSelf();
int32_t TerminateSelfWithResult(AAFwk::Want* want, int32_t resultCode);
int32_t SetWindowPrivacyMode(bool isPrivacyMode);
int32_t StartAbilityByType(const std::string &type, AAFwk::WantParams &wantParam,
const std::shared_ptr<CjUIExtensionCallback> &uiExtensionCallbacks);
#ifdef SUPPORT_SCREEN
private:
void InitDisplayId(AAFwk::Want &want);
#endif
private:
sptr<AAFwk::SessionInfo> sessionInfo_;
sptr<Rosen::Window> uiWindow_;
std::weak_ptr<AbilityRuntime::Context> context_;
bool isFirstTriggerBindModal_ {true};
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_CONTENT_SESSION_H
@@ -0,0 +1,37 @@
/*
* 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 OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_CONTEXT_H
#define OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_CONTEXT_H
#include <memory>
#include "ui_extension_context.h"
#include "cj_extension_context.h"
namespace OHOS {
namespace AbilityRuntime {
class CJUIExtensionContextImpl;
class CJUIExtensionContext : public CJExtensionContext {
public:
explicit CJUIExtensionContext(const std::shared_ptr<UIExtensionContext> &context);
virtual ~CJUIExtensionContext() = default;
std::shared_ptr<CJUIExtensionContextImpl> impl;
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_CJ_UI_EXTENSION_CONTEXT_H
@@ -16,6 +16,7 @@
#ifndef OHOS_ABILITY_RUNTIME_JS_UI_EXTENSION_CONTENT_SESSION_H
#define OHOS_ABILITY_RUNTIME_JS_UI_EXTENSION_CONTENT_SESSION_H
#include "ability_result_listener.h"
#include "native_engine/native_engine.h"
#include "js_free_install_observer.h"
#include "js_runtime_utils.h"
@@ -27,25 +28,6 @@ namespace OHOS {
namespace AbilityRuntime {
using RuntimeTask = std::function<void(int, const AAFwk::Want&, bool)>;
class AbilityResultListener {
public:
AbilityResultListener() = default;
virtual ~AbilityResultListener() = default;
virtual void OnAbilityResult(int requestCode, int resultCode, const AAFwk::Want &resultData) = 0;
virtual bool IsMatch(int requestCode) = 0;
};
class AbilityResultListeners {
public:
AbilityResultListeners() = default;
virtual ~AbilityResultListeners() = default;
void AddListener(const uint64_t &uiExtensionComponentId, std::shared_ptr<AbilityResultListener> listener);
void RemoveListener(const uint64_t &uiExtensionComponentId);
void OnAbilityResult(int requestCode, int resultCode, const AAFwk::Want &resultData);
private:
std::map<uint64_t, std::shared_ptr<AbilityResultListener>> listeners_;
};
class UISessionAbilityResultListener : public AbilityResultListener {
public:
UISessionAbilityResultListener() = default;
@@ -21,6 +21,7 @@
#include "bundle_manager_convert.h"
#include "cj_common_ffi.h"
#include "cj_utils_ffi.h"
#include "cj_context.h"
#include "configuration.h"
#include "ffi_remote_data.h"
#include "hap_module_info.h"
@@ -31,18 +32,14 @@ namespace AbilityRuntime {
class Context;
using OHOS::CJSystemapi::BundleManager::RetHapModuleInfo;
class CJAbilityStageContext : public FFI::FFIData {
class CJAbilityStageContext : public FfiContext::CJContext {
public:
explicit CJAbilityStageContext(std::weak_ptr<AbilityRuntime::Context> &&abilityStageContext)
:abilityStageContext_(std::move(abilityStageContext)){};
: FfiContext::CJContext(abilityStageContext.lock()), abilityStageContext_(std::move(abilityStageContext)) {};
std::shared_ptr<AppExecFwk::HapModuleInfo> GetHapModuleInfo();
RetHapModuleInfo GetRetHapModuleInfo();
CConfiguration GetConfiguration();
std::shared_ptr<Context> GetContext()
{
return abilityStageContext_.lock();
}
private:
std::weak_ptr<AbilityRuntime::Context> abilityStageContext_;
@@ -578,6 +578,7 @@ private:
*/
void LoadAllExtensions(NativeEngine &nativeEngine);
void LoadAllExtensions();
/**
*
* @brief Ability Delegator Prepare.