From 849314338496338d47919f344650e78e37904528 Mon Sep 17 00:00:00 2001 From: liweifeng Date: Sun, 21 May 2023 14:35:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E5=8D=A1=E7=89=87=E7=AE=A1=E7=90=86=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liweifeng Change-Id: I8d2011075f07fc5e3d4c470283e19d599f18548a --- BUILD.gn | 3 + .../include/form_provider_data_proxy.h | 32 ++ .../inner_api/include/form_provider_info.h | 13 + .../inner_api/src/form_provider_info.cpp | 35 ++ services/include/form_bms_helper.h | 3 + services/include/form_data_proxy_mgr.h | 44 +++ services/include/form_data_proxy_record.h | 64 ++++ services/include/form_record.h | 1 + services/include/form_util.h | 10 + services/src/form_bms_helper.cpp | 13 + services/src/form_data_proxy_mgr.cpp | 88 +++++ services/src/form_data_proxy_record.cpp | 306 ++++++++++++++++++ services/src/form_mgr_adapter.cpp | 2 + services/src/form_supply_callback.cpp | 3 + services/src/form_util.cpp | 56 ++++ 15 files changed, 673 insertions(+) create mode 100644 interfaces/inner_api/include/form_provider_data_proxy.h create mode 100644 services/include/form_data_proxy_mgr.h create mode 100644 services/include/form_data_proxy_record.h create mode 100644 services/src/form_data_proxy_mgr.cpp create mode 100644 services/src/form_data_proxy_record.cpp diff --git a/BUILD.gn b/BUILD.gn index 1ddde08fdc..6f77859451 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -49,6 +49,8 @@ ohos_shared_library("libfms") { "services/src/form_cache_mgr.cpp", "services/src/form_cast_temp_connection.cpp", "services/src/form_data_mgr.cpp", + "services/src/form_data_proxy_mgr.cpp", + "services/src/form_data_proxy_record.cpp", "services/src/form_db_cache.cpp", "services/src/form_db_info.cpp", "services/src/form_delete_connection.cpp", @@ -112,6 +114,7 @@ ohos_shared_library("libfms") { "c_utils:utils", "common_event_service:cesfwk_core", "common_event_service:cesfwk_innerkits", + "data_share:datashare_consumer", "eventhandler:libeventhandler", "form_fwk:form_manager", "hicollie_native:libhicollie", diff --git a/interfaces/inner_api/include/form_provider_data_proxy.h b/interfaces/inner_api/include/form_provider_data_proxy.h new file mode 100644 index 0000000000..ba70f131c5 --- /dev/null +++ b/interfaces/inner_api/include/form_provider_data_proxy.h @@ -0,0 +1,32 @@ +/* + * 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_PROVIDER_DATA_PROXY_H +#define OHOS_FORM_FWK_FORM_PROVIDER_DATA_PROXY_H + +#include + +namespace OHOS { +namespace AppExecFwk { +struct FormDataProxy { + std::string key; + std::string subscribeId; + + FormDataProxy(const std::string &proxyKey, const std::string &proxySubscribeId) + : key(proxyKey), subscribeId(proxySubscribeId) {}; +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // OHOS_FORM_FWK_FORM_PROVIDER_DATA_PROXY_H diff --git a/interfaces/inner_api/include/form_provider_info.h b/interfaces/inner_api/include/form_provider_info.h index 90105f5af9..2b002f9ce6 100644 --- a/interfaces/inner_api/include/form_provider_info.h +++ b/interfaces/inner_api/include/form_provider_info.h @@ -18,9 +18,11 @@ #include #include +#include #include "form_ashmem.h" #include "form_provider_data.h" +#include "form_provider_data_proxy.h" #include "nlohmann/json_fwd.hpp" #include "parcel.h" #include "refbase.h" @@ -109,12 +111,23 @@ public: */ bool NeedCache() const; + void SetFormDataProxies(std::vector &formDataProxies) + { + formDataProxies_ = formDataProxies; + } + + std::vector GetFormProxies() const + { + return formDataProxies_; + } + bool ReadFromParcel(Parcel &parcel); virtual bool Marshalling(Parcel &parcel) const override; static FormProviderInfo *Unmarshalling(Parcel &parcel); private: FormProviderData jsBindingData_; bool upgradeFlg_; + std::vector formDataProxies_; }; } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/inner_api/src/form_provider_info.cpp b/interfaces/inner_api/src/form_provider_info.cpp index 0b280d9f10..6f26e81864 100644 --- a/interfaces/inner_api/src/form_provider_info.cpp +++ b/interfaces/inner_api/src/form_provider_info.cpp @@ -15,12 +15,30 @@ #include "form_provider_info.h" +#include "string_ex.h" + +#include "hilog_wrapper.h" + namespace OHOS { namespace AppExecFwk { bool FormProviderInfo::ReadFromParcel(Parcel &parcel) { std::unique_ptr bindingData(parcel.ReadParcelable()); jsBindingData_ = *bindingData; + + auto number = parcel.ReadInt32(); + if (number < 0 || number > INT16_MAX) { + HILOG_ERROR("proxies number over limit: %{public}d.", number); + return false; + } + HILOG_DEBUG("proxies number: %{public}d.", number); + for (auto i = 0; i < number; i++) { + FormDataProxy formDataProxy("", ""); + formDataProxy.key = Str16ToStr8(parcel.ReadString16()); + formDataProxy.subscribeId = Str16ToStr8(parcel.ReadString16()); + formDataProxies_.push_back(formDataProxy); + } + return true; } @@ -38,6 +56,23 @@ bool FormProviderInfo::Marshalling(Parcel &parcel) const if (!parcel.WriteParcelable(&jsBindingData_)) { return false; } + HILOG_DEBUG("proxies size: %{public}zu.", formDataProxies_.size()); + if (!parcel.WriteInt32(formDataProxies_.size())) { + HILOG_ERROR("failed to marshalling form data proxies size."); + return false; + } + for (const auto &formDataProxy : formDataProxies_) { + // write key + if (!parcel.WriteString16(Str8ToStr16(formDataProxy.key))) { + HILOG_ERROR("failed to marshalling form data proxies key: %{public}s.", formDataProxy.key.c_str()); + return false; + } + if (!parcel.WriteString16(Str8ToStr16(formDataProxy.subscribeId))) { + HILOG_ERROR("failed to marshalling form data proxies subscribeId: %{public}s.", + formDataProxy.subscribeId.c_str()); + return false; + } + } return true; } void FormProviderInfo::SetFormDataString(std::string &dataString) diff --git a/services/include/form_bms_helper.h b/services/include/form_bms_helper.h index 8e866a3582..25fca64f7a 100644 --- a/services/include/form_bms_helper.h +++ b/services/include/form_bms_helper.h @@ -144,6 +144,9 @@ public: int32_t GetBundleNameByUid(const int32_t uid, std::string &bundleName); + ErrCode GetProxyDataInfos(const std::string &bundleName, const std::string &moduleName, + int32_t userId, std::vector &proxyData); + static constexpr int64_t INVALID_UID = -1; private: /** diff --git a/services/include/form_data_proxy_mgr.h b/services/include/form_data_proxy_mgr.h new file mode 100644 index 0000000000..de42b3722c --- /dev/null +++ b/services/include/form_data_proxy_mgr.h @@ -0,0 +1,44 @@ +/* + * 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_DATA_PROXY_MGR_H +#define OHOS_FORM_FWK_FORM_DATA_PROXY_MGR_H + +#include +#include + +#include "form_data_proxy_record.h" + +namespace OHOS { +namespace AppExecFwk { +/** + * @class FormDataProxyMgr + * data proxy form mananger. + */ +class FormDataProxyMgr final : public DelayedRefSingleton { + DECLARE_DELAYED_REF_SINGLETON(FormDataProxyMgr) +public: + DISALLOW_COPY_AND_MOVE(FormDataProxyMgr); + + ErrCode SubscribeFormData(int64_t formId, const std::vector &formDataProxies); + ErrCode UnsubscribeFormData(int64_t formId); +private: + std::mutex formDataProxyRecordMutex_; + std::map> formDataProxyRecordMap_; // formId:FormDataProxyRecord +}; +} // namespace AppExecFwk +} // namespace OHOS + +#endif // OHOS_FORM_FWK_FORM_DATA_PROXY_MGR_H \ No newline at end of file diff --git a/services/include/form_data_proxy_record.h b/services/include/form_data_proxy_record.h new file mode 100644 index 0000000000..f6fa268e8e --- /dev/null +++ b/services/include/form_data_proxy_record.h @@ -0,0 +1,64 @@ +/* + * 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_DATA_PROXY_RECORD_H +#define OHOS_FORM_FWK_FORM_DATA_PROXY_RECORD_H + +#include + +#include "datashare_helper.h" +#include "form_provider_data_proxy.h" + +namespace OHOS { +namespace AppExecFwk { +/** + * @class FormDataSharerRecord + * data share form record. + */ +class FormDataProxyRecord : public std::enable_shared_from_this { +public: + FormDataProxyRecord(int64_t formId, const std::string &bundleName, const std::string &moduleName); + ~FormDataProxyRecord(); + + ErrCode SubscribeFormData(const std::vector &formDataProxies); + ErrCode UnsubscribeFormData(); +private: + struct FormDataProxyRequest { + int64_t subscribeId; + std::vector uris; + }; + + void ParseFormDataProxies(const std::vector &formDataProxies); + void ConvertSubscribeMapToRequests(std::map &subscribeMap, + std::vector &formDataProxyRequests); + void UpdatePublishedDataForm(const std::vector &data); + void UpdateRdbDataForm(const std::vector &data); + ErrCode SubscribeRdbFormData(); + ErrCode SubscribePublishFormData(); + + void OnRdbDataChange(const DataShare::RdbChangeNode &changeNode); + void OnPublishedDataChange(const DataShare::PublishedDataChangeNode &changeNode); + + std::shared_ptr dataShareHelper_; + int64_t formId_ = -1; + std::string bundleName_; + std::string moduleName_; + std::map rdbSubscribeMap_; // key: subscribeId + std::map publishSubscribeMap_; // key: subscribeId +}; +} // namespace AppExecFwk +} // namespace OHOS + +#endif // OHOS_FORM_FWK_FORM_DATA_PROXY_RECORD_H \ No newline at end of file diff --git a/services/include/form_record.h b/services/include/form_record.h index 38827db593..8e133303a5 100644 --- a/services/include/form_record.h +++ b/services/include/form_record.h @@ -63,6 +63,7 @@ public: FormType type = FormType::JS; FormType uiSyntax = FormType::JS; bool isTimerRefresh = false; + bool isDataProxy = false; }; } // namespace AppExecFwk } // namespace OHOS diff --git a/services/include/form_util.h b/services/include/form_util.h index 94810ca4af..75c294001d 100644 --- a/services/include/form_util.h +++ b/services/include/form_util.h @@ -114,6 +114,16 @@ public: * @return Returns true if the caller has certain permissions; returns false otherwise. */ static bool VerifyCallingPermission(const std::string &permissionName); + + /** + * @brief Convert string to int64_t + * + * @param[in] strInfo The string information + * @param[out] int64Value Convert string to int64_t + * + * @return Return the convert result + */ + static bool ConvertStringToInt64(const std::string &strInfo, int64_t &int64Value); }; } // namespace AppExecFwk } // namespace OHOS diff --git a/services/src/form_bms_helper.cpp b/services/src/form_bms_helper.cpp index 798d29e109..a72601db46 100644 --- a/services/src/form_bms_helper.cpp +++ b/services/src/form_bms_helper.cpp @@ -342,5 +342,18 @@ bool FormBmsHelper::GetCompatibleVersionCode( minCompatibleVersionCode = bundleInfo.minCompatibleVersionCode; return true; } + +ErrCode FormBmsHelper::GetProxyDataInfos(const std::string &bundleName, const std::string &moduleName, + int32_t userId, std::vector &proxyData) +{ + HILOG_DEBUG("called."); + sptr iBundleMgr = GetBundleMgr(); + if (iBundleMgr == nullptr) { + HILOG_ERROR("iBundleMgr is nullptr"); + return false; + } + + return IN_PROCESS_CALL(iBundleMgr->GetProxyDataInfos(bundleName, moduleName, proxyData, userId)); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/src/form_data_proxy_mgr.cpp b/services/src/form_data_proxy_mgr.cpp new file mode 100644 index 0000000000..70249be1ae --- /dev/null +++ b/services/src/form_data_proxy_mgr.cpp @@ -0,0 +1,88 @@ +/* + * 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_data_proxy_mgr.h" + +#include "form_data_mgr.h" +#include "form_mgr_errors.h" +#include "hilog_wrapper.h" + +namespace OHOS { +namespace AppExecFwk { +FormDataProxyMgr::FormDataProxyMgr() +{} + +FormDataProxyMgr::~FormDataProxyMgr() +{} + +ErrCode FormDataProxyMgr::SubscribeFormData(int64_t formId, const std::vector &formDataProxies) +{ + HILOG_DEBUG("subscribe form data. formId: %{public}s, proxy data size: %{public}zu", + std::to_string(formId).c_str(), formDataProxies.size()); + if (formDataProxies.empty()) { + HILOG_DEBUG("formDataProxies is empty."); + return ERR_OK; + } + + FormRecord formRecord; + if (!FormDataMgr::GetInstance().GetFormRecord(formId, formRecord)) { + HILOG_ERROR("not exist such form:%{public}" PRId64 ".", formId); + return ERR_APPEXECFWK_FORM_NOT_EXIST_ID; + } + + if (!formRecord.isDataProxy) { + HILOG_DEBUG("not data proxy form, formId:%{public}" PRId64 ".", formId); + return ERR_OK; + } + + std::lock_guard lock(formDataProxyRecordMutex_); + auto search = formDataProxyRecordMap_.find(formId); + if (search != formDataProxyRecordMap_.end()) { + if (search->second != nullptr) { + HILOG_DEBUG("the form has already subscribed, formId: %{public}s.", std::to_string(formId).c_str()); + return ERR_OK; + } else { + HILOG_WARN("formDataProxyRecord is nullptr."); + formDataProxyRecordMap_.erase(formId); + } + } + + std::shared_ptr formDataProxyRecord = + std::make_shared(formId, formRecord.bundleName, formRecord.moduleName); + auto ret = formDataProxyRecord->SubscribeFormData(formDataProxies); + if (ret != ERR_OK) { + HILOG_ERROR("SubscribeFormData failed."); + return ret; + } + formDataProxyRecordMap_.emplace(formId, formDataProxyRecord); + return ERR_OK; +} + +ErrCode FormDataProxyMgr::UnsubscribeFormData(int64_t formId) +{ + HILOG_DEBUG("unsubscribe form data. formId: %{public}s", std::to_string(formId).c_str()); + std::lock_guard lock(formDataProxyRecordMutex_); + auto search = formDataProxyRecordMap_.find(formId); + if (search != formDataProxyRecordMap_.end()) { + if (search->second != nullptr) { + search->second->UnsubscribeFormData(); + } + formDataProxyRecordMap_.erase(formId); + } + + return ERR_OK; +} +} // namespace AppExecFwk +} // namespace OHOS diff --git a/services/src/form_data_proxy_record.cpp b/services/src/form_data_proxy_record.cpp new file mode 100644 index 0000000000..a7c9cb2711 --- /dev/null +++ b/services/src/form_data_proxy_record.cpp @@ -0,0 +1,306 @@ +/* + * 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_data_proxy_record.h" + +#include + +#include "form_ashmem.h" +#include "form_bms_helper.h" +#include "form_data_mgr.h" +#include "form_mgr_adapter.h" +#include "form_mgr_errors.h" +#include "form_util.h" +#include "hilog_wrapper.h" +#include "nlohmann/json.hpp" +#include "ipc_skeleton.h" + +namespace OHOS { +namespace AppExecFwk { +void FormDataProxyRecord::OnRdbDataChange(const DataShare::RdbChangeNode &changeNode) +{ + HILOG_DEBUG("on rdb data change."); + UpdateRdbDataForm(changeNode.data_); +} + +void FormDataProxyRecord::OnPublishedDataChange(const DataShare::PublishedDataChangeNode &changeNode) +{ + HILOG_DEBUG("on published data change."); + UpdatePublishedDataForm(changeNode.datas_); +} + +FormDataProxyRecord::FormDataProxyRecord(int64_t formId, const std::string &bundleName, const std::string &moduleName) + : formId_(formId), bundleName_(bundleName), moduleName_(moduleName) +{ + std::string uri = "datashareproxy:://" + bundleName; + DataShare::CreateOptions options; + options.isProxy_ = true; + dataShareHelper_ = DataShare::DataShareHelper::Creator(uri, options); +} + +FormDataProxyRecord::~FormDataProxyRecord() +{ + if (dataShareHelper_ != nullptr) { + dataShareHelper_->Release(); + } +} + +ErrCode FormDataProxyRecord::SubscribeFormData(const std::vector &formDataProxies) +{ + HILOG_DEBUG("subscribe form data."); + ParseFormDataProxies(formDataProxies); + ErrCode ret = ERR_OK; + ret = SubscribeRdbFormData(); + if (ret != ERR_OK) { + HILOG_ERROR("subscribe rdb form data failed."); + return ret; + } + ret = SubscribePublishFormData(); + if (ret != ERR_OK) { + HILOG_ERROR("subscribe publish form data failed."); + return ret; + } + return ret; +} + +ErrCode FormDataProxyRecord::SubscribeRdbFormData() +{ + if (dataShareHelper_ == nullptr) { + HILOG_ERROR("dataShareHelper is nullptr."); + return ERR_APPEXECFWK_FORM_INVALID_PARAM; + } + + if (rdbSubscribeMap_.empty()) { + HILOG_DEBUG("rdbSubscribeMap_ is nullptr."); + return ERR_OK; + } + + std::vector formDataProxyRequests; + ConvertSubscribeMapToRequests(rdbSubscribeMap_, formDataProxyRequests); + + std::weak_ptr weak(shared_from_this()); + auto rdbTask = [weak](const DataShare::RdbChangeNode &changeNode) { + auto formDataRecord = weak.lock(); + if (formDataRecord == nullptr) { + HILOG_ERROR("formDataRecord is nullptr."); + return; + } + formDataRecord->OnRdbDataChange(changeNode); + }; + for (const auto &search : formDataProxyRequests) { + DataShare::TemplateId templateId; + templateId.subscriberId_ = search.subscribeId; + templateId.bundleName_ = bundleName_; + auto ret = dataShareHelper_->SubscribeRdbData(search.uris, templateId, rdbTask); + HILOG_DEBUG("subscribe rdb data. subscribeId is %{public}s", std::to_string(search.subscribeId).c_str()); + for (const auto &iter : ret) { + if (iter.errCode_ != 0) { + HILOG_DEBUG("subscribe rdb data failed. %{public}s", iter.key_.c_str()); + } + } + } + + return ERR_OK; +} + +ErrCode FormDataProxyRecord::SubscribePublishFormData() +{ + if (dataShareHelper_ == nullptr) { + HILOG_ERROR("dataShareHelper is nullptr."); + return ERR_APPEXECFWK_FORM_INVALID_PARAM; + } + + if (publishSubscribeMap_.empty()) { + HILOG_DEBUG("publishSubscribeMap_ is nullptr."); + return ERR_OK; + } + + std::vector formDataProxyRequests; + ConvertSubscribeMapToRequests(publishSubscribeMap_, formDataProxyRequests); + + std::weak_ptr weak(shared_from_this()); + auto publishedTask = [weak](const DataShare::PublishedDataChangeNode &changeNode) { + auto formDataRecord = weak.lock(); + if (formDataRecord == nullptr) { + HILOG_ERROR("formDataRecord is nullptr."); + return; + } + formDataRecord->OnPublishedDataChange(changeNode); + }; + for (const auto &search : formDataProxyRequests) { + auto ret = dataShareHelper_->SubscribePublishedData(search.uris, search.subscribeId, publishedTask); + HILOG_DEBUG("subscribe published data. subscribeId is %{public}s", std::to_string(search.subscribeId).c_str()); + for (const auto &iter : ret) { + if (iter.errCode_ != 0) { + HILOG_DEBUG("subscribe published data failed. %{public}s", iter.key_.c_str()); + } + } + } + + return ERR_OK; +} + +ErrCode FormDataProxyRecord::UnsubscribeFormData() +{ + if (dataShareHelper_ == nullptr) { + HILOG_ERROR("dataShareHelper is nullptr."); + return ERR_APPEXECFWK_FORM_INVALID_PARAM; + } + + std::vector rdbRequests; + ConvertSubscribeMapToRequests(rdbSubscribeMap_, rdbRequests); + for (const auto &search : rdbRequests) { + DataShare::TemplateId templateId; + templateId.subscriberId_ = search.subscribeId; + templateId.bundleName_ = bundleName_; + dataShareHelper_->UnsubscribeRdbData(search.uris, templateId); + } + rdbSubscribeMap_.clear(); + + std::vector publishRequests; + ConvertSubscribeMapToRequests(publishSubscribeMap_, publishRequests); + for (const auto &search : publishRequests) { + dataShareHelper_->UnsubscribePublishedData(search.uris, search.subscribeId); + } + publishSubscribeMap_.clear(); + return ERR_OK; +} + +void FormDataProxyRecord::ParseFormDataProxies(const std::vector &formDataProxies) +{ + std::vector proxyData; + FormBmsHelper::GetInstance().GetProxyDataInfos(bundleName_, moduleName_, FormUtil::GetCurrentAccountId(), + proxyData); + + for (const auto& formDataProxy : formDataProxies) { + auto subscribe = formDataProxy.subscribeId.empty() ? std::to_string(formId_) : formDataProxy.subscribeId; + bool isRdbSubscribe = false; + for (const auto& iter : proxyData) { + if (formDataProxy.key == iter.uri) { + rdbSubscribeMap_[formDataProxy.key] = subscribe; + isRdbSubscribe = true; + HILOG_DEBUG("subscribe rdb data. key: %{public}s, subscribeId: %{public}s", + formDataProxy.key.c_str(), subscribe.c_str()); + break; + } + } + if (isRdbSubscribe == false) { + publishSubscribeMap_[formDataProxy.key] = subscribe; + HILOG_DEBUG("subscribe publish data. key: %{public}s, subscribeId: %{public}s", + formDataProxy.key.c_str(), subscribe.c_str()); + } + } +} + +void FormDataProxyRecord::ConvertSubscribeMapToRequests(std::map &subscribeMap, + std::vector &formDataProxyRequests) +{ + std::string userId = std::to_string(FormUtil::GetCurrentAccountId()); + std::string tokenId = std::to_string(IPCSkeleton::GetCallingTokenID()); + for (const auto &subscribe : subscribeMap) { + int64_t subscriberId; + if (!FormUtil::ConvertStringToInt64(subscribe.second, subscriberId)) { + HILOG_ERROR("Convert string to int64 failed, subscriberId is %{public}s.", subscribe.second.c_str()); + continue; + } + bool isNewSubscriberId = true; + std::string uri; + for (auto &search : formDataProxyRequests) { + if (search.subscribeId == subscriberId) { + uri = subscribe.first + "?" + "user=" + userId + "&srcToken=" + tokenId; + search.uris.push_back(uri); + isNewSubscriberId = false; + break; + } + } + if (isNewSubscriberId == true) { + FormDataProxyRequest formDataProxyRequest; + formDataProxyRequest.subscribeId = subscriberId; + uri = subscribe.first + "?" + "user=" + userId + "&srcToken=" + tokenId; + formDataProxyRequest.uris.emplace_back(uri); + formDataProxyRequests.push_back(formDataProxyRequest); + } + } +} + +void FormDataProxyRecord::UpdatePublishedDataForm(const std::vector &data) +{ + std::map, int32_t>> imageDataMap; + nlohmann::json object; + for (const auto& iter : data) { + if (iter.key_.empty()) { + HILOG_ERROR("key is empty."); + continue; + } + if (iter.IsAshmem()) { + auto node = std::get(iter.value_); + if (node.ashmem == nullptr) { + HILOG_ERROR("ashmem form data share is nullptr."); + continue; + } + + sptr formAshmem = new (std::nothrow) FormAshmem(); + if (formAshmem == nullptr) { + HILOG_ERROR("alloc shmem failed"); + continue; + } + auto size = node.ashmem->GetAshmemSize(); + if (!formAshmem->WriteToAshmem(iter.key_, (char *)node.ashmem->ReadFromAshmem(size, 0), size)) { + HILOG_ERROR("write to shmem failed"); + continue; + } + std::pair, int32_t> imageDataRecord = std::make_pair(formAshmem, sizeof(formAshmem)); + imageDataMap[iter.key_] = imageDataRecord; + } else { + auto value = std::get(iter.value_); + nlohmann::json dataObject = nlohmann::json::parse(value, nullptr, false); + if (dataObject.is_discarded()) { + HILOG_ERROR("failed to parse data: %{public}s.", value.c_str()); + continue; + } + object[iter.key_] = dataObject; + } + } + std::string formDataStr = object.empty() ? "" : object.dump(); + HILOG_DEBUG("formDataStr: %{private}s.", formDataStr.c_str()); + FormProviderData formProviderData; + formProviderData.SetDataString(formDataStr); + if (!imageDataMap.empty()) { + formProviderData.SetImageDataState(FormProviderData::IMAGE_DATA_STATE_ADDED); + formProviderData.SetImageDataMap(imageDataMap); + } + FormMgrAdapter::GetInstance().UpdateForm(formId_, bundleName_, formProviderData); +} + +void FormDataProxyRecord::UpdateRdbDataForm(const std::vector &data) +{ + nlohmann::json object; + for (const auto& iter : data) { + nlohmann::json dataObject = nlohmann::json::parse(iter, nullptr, false); + if (dataObject.is_discarded()) { + HILOG_ERROR("failed to parse data: %{public}s.", iter.c_str()); + continue; + } + object.merge_patch(dataObject); + } + + std::string formDataStr = object.empty() ? "" : object.dump(); + HILOG_DEBUG("formDataStr: %{private}s.", formDataStr.c_str()); + FormProviderData formProviderData; + formProviderData.SetDataString(formDataStr); + FormMgrAdapter::GetInstance().UpdateForm(formId_, bundleName_, formProviderData); +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/src/form_mgr_adapter.cpp b/services/src/form_mgr_adapter.cpp index 867cf53673..26cf521fd1 100644 --- a/services/src/form_mgr_adapter.cpp +++ b/services/src/form_mgr_adapter.cpp @@ -34,6 +34,7 @@ #include "form_cast_temp_connection.h" #include "form_constants.h" #include "form_data_mgr.h" +#include "form_data_proxy_mgr.h" #include "form_db_cache.h" #include "form_db_info.h" #include "form_dump_mgr.h" @@ -236,6 +237,7 @@ int FormMgrAdapter::DeleteForm(const int64_t formId, const sptr & int64_t matchedFormId = FormDataMgr::GetInstance().FindMatchedFormId(formId); // remove connection for in application form FormSupplyCallback::GetInstance()->RemoveConnection(matchedFormId, callerToken); + FormDataProxyMgr::GetInstance().UnsubscribeFormData(matchedFormId); if (FormDataMgr::GetInstance().ExistTempForm(matchedFormId)) { // delete temp form if receive delete form call return HandleDeleteTempForm(matchedFormId, callerToken); diff --git a/services/src/form_supply_callback.cpp b/services/src/form_supply_callback.cpp index b6a0b734a2..985be9f7b2 100644 --- a/services/src/form_supply_callback.cpp +++ b/services/src/form_supply_callback.cpp @@ -19,6 +19,7 @@ #include "form_ams_helper.h" #include "form_constants.h" +#include "form_data_proxy_mgr.h" #include "form_mgr_errors.h" #include "form_provider_mgr.h" #include "form_render_mgr.h" @@ -75,6 +76,8 @@ int FormSupplyCallback::OnAcquire(const FormProviderInfo &formProviderInfo, cons RemoveConnection(connectId); } + FormDataProxyMgr::GetInstance().SubscribeFormData(formId, formProviderInfo.GetFormProxies()); + if (FormRenderMgr::GetInstance().IsNeedRender(formId)) { return FormRenderMgr::GetInstance().UpdateRenderingForm(formId, formProviderInfo.GetFormData(), want.GetParams(), false); diff --git a/services/src/form_util.cpp b/services/src/form_util.cpp index fe33848c14..b248b084cc 100644 --- a/services/src/form_util.cpp +++ b/services/src/form_util.cpp @@ -34,6 +34,10 @@ constexpr int64_t SEC_TO_MILLISEC = 1000; constexpr int64_t MILLISEC_TO_NANOSEC = 1000000; constexpr int64_t INVALID_UDID_HASH = 0; constexpr int32_t SYSTEM_UID = 1000; +constexpr int INT_64_LENGTH = 19; +constexpr int ZERO_VALUE = 0; +constexpr int BASE_NUMBER = 9; +constexpr int DECIMAL_VALUE = 10; } // namespace using namespace std; @@ -240,5 +244,57 @@ bool FormUtil::VerifyCallingPermission(const std::string &permissionName) HILOG_DEBUG("Verify calling permission success"); return true; } + +bool FormUtil::ConvertStringToInt64(const std::string &strInfo, int64_t &int64Value) +{ + size_t strLength = strInfo.size(); + if (strLength == ZERO_VALUE) { + int64Value = ZERO_VALUE; + return true; + } + std::regex pattern("^0|-?[1-9][0-9]{0,18}$"); // "^-?[0-9]{1,19}$" + std::smatch match; + if (regex_match(strInfo, match, pattern)) { + HILOG_DEBUG("%{public}s, regex_match successed.", __func__); + if (strInfo.substr(ZERO_VALUE, ZERO_VALUE + 1) != "-") { // maximum: 9223372036854775807 + if (strLength < INT_64_LENGTH) { + int64Value = std::stoll(strInfo); + return true; + } + int maxSubValue = std::stoi(strInfo.substr(ZERO_VALUE, ZERO_VALUE + 1)); + if (strLength == INT_64_LENGTH && maxSubValue < BASE_NUMBER) { + int64Value = std::stoll(strInfo); + return true; + } + // Means 0x7FFFFFFFFFFFFFFF remove the first number:(2^63 - 1 - 9 * 10 ^ 19) + int subValue = std::stoll(strInfo.substr(ZERO_VALUE + 1, INT_64_LENGTH - 1)); + if (strLength == INT_64_LENGTH && subValue <= INT64_MAX - BASE_NUMBER * + pow(DECIMAL_VALUE, INT_64_LENGTH - 1)) { + int64Value = std::stoll(strInfo); + return true; + } + } + if (strLength < INT_64_LENGTH + 1) { // The minimum value: -9223372036854775808 + int64Value = std::stoll(strInfo); + return true; + } + if (strLength == INT_64_LENGTH + 1) { + int minSubValue = std::stoi(strInfo.substr(1, 1)); + if (minSubValue < BASE_NUMBER) { + int64Value = std::stoll(strInfo); + return true; + } + + // Means 0x8000000000000000 remove the first number:-(2^63 - 9 * 10 ^ 19) + if (std::stoll(strInfo.substr(ZERO_VALUE + 2, INT_64_LENGTH - 1)) <= + (INT64_MAX - BASE_NUMBER * pow(DECIMAL_VALUE, INT_64_LENGTH) + 1)) { + int64Value = std::stoll(strInfo); + return true; + } + } + } + HILOG_DEBUG("%{public}s, regex_match failed.", __func__); + return false; +} } // namespace AppExecFwk } // namespace OHOS \ No newline at end of file -- Gitee