diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index a5f539cc583e09e13683df98b3177ccce398fbce..5c73b387dfed7f6467089e900f81f2469bee9ed1 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -1154,6 +1154,7 @@ ohos_unittest("UdmfServiceImplTest") { ] include_dirs = [ + "${data_service_path}/service/udmf/preprocess", "${data_service_path}/service/udmf/store", "${data_service_path}/service/udmf", "${data_service_path}/framework/include", @@ -1194,6 +1195,7 @@ ohos_unittest("UdmfServiceStubTest") { sources = [ "udmf_service_stub_test.cpp" ] include_dirs = [ + "${data_service_path}/service/udmf/preprocess", "${data_service_path}/service/udmf/store", "${data_service_path}/service/udmf", "${data_service_path}/framework/include", @@ -1256,6 +1258,7 @@ ohos_unittest("UdmfServiceStubMockTest") { "${data_service_path}/service/udmf/permission/uri_permission_manager.cpp", "${data_service_path}/service/udmf/preprocess/data_handler.cpp", "${data_service_path}/service/udmf/preprocess/preprocess_utils.cpp", + "${data_service_path}/service/udmf/preprocess/udmf_notifier_proxy.cpp", "${data_service_path}/service/udmf/store/runtime_store.cpp", "${data_service_path}/service/udmf/store/store_account_observer.cpp", "${data_service_path}/service/udmf/store/store_cache.cpp", diff --git a/services/distributeddataservice/service/udmf/BUILD.gn b/services/distributeddataservice/service/udmf/BUILD.gn index 8176548a1cdd0cdfd3b02c6a6a9689f315786b0e..3b81c5f3fefd298365a2e08fee05bc64179cf0a6 100644 --- a/services/distributeddataservice/service/udmf/BUILD.gn +++ b/services/distributeddataservice/service/udmf/BUILD.gn @@ -57,6 +57,7 @@ ohos_source_set("udmf_server") { "permission/uri_permission_manager.cpp", "preprocess/data_handler.cpp", "preprocess/preprocess_utils.cpp", + "preprocess/udmf_notifier_proxy.cpp", "store/runtime_store.cpp", "store/store_account_observer.cpp", "store/store_cache.cpp", diff --git a/services/distributeddataservice/service/udmf/preprocess/udmf_notifier_proxy.cpp b/services/distributeddataservice/service/udmf/preprocess/udmf_notifier_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..503b0a6bc76c80883ab9c8477b3712be8da6380c --- /dev/null +++ b/services/distributeddataservice/service/udmf/preprocess/udmf_notifier_proxy.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2025 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. + */ + +#define LOG_TAG "UDMFNotifierProxy" +#include "udmf_notifier_proxy.h" + +#include "distributeddata_udmf_ipc_interface_code.h" +#include "log_print.h" +#include "message_parcel.h" +#include "message_option.h" +#include "udmf_types_util.h" +#include "utils/anonymous.h" + +namespace OHOS { +namespace UDMF { +#define IPC_SEND(code, reply, ...) \ + ({ \ + int32_t ipcStatus = E_OK; \ + do { \ + MessageParcel request; \ + if (!request.WriteInterfaceToken(GetDescriptor())) { \ + ipcStatus = E_WRITE_PARCEL_ERROR; \ + break; \ + } \ + if (!ITypesUtil::Marshal(request, ##__VA_ARGS__)) { \ + ipcStatus = E_WRITE_PARCEL_ERROR; \ + break; \ + } \ + MessageOption option; \ + auto result = remote_->SendRequest((code), request, reply, option); \ + if (result != 0) { \ + ZLOGE("SendRequest failed, result = %{public}d!", result); \ + ipcStatus = E_IPC; \ + break; \ + } \ + ITypesUtil::Unmarshal(reply, ipcStatus); \ + } while (0); \ + ipcStatus; \ + }) + +UdmfNotifierProxy::UdmfNotifierProxy(const sptr &impl) + : IRemoteProxy(impl) +{ + remote_ = Remote(); +} + +void UdmfNotifierProxy::HandleDelayObserver(const std::string &key, const DataLoadInfo &dataLoadInfo) +{ + MessageParcel reply; + int32_t status = + IPC_SEND(static_cast(UdmfServiceInterfaceCode::HANDLE_DELAY_OBSERVER), reply, key, dataLoadInfo); + if (status != E_OK) { + ZLOGE("status:%{public}d" PRIu64, status); + } +} + +DelayDataCallbackProxy::DelayDataCallbackProxy(const sptr &impl) + : IRemoteProxy(impl) +{ + remote_ = Remote(); +} + +void DelayDataCallbackProxy::DelayDataCallback(const std::string &key, const UnifiedData &data) +{ + MessageParcel reply; + int32_t status = + IPC_SEND(static_cast(UdmfServiceInterfaceCode::HANDLE_DELAY_OBSERVER), reply, key, data); + if (status != E_OK) { + ZLOGE("status:%{public}d" PRIu64, status); + } +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/preprocess/udmf_notifier_proxy.h b/services/distributeddataservice/service/udmf/preprocess/udmf_notifier_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..782ed38cb1c21bddda356828c1b96eb39f99308c --- /dev/null +++ b/services/distributeddataservice/service/udmf/preprocess/udmf_notifier_proxy.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 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 UDMF_NOTIFIER_PROXY_H +#define UDMF_NOTIFIER_PROXY_H + +#include "iremote_broker.h" +#include "iremote_proxy.h" +#include "iudmf_notifier.h" + +namespace OHOS { +namespace UDMF { +class UdmfNotifierProxy : public IRemoteProxy { +public: + explicit UdmfNotifierProxy(const sptr &impl); + ~UdmfNotifierProxy() = default; + void HandleDelayObserver(const std::string &key, const DataLoadInfo &dataLoadInfo) override; + +private: + static inline BrokerDelegator delegator_; + sptr remote_; +}; + +class DelayDataCallbackProxy : public IRemoteProxy { +public: + explicit DelayDataCallbackProxy(const sptr &impl); + ~DelayDataCallbackProxy() = default; + void DelayDataCallback(const std::string &key, const UnifiedData &data) override; + +private: + static inline BrokerDelegator delegator_; + sptr remote_; +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_NOTIFIER_PROXY_H \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/services/distributeddataservice/service/udmf/store/runtime_store.cpp index fa6f511e98b815d45800cf80844c12ecfaf13649..60e59ff40b93700eed9fbde7e7822c52be28c3a4 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -147,6 +147,20 @@ Status RuntimeStore::PutSummary(const UnifiedData &data, std::vector &ent return E_OK; } +Status RuntimeStore::PutSummary(UnifiedKey &key, const Summary &summary) +{ + auto propertyKey = key.GetKeyCommonPrefix(); + Value value; + auto status = DataHandler::MarshalToEntries(summary, value, TAG::TAG_SUMMARY); + if (status != E_OK) { + ZLOGE("Marshal summary failed, key: %{public}s, status:%{public}d", propertyKey.c_str(), status); + return status; + } + auto summaryKey = propertyKey + SUMMARY_SUFIX; + std::vector entries{{{summaryKey.begin(), summaryKey.end()}, value}};; + return PutEntries(std::move(entries)); +} + Status RuntimeStore::GetSummary(UnifiedKey &key, Summary &summary) { UpdateTime(); diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.h b/services/distributeddataservice/service/udmf/store/runtime_store.h index eb83a3503cefebf22a1a7ce15f9f801508ff7228..107ac11bc4991f3c7427e4c7fea0faf321920e0c 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.h +++ b/services/distributeddataservice/service/udmf/store/runtime_store.h @@ -43,6 +43,7 @@ public: Status DeleteLocal(const std::string &key) override; Status PutRuntime(const std::string &key, const Runtime &runtime) override; Status GetRuntime(const std::string &key, Runtime &runtime) override; + Status PutSummary(UnifiedKey &key, const Summary &summary) override; void Close() override; bool Init() override; diff --git a/services/distributeddataservice/service/udmf/store/store.h b/services/distributeddataservice/service/udmf/store/store.h index aaf6fade14404514789d4b98cedfbe8b1afbcff9..69091ed91cfe198454f88f6aac209634e88e4b43 100644 --- a/services/distributeddataservice/service/udmf/store/store.h +++ b/services/distributeddataservice/service/udmf/store/store.h @@ -39,6 +39,7 @@ public: virtual Status DeleteLocal(const std::string &key) = 0; virtual Status PutRuntime(const std::string &key, const Runtime &runtime) = 0; virtual Status GetRuntime(const std::string &key, Runtime &runtime) = 0; + virtual Status PutSummary(UnifiedKey &key, const Summary &summary) = 0; virtual bool Init() = 0; virtual void Close() = 0; diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 86b9e3d0874510d5dda720997fe7c73b4cfaa3ca..f48bb49536f39e21227c499ed6d3114101af1a9e 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -141,9 +141,8 @@ int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData); if (ret != E_OK) { - ZLOGE("SetRemoteUri failed, ret: %{public}d, bundleName:%{public}s.", ret, + ZLOGW("SetRemoteUri failed, ret: %{public}d, bundleName:%{public}s.", ret, unifiedData.GetRuntime()->createPackage.c_str()); - return ret; } } PreProcessUtils::SetRecordUid(unifiedData); @@ -1037,5 +1036,112 @@ bool UdmfServiceImpl::IsValidOptionsNonDrag(UnifiedKey &key, const std::string & } return false; } + +int32_t UdmfServiceImpl::SetDelayInfo(const DataLoadInfo &dataLoadInfo, sptr iUdmfNotifier, std::string &key) +{ + std::string bundleName; + auto tokenId = static_cast(IPCSkeleton::GetCallingTokenID()); + PreProcessUtils::GetHapBundleNameByToken(tokenId, bundleName); + UnifiedKey udkey(UD_INTENTION_MAP.at(UD_INTENTION_DRAG), bundleName, dataLoadInfo.sequenceKey); + key = udkey.GetUnifiedKey(); + dataLoadCallback_.Insert(key, iface_cast(iUdmfNotifier)); + + auto store = StoreCache::GetInstance().GetStore(UD_INTENTION_MAP.at(UD_INTENTION_DRAG)); + if (store == nullptr) { + ZLOGE("Get store failed:%{public}s", key.c_str()); + return E_DB_ERROR; + } + + Summary summary; + UnifiedDataHelper::GetSummaryFromLoadInfo(dataLoadInfo, summary); + if (store->PutSummary(udkey, summary) != E_OK) { + ZLOGE("Put summary failed:%{public}s", key.c_str()); + return E_DB_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceImpl::PushDelayData(const std::string &key, UnifiedData &unifiedData) +{ + CustomOption option { + .intention = UD_INTENTION_DRAG, + .tokenId = static_cast(IPCSkeleton::GetCallingTokenID()), + }; + if (PreProcessUtils::RuntimeDataImputation(unifiedData, option) != E_OK) { + ZLOGE("Imputation failed"); + return E_ERROR; + } + int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData); + if (ret != E_OK) { + ZLOGW("SetRemoteUri failed, ret:%{public}d, key:%{public}s.", ret, key.c_str()); + } + + auto it = delayDataCallback_.Find(key); + if (!it.first) { + ZLOGE("DelayData callback no exist, key:%{public}s", key.c_str()); + return E_ERROR; + } + QueryOption query { + .tokenId = it.second.tokenId, + .key = key + }; + if (option.tokenId != query.tokenId && !IsPermissionInCache(query)) { + ZLOGE("No permission"); + return E_NO_PERMISSION; + } + ret = ProcessUri(query, unifiedData); + if (ret != E_OK) { + ZLOGE("ProcessUri failed:%{public}d", ret); + return E_NO_PERMISSION; + } + privilegeCache_.erase(key); + PreProcessUtils::SetRemoteData(unifiedData); + + TransferToEntriesIfNeed(query, unifiedData); + auto callback = iface_cast(it.second.dataCallback); + if (callback == nullptr) { + ZLOGE("Delay data callback is null, key:%{public}s", key.c_str()); + return E_ERROR; + } + callback->DelayDataCallback(key, unifiedData); + delayDataCallback_.Erase(key); + return E_OK; +} + +int32_t UdmfServiceImpl::GetDataIfAvailable(const std::string &key, const DataLoadInfo &dataLoadInfo, + sptr iUdmfNotifier, std::shared_ptr unifiedData) +{ + ZLOGD("start"); + QueryOption query { + .tokenId = static_cast(IPCSkeleton::GetCallingTokenID()), + .key = key + }; + if (unifiedData == nullptr) { + ZLOGE("Data is null, key:%{public}s", key.c_str()); + return E_ERROR; + } + auto status = RetrieveData(query, *unifiedData); + if (status == E_OK) { + return E_OK; + } + if (status != E_NOT_FOUND) { + ZLOGE("Retrieve data failed, key:%{public}s", key.c_str()); + return status; + } + DelayGetDataInfo delayGetDataInfo = { + .dataCallback = iUdmfNotifier, + .tokenId = static_cast(IPCSkeleton::GetCallingTokenID()), + }; + delayDataCallback_.InsertOrAssign(key, std::move(delayGetDataInfo)); + + auto it = dataLoadCallback_.Find(key); + if (!it.first) { + ZLOGE("DataLoad callback no exist, key:%{public}s", key.c_str()); + return E_ERROR; + } + it.second->HandleDelayObserver(key, dataLoadInfo); + dataLoadCallback_.Erase(key); + return E_OK; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h index 16b46026b9922825cda2b6344a3b8270c74cae8d..09127a317b0703a0a92ec53d9097d0d66134ab3b 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -20,6 +20,7 @@ #include "udmf_service_stub.h" #include "kv_store_delegate_manager.h" #include "checker_manager.h" +#include "udmf_notifier_proxy.h" namespace OHOS { namespace UDMF { /* @@ -48,6 +49,11 @@ public: int32_t ClearAsynProcessByKey(const std::string &businessUdKey) override; int32_t ResolveAutoLaunch(const std::string &identifier, DBLaunchParam ¶m) override; int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; + int32_t SetDelayInfo(const DataLoadInfo &dataLoadInfo, sptr iUdmfNotifier, + std::string &key) override; + int32_t PushDelayData(const std::string &key, UnifiedData &unifiedData) override; + int32_t GetDataIfAvailable(const std::string &key, const DataLoadInfo &dataLoadInfo, + sptr iUdmfNotifier, std::shared_ptr unifiedData) override; private: int32_t SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key); int32_t RetrieveData(const QueryOption &query, UnifiedData &unifiedData); @@ -84,6 +90,8 @@ private: std::mutex mutex_; std::unordered_map asyncProcessInfoMap_; + ConcurrentMap> dataLoadCallback_; + ConcurrentMap delayDataCallback_; }; } // namespace UDMF } // namespace OHOS diff --git a/services/distributeddataservice/service/udmf/udmf_service_stub.cpp b/services/distributeddataservice/service/udmf/udmf_service_stub.cpp index f433413b02364d003f934d1c0f53b8a92d59df60..9e9a05f14c59201459aa1883299f3010ca743e06 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_stub.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_stub.cpp @@ -289,5 +289,66 @@ int32_t UdmfServiceStub::OnClearAsynProcessByKey(MessageParcel &data, MessagePar } return E_OK; } + +int32_t UdmfServiceStub::OnSetDelayInfo(MessageParcel &data, MessageParcel &reply) +{ + ZLOGD("start"); + DataLoadInfo dataLoadInfo; + sptr iUdmfNotifier; + + if (!ITypesUtil::Unmarshal(data, dataLoadInfo, iUdmfNotifier)) { + ZLOGE("Unmarshal failed!"); + return E_READ_PARCEL_ERROR; + } + std::string key; + int32_t status = SetDelayInfo(dataLoadInfo, iUdmfNotifier, key); + if (!ITypesUtil::Marshal(reply, status, key)) { + ZLOGE("Marshal failed:%{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnPushDelayData(MessageParcel &data, MessageParcel &reply) +{ + ZLOGD("start"); + std::string key; + UnifiedData unifiedData; + + if (!ITypesUtil::Unmarshal(data, key, unifiedData)) { + ZLOGE("Unmarshal failed!"); + return E_READ_PARCEL_ERROR; + } + + int32_t status = PushDelayData(key, unifiedData); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal failed:%{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnGetDataIfAvailable(MessageParcel &data, MessageParcel &reply) +{ + ZLOGD("start"); + std::string key; + DataLoadInfo dataLoadInfo; + sptr iUdmfNotifier; + if (!ITypesUtil::Unmarshal(data, key, dataLoadInfo, iUdmfNotifier)) { + ZLOGE("Unmarshal failed!"); + return E_READ_PARCEL_ERROR; + } + auto unifiedData = std::make_shared(); + int32_t status = GetDataIfAvailable(key, dataLoadInfo, iUdmfNotifier, unifiedData); + if (unifiedData == nullptr) { + ZLOGE("Data is null, key:%{public}s", key.c_str()); + return E_ERROR; + } + if (!ITypesUtil::Marshal(reply, status, *unifiedData)) { + ZLOGE("Marshal failed:%{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/udmf_service_stub.h b/services/distributeddataservice/service/udmf/udmf_service_stub.h index 793a13d997e4677012e6d3166da5b2760c2cbca5..c5f617a9fb54da2375ef7aea2e04e71b3b363e1c 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_stub.h +++ b/services/distributeddataservice/service/udmf/udmf_service_stub.h @@ -46,6 +46,9 @@ private: int32_t OnObtainAsynProcess(MessageParcel &data, MessageParcel &reply); int32_t OnClearAsynProcessByKey(MessageParcel &data, MessageParcel &reply); int32_t OnInvokeHap(MessageParcel &data, MessageParcel &reply); + int32_t OnPushDelayData(MessageParcel &data, MessageParcel &reply); + int32_t OnSetDelayInfo(MessageParcel &data, MessageParcel &reply); + int32_t OnGetDataIfAvailable(MessageParcel &data, MessageParcel &reply); using Handler = int32_t (UdmfServiceStub::*)(MessageParcel &data, MessageParcel &reply); static constexpr Handler HANDLERS[static_cast(UdmfServiceInterfaceCode::CODE_BUTT)] = { @@ -62,7 +65,10 @@ private: &UdmfServiceStub::OnGetAppShareOption, &UdmfServiceStub::OnRemoveAppShareOption, &UdmfServiceStub::OnObtainAsynProcess, - &UdmfServiceStub::OnClearAsynProcessByKey + &UdmfServiceStub::OnClearAsynProcessByKey, + &UdmfServiceStub::OnSetDelayInfo, + &UdmfServiceStub::OnPushDelayData, + &UdmfServiceStub::OnGetDataIfAvailable, }; }; } // namespace UDMF