diff --git a/BUILD.gn b/BUILD.gn index 64167de8dafccdcf5dcf63161187e6623259cd50..2930ba2f87788f59c602ccd33b8fe6583b325b50 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -68,8 +68,11 @@ ohos_shared_library("libfms") { "services/src/form_rdb_data_mgr.cpp", "services/src/form_refresh_connection.cpp", "services/src/form_refresh_limiter.cpp", + "services/src/form_render_connection.cpp", + "services/src/form_render_mgr.cpp", "services/src/form_share_connection.cpp", "services/src/form_share_mgr.cpp", + "services/src/form_stop_rendering_connection.cpp", "services/src/form_supply_callback.cpp", "services/src/form_sys_event_receiver.cpp", "services/src/form_task_mgr.cpp", diff --git a/interfaces/inner_api/include/form_render_interface.h b/interfaces/inner_api/include/form_render_interface.h index 6698d4e3835691558ffb15ac5e62c4c4e0dd61c0..864151f6d9abff53aa861484d1af5f4ba8682f1c 100755 --- a/interfaces/inner_api/include/form_render_interface.h +++ b/interfaces/inner_api/include/form_render_interface.h @@ -30,7 +30,7 @@ using OHOS::AAFwk::Want; * @class IFormProvider * IFormProvider interface is used to access form render service. */ -class IFormRender : public OHOS::IRemoteBroker { +class IFormRender : public IRemoteBroker { public: DECLARE_INTERFACE_DESCRIPTOR(u"ohos.appexecfwk.FormRender"); @@ -44,12 +44,27 @@ public: virtual int32_t RenderForm(const FormJsInfo &formJsInfo, const Want &want, const sptr &callerToken) = 0; - virtual int32_t DeleteRenderForm(const int64_t &formId, const Want &want, - const sptr &callerToken) = 0; + /** + * @brief Stop rendering form. This is sync API. + * @param formId Indicates The Id of the form to stop rendering. + * @param want Indicates the {@link Want} structure containing form info. + * @param callerToken Caller ability token. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int32_t StopRenderingForm(int64_t formId, const Want &want, const sptr &callerToken) = 0; enum class Message { + // ipc id 1-1000 for kit + // ipc id 1001-2000 for DMS + // ipc id 2001-3000 for tools + // ipc id for form mgr (3001) + // ipc id for form provider (3051) + // ipc id for form render (3101) + // ipc id for form supply (3201) + // ipc id for form host (3681) + FORM_RENDER_RENDER_FORM = 3101, - FORM_RENDER_DELETE_RENDER_FORM = 3102, + FORM_RENDER_STOP_RENDERING_FORM = 3102, }; }; } // namespace AppExecFwk diff --git a/interfaces/inner_api/include/form_render_proxy.h b/interfaces/inner_api/include/form_render_proxy.h index 70b633b5f1c47792cf5bdc901aa897d99b3cbb05..73413326ba0aa63b2b982a3d4d21de00f4a20000 100755 --- a/interfaces/inner_api/include/form_render_proxy.h +++ b/interfaces/inner_api/include/form_render_proxy.h @@ -41,7 +41,7 @@ public: */ int32_t RenderForm(const FormJsInfo &formJsInfo, const Want &want, const sptr &callerToken) override; - int32_t DeleteRenderForm(const int64_t &formId, const Want &want, const sptr &callerToken) override; + int32_t StopRenderingForm(int64_t formId, const Want &want, const sptr &callerToken) override; private: template int32_t GetParcelableInfos(MessageParcel &reply, std::vector &parcelableInfos); diff --git a/interfaces/inner_api/include/form_render_stub.h b/interfaces/inner_api/include/form_render_stub.h index 9cedf5e227b24d268da79a2aa403de22a3ecc3a9..c7ccd5c404b6714e65fd7e3efeb17e808a6b481d 100755 --- a/interfaces/inner_api/include/form_render_stub.h +++ b/interfaces/inner_api/include/form_render_stub.h @@ -51,8 +51,7 @@ private: */ int32_t HandleRenderForm(MessageParcel &data, MessageParcel &reply); - int32_t HandleDeleteRenderForm(MessageParcel &data, MessageParcel &reply); - + int32_t HandleStopRenderingForm(MessageParcel &data, MessageParcel &reply); private: using FormRenderFunc = int32_t (FormRenderStub::*)(MessageParcel &data, MessageParcel &reply); std::map memberFuncMap_; diff --git a/interfaces/inner_api/src/form_render_proxy.cpp b/interfaces/inner_api/src/form_render_proxy.cpp index edd1711bb06991ce11644b03da8d34f4bc3417a4..b418941da28205aa5408ec4034b762d0d39ceab9 100755 --- a/interfaces/inner_api/src/form_render_proxy.cpp +++ b/interfaces/inner_api/src/form_render_proxy.cpp @@ -62,7 +62,7 @@ int32_t FormRenderProxy::RenderForm(const FormJsInfo &formJsInfo, const Want &wa return ERR_OK; } -int32_t FormRenderProxy::DeleteRenderForm(const int64_t &formId, const Want &want, +int32_t FormRenderProxy::StopRenderingForm(int64_t formId, const Want &want, const sptr &callerToken) { MessageParcel data; @@ -93,7 +93,7 @@ int32_t FormRenderProxy::DeleteRenderForm(const int64_t &formId, const Want &wan } int error = Remote()->SendRequest( - static_cast(IFormRender::Message::FORM_RENDER_DELETE_RENDER_FORM), + static_cast(IFormRender::Message::FORM_RENDER_STOP_RENDERING_FORM), data, reply, option); @@ -104,7 +104,7 @@ int32_t FormRenderProxy::DeleteRenderForm(const int64_t &formId, const Want &wan return ERR_OK; } -bool FormRenderProxy::WriteInterfaceToken(MessageParcel &data) +bool FormRenderProxy::WriteInterfaceToken(MessageParcel &data) { if (!data.WriteInterfaceToken(FormRenderProxy::GetDescriptor())) { HILOG_ERROR("%{public}s, failed to write interface token", __func__); diff --git a/interfaces/inner_api/src/form_render_stub.cpp b/interfaces/inner_api/src/form_render_stub.cpp index fb18bbf7d213728448d154773e110e951afa4421..7e17452fdac03a22e6964a74f4a6f81945382721 100755 --- a/interfaces/inner_api/src/form_render_stub.cpp +++ b/interfaces/inner_api/src/form_render_stub.cpp @@ -28,8 +28,8 @@ FormRenderStub::FormRenderStub() { memberFuncMap_[static_cast(IFormRender::Message::FORM_RENDER_RENDER_FORM)] = &FormRenderStub::HandleRenderForm; - memberFuncMap_[static_cast(IFormRender::Message::FORM_RENDER_DELETE_RENDER_FORM)] = - &FormRenderStub::HandleDeleteRenderForm; + memberFuncMap_[static_cast(IFormRender::Message::FORM_RENDER_STOP_RENDERING_FORM)] = + &FormRenderStub::HandleStopRenderingForm; } FormRenderStub::~FormRenderStub() @@ -82,7 +82,7 @@ int FormRenderStub::HandleRenderForm(MessageParcel &data, MessageParcel &reply) return result; } -int FormRenderStub::HandleDeleteRenderForm(MessageParcel &data, MessageParcel &reply) +int FormRenderStub::HandleStopRenderingForm(MessageParcel &data, MessageParcel &reply) { int64_t formId = data.ReadInt64(); std::unique_ptr want(data.ReadParcelable()); @@ -97,7 +97,7 @@ int FormRenderStub::HandleDeleteRenderForm(MessageParcel &data, MessageParcel &r return ERR_APPEXECFWK_PARCEL_ERROR; } - int32_t result = DeleteRenderForm(formId, *want, client); + int32_t result = StopRenderingForm(formId, *want, client); reply.WriteInt32(result); return result; } diff --git a/services/form_render_service/include/form_render_impl.h b/services/form_render_service/include/form_render_impl.h index 15fc65742d60c735c418609442fc5862ed32413f..83badd1cd0b4d911294ef7440ccdd46d295ff64c 100755 --- a/services/form_render_service/include/form_render_impl.h +++ b/services/form_render_service/include/form_render_impl.h @@ -55,8 +55,7 @@ public: */ void SetRuntime(AbilityRuntime::Runtime& runtime); - int32_t DeleteRenderForm(const int64_t &formId, const Want &want, - const sptr &callerToken) override; + int32_t StopRenderingForm(int64_t formId, const Want &want, const sptr &callerToken) override; private: int32_t AddForm(const FormJsInfo &formJsInfo, const Want &want); diff --git a/services/form_render_service/src/form_render_impl.cpp b/services/form_render_service/src/form_render_impl.cpp index 9bd69114ac2d0efcc675c2d927f501c7ed7c47c2..052f9600869c5e0153f4cb0349b67f1f6142a302 100755 --- a/services/form_render_service/src/form_render_impl.cpp +++ b/services/form_render_service/src/form_render_impl.cpp @@ -65,8 +65,7 @@ int32_t FormRenderImpl::AddForm(const FormJsInfo &formJsInfo, const Want &want) return ERR_OK; } -int32_t FormRenderImpl::DeleteRenderForm( - const int64_t &formId, const Want &want, const sptr &callerToken) +int32_t FormRenderImpl::StopRenderingForm(int64_t formId, const Want &want, const sptr &callerToken) { HILOG_INFO("%{public}s called.", __func__); return ERR_OK; diff --git a/services/include/form_render_connection.h b/services/include/form_render_connection.h new file mode 100644 index 0000000000000000000000000000000000000000..90b5571523637022dae63261f85929890e2afb17 --- /dev/null +++ b/services/include/form_render_connection.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 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_FORM_FWK_FORM_RENDER_CONNECTION_H +#define OHOS_FORM_FWK_FORM_RENDER_CONNECTION_H + +#include "form_ability_connection.h" +#include "form_item_info.h" +#include "want.h" + +namespace OHOS { +namespace AppExecFwk { +/** + * @class FormRenderConnection + * Form Render Connection Stub. + */ +class FormRenderConnection : public FormAbilityConnection { +public: + FormRenderConnection(const FormRecord &formRecord, const WantParams &wantParams); + FormRenderConnection() = delete; // disable default constructor. + virtual ~FormRenderConnection() = default; + + /** + * @brief OnAbilityConnectDone, AbilityMs notify caller ability the result of connect. + * + * @param element service ability's ElementName. + * @param remoteObject the session proxy of service ability. + * @param resultCode ERR_OK on success, others on failure. + */ + void OnAbilityConnectDone(const AppExecFwk::ElementName &element, + const sptr &remoteObject, int resultCode) override; +private: + FormRecord formRecord_; + WantParams wantParams_; + + DISALLOW_COPY_AND_MOVE(FormRenderConnection); +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // OHOS_FORM_FWK_FORM_RENDER_CONNECTION_H diff --git a/services/include/form_render_mgr.h b/services/include/form_render_mgr.h new file mode 100644 index 0000000000000000000000000000000000000000..987d2869e94fbec4bc9e3c0c14d2daee0bcefb89 --- /dev/null +++ b/services/include/form_render_mgr.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023 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_FORM_FWK_FORM_RENDER_MGR_H +#define OHOS_FORM_FWK_FORM_RENDER_MGR_H + +#include + +#include "form_record.h" +#include "form_ability_connection.h" +#include "want.h" + +namespace OHOS { +namespace AppExecFwk { +using Want = OHOS::AAFwk::Want; +using WantParams = OHOS::AAFwk::WantParams; +/** + * @class FormRenderService + * FormRenderService provides a facility for managing form render life cycle. + */ +class FormRenderMgr final : public DelayedRefSingleton { +DECLARE_DELAYED_REF_SINGLETON(FormRenderMgr) +public: + DISALLOW_COPY_AND_MOVE(FormRenderMgr); + + ErrCode RenderForm(const FormRecord &formRecord, const WantParams &wantParams); + + ErrCode RenderForm(int64_t formId, const FormProviderInfo &formProviderInfo, + const WantParams &wantParams); + + ErrCode StopRenderingForm(int64_t formId, const FormRecord &formRecord); + + ErrCode RenderFormCallback(int64_t &formId, const Want &want); + + ErrCode StopRenderingFormCallback(int64_t &formId, const Want &want); + + ErrCode AddConnection(sptr connection); + + void HandleHostDied(int64_t formId); + + bool IsNeedRender(int64_t formId); +private: + bool IsRemoveConnection(int64_t formId); +private: + mutable std::mutex conMutex_; + std::map> renderFormConnections_; +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // OHOS_FORM_FWK_FORM_RENDER_MGR_H diff --git a/services/include/form_stop_rendering_connection.h b/services/include/form_stop_rendering_connection.h new file mode 100644 index 0000000000000000000000000000000000000000..188e9e98f9548e297d68c63816d2138c748f7b10 --- /dev/null +++ b/services/include/form_stop_rendering_connection.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 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_FORM_FWK_FORM_DELETE_RENDER_CONNECTION_H +#define OHOS_FORM_FWK_FORM_DELETE_RENDER_CONNECTION_H + +#include "form_ability_connection.h" + +namespace OHOS { +namespace AppExecFwk { +/** + * @class FormStopRenderingConnection + * Form Delete Render Connection Stub. + */ +class FormStopRenderingConnection : public FormAbilityConnection { +public: + FormStopRenderingConnection(const int64_t formId, const std::string &bundleName, const std::string &abilityName); + virtual ~FormStopRenderingConnection() = default; + + /** + * @brief OnAbilityConnectDone, AbilityMs notify caller ability the result of connect. + * @param element service ability's ElementName. + * @param remoteObject the session proxy of service ability. + * @param resultCode ERR_OK on success, others on failure. + */ + void OnAbilityConnectDone( + const AppExecFwk::ElementName &element, const sptr &remoteObject, int resultCode) override; + +private: + int64_t formId_ = -1; + DISALLOW_COPY_AND_MOVE(FormStopRenderingConnection); +}; +} // namespace AppExecFwk +} // namespace OHOS + +#endif // OHOS_FORM_FWK_FORM_DELETE_RENDER_CONNECTION_H diff --git a/services/include/form_task_mgr.h b/services/include/form_task_mgr.h index 432000bb77b347ddbf17d6059503cc5315334b8c..16d96ecbfd4d2380e9290fea032faad3e6bf5628 100644 --- a/services/include/form_task_mgr.h +++ b/services/include/form_task_mgr.h @@ -178,6 +178,10 @@ public: * @param result The error code of this share. */ void PostFormShareSendResponse(int64_t formShareRequestCode, int32_t result); + + void PostRenderForm(const FormRecord &formRecord, const Want &want, const sptr &remoteObject); + + void PostStopRenderingForm(int64_t formId, const Want &want, const sptr &remoteObject); private: /** * @brief Acquire form data from form provider. @@ -312,6 +316,15 @@ private: * @param result The error code of this share. */ void FormShareSendResponse(int64_t formShareRequestCode, int32_t result); + + /** + * @brief Post form share error code to form host(task). + * @param formShareRequestCode The request code for this share. + * @param result The error code of this share. + */ + void RenderForm(const FormRecord &formRecord, const Want &want, const sptr &remoteObject); + + void StopRenderingForm(int64_t formId, const Want &want, const sptr &remoteObject); private: std::shared_ptr eventHandler_ = nullptr; }; diff --git a/services/src/form_delete_connection.cpp b/services/src/form_delete_connection.cpp index 3a9ed95c345c3d78aa4d55af6061f64f3d8486cc..de80c9015c9d24cbae4c11a89537396eb02ef892 100644 --- a/services/src/form_delete_connection.cpp +++ b/services/src/form_delete_connection.cpp @@ -1,6 +1,5 @@ - /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2023 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 diff --git a/services/src/form_mgr_adapter.cpp b/services/src/form_mgr_adapter.cpp index f19bd303088b97732a725de807d80f372eb9df45..2d6d976a73c6a3c0d1ac31c417a254c1a7dce6f0 100644 --- a/services/src/form_mgr_adapter.cpp +++ b/services/src/form_mgr_adapter.cpp @@ -39,6 +39,8 @@ #include "form_provider_info.h" #include "form_provider_interface.h" #include "form_provider_mgr.h" +#include "form_render_connection.h" +#include "form_render_mgr.h" #include "form_share_mgr.h" #include "form_supply_callback.h" #include "form_timer_mgr.h" @@ -123,6 +125,7 @@ int FormMgrAdapter::AddForm(const int64_t formId, const Want &want, HILOG_DEBUG("form in application"); newWant.SetParam(Constants::PARAM_FORM_HOST_TOKEN, callerToken); } + WantParams wantParams = newWant.GetParams(); // share form if (formId == 0 && DelayedSingleton::GetInstance()->IsShareForm(newWant)) { @@ -260,7 +263,7 @@ ErrCode FormMgrAdapter::HandleDeleteForm(const int64_t formId, const sptr + +#include "form_constants.h" +#include "form_supply_callback.h" +#include "form_render_mgr.h" +#include "form_task_mgr.h" +#include "form_util.h" +#include "hilog_wrapper.h" +#include "want.h" + +namespace OHOS { +namespace AppExecFwk { +FormRenderConnection::FormRenderConnection(const FormRecord &formRecord, + const WantParams &wantParams) : formRecord_(formRecord), wantParams_(wantParams) +{ + SetFormId(formRecord.formId); + SetProviderKey(formRecord.bundleName, formRecord.abilityName); +} + +void FormRenderConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element, + const sptr &remoteObject, int resultCode) +{ + HILOG_INFO("%{public}s called.", __func__); + if (resultCode != ERR_OK) { + HILOG_ERROR("%{public}s, abilityName:%{public}s, formId:%{public}" PRId64 ", resultCode:%{public}d", + __func__, element.GetAbilityName().c_str(), GetFormId(), resultCode); + return; + } + FormRenderMgr::GetInstance().AddConnection(this); + Want want; + want.SetParams(wantParams_); + want.SetParam(Constants::FORM_CONNECT_ID, this->GetConnectId()); + FormTaskMgr::GetInstance().PostRenderForm(formRecord_, want, remoteObject); +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/src/form_render_mgr.cpp b/services/src/form_render_mgr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a7162a6f706da527d94101cf6c002093f42c3c4 --- /dev/null +++ b/services/src/form_render_mgr.cpp @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2023 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 "form_render_mgr.h" + +#include "form_ams_helper.h" +#include "form_constants.h" +#include "form_data_mgr.h" +#include "form_mgr_errors.h" +#include "form_render_connection.h" +#include "form_stop_rendering_connection.h" +#include "form_supply_callback.h" +#include "form_util.h" +#include "hilog_wrapper.h" +#include "want.h" + +namespace OHOS { +namespace AppExecFwk { +using Want = OHOS::AAFwk::Want; +FormRenderMgr::FormRenderMgr() +{ +} +FormRenderMgr::~FormRenderMgr() +{ +} +ErrCode FormRenderMgr::RenderForm(const FormRecord &formRecord, const WantParams &wantParams) +{ + HILOG_DEBUG("%{public}s called.", __func__); + if (formRecord.uiSyntax != FormType::ETS) { + return ERR_OK; + } + + if (formRecord.formId <= 0) { + HILOG_ERROR("%{public}s fail, formId should be greater than 0", __func__); + return ERR_APPEXECFWK_FORM_INVALID_PARAM; + } + + sptr formRenderConnection = new (std::nothrow) FormRenderConnection(formRecord, wantParams); + if (formRenderConnection == nullptr) { + HILOG_ERROR("formRenderConnection is null."); + return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED; + } + + Want want; + want.SetElementName("com.ohos.formrenderservice", "ServiceExtension"); + want.AddFlags(Want::FLAG_ABILITY_FORM_ENABLED); + ErrCode errorCode = FormAmsHelper::GetInstance().ConnectServiceAbility(want, formRenderConnection); + if (errorCode != ERR_OK) { + HILOG_ERROR("%{public}s fail, ConnectServiceAbility failed.", __func__); + return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED; + } + return ERR_OK; +} + +ErrCode FormRenderMgr::RenderForm(int64_t formId, const FormProviderInfo &formProviderInfo, + const WantParams &wantParams) +{ + FormRecord formRecord; + bool isGetFormRecord = FormDataMgr::GetInstance().GetFormRecord(formId, formRecord); + if (!isGetFormRecord) { + HILOG_ERROR("%{public}s fail, not exist such form, formId:%{public}" PRId64 "", __func__, formId); + return ERR_APPEXECFWK_FORM_NOT_EXIST_ID; + } + formRecord.formProviderInfo = formProviderInfo; + + return RenderForm(formRecord, wantParams); +} + +ErrCode FormRenderMgr::StopRenderingForm(int64_t formId, const FormRecord &formRecord) +{ + HILOG_DEBUG("%{public}s called.", __func__); + if (formRecord.uiSyntax != FormType::ETS) { + return ERR_OK; + } + + if (formRecord.abilityName.empty()) { + HILOG_ERROR("%{public}s, formRecord.abilityName is empty.", __func__); + return ERR_APPEXECFWK_FORM_INVALID_PARAM; + } + + if (formRecord.bundleName.empty()) { + HILOG_ERROR("%{public}s, formRecord.bundleName is empty.", __func__); + return ERR_APPEXECFWK_FORM_INVALID_PARAM; + } + + sptr formStopRenderingConnection = new (std::nothrow) FormStopRenderingConnection(formId, + formRecord.bundleName, formRecord.abilityName); + if (formStopRenderingConnection == nullptr) { + HILOG_ERROR("formStopRenderingConnection is null."); + return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED; + } + + Want want; + want.SetElementName("com.ohos.formrenderservice", "ServiceExtension"); + want.AddFlags(Want::FLAG_ABILITY_FORM_ENABLED); + ErrCode errorCode = FormAmsHelper::GetInstance().ConnectServiceAbility(want, formStopRenderingConnection); + if (errorCode != ERR_OK) { + HILOG_ERROR("%{public}s fail, ConnectServiceAbility failed.", __func__); + return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED; + } + return ERR_OK; +} + +ErrCode FormRenderMgr::RenderFormCallback(int64_t &formId, const Want &want) +{ + HILOG_INFO("%{public}s called.", __func__); + auto connectId = want.GetIntParam(Constants::FORM_CONNECT_ID, 0); + { + std::lock_guard lock(conMutex_); + sptr formAbilityConnection; + auto conIterator = renderFormConnections_.find(connectId); + if (IsRemoveConnection(formId)) { + FormAmsHelper::GetInstance().DisconnectServiceAbility(conIterator->second); + renderFormConnections_.erase(connectId); + } + } + return ERR_OK; +} + +ErrCode FormRenderMgr::StopRenderingFormCallback(int64_t &formId, const Want &want) +{ + HILOG_INFO("%{public}s called.", __func__); + auto connectId = want.GetIntParam(Constants::FORM_CONNECT_ID, 0); + sptr connection = nullptr; + { + std::lock_guard lock(conMutex_); + auto conIterator = renderFormConnections_.find(connectId); + FormAmsHelper::GetInstance().DisconnectServiceAbility(conIterator->second); + renderFormConnections_.erase(connectId); + for (auto &conn : renderFormConnections_) { + if (conn.second->GetFormId() == formId) { + FormAmsHelper::GetInstance().DisconnectServiceAbility(conn.second); + renderFormConnections_.erase(conn.first); + break; + } + } + } + return ERR_OK; +} + +ErrCode FormRenderMgr::AddConnection(sptr connection) +{ + HILOG_INFO("%{public}s called.", __func__); + if (connection == nullptr) { + return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED; + } + { + int32_t connectKey = static_cast(FormUtil::GetCurrentMillisecond()); + std::lock_guard lock(conMutex_); + while (renderFormConnections_.find(connectKey) != renderFormConnections_.end()) { + connectKey++; + } + connection->SetConnectId(connectKey); + renderFormConnections_.emplace(connectKey, connection); + } + HILOG_INFO("%{public}s end.", __func__); + return ERR_OK; +} + +void FormRenderMgr::HandleHostDied(int64_t formId) +{ + HILOG_DEBUG("%{public}s called.", __func__); + { + std::lock_guard lock(conMutex_); + for (const auto &conn : renderFormConnections_) { + if (conn.second->GetFormId() == formId) { + FormAmsHelper::GetInstance().DisconnectServiceAbility(conn.second); + renderFormConnections_.erase(conn.first); + HILOG_DEBUG("remove the connection, connect id is %{public}d", conn.first); + break; + } + } + } +} + +bool FormRenderMgr::IsRemoveConnection(int64_t formId) +{ + HILOG_DEBUG("%{public}s called. formId is %{public}" PRId64, __func__, formId); + // keep one connection for each in application form in the same host + int32_t count = 0; + for (const auto &conn : renderFormConnections_) { + if (formId == conn.second->GetFormId()) { + count++; + } + } + HILOG_DEBUG("%{public}s called. count is %{public}d", __func__, count); + if (count == 1) { + HILOG_DEBUG("keep the connection"); + return false; + } + return true; +} + +bool FormRenderMgr::IsNeedRender(int64_t formId) +{ + FormRecord formRecord; + bool isGetFormRecord = FormDataMgr::GetInstance().GetFormRecord(formId, formRecord); + if (!isGetFormRecord) { + HILOG_ERROR("%{public}s fail, not exist such form, formId:%{public}" PRId64 "", __func__, formId); + return false; + } + if (formRecord.uiSyntax != FormType::ETS) { + HILOG_DEBUG("%{public}s fail, no need render, formId:%{public}" PRId64 "", __func__, formId); + return false; + } + return true; +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/src/form_stop_rendering_connection.cpp b/services/src/form_stop_rendering_connection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f961c86bfd1e482796492d44c1b5cdb1b8724ffe --- /dev/null +++ b/services/src/form_stop_rendering_connection.cpp @@ -0,0 +1,57 @@ + +/* + * Copyright (c) 2023 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 "form_stop_rendering_connection.h" + +#include + +#include "form_constants.h" +#include "form_supply_callback.h" +#include "form_render_mgr.h" +#include "form_task_mgr.h" +#include "hilog_wrapper.h" +#include "want.h" + +namespace OHOS { +namespace AppExecFwk { +FormStopRenderingConnection::FormStopRenderingConnection(const int64_t formId, const std::string &bundleName, + const std::string &abilityName) : formId_(formId) +{ + SetProviderKey(bundleName, abilityName); +} +/** + * @brief OnAbilityConnectDone, AbilityMs notify caller ability the result of connect. + * @param element service ability's ElementName. + * @param remoteObject the session proxy of service ability. + * @param resultCode ERR_OK on success, others on failure. + */ +void FormStopRenderingConnection::OnAbilityConnectDone( + const AppExecFwk::ElementName &element, const sptr &remoteObject, int resultCode) +{ + HILOG_INFO("%{public}s called.", __func__); + if (resultCode != ERR_OK) { + HILOG_ERROR("%{public}s, abilityName:%{public}s, formId:%{public}" PRId64 ", resultCode:%{public}d", + __func__, element.GetAbilityName().c_str(), formId_, resultCode); + return; + } + FormRenderMgr::GetInstance().AddConnection(this); + Want want; + want.SetParam(Constants::FORM_CONNECT_ID, this->GetConnectId()); + HILOG_DEBUG("%{public}s, connectId:%{public}d", __func__, this->GetConnectId()); + FormTaskMgr::GetInstance().PostStopRenderingForm(formId_, want, remoteObject); +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/src/form_supply_callback.cpp b/services/src/form_supply_callback.cpp index f5e93ebff8fa9f505bbb7713a098e41861abeccb..06520954b7835932789a08918f1cad366c16ee5a 100644 --- a/services/src/form_supply_callback.cpp +++ b/services/src/form_supply_callback.cpp @@ -21,6 +21,7 @@ #include "form_constants.h" #include "form_mgr_errors.h" #include "form_provider_mgr.h" +#include "form_render_mgr.h" #include "form_share_mgr.h" #include "form_task_mgr.h" #include "form_util.h" @@ -70,14 +71,17 @@ int FormSupplyCallback::OnAcquire(const FormProviderInfo &formProviderInfo, cons return ERR_APPEXECFWK_FORM_INVALID_PARAM; } int64_t formId = std::stoll(strFormId); - int type = want.GetIntParam(Constants::ACQUIRE_TYPE, 0); - HILOG_DEBUG("%{public}s come: %{public}" PRId64 ", %{public}d, %{public}d", - __func__, formId, connectId, type); - if (IsRemoveConnection(formId, want.GetRemoteObject(Constants::PARAM_FORM_HOST_TOKEN))) { RemoveConnection(connectId); } + if (FormRenderMgr::GetInstance().IsNeedRender(formId)) { + return FormRenderMgr::GetInstance().RenderForm(formId, formProviderInfo, want.GetParams()); + } + + int type = want.GetIntParam(Constants::ACQUIRE_TYPE, 0); + HILOG_DEBUG("%{public}s come: %{public}" PRId64 ", %{public}d, %{public}d", + __func__, formId, connectId, type); switch (type) { case Constants::ACQUIRE_TYPE_CREATE_FORM: return FormProviderMgr::GetInstance().AcquireForm(formId, formProviderInfo); diff --git a/services/src/form_task_mgr.cpp b/services/src/form_task_mgr.cpp index f70b8a814b89ab078f60b609261e741115b8fb3e..9152ac3f49b1d13a34e9c6818659cfd92a2fd10b 100644 --- a/services/src/form_task_mgr.cpp +++ b/services/src/form_task_mgr.cpp @@ -23,6 +23,7 @@ #include "form_mgr_adapter.h" #include "form_mgr_errors.h" #include "form_provider_interface.h" +#include "form_render_interface.h" #include "form_share_mgr.h" #include "form_supply_callback.h" #include "hilog_wrapper.h" @@ -648,5 +649,80 @@ void FormTaskMgr::FormShareSendResponse(int64_t formShareRequestCode, int32_t re { DelayedSingleton::GetInstance()->SendResponse(formShareRequestCode, result); } + +void FormTaskMgr::PostRenderForm(const FormRecord &formRecord, const Want &want, + const sptr &remoteObject) +{ + HILOG_INFO("%{public}s start", __func__); + if (eventHandler_ == nullptr) { + HILOG_ERROR("eventHandler_ is nullptr."); + return; + } + + auto renderForm = [formRecord, want, remoteObject]() { + FormTaskMgr::GetInstance().RenderForm(formRecord, want, remoteObject); + }; + eventHandler_->PostTask(renderForm, FORM_TASK_DELAY_TIME); + HILOG_INFO("%{public}s end", __func__); +} + +void FormTaskMgr::RenderForm(const FormRecord &formRecord, const Want &want, const sptr &remoteObject) +{ + HILOG_INFO("%{public}s begin", __func__); + auto connectId = want.GetIntParam(Constants::FORM_CONNECT_ID, 0); + sptr remoteFormRender = iface_cast(remoteObject); + if (remoteFormRender == nullptr) { + FormSupplyCallback::GetInstance()->RemoveConnection(connectId); + HILOG_ERROR("%{public}s fail, Failed to get form render proxy.", __func__); + return; + } + + FormJsInfo formJsInfo = CreateFormJsInfo(formRecord.formId, formRecord); + HILOG_INFO("raul %{public}s begin, data = %{public}s", __func__, formJsInfo.formData.c_str()); + int32_t error = remoteFormRender->RenderForm(formJsInfo, want, FormSupplyCallback::GetInstance()); + if (error != ERR_OK) { + FormSupplyCallback::GetInstance()->RemoveConnection(connectId); + HILOG_ERROR("%{public}s fail, Failed to add form renderer", __func__); + return; + } + + HILOG_INFO("%{public}s end", __func__); +} + +void FormTaskMgr::PostStopRenderingForm(int64_t formId, const Want &want, const sptr &remoteObject) +{ + HILOG_INFO("%{public}s start", __func__); + if (eventHandler_ == nullptr) { + HILOG_ERROR("eventHandler_ is nullptr."); + return; + } + + auto deleterenderForm = [formId, want, remoteObject]() { + FormTaskMgr::GetInstance().StopRenderingForm(formId, want, remoteObject); + }; + eventHandler_->PostTask(deleterenderForm, FORM_TASK_DELAY_TIME); + HILOG_INFO("%{public}s end", __func__); +} + +void FormTaskMgr::StopRenderingForm(int64_t formId, const Want &want, const sptr &remoteObject) +{ + HILOG_INFO("%{public}s begin", __func__); + auto connectId = want.GetIntParam(Constants::FORM_CONNECT_ID, 0); + sptr remoteFormDeleteRender = iface_cast(remoteObject); + if (remoteFormDeleteRender == nullptr) { + FormSupplyCallback::GetInstance()->RemoveConnection(connectId); + HILOG_ERROR("%{public}s fail, Failed to get form render proxy.", __func__); + return; + } + + int32_t error = remoteFormDeleteRender->StopRenderingForm(formId, want, FormSupplyCallback::GetInstance()); + if (error != ERR_OK) { + FormSupplyCallback::GetInstance()->RemoveConnection(connectId); + HILOG_ERROR("%{public}s fail, Failed to add form renderer", __func__); + return; + } + + HILOG_INFO("%{public}s end", __func__); +} } // namespace AppExecFwk } // namespace OHOS