修复移动arkts卡片,卡片数据还原问题

Signed-off-by: liweifeng <liweifeng2@huawei.com>
Change-Id: I4cf22aac1a7e5c4e0477b865a4023c4e76066dce
This commit is contained in:
liweifeng 2023-03-30 15:32:00 +08:00
parent 1a63aedf87
commit d34077d7ce
14 changed files with 322 additions and 116 deletions

View File

@ -128,7 +128,7 @@ private:
// ITouchOutsideListener is used for touching out of hot areas of window.
OHOS::sptr<OHOS::Rosen::ITouchOutsideListener> touchOutsideListener_ = nullptr;
// ArkTS Form
bool isFormRender_ = false;
bool isFormRenderInit_ = false;

View File

@ -40,6 +40,14 @@ Local<JSValueRef> FunctionCallback(panda::JsiRuntimeCallInfo* info)
return package->Callback(info);
}
void FunctionDeleter(void *nativePointer, void *data)
{
auto info = reinterpret_cast<PandaFunctionData*>(data);
if (info != nullptr) {
delete info;
}
}
bool ArkJSRuntime::Initialize(const std::string& libraryPath, bool isDebugMode, int32_t instanceId)
{
RuntimeOption option;
@ -86,10 +94,6 @@ void ArkJSRuntime::Reset()
vm_ = nullptr;
}
}
for (auto data : dataList_) {
delete data;
}
dataList_.clear();
#if defined(PREVIEW)
previewComponents_.clear();
#endif
@ -235,8 +239,8 @@ shared_ptr<JsValue> ArkJSRuntime::NewFunction(RegisterFunctionType func)
{
LocalScope scope(vm_);
auto data = new PandaFunctionData(shared_from_this(), func);
dataList_.emplace_back(data);
return std::make_shared<ArkJSValue>(shared_from_this(), FunctionRef::New(vm_, FunctionCallback, nullptr, data));
return std::make_shared<ArkJSValue>(shared_from_this(),
FunctionRef::New(vm_, FunctionCallback, FunctionDeleter, data));
}
shared_ptr<JsValue> ArkJSRuntime::NewNativePointer(void* ptr)
@ -312,19 +316,24 @@ void ArkJSRuntime::DumpHeapSnapshot(bool isPrivate)
Local<JSValueRef> PandaFunctionData::Callback(panda::JsiRuntimeCallInfo* info) const
{
EscapeLocalScope scope(runtime_->GetEcmaVm());
auto runtime = runtime_.lock();
if (runtime == nullptr) {
LOGE("runtime is nullptr");
return Local<JSValueRef>();
}
EscapeLocalScope scope(runtime->GetEcmaVm());
shared_ptr<JsValue> thisPtr =
std::static_pointer_cast<JsValue>(std::make_shared<ArkJSValue>(runtime_, info->GetThisRef()));
std::static_pointer_cast<JsValue>(std::make_shared<ArkJSValue>(runtime, info->GetThisRef()));
std::vector<shared_ptr<JsValue>> argv;
int32_t length = info->GetArgsNumber();
argv.reserve(length);
for (int32_t i = 0; i < length; ++i) {
argv.emplace_back(
std::static_pointer_cast<JsValue>(std::make_shared<ArkJSValue>(runtime_, info->GetCallArgRef(i))));
std::static_pointer_cast<JsValue>(std::make_shared<ArkJSValue>(runtime, info->GetCallArgRef(i))));
}
shared_ptr<JsValue> result = func_(runtime_, thisPtr, argv, length);
return scope.Escape(std::static_pointer_cast<ArkJSValue>(result)->GetValue(runtime_));
shared_ptr<JsValue> result = func_(runtime, thisPtr, argv, length);
return scope.Escape(std::static_pointer_cast<ArkJSValue>(result)->GetValue(runtime));
}
} // namespace OHOS::Ace::Framework

View File

@ -197,7 +197,6 @@ public:
private:
EcmaVM* vm_ = nullptr;
int32_t instanceId_ = 0;
std::vector<PandaFunctionData*> dataList_;
LOG_PRINT print_ { nullptr };
UncaughtExceptionCallback uncaughtErrorHandler_ { nullptr };
std::string libPath_ {};
@ -215,8 +214,8 @@ private:
class PandaFunctionData {
public:
PandaFunctionData(shared_ptr<ArkJSRuntime> runtime, RegisterFunctionType func)
: runtime_(std::move(runtime)), func_(std::move(func))
PandaFunctionData(std::weak_ptr<ArkJSRuntime> runtime, RegisterFunctionType func)
: runtime_(runtime), func_(std::move(func))
{}
~PandaFunctionData() = default;
@ -226,7 +225,7 @@ public:
private:
Local<JSValueRef> Callback(panda::JsiRuntimeCallInfo* info) const;
shared_ptr<ArkJSRuntime> runtime_;
std::weak_ptr<ArkJSRuntime> runtime_;
RegisterFunctionType func_;
friend Local<JSValueRef> FunctionCallback(panda::JsiRuntimeCallInfo* info);
};

View File

@ -48,15 +48,18 @@ public:
bool IsAllowUpdate();
void OnSurfaceCreate(const OHOS::AppExecFwk::FormJsInfo& formJsInfo);
void OnSurfaceReuse(const OHOS::AppExecFwk::FormJsInfo& formJsInfo);
void OnActionEvent(const std::string& action);
void OnError(const std::string& code, const std::string& msg);
void OnSurfaceChange(float width, float height);
void UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config);
void AttachForm(const OHOS::AAFwk::Want& want, const OHOS::AppExecFwk::FormJsInfo& formJsInfo);
private:
void InitUIContent(const OHOS::AppExecFwk::FormJsInfo& formJsInfo);
void ParseWant(const OHOS::AAFwk::Want& want);
void SetRenderDelegate(const sptr<IRemoteObject> &renderRemoteObj);
void AttachUIContent(const OHOS::AppExecFwk::FormJsInfo& formJsInfo);
bool allowUpdate_ = true;
float width_ = 0.0f;

View File

@ -47,6 +47,26 @@ public:
const std::shared_ptr<Rosen::RSSurfaceNode>& surfaceNode,
const OHOS::AppExecFwk::FormJsInfo& formJsInfo,
const AAFwk::Want& want) = 0;
/**
* @brief OnSurfaceReuse.
* @param surfaceId The surfaceNode ID.
* @param formJsInfo The formJsInfo.
* @param want The want.
*/
virtual int32_t OnSurfaceReuse(uint64_t surfaceId,
const OHOS::AppExecFwk::FormJsInfo& formJsInfo,
const AAFwk::Want& want)
{
return ERR_OK;
}
/**
* @brief OnSurfaceRelease.
* @param surfaceId The surfaceNode ID.
*/
virtual int32_t OnSurfaceRelease(uint64_t surfaceId)
{
return ERR_OK;
}
/**
* @brief OnActionEvent.
* @param action The action.
@ -67,6 +87,8 @@ public:
enum Message : uint32_t {
ON_SURFACE_CREATE = 1,
ON_SURFACE_REUSE,
ON_SURFACE_RELEASE,
ON_ACTION_CREATE,
ON_ERROR,
ON_SURFACE_CHANGE,

View File

@ -35,6 +35,11 @@ public:
int32_t OnSurfaceCreate(const std::shared_ptr<Rosen::RSSurfaceNode>& surfaceNode,
const OHOS::AppExecFwk::FormJsInfo& formJsInfo, const AAFwk::Want& want) override;
int32_t OnSurfaceReuse(uint64_t surfaceId,
const OHOS::AppExecFwk::FormJsInfo& formJsInfo, const AAFwk::Want& want) override;
int32_t OnSurfaceRelease(uint64_t surfaceId) override;
int32_t OnActionEvent(const std::string& action) override;
int32_t OnError(const std::string& code, const std::string& msg) override;

View File

@ -46,6 +46,8 @@ public:
private:
int32_t HandleOnSurfaceCreate(MessageParcel &data, MessageParcel &reply);
int32_t HandleOnSurfaceReuse(MessageParcel &data, MessageParcel &reply);
int32_t HandleOnSurfaceRelease(MessageParcel &data, MessageParcel &reply);
int32_t HandleOnActionEvent(MessageParcel &data, MessageParcel &reply);
int32_t HandleOnError(MessageParcel &data, MessageParcel &reply);
int32_t HandleOnSurfaceChange(MessageParcel &data, MessageParcel &reply);

View File

@ -16,9 +16,12 @@
#ifndef FOUNDATION_ACE_INTERFACE_INNERKITS_FORM_RENDERER_GROUP_H
#define FOUNDATION_ACE_INTERFACE_INNERKITS_FORM_RENDERER_GROUP_H
#include <unordered_map>
#include <memory>
#include <string>
#include <vector>
#include "form_js_info.h"
#include "want.h"
namespace OHOS {
namespace AbilityRuntime {
@ -26,12 +29,7 @@ class Context;
class Runtime;
}
namespace AAFwk {
class Want;
}
namespace AppExecFwk {
struct FormJsInfo;
class Configuration;
}
@ -46,7 +44,7 @@ class FormRenderer;
* @class FormRendererGroup
* FormRendererGroup interface is used to form renderer group.
* Provider:FormRendererGroup:runtime = 1:1:1
* FormRendererGroup:FormRenderer = 1:compId
* FormRendererGroup:FormRenderer = 1:1
*/
class ACE_EXPORT FormRendererGroup {
public:
@ -62,13 +60,18 @@ public:
void DeleteForm();
void DeleteForm(const std::string& compId);
void ReloadForm();
bool IsEmpty();
void UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config);
private:
struct FormRequest {
std::string compId;
OHOS::AAFwk::Want want;
OHOS::AppExecFwk::FormJsInfo formJsInfo;
};
std::shared_ptr<OHOS::AbilityRuntime::Context> context_;
std::shared_ptr<OHOS::AbilityRuntime::Runtime> runtime_;
std::unordered_map<std::string, std::shared_ptr<FormRenderer>> rendererMap_;
std::shared_ptr<FormRenderer> formRenderer_;
std::vector<FormRequest> formRequests_;
std::string currentCompId_;
};
} // namespace Ace
} // namespace OHOS

View File

@ -134,7 +134,6 @@ void FormRenderer::UpdateForm(const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
HILOG_ERROR("uiContent_ is null");
return;
}
uiContent_->UpdateFormSharedImage(formJsInfo.imageDataMap);
uiContent_->UpdateFormData(formJsInfo.formData);
}
@ -142,6 +141,14 @@ void FormRenderer::UpdateForm(const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
void FormRenderer::Destroy()
{
HILOG_INFO("Destroy FormRenderer start.");
if (formRendererDelegate_ != nullptr) {
auto rsSurfaceNode = uiContent_->GetFormRootNode();
if (rsSurfaceNode != nullptr) {
HILOG_INFO("Form OnSurfaceRelease!");
formRendererDelegate_->OnSurfaceRelease(rsSurfaceNode->GetId());
}
}
if (formRendererDelegate_ != nullptr && formRendererDelegate_->AsObject() != nullptr) {
formRendererDelegate_->AsObject()->RemoveDeathRecipient(renderDelegateDeathRecipient_);
}
@ -183,6 +190,27 @@ void FormRenderer::OnSurfaceCreate(const OHOS::AppExecFwk::FormJsInfo& formJsInf
formRendererDelegate_->OnSurfaceCreate(rsSurfaceNode, formJsInfo, newWant);
}
void FormRenderer::OnSurfaceReuse(const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
{
if (!formRendererDispatcherImpl_) {
HILOG_ERROR("form renderer dispatcher is null!");
return;
}
if (!formRendererDelegate_) {
HILOG_ERROR("form renderer delegate is null!");
return;
}
auto rsSurfaceNode = uiContent_->GetFormRootNode();
if (rsSurfaceNode == nullptr) {
HILOG_ERROR("form renderer rsSurfaceNode is null!");
return;
}
OHOS::AAFwk::Want newWant;
newWant.SetParam(FORM_RENDERER_DISPATCHER, formRendererDispatcherImpl_->AsObject());
HILOG_INFO("Form OnSurfaceReuse.");
formRendererDelegate_->OnSurfaceReuse(rsSurfaceNode->GetId(), formJsInfo, newWant);
}
void FormRenderer::OnActionEvent(const std::string& action)
{
if (!formRendererDelegate_) {
@ -211,21 +239,19 @@ void FormRenderer::SetRenderDelegate(const sptr<IRemoteObject> &remoteObj)
HILOG_ERROR("renderRemoteObj is nullptr.");
return;
}
if (formRendererDelegate_ == nullptr) {
formRendererDelegate_ = renderRemoteObj;
}
if (renderDelegateDeathRecipient_) {
return;
formRendererDelegate_ = renderRemoteObj;
if (renderDelegateDeathRecipient_ == nullptr) {
renderDelegateDeathRecipient_ = new FormRenderDelegateRecipient([weak = weak_from_this()]() {
auto formRender = weak.lock();
if (!formRender) {
HILOG_ERROR("formRender is nullptr");
return;
}
formRender->ResetRenderDelegate();
});
}
renderDelegateDeathRecipient_ = new FormRenderDelegateRecipient([weak = weak_from_this()]() {
auto formRender = weak.lock();
if (!formRender) {
HILOG_ERROR("formRender is nullptr");
return;
}
formRender->ResetRenderDelegate();
});
auto renderDelegate = formRendererDelegate_->AsObject();
if (renderDelegate == nullptr) {
HILOG_ERROR("renderDelegate is nullptr, can not get obj from renderRemoteObj.");
@ -236,6 +262,7 @@ void FormRenderer::SetRenderDelegate(const sptr<IRemoteObject> &remoteObj)
void FormRenderer::ResetRenderDelegate()
{
HILOG_INFO("ResetRenderDelegate.");
formRendererDelegate_ = nullptr;
}
@ -261,5 +288,29 @@ void FormRenderDelegateRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote
handler_();
}
}
void FormRenderer::AttachForm(const OHOS::AAFwk::Want& want, const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
{
if (uiContent_ == nullptr) {
HILOG_ERROR("uiContent is null!");
return;
}
ParseWant(want);
AttachUIContent(formJsInfo);
SetRenderDelegate(proxy_);
OnSurfaceReuse(formJsInfo);
}
void FormRenderer::AttachUIContent(const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
{
HILOG_INFO("AttachUIContent width = %{public}f , height = %{public}f.", width_, height_);
SetAllowUpdate(allowUpdate_);
auto rsSurfaceNode = uiContent_->GetFormRootNode();
if (rsSurfaceNode == nullptr) {
HILOG_ERROR("rsSurfaceNode is nullptr.");
return;
}
rsSurfaceNode->SetBounds(0.0f, 0.0f, width_, height_);
}
} // namespace Ace
} // namespace OHOS

View File

@ -32,27 +32,29 @@ int32_t FormRendererDelegateProxy::OnSurfaceCreate(
HILOG_ERROR("%{public}s, failed to write interface token", __func__);
return ERR_INVALID_VALUE;
}
if (surfaceNode == nullptr || !surfaceNode->Marshalling(data)) {
if (surfaceNode == nullptr) {
HILOG_ERROR("%{public}s fail, surfaceNode is nullptr", __func__);
return ERR_INVALID_VALUE;
}
if (!surfaceNode->Marshalling(data)) {
HILOG_ERROR("%{public}s fail, write surfaceNode error", __func__);
return ERR_INVALID_VALUE;
}
if (!data.WriteParcelable(&formJsInfo)) {
HILOG_ERROR("%{public}s fail, write formJsInfo error", __func__);
return ERR_INVALID_VALUE;
}
if (!data.WriteParcelable(&want)) {
HILOG_ERROR("%{public}s fail, write want error", __func__);
return ERR_INVALID_VALUE;
}
HILOG_INFO("Proxy create surfaceNode:%{public}s", std::to_string(surfaceNode->GetId()).c_str());
MessageParcel reply;
MessageOption option;
auto remoteProxy = Remote();
if (!remoteProxy) {
HILOG_ERROR("Send surfaceNode failed, ipc remoteobj is null");
HILOG_ERROR("Send surfaceNode failed, ipc remoteObj is null");
return IPC_PROXY_ERR;
}
int32_t error = remoteProxy->SendRequest(
@ -65,6 +67,69 @@ int32_t FormRendererDelegateProxy::OnSurfaceCreate(
return reply.ReadInt32();
}
int32_t FormRendererDelegateProxy::OnSurfaceReuse(uint64_t surfaceId,
const OHOS::AppExecFwk::FormJsInfo& formJsInfo, const AAFwk::Want& want)
{
MessageParcel data;
if (!WriteInterfaceToken(data)) {
HILOG_ERROR("%{public}s, failed to write interface token", __func__);
return ERR_INVALID_VALUE;
}
data.WriteUint64(surfaceId);
if (!data.WriteParcelable(&formJsInfo)) {
HILOG_ERROR("%{public}s fail, write formJsInfo error", __func__);
return ERR_INVALID_VALUE;
}
if (!data.WriteParcelable(&want)) {
HILOG_ERROR("%{public}s fail, write want error", __func__);
return ERR_INVALID_VALUE;
}
HILOG_INFO("Proxy reuse surfaceNode:%{public}s", std::to_string(surfaceId).c_str());
MessageParcel reply;
MessageOption option;
auto remoteProxy = Remote();
if (!remoteProxy) {
HILOG_ERROR("Send surfaceNode failed, ipc remoteObj is null");
return IPC_PROXY_ERR;
}
int32_t error = remoteProxy->SendRequest(
static_cast<uint32_t>(IFormRendererDelegate::Message::ON_SURFACE_REUSE), data, reply, option);
if (error != NO_ERROR) {
HILOG_ERROR("%{public}s, failed to SendRequest: %{public}d", __func__, error);
return error;
}
return reply.ReadInt32();
}
int32_t FormRendererDelegateProxy::OnSurfaceRelease(uint64_t surfaceId)
{
MessageParcel data;
if (!WriteInterfaceToken(data)) {
HILOG_ERROR("%{public}s, failed to write interface token", __func__);
return ERR_INVALID_VALUE;
}
data.WriteUint64(surfaceId);
HILOG_INFO("Proxy release surfaceNode:%{public}s", std::to_string(surfaceId).c_str());
MessageParcel reply;
MessageOption option;
auto remoteProxy = Remote();
if (!remoteProxy) {
HILOG_ERROR("Send surfaceNode failed, ipc remoteObj is null");
return IPC_PROXY_ERR;
}
int32_t error = remoteProxy->SendRequest(
static_cast<uint32_t>(IFormRendererDelegate::Message::ON_SURFACE_RELEASE), data, reply, option);
if (error != NO_ERROR) {
HILOG_ERROR("%{public}s, failed to SendRequest: %{public}d", __func__, error);
return error;
}
return reply.ReadInt32();
}
int32_t FormRendererDelegateProxy::OnActionEvent(const std::string& action)
{
MessageParcel data;

View File

@ -18,10 +18,17 @@
namespace OHOS {
namespace Ace {
static std::mutex g_surfaceNodeMutex_;
static std::map<uint64_t, std::shared_ptr<Rosen::RSSurfaceNode>> g_surfaceNodeMap_;
FormRendererDelegateStub::FormRendererDelegateStub()
{
memberFuncMap_[static_cast<uint32_t>(IFormRendererDelegate::Message::ON_SURFACE_CREATE)] =
&FormRendererDelegateStub::HandleOnSurfaceCreate;
memberFuncMap_[static_cast<uint32_t>(IFormRendererDelegate::Message::ON_SURFACE_REUSE)] =
&FormRendererDelegateStub::HandleOnSurfaceReuse;
memberFuncMap_[static_cast<uint32_t>(IFormRendererDelegate::Message::ON_SURFACE_RELEASE)] =
&FormRendererDelegateStub::HandleOnSurfaceRelease;
memberFuncMap_[static_cast<uint32_t>(IFormRendererDelegate::Message::ON_ACTION_CREATE)] =
&FormRendererDelegateStub::HandleOnActionEvent;
memberFuncMap_[static_cast<uint32_t>(IFormRendererDelegate::Message::ON_ERROR)] =
@ -60,12 +67,16 @@ int FormRendererDelegateStub::OnRemoteRequest(
int FormRendererDelegateStub::HandleOnSurfaceCreate(MessageParcel &data, MessageParcel &reply)
{
std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode = Rosen::RSSurfaceNode::Unmarshalling(data);
auto surfaceNode = Rosen::RSSurfaceNode::Unmarshalling(data);
if (surfaceNode == nullptr) {
HILOG_ERROR("surfaceNode is nullptr");
return ERR_INVALID_VALUE;
}
{
std::lock_guard<std::mutex> lock(g_surfaceNodeMutex_);
g_surfaceNodeMap_[surfaceNode->GetId()] = surfaceNode;
}
HILOG_INFO("Stub create surfaceNode:%{public}s", std::to_string(surfaceNode->GetId()).c_str());
std::unique_ptr<AppExecFwk::FormJsInfo> formJsInfo(data.ReadParcelable<AppExecFwk::FormJsInfo>());
if (formJsInfo == nullptr) {
HILOG_ERROR("formJsInfo is nullptr");
@ -83,6 +94,55 @@ int FormRendererDelegateStub::HandleOnSurfaceCreate(MessageParcel &data, Message
return ERR_OK;
}
int32_t FormRendererDelegateStub::HandleOnSurfaceReuse(MessageParcel &data, MessageParcel &reply)
{
uint64_t id = UINT64_MAX;
data.ReadUint64(id);
std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode;
{
std::lock_guard<std::mutex> lock(g_surfaceNodeMutex_);
surfaceNode = g_surfaceNodeMap_[id];
}
if (surfaceNode == nullptr) {
HILOG_ERROR("surfaceNode:%{public}s is nullptr", std::to_string(id).c_str());
return ERR_INVALID_VALUE;
}
HILOG_INFO("Stub reuse surfaceNode:%{public}s", std::to_string(id).c_str());
std::unique_ptr<AppExecFwk::FormJsInfo> formJsInfo(data.ReadParcelable<AppExecFwk::FormJsInfo>());
if (formJsInfo == nullptr) {
HILOG_ERROR("formJsInfo is nullptr");
return ERR_INVALID_VALUE;
}
std::shared_ptr<AAFwk::Want> want(data.ReadParcelable<AAFwk::Want>());
if (want == nullptr) {
HILOG_ERROR("want is nullptr");
return ERR_INVALID_VALUE;
}
int32_t errCode = OnSurfaceCreate(surfaceNode, *formJsInfo, *want);
reply.WriteInt32(errCode);
return ERR_OK;
}
int32_t FormRendererDelegateStub::HandleOnSurfaceRelease(MessageParcel &data, MessageParcel &reply)
{
uint64_t id = UINT64_MAX;
data.ReadUint64(id);
HILOG_INFO("Stub release surfaceNode:%{public}s start", std::to_string(id).c_str());
{
std::lock_guard<std::mutex> lock(g_surfaceNodeMutex_);
auto iter = g_surfaceNodeMap_.find(id);
if (iter != g_surfaceNodeMap_.end()) {
HILOG_INFO("Stub release surfaceNode:%{public}s finish", std::to_string(id).c_str());
g_surfaceNodeMap_.erase(iter);
}
}
reply.WriteInt32(ERR_OK);
return ERR_OK;
}
int FormRendererDelegateStub::HandleOnActionEvent(MessageParcel &data, MessageParcel &reply)
{
std::string action = data.ReadString();

View File

@ -16,7 +16,6 @@
#include "form_renderer_group.h"
#include "configuration.h"
#include "form_js_info.h"
#include "form_renderer.h"
#include "form_renderer_hilog.h"
@ -40,76 +39,78 @@ FormRendererGroup::FormRendererGroup(
void FormRendererGroup::AddForm(const OHOS::AAFwk::Want& want, const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
{
auto compId = want.GetStringParam(FORM_RENDERER_COMP_ID);
HILOG_INFO("AddForm compId %{public}s.", compId.c_str());
auto iter = rendererMap_.find(compId);
if (iter != rendererMap_.end()) {
HILOG_WARN("AddForm compId: %{public}s exist", compId.c_str());
auto renderer = iter->second;
renderer->Destroy();
rendererMap_.erase(iter);
currentCompId_ = compId;
FormRequest formRequest;
formRequest.compId = compId;
formRequest.want = want;
formRequest.formJsInfo = formJsInfo;
formRequests_.push_back(formRequest);
if (formRenderer_ == nullptr) {
formRenderer_ = std::make_shared<FormRenderer>(context_, runtime_);
if (!formRenderer_) {
HILOG_ERROR("AddForm create form render failed");
return;
}
HILOG_INFO("AddForm compId is %{public}s. formId is %{public}s", compId.c_str(),
std::to_string(formJsInfo.formId).c_str());
formRenderer_->AddForm(want, formJsInfo);
} else {
HILOG_INFO("AttachForm compId is %{public}s formRequests size is :%{public}s.",
compId.c_str(), std::to_string(formRequests_.size()).c_str());
formRenderer_->AttachForm(want, formJsInfo);
}
auto formRenderer = std::make_shared<FormRenderer>(context_, runtime_);
if (!formRenderer) {
HILOG_ERROR("AddForm create formrender failed");
return;
}
rendererMap_.try_emplace(compId, formRenderer);
formRenderer->AddForm(want, formJsInfo);
}
void FormRendererGroup::ReloadForm()
{
auto iter = rendererMap_.begin();
while (iter != rendererMap_.end()) {
auto renderer = iter->second;
renderer->ReloadForm();
iter++;
if (formRenderer_ == nullptr) {
HILOG_ERROR("ReloadForm failed, formRenderer is null");
return;
}
formRenderer_->ReloadForm();
}
void FormRendererGroup::UpdateForm(const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
{
HILOG_INFO("UpdateForm formId %{public}s.", std::to_string(formJsInfo.formId).c_str());
auto iter = rendererMap_.begin();
while (iter!= rendererMap_.end()) {
auto renderer = iter->second;
renderer->UpdateForm(formJsInfo);
iter++;
if (formRenderer_ == nullptr) {
HILOG_ERROR("UpdateForm failed, formRenderer is null");
return;
}
formRenderer_->UpdateForm(formJsInfo);
}
void FormRendererGroup::DeleteForm(const std::string& compId)
{
HILOG_INFO("DeleteForm compId %{public}s.", compId.c_str());
auto iter = rendererMap_.find(compId);
if (iter == rendererMap_.end()) {
return;
HILOG_INFO("DeleteForm compId is %{public}s, currentCompId is %{public}s, formRequests size is %{public}s.",
compId.c_str(), currentCompId_.c_str(), std::to_string(formRequests_.size()).c_str());
for (auto iter = formRequests_.begin(); iter != formRequests_.end(); ++iter) {
if (iter->compId == compId) {
formRequests_.erase(iter);
break;
}
}
auto renderer = iter->second;
// should release the occupancy of resources of the context, runtime and ui content
if (!renderer) {
HILOG_ERROR("DeleteForm compId %{public}s renderer is null.", compId.c_str());
if (formRequests_.empty() || compId != currentCompId_) {
return;
}
renderer->Destroy();
rendererMap_.erase(iter);
FormRequest request = formRequests_.back();
currentCompId_ = request.compId;
HILOG_INFO("RestoreForm compId is %{public}s.", currentCompId_.c_str());
formRenderer_->AttachForm(request.want, request.formJsInfo);
}
void FormRendererGroup::DeleteForm()
{
HILOG_INFO("DeleteForm all compIds, size: %{public}zu", rendererMap_.size());
for (const auto &iter : rendererMap_) {
HILOG_INFO("DeleteForm compId %{public}s.", iter.first.c_str());
iter.second->Destroy();
if (formRenderer_ == nullptr) {
HILOG_ERROR("DeleteForm failed, formRenderer is null");
return;
}
rendererMap_.clear();
}
bool FormRendererGroup::IsEmpty()
{
return rendererMap_.empty();
formRenderer_->Destroy();
formRenderer_ = nullptr;
formRequests_.clear();
}
void FormRendererGroup::UpdateConfiguration(
@ -119,11 +120,11 @@ void FormRendererGroup::UpdateConfiguration(
HILOG_ERROR("UpdateConfiguration config is null");
return;
}
HILOG_INFO("UpdateConfiguration all compIds, size: %{public}zu", rendererMap_.size());
for (const auto& iter : rendererMap_) {
iter.second->UpdateConfiguration(config);
if (formRenderer_ == nullptr) {
HILOG_ERROR("UpdateConfiguration failed, formRenderer is null");
return;
}
formRenderer_->UpdateConfiguration(config);
}
} // namespace Ace
} // namespace OHOS

View File

@ -36,9 +36,6 @@ bool FormRenderGroup(const std::string data, size_t size)
fromGroup->ReloadForm();
auto id = size % u16m;
fromGroup->DeleteForm(std::to_string(id));
if (fromGroup->IsEmpty()) {
return false;
}
return true;
}
}

View File

@ -67,19 +67,15 @@ HWTEST_F(FormRenderTest, FormRenderTest001, TestSize.Level1)
* @tc.steps: step2. call AddForm
* @tc.expected: step2. formRenderer is created successfully and added to the formRendererGroup
*/
EXPECT_TRUE(formRendererGroup->IsEmpty());
// formRenderer->uiContent_ is null, so formRenderer->AddForm will not be called
formRendererGroup->AddForm(want, formJsInfo);
EXPECT_FALSE(formRendererGroup->IsEmpty());
auto renderMap = formRendererGroup->rendererMap_;
auto iter = renderMap.find(FORM_COMPONENT_ID_1);
EXPECT_TRUE(iter != renderMap.end());
EXPECT_TRUE(formRendererGroup->formRenderer_ != nullptr);
/**
* @tc.steps: step3. call formRenderer's AddForm
* @tc.expected: step3. uiContent's relevant methods are called & formRenderer's property are set
*/
auto formRenderer = iter->second;
auto formRenderer = formRendererGroup->formRenderer_;
EXPECT_TRUE(formRenderer);
formRenderer->uiContent_ = UIContent::Create(nullptr, nullptr);
EXPECT_TRUE(formRenderer->uiContent_);
@ -91,7 +87,7 @@ HWTEST_F(FormRenderTest, FormRenderTest001, TestSize.Level1)
.WillOnce(Return());
EXPECT_CALL(*((MockUIContent*)(formRenderer->uiContent_.get())), SetActionEventHandler(_)).WillOnce(Return());
EXPECT_CALL(*((MockUIContent*)(formRenderer->uiContent_.get())), SetErrorEventHandler(_)).WillOnce(Return());
EXPECT_CALL(*((MockUIContent*)(formRenderer->uiContent_.get())), GetFormRootNode()).WillOnce(Return(nullptr));
EXPECT_CALL(*((MockUIContent*)(formRenderer->uiContent_.get())), GetFormRootNode()).Times(Exactly(2));
// call AddForm manually
formRenderer->AddForm(want, formJsInfo);
EXPECT_EQ(formRenderer->allowUpdate_, true);
@ -108,9 +104,7 @@ HWTEST_F(FormRenderTest, FormRenderTest001, TestSize.Level1)
want2.SetParam(FORM_RENDERER_COMP_ID, FORM_COMPONENT_ID_2);
want2.SetParam(FORM_RENDERER_ALLOW_UPDATE, true);
formRendererGroup->AddForm(want2, formJsInfo);
EXPECT_EQ(static_cast<int32_t>(formRendererGroup->rendererMap_.size()), 2);
// call formRenderer2's events, nothing will happen for formRendererDelegate_ is null
auto formRenderer2 = formRendererGroup->rendererMap_.find(FORM_COMPONENT_ID_2)->second;
auto formRenderer2 = formRendererGroup->formRenderer_;
formRenderer2->OnActionEvent("");
formRenderer2->OnError("", "");
formRenderer2->OnSurfaceChange(0.0f, 0.0f);
@ -135,7 +129,6 @@ HWTEST_F(FormRenderTest, FormRenderTest001, TestSize.Level1)
* @tc.expected: step7. delete fail
*/
formRendererGroup->DeleteForm(FORM_COMPONENT_ID_3);
EXPECT_EQ(static_cast<int32_t>(formRendererGroup->rendererMap_.size()), 2);
/**
* @tc.steps: step8. delete formRenderer whose compId exists
@ -144,14 +137,12 @@ HWTEST_F(FormRenderTest, FormRenderTest001, TestSize.Level1)
EXPECT_CALL(*((MockUIContent*)(formRenderer->uiContent_.get())), Destroy()).WillOnce(Return());
// delete formRenderer that compId exists
formRendererGroup->DeleteForm(FORM_COMPONENT_ID_1);
EXPECT_EQ(static_cast<int32_t>(formRendererGroup->rendererMap_.size()), 1);
/**
* @tc.steps: step9. delete all formRenderers
* @tc.expected: step9. delete successfully
*/
formRendererGroup->DeleteForm();
EXPECT_TRUE(formRendererGroup->IsEmpty());
}
/**
@ -175,9 +166,7 @@ HWTEST_F(FormRenderTest, FormRenderTest002, TestSize.Level1)
want.SetParam(FORM_RENDERER_PROCESS_ON_ADD_SURFACE, renderDelegate->AsObject());
OHOS::AppExecFwk::FormJsInfo formJsInfo;
formRendererGroup->AddForm(want, formJsInfo);
auto renderMap = formRendererGroup->rendererMap_;
auto iter = renderMap.find(FORM_COMPONENT_ID_1);
auto formRenderer = iter->second;
auto formRenderer = formRendererGroup->formRenderer_;;
EXPECT_TRUE(formRenderer);
formRenderer->uiContent_ = UIContent::Create(nullptr, nullptr);
EXPECT_TRUE(formRenderer->uiContent_);