diff --git a/bundle.json b/bundle.json index 3a7ca7ec2bb4bb002e420614ff42f59bd29f7c54..61f8c50d06a59115630abfeb06b370691ce1d4da 100644 --- a/bundle.json +++ b/bundle.json @@ -48,6 +48,8 @@ "ram": "", "deps": { "components": [ + "ability_base", + "ability_runtime", "libhilog", "ipc_core", "utils", diff --git a/frameworks/innerkitsimpl/distributeddatafwk/include/itypes_util.h b/frameworks/innerkitsimpl/distributeddatafwk/include/itypes_util.h index d55c2b534295d489fc45a3f0314e9bbe10187492..1bca607e6fb6340e492b7ec9e2b823dce4431564 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/include/itypes_util.h +++ b/frameworks/innerkitsimpl/distributeddatafwk/include/itypes_util.h @@ -48,7 +48,16 @@ public: static bool Marshalling(const DistributedRdb::RdbSyncerParam& param, MessageParcel& parcel); static bool UnMarshalling(MessageParcel& parcel, DistributedRdb::RdbSyncerParam& param); - + + static bool Marshalling(const DistributedRdb::SyncResult& result, MessageParcel& parcel); + static bool UnMarshalling(MessageParcel& parcel, DistributedRdb::SyncResult& result); + + static bool Marshalling(const DistributedRdb::SyncOption& option, MessageParcel& parcel); + static bool UnMarshalling(MessageParcel& parcel, DistributedRdb::SyncOption& option); + + static bool Marshalling(const DistributedRdb::RdbPredicates& predicates, MessageParcel& parcel); + static bool UnMarshalling(MessageParcel& parcel, DistributedRdb::RdbPredicates& predicates); + static int64_t GetTotalSize(const std::vector &entries); static int64_t GetTotalSize(const std::vector &entries); diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_data_service.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_data_service.cpp index 426b784cbe83fa39012909d65fc5f95ed655e772..18cd0fee44960ec383ebf630abb21aa26d040ee6 100755 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_data_service.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_data_service.cpp @@ -18,6 +18,8 @@ #include "ikvstore_data_service.h" #include "constant.h" #include "irdb_service.h" +#include "rdb_service_proxy.h" +#include "itypes_util.h" #include "message_parcel.h" #include "types.h" #include "log_print.h" @@ -392,20 +394,26 @@ Status KvStoreDataServiceProxy::StopWatchDeviceChange(sptr KvStoreDataServiceProxy::GetRdbService() { + ZLOGI("enter"); MessageParcel data; if (!data.WriteInterfaceToken(KvStoreDataServiceProxy::GetDescriptor())) { ZLOGE("write descriptor failed"); return nullptr; } + MessageParcel reply; MessageOption mo { MessageOption::TF_SYNC }; int32_t error = Remote()->SendRequest(GET_RDB_SERVICE, data, reply, mo); if (error != 0) { - ZLOGW("SendRequest returned %{public}d", error); + ZLOGE("SendRequest returned %{public}d", error); return nullptr; } auto remoteObject = reply.ReadRemoteObject(); - return iface_cast(remoteObject); + if (remoteObject == nullptr) { + ZLOGE("remote object is nullptr"); + return nullptr; + } + return iface_cast(remoteObject); } int32_t KvStoreDataServiceStub::GetKvStoreOnRemote(MessageParcel &data, MessageParcel &reply) diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/itypes_util.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/itypes_util.cpp index f7801e5fd0f3b71d5cd9a13e10f27f45c29b08ba..2f084d300ac84a00d9028d6a2b4a7bccf606ea85 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/itypes_util.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/itypes_util.cpp @@ -200,6 +200,149 @@ bool ITypesUtil::UnMarshalling(MessageParcel& parcel, DistributedRdb::RdbSyncerP return true; } +bool ITypesUtil::Marshalling(const DistributedRdb::SyncResult &result, MessageParcel &parcel) +{ + if (!parcel.WriteInt32(static_cast(result.size()))) { + ZLOGE("SyncResult write size failed"); + return false; + } + + for (const auto& entry : result) { + if (!parcel.WriteString(entry.first)) { + ZLOGE("SyncResult write device failed"); + return false; + } + if (!parcel.WriteInt32(entry.second)) { + ZLOGE("SyncResult write int failed"); + return false; + } + } + return true; +} + +bool ITypesUtil::UnMarshalling(MessageParcel &parcel, DistributedRdb::SyncResult &result) +{ + int32_t size = 0; + if (!parcel.ReadInt32(size)) { + ZLOGE("SyncResult read size failed"); + return false; + } + if (size <= 0) { + ZLOGE("SyncResult size invalid"); + return false; + } + + for (int32_t i = 0; i < size; i++) { + std::string device; + if (!parcel.ReadString(device)) { + ZLOGE("SyncResult read device failed"); + return false; + } + int32_t error; + if (!parcel.ReadInt32(error)) { + ZLOGE("SyncResult read int failed"); + return false; + } + result.insert({ device, error }); + } + return true; +} + +bool ITypesUtil::Marshalling(const DistributedRdb::SyncOption &option, MessageParcel &parcel) +{ + if (!parcel.WriteInt32(option.mode)) { + ZLOGE("SyncOption write mode failed"); + return false; + } + if (!parcel.WriteBool(option.isBlock)) { + ZLOGE("SyncOption write isBlock failed"); + return false; + } + return true; +} + +bool ITypesUtil::UnMarshalling(MessageParcel &parcel, DistributedRdb::SyncOption &option) +{ + int32_t mode; + if (!parcel.ReadInt32(mode)) { + ZLOGE("SyncOption read mode failed"); + return false; + } + option.mode = static_cast(mode); + if (!parcel.ReadBool(option.isBlock)) { + ZLOGE("SyncOption read isBlock failed"); + return false; + } + return true; +} + +bool ITypesUtil::Marshalling(const DistributedRdb::RdbPredicates &predicates, MessageParcel &parcel) +{ + if (!parcel.WriteString(predicates.table_)) { + ZLOGE("predicate write table failed"); + return false; + } + if (!parcel.WriteStringVector(predicates.devices_)) { + ZLOGE("predicate write devices failed"); + return false; + } + if (!parcel.WriteUint32(predicates.operations_.size())) { + ZLOGE("predicate write operation size failed"); + return false; + } + for (const auto& operation : predicates.operations_) { + if (!parcel.WriteInt32(operation.operator_)) { + ZLOGE("predicate write operator failed"); + return false; + } + if (!parcel.WriteString(operation.field_)) { + ZLOGE("predicate write field failed"); + return false; + } + if (!parcel.WriteStringVector(operation.values_)) { + ZLOGE("predicate write values failed"); + return false; + } + } + return true; +} + +bool ITypesUtil::UnMarshalling(MessageParcel &parcel, DistributedRdb::RdbPredicates &predicates) +{ + if (!parcel.ReadString(predicates.table_)) { + ZLOGE("predicate read table failed"); + return false; + } + if (!parcel.ReadStringVector(&predicates.devices_)) { + ZLOGE("predicate read devices failed"); + return false; + } + uint32_t size = 0; + if (!parcel.ReadUint32(size)) { + ZLOGE("predicate read operation size failed"); + return false; + } + for (uint32_t i = 0; i < size; i++) { + int32_t op; + if (!parcel.ReadInt32(op)) { + ZLOGE("predicate read operator failed"); + return false; + } + DistributedRdb::RdbPredicateOperation operation; + operation.operator_ = static_cast(op); + if (!parcel.ReadString(operation.field_)) { + ZLOGE("predicate read field failed"); + return false; + } + if (!parcel.ReadStringVector(&operation.values_)) { + ZLOGE("predicate read values failed"); + return false; + } + predicates.operations_.push_back(std::move(operation)); + } + return true; +} + template std::vector ITypesUtil::Convert2Vector(const std::list &entries) { diff --git a/frameworks/innerkitsimpl/rdb/src/irdb_service.h b/frameworks/innerkitsimpl/rdb/include/irdb_service.h similarity index 52% rename from frameworks/innerkitsimpl/rdb/src/irdb_service.h rename to frameworks/innerkitsimpl/rdb/include/irdb_service.h index a7cbc707ea7befe6385a637cc066b078641847c9..399be4fe03d853de62428b612a9353130f167fc6 100644 --- a/frameworks/innerkitsimpl/rdb/src/irdb_service.h +++ b/frameworks/innerkitsimpl/rdb/include/irdb_service.h @@ -20,20 +20,39 @@ #include #include "rdb_service.h" -#include "irdb_syncer.h" #include "rdb_types.h" -#include "rdb_client_death_recipient.h" namespace OHOS::DistributedRdb { class IRdbService : public RdbService, public IRemoteBroker { public: enum { - RDB_SERVICE_CMD_GET_SYNCER, - RDB_SERVICE_CMD_REGISTER_CLIENT_DEATH, + RDB_SERVICE_CMD_OBTAIN_TABLE, + RDB_SERVICE_CMD_GET_DEVICES, + RDB_SERVICE_CMD_INIT_NOTIFIER, + RDB_SERVICE_CMD_SET_DIST_TABLE, + RDB_SERVICE_CMD_SYNC, + RDB_SERVICE_CMD_ASYNC, + RDB_SERVICE_CMD_SUBSCRIBE, + RDB_SERVICE_CMD_UNSUBSCRIBE, RDB_SERVICE_CMD_MAX }; DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedRdb.IRdbService"); + + virtual std::vector GetConnectDevices() = 0; + + virtual int32_t InitNotifier(const RdbSyncerParam& param, const sptr notifier) = 0; + +protected: + virtual int32_t DoSync(const RdbSyncerParam& param, const SyncOption& option, + const RdbPredicates& predicates, SyncResult& result) = 0; + + virtual int32_t DoAsync(const RdbSyncerParam& param, uint32_t seqNum, + const SyncOption& option, const RdbPredicates& predicates) = 0; + + virtual int32_t DoSubscribe(const RdbSyncerParam& param) = 0; + + virtual int32_t DoUnSubscribe(const RdbSyncerParam& param) = 0; }; } #endif diff --git a/frameworks/innerkitsimpl/rdb/include/rdb_manager.h b/frameworks/innerkitsimpl/rdb/include/rdb_manager.h index 8f3b6882bdf476c71a9483c6a4086743300b2a16..fe1d95307d90d03b329c0606c63507733bd943db 100644 --- a/frameworks/innerkitsimpl/rdb/include/rdb_manager.h +++ b/frameworks/innerkitsimpl/rdb/include/rdb_manager.h @@ -20,18 +20,15 @@ #include #include +#include "rdb_service.h" +#include "rdb_types.h" namespace OHOS::DistributedRdb { -struct RdbSyncerParam; -class RdbSyncer; - class RdbManager { public: - static std::shared_ptr GetRdbSyncer(const RdbSyncerParam& param); - - static int RegisterRdbServiceDeathObserver(const std::string &storeName, const std::function& observer); - - static int UnRegisterRdbServiceDeathObserver(const std::string &storeName); + static std::vector GetConnectDevices(); + + static std::shared_ptr GetRdbService(const RdbSyncerParam& param); }; } #endif diff --git a/frameworks/innerkitsimpl/rdb/include/rdb_notifier.h b/frameworks/innerkitsimpl/rdb/include/rdb_notifier.h new file mode 100644 index 0000000000000000000000000000000000000000..81aa43373af0cd1da735e1e6a672bc6580d1ee5d --- /dev/null +++ b/frameworks/innerkitsimpl/rdb/include/rdb_notifier.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022 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 DISTRIBUTED_RDB_NOTIFIER_H +#define DISTRIBUTED_RDB_NOTIFIER_H + +#include +#include +#include + +#include "rdb_types.h" + +namespace OHOS::DistributedRdb { +class IRdbNotifier : public IRemoteBroker { +public: + enum { + RDB_NOTIFIER_CMD_SYNC_COMPLETE, + RDB_NOTIFIER_CMD_DATA_CHANGE, + RDB_NOTIFIER_CMD_MAX + }; + + virtual int32_t OnComplete(uint32_t seqNum, const SyncResult& result) = 0; + + virtual int32_t OnChange(const std::string& storeName, const std::vector& devices) = 0; + + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedRdb.IRdbNotifier"); +}; + +class RdbNotifierProxy : public IRemoteProxy { +public: + explicit RdbNotifierProxy(const sptr& object); + virtual ~RdbNotifierProxy() noexcept; + + int32_t OnComplete(uint32_t seqNum, const SyncResult& result) override; + + int32_t OnChange(const std::string& storeName, const std::vector& devices) override; + +private: + static inline BrokerDelegator delegator_; +}; + +using RdbSyncCompleteNotifier = std::function; +using RdbDataChangeNotifier = std::function&)>; + +class RdbNotifierStub : public IRemoteStub { +public: + RdbNotifierStub(const RdbSyncCompleteNotifier&, const RdbDataChangeNotifier&); + virtual ~RdbNotifierStub() noexcept; + + int OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) override; + + int32_t OnCompleteInner(MessageParcel& data, MessageParcel& reply); + int32_t OnComplete(uint32_t seqNum, const SyncResult& result) override; + + int32_t OnChangeInner(MessageParcel&data, MessageParcel& reply); + int32_t OnChange(const std::string& storeName, const std::vector& devices) override; + +private: + bool CheckInterfaceToken(MessageParcel& data); + + using RequestHandle = int32_t (RdbNotifierStub::*)(MessageParcel&, MessageParcel&); + static constexpr RequestHandle HANDLES[RDB_NOTIFIER_CMD_MAX] = { + [RDB_NOTIFIER_CMD_SYNC_COMPLETE] = &RdbNotifierStub::OnCompleteInner, + [RDB_NOTIFIER_CMD_DATA_CHANGE] = &RdbNotifierStub::OnChangeInner, + }; + + RdbSyncCompleteNotifier completeNotifier_; + RdbDataChangeNotifier changeNotifier_; +}; +} +#endif diff --git a/frameworks/innerkitsimpl/rdb/src/irdb_syncer.h b/frameworks/innerkitsimpl/rdb/include/rdb_service.h similarity index 43% rename from frameworks/innerkitsimpl/rdb/src/irdb_syncer.h rename to frameworks/innerkitsimpl/rdb/include/rdb_service.h index 68cf35947e905160ee741fdeb804d98a2ba66cd6..b5dff6d3318911c8c11aa9e58eea9be16f781062 100644 --- a/frameworks/innerkitsimpl/rdb/src/irdb_syncer.h +++ b/frameworks/innerkitsimpl/rdb/include/rdb_service.h @@ -13,24 +13,30 @@ * limitations under the License. */ -#ifndef DISTRUBTED_IRDB_SYNCER_H -#define DISTRUBTED_IRDB_SYNCER_H +#ifndef DISTRIBUTED_RDB_SERVICE_H +#define DISTRIBUTED_RDB_SERVICE_H + +#include +#include -#include #include "rdb_types.h" -#include "rdb_syncer.h" namespace OHOS::DistributedRdb { -class IRdbSyncer : public RdbSyncer, public IRemoteBroker { +class RdbService { public: - enum { - RDB_SYNCER_CMD_SET_DIST_TABLES, - RDB_SYNCER_CMD_SYNC, - RDB_SYNCER_CMD_SUBSCRIBE, - RDB_SYNCER_CMD_REMOVE_DEVICE_DATA, - RDB_SYNCER_CMD_MAX - }; - DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedRdb.IRdbSyncer"); + virtual std::string ObtainDistributedTableName(const std::string& device, const std::string& table) = 0; + + virtual int32_t SetDistributedTables(const RdbSyncerParam& param, + const std::vector& tables) = 0; + + virtual int32_t Sync(const RdbSyncerParam& param, const SyncOption& option, + const RdbPredicates& predicates, const SyncCallback& callback) = 0; + + virtual int32_t Subscribe(const RdbSyncerParam& param, const SubscribeOption& option, + RdbStoreObserver *observer) = 0; + + virtual int32_t UnSubscribe(const RdbSyncerParam& param, const SubscribeOption& option, + RdbStoreObserver *observer) = 0; }; } #endif diff --git a/frameworks/innerkitsimpl/rdb/include/rdb_syncer.h b/frameworks/innerkitsimpl/rdb/include/rdb_syncer.h deleted file mode 100644 index 890be310573b674a7a9b707face3e61ab966eeee..0000000000000000000000000000000000000000 --- a/frameworks/innerkitsimpl/rdb/include/rdb_syncer.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2022 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 DISTRIBUTED_RDB_SYNCER_H -#define DISTRIBUTED_RDB_SYNCER_H - -#include -#include - -namespace OHOS::DistributedRdb { -class RdbSyncer { -public: - virtual int SetDistributedTables(const std::vector& tables) = 0; -}; -} -#endif diff --git a/frameworks/innerkitsimpl/rdb/include/rdb_types.h b/frameworks/innerkitsimpl/rdb/include/rdb_types.h index c6c5b5375b2a3002c9605e53d5826b6248ac8d8c..6874093c00c61da0ddddf506b80d9eb8bb8c8407 100644 --- a/frameworks/innerkitsimpl/rdb/include/rdb_types.h +++ b/frameworks/innerkitsimpl/rdb/include/rdb_types.h @@ -19,10 +19,16 @@ #include #include #include +#include namespace OHOS::DistributedRdb { +enum RdbStatus { + RDB_OK, + RDB_ERROR, +}; + enum RdbDistributedType { - RDB_DEVICE_COLLABORATION, + RDB_DEVICE_COLLABORATION = 10, RDB_DISTRIBUTED_TYPE_MAX }; @@ -45,18 +51,55 @@ struct SyncOption { }; using SyncResult = std::map; // networkId -using SyncCallback = std::function; +using SyncCallback = std::function; + +enum RdbPredicateOperator { + EQUAL_TO, + NOT_EQUAL_TO, + AND, + OR, + ORDER_BY, + LIMIT, + OPERATOR_MAX +}; + +struct RdbPredicateOperation { + RdbPredicateOperator operator_; + std::string field_; + std::vector values_; +}; + +struct RdbPredicates { + inline void AddOperation(const RdbPredicateOperator op, const std::string& field, + const std::string& value) + { + operations_.push_back({ op, field, { value } }); + } + inline void AddOperation(const RdbPredicateOperator op, const std::string& field, + const std::vector& values) + { + operations_.push_back({ op, field, values }); + } + + std::string table_; + std::vector devices_; + std::vector operations_; +}; enum SubscribeMode { - LOCAL, REMOTE, - LOCAL_AND_REMOTE, + SUBSCRIBE_MODE_MAX }; struct SubscribeOption { SubscribeMode mode; }; +class RdbStoreObserver { +public: + virtual void OnChange(const std::vector& devices) = 0; // networkid +}; + struct DropOption { }; } diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_client_death_recipient.cpp b/frameworks/innerkitsimpl/rdb/src/rdb_client_death_recipient.cpp deleted file mode 100644 index c61fdc1a5daec84c6f23b35a0e59cc9e3ef59209..0000000000000000000000000000000000000000 --- a/frameworks/innerkitsimpl/rdb/src/rdb_client_death_recipient.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2022 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 "RdbClientDeathRecipientProxy" - -#include "rdb_client_death_recipient.h" -#include "log_print.h" - -namespace OHOS::DistributedRdb { -RdbClientDeathRecipientProxy::RdbClientDeathRecipientProxy(const sptr &object) - : IRemoteProxy(object) -{ - ZLOGI("construct"); -} - -RdbClientDeathRecipientProxy::~RdbClientDeathRecipientProxy() -{ - ZLOGI("deconstruct"); -} - -RdbClientDeathRecipientStub::RdbClientDeathRecipientStub() -{ - ZLOGI("construct"); -} - -RdbClientDeathRecipientStub::~RdbClientDeathRecipientStub() -{ - ZLOGI("deconstruct"); -} - -int RdbClientDeathRecipientStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, - MessageOption &option) -{ - return IPCObjectStub::OnRemoteRequest(code, data, reply, option); -} -} diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_client_death_recipient.h b/frameworks/innerkitsimpl/rdb/src/rdb_client_death_recipient.h deleted file mode 100644 index b9e45fd7b515c0b343caf014403f668bfc890eb5..0000000000000000000000000000000000000000 --- a/frameworks/innerkitsimpl/rdb/src/rdb_client_death_recipient.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2022 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 IRDB_CLIENT_DEATH_RECIPIENT_H -#define IRDB_CLIENT_DEATH_RECIPIENT_H - -#include -#include -#include - -namespace OHOS::DistributedRdb { -class IRdbClientDeathRecipient : public IRemoteBroker { -public: - DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedRdb.IRdbClientDeathRecipient"); -}; - -class RdbClientDeathRecipientProxy : public IRemoteProxy { -public: - explicit RdbClientDeathRecipientProxy(const sptr& object); - virtual ~RdbClientDeathRecipientProxy(); - -private: - static inline BrokerDelegator delegator_; -}; - -class RdbClientDeathRecipientStub : public IRemoteStub { -public: - RdbClientDeathRecipientStub(); - virtual ~RdbClientDeathRecipientStub(); - int OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) override; -}; -} -#endif diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_manager.cpp b/frameworks/innerkitsimpl/rdb/src/rdb_manager.cpp index 671169f972eeb6f9bae09bdb8d239237f3563d81..7a438892cd1f4b715f428601f2a53e74d612f67c 100644 --- a/frameworks/innerkitsimpl/rdb/src/rdb_manager.cpp +++ b/frameworks/innerkitsimpl/rdb/src/rdb_manager.cpp @@ -17,18 +17,13 @@ #include "rdb_manager_impl.h" namespace OHOS::DistributedRdb { -std::shared_ptr RdbManager::GetRdbSyncer(const RdbSyncerParam ¶m) +std::vector RdbManager::GetConnectDevices() { - return RdbManagerImpl::GetInstance().GetRdbSyncer(param); + return RdbManagerImpl::GetInstance().GetConnectDevices(); } -int RdbManager::RegisterRdbServiceDeathObserver(const std::string &storeName, const std::function& observer) +std::shared_ptr RdbManager::GetRdbService(const RdbSyncerParam& param) { - return RdbManagerImpl::GetInstance().RegisterRdbServiceDeathObserver(storeName, observer); -} - -int RdbManager::UnRegisterRdbServiceDeathObserver(const std::string &storeName) -{ - return RdbManagerImpl::GetInstance().UnRegisterRdbServiceDeathObserver(storeName); + return RdbManagerImpl::GetInstance().GetRdbService(param); } } \ No newline at end of file diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_manager_impl.cpp b/frameworks/innerkitsimpl/rdb/src/rdb_manager_impl.cpp index a12c6f4b77fe5c1144966d44b0074e2f9fc5eb35..b0c55b370e5d103568be8b3a60941fe3ce653c6f 100644 --- a/frameworks/innerkitsimpl/rdb/src/rdb_manager_impl.cpp +++ b/frameworks/innerkitsimpl/rdb/src/rdb_manager_impl.cpp @@ -17,6 +17,7 @@ #include "rdb_manager_impl.h" +#include #include "iservice_registry.h" #include "ipc_skeleton.h" #include "system_ability_definition.h" @@ -24,18 +25,30 @@ #include "log_print.h" #include "ikvstore_data_service.h" #include "irdb_service.h" +#include "rdb_service_proxy.h" namespace OHOS::DistributedRdb { -static sptr GetDistributedDataManager() +static sptr GetDistributedDataManager() { - auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (manager == nullptr) { - ZLOGE("get system ability manager failed"); - return nullptr; + int retry = 0; + while (++retry <= RdbManagerImpl::GET_SA_RETRY_TIMES) { + auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (manager == nullptr) { + ZLOGE("get system ability manager failed"); + return nullptr; + } + ZLOGI("get distributed data manager %{public}d", retry); + auto remoteObject = manager->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID); + if (remoteObject == nullptr) { + std::this_thread::sleep_for(std::chrono::seconds(RdbManagerImpl::RETRY_INTERVAL)); + continue; + } + ZLOGI("get distributed data manager success"); + return iface_cast(remoteObject); } - ZLOGI("get distributed data manager"); - auto remoteObject = manager->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID); - return iface_cast(remoteObject); + + ZLOGE("get distributed data manager failed"); + return nullptr; } static void LinkToDeath(const sptr& remote) @@ -56,7 +69,7 @@ RdbManagerImpl::RdbManagerImpl() RdbManagerImpl::~RdbManagerImpl() { - ZLOGI("deconstruct"); + ZLOGI("destroy"); } RdbManagerImpl& RdbManagerImpl::GetInstance() @@ -65,13 +78,20 @@ RdbManagerImpl& RdbManagerImpl::GetInstance() return manager; } -std::shared_ptr RdbManagerImpl::GetRdbService() +std::vector RdbManagerImpl::GetConnectDevices() { std::lock_guard lock(mutex_); - if (rdbService_ != nullptr) { - return rdbService_; + auto service = GetRdbService(); + if (service == nullptr) { + ZLOGE("get service failed"); + return std::vector(); } - + + return ((RdbServiceProxy *)service.GetRefPtr())->GetConnectDevices(); +} + +sptr RdbManagerImpl::GetRdbService() +{ if (distributedDataMgr_ == nullptr) { distributedDataMgr_ = GetDistributedDataManager(); } @@ -79,50 +99,55 @@ std::shared_ptr RdbManagerImpl::GetRdbService() ZLOGE("get distributed data manager failed"); return nullptr; } - - auto serviceObject = distributedDataMgr_->GetRdbService(); - if (serviceObject == nullptr) { + + auto service = distributedDataMgr_->GetRdbService(); + if (service == nullptr) { ZLOGE("get rdb service failed"); return nullptr; } - LinkToDeath(serviceObject->AsObject()); - rdbService_ = std::shared_ptr(serviceObject.GetRefPtr(), [holder = serviceObject] (const auto*) {}); - return rdbService_; + return service; } -std::shared_ptr RdbManagerImpl::GetRdbSyncer(const RdbSyncerParam ¶m) +std::shared_ptr RdbManagerImpl::GetRdbService(const RdbSyncerParam& param) { - if (param.bundleName_.empty() || param.path_.empty() || param.storeName_.empty()) { - ZLOGE("param is invalid"); - return nullptr; + std::lock_guard lock(mutex_); + if (rdbService_ != nullptr) { + return rdbService_; } auto service = GetRdbService(); if (service == nullptr) { return nullptr; } - RegisterClientDeathRecipient(param.bundleName_); - return service->GetRdbSyncer(param); -} - -int RdbManagerImpl::RegisterRdbServiceDeathObserver(const std::string& storeName, - const std::function& observer) -{ - serviceDeathObservers_.Insert(storeName, observer); - return 0; -} - -int RdbManagerImpl::UnRegisterRdbServiceDeathObserver(const std::string& storeName) -{ - std::lock_guard lock(mutex_); - serviceDeathObservers_.Erase(storeName); - return 0; + if (((RdbServiceProxy *)service.GetRefPtr())->InitNotifier(param) != RDB_OK) { + ZLOGE("init notifier failed"); + return nullptr; + } + LinkToDeath(service->AsObject()); + rdbService_ = std::shared_ptr(service.GetRefPtr(), [holder = service] (const auto*) {}); + bundleName_ = param.bundleName_; + return rdbService_; } void RdbManagerImpl::OnRemoteDied() { ZLOGI("rdb service has dead!!"); - NotifyServiceDeath(); + auto proxy = std::static_pointer_cast(rdbService_); + auto observers = proxy->ExportObservers(); ResetServiceHandle(); + + std::this_thread::sleep_for(std::chrono::seconds(WAIT_TIME)); + RdbSyncerParam param; + param.bundleName_ = bundleName_; + auto service = GetRdbService(param); + if (service == nullptr) { + return; + } + proxy = std::static_pointer_cast(service); + if (proxy == nullptr) { + return; + } + ZLOGI("restore observer"); + proxy->ImportObservers(observers); } void RdbManagerImpl::ResetServiceHandle() @@ -131,33 +156,5 @@ void RdbManagerImpl::ResetServiceHandle() std::lock_guard lock(mutex_); distributedDataMgr_ = nullptr; rdbService_ = nullptr; - clientDeathObject_ = nullptr; -} - -void RdbManagerImpl::NotifyServiceDeath() -{ - ZLOGI("enter"); - serviceDeathObservers_.ForEach([] (const auto& key, const auto& value) { - if (value != nullptr) { - value(); - } - return false; - }); -} - -void RdbManagerImpl::RegisterClientDeathRecipient(const std::string& bundleName) -{ - std::lock_guard lock(mutex_); - if (clientDeathObject_ != nullptr) { - return; - } - if (rdbService_ != nullptr) { - sptr object = new(std::nothrow) RdbClientDeathRecipientStub(); - if (rdbService_->RegisterClientDeathRecipient(bundleName, object) != 0) { - ZLOGE("register client death recipient failed"); - } else { - clientDeathObject_ = object; - } - } } } diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_manager_impl.h b/frameworks/innerkitsimpl/rdb/src/rdb_manager_impl.h index cf7298ed3c4abe08341565f79ddf3929b858b3b3..95ea174c5db1b1caeec357a04b2512a3f14b7165 100644 --- a/frameworks/innerkitsimpl/rdb/src/rdb_manager_impl.h +++ b/frameworks/innerkitsimpl/rdb/src/rdb_manager_impl.h @@ -24,23 +24,25 @@ #include "iremote_object.h" #include "concurrent_map.h" #include "rdb_types.h" -#include "rdb_syncer.h" namespace OHOS::DistributedKv { -class IKvStoreDataService; +class KvStoreDataServiceProxy; } namespace OHOS::DistributedRdb { class RdbService; +class IRdbService; class RdbManagerImpl { public: + static constexpr int GET_SA_RETRY_TIMES = 3; + static constexpr int RETRY_INTERVAL = 1; + static constexpr int WAIT_TIME = 2; + static RdbManagerImpl &GetInstance(); - - std::shared_ptr GetRdbSyncer(const RdbSyncerParam& param); - - int RegisterRdbServiceDeathObserver(const std::string &storeName, const std::function& callback); - - int UnRegisterRdbServiceDeathObserver(const std::string &storeName); + + std::vector GetConnectDevices(); + + std::shared_ptr GetRdbService(const RdbSyncerParam& param); void OnRemoteDied(); @@ -61,21 +63,15 @@ private: RdbManagerImpl(); ~RdbManagerImpl(); - - std::shared_ptr GetRdbService(); - + + sptr GetRdbService(); + void ResetServiceHandle(); - - void NotifyServiceDeath(); - - void RegisterClientDeathRecipient(const std::string &bundleName); - + std::mutex mutex_; - sptr distributedDataMgr_; + sptr distributedDataMgr_; std::shared_ptr rdbService_; - sptr clientDeathObject_; - - ConcurrentMap> serviceDeathObservers_; + std::string bundleName_; }; } #endif diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_notifier.cpp b/frameworks/innerkitsimpl/rdb/src/rdb_notifier.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0893214aa8028df547b90ae6e809641f439533a1 --- /dev/null +++ b/frameworks/innerkitsimpl/rdb/src/rdb_notifier.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2022 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 "RdbNotifier" + +#include "rdb_notifier.h" +#include "itypes_util.h" +#include "log_print.h" + + +namespace OHOS::DistributedRdb { +RdbNotifierProxy::RdbNotifierProxy(const sptr &object) + : IRemoteProxy(object) +{ + ZLOGI("construct"); +} + +RdbNotifierProxy::~RdbNotifierProxy() noexcept +{ + ZLOGI("destroy"); +} + +int32_t RdbNotifierProxy::OnComplete(uint32_t seqNum, const SyncResult &result) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(IRdbNotifier::GetDescriptor())) { + ZLOGE("write descriptor failed"); + return RDB_ERROR; + } + if (!data.WriteUint32(seqNum)) { + ZLOGE("write seq num failed"); + return RDB_ERROR; + } + if (!DistributedKv::ITypesUtil::Marshalling(result, data)) { + return RDB_ERROR; + } + + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (Remote()->SendRequest(RDB_NOTIFIER_CMD_SYNC_COMPLETE, data, reply, option) != 0) { + ZLOGE("send request failed"); + return RDB_ERROR; + } + return RDB_OK; +} + +int RdbNotifierProxy::OnChange(const std::string& storeName, const std::vector &devices) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(IRdbNotifier::GetDescriptor())) { + ZLOGE("write descriptor failed"); + return RDB_ERROR; + } + if (!data.WriteString(storeName)) { + ZLOGE("write store name failed"); + return RDB_ERROR; + } + if (!data.WriteStringVector(devices)) { + ZLOGE("write devices failed"); + return RDB_ERROR; + } + + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (Remote()->SendRequest(RDB_NOTIFIER_CMD_DATA_CHANGE, data, reply, option) != 0) { + ZLOGE("send request failed"); + return RDB_ERROR; + } + return RDB_OK; +} + +RdbNotifierStub::RdbNotifierStub(const RdbSyncCompleteNotifier& completeNotifier, + const RdbDataChangeNotifier& changeNotifier) + : IRemoteStub(), completeNotifier_(completeNotifier), changeNotifier_(changeNotifier) +{ + ZLOGI("construct"); +} + +RdbNotifierStub::~RdbNotifierStub() noexcept +{ + ZLOGI("destroy"); +} + +bool RdbNotifierStub::CheckInterfaceToken(MessageParcel& data) +{ + auto localDescriptor = IRdbNotifier::GetDescriptor(); + auto remoteDescriptor = data.ReadInterfaceToken(); + if (remoteDescriptor != localDescriptor) { + ZLOGE("interface token is not equal"); + return false; + } + return true; +} + +int RdbNotifierStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + ZLOGI("code=%{public}u", code); + if (!CheckInterfaceToken(data)) { + return RDB_ERROR; + } + + if (code >= 0 && code < RDB_NOTIFIER_CMD_MAX) { + return (this->*HANDLES[code])(data, reply); + } + + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} + +int32_t RdbNotifierStub::OnCompleteInner(MessageParcel &data, MessageParcel &reply) +{ + uint32_t seqNum; + if (!data.ReadUint32(seqNum)) { + ZLOGI("read seq num failed"); + return RDB_ERROR; + } + SyncResult result; + if (!DistributedKv::ITypesUtil::UnMarshalling(data, result)) { + ZLOGE("read sync result failed"); + return RDB_ERROR; + } + return OnComplete(seqNum, result); +} + +int32_t RdbNotifierStub::OnComplete(uint32_t seqNum, const SyncResult &result) +{ + if (completeNotifier_) { + completeNotifier_(seqNum, result); + } + return RDB_OK; +} + +int32_t RdbNotifierStub::OnChangeInner(MessageParcel &data, MessageParcel &reply) +{ + std::string storeName; + if (!data.ReadString(storeName)) { + ZLOGE("read store name failed"); + return RDB_ERROR; + } + std::vector devices; + if (!data.ReadStringVector(&devices)) { + ZLOGE("read devices faield"); + return RDB_ERROR; + } + return OnChange(storeName, devices); +} + +int32_t RdbNotifierStub::OnChange(const std::string& storeName, const std::vector &devices) +{ + if (changeNotifier_) { + changeNotifier_(storeName, devices); + } + return RDB_OK; +} +} \ No newline at end of file diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_service_proxy.cpp b/frameworks/innerkitsimpl/rdb/src/rdb_service_proxy.cpp index ce63bdee0515a7eb17bd4ef2aadda7eca32147ea..3f1e9ec240521f0060bb5e34e0ab08d597f75c2e 100644 --- a/frameworks/innerkitsimpl/rdb/src/rdb_service_proxy.cpp +++ b/frameworks/innerkitsimpl/rdb/src/rdb_service_proxy.cpp @@ -16,7 +16,6 @@ #define LOG_TAG "RdbServiceProxy" #include "rdb_service_proxy.h" -#include "rdb_syncer.h" #include "itypes_util.h" #include "log_print.h" @@ -24,53 +23,381 @@ namespace OHOS::DistributedRdb { RdbServiceProxy::RdbServiceProxy(const sptr &object) : IRemoteProxy(object) { + ZLOGI("construct"); } -std::shared_ptr RdbServiceProxy::GetRdbSyncer(const RdbSyncerParam& param) +void RdbServiceProxy::OnSyncComplete(uint32_t seqNum, const SyncResult &result) +{ + syncCallbacks_.ComputeIfPresent(seqNum, [&result] (const auto& key, const SyncCallback& callback) { + callback(result); + }); + syncCallbacks_.Erase(seqNum); +} + +void RdbServiceProxy::OnDataChange(const std::string& storeName, const std::vector &devices) +{ + ZLOGI("%{public}s", storeName.c_str()); + observers_.ComputeIfPresent( + storeName, [&devices] (const auto& key, const ObserverMapValue& value) { + for (const auto& observer : value.first) { + observer->OnChange(devices); + } + }); +} + +std::string RdbServiceProxy::ObtainDistributedTableName(const std::string &device, const std::string &table) { MessageParcel data; if (!data.WriteInterfaceToken(IRdbService::GetDescriptor())) { ZLOGE("write descriptor failed"); - return nullptr; + return ""; + } + if (!data.WriteString(device)) { + ZLOGE("write device failed"); + return ""; + } + if (!data.WriteString(table)) { + ZLOGE("write table failed"); + return ""; + } + + MessageParcel reply; + MessageOption option; + if (Remote()->SendRequest(RDB_SERVICE_CMD_OBTAIN_TABLE, data, reply, option) != 0) { + ZLOGE("send request failed"); + return ""; + } + return reply.ReadString(); +} + +int32_t RdbServiceProxy::InitNotifier(const RdbSyncerParam& param) +{ + notifier_ = new (std::nothrow) RdbNotifierStub( + [this] (uint32_t seqNum, const SyncResult& result) { + OnSyncComplete(seqNum, result); + }, + [this] (const std::string& storeName, const std::vector& devices) { + OnDataChange(storeName, devices); + } + ); + if (notifier_ == nullptr) { + ZLOGE("create notifier failed"); + return RDB_ERROR; + } + + if (InitNotifier(param, notifier_->AsObject()) != RDB_OK) { + notifier_ = nullptr; + return RDB_ERROR; + } + + ZLOGI("success"); + return RDB_OK; +} + +int32_t RdbServiceProxy::InitNotifier(const RdbSyncerParam ¶m, const sptr notifier) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(IRdbService::GetDescriptor())) { + ZLOGE("write descriptor failed"); + return RDB_ERROR; } if (!DistributedKv::ITypesUtil::Marshalling(param, data)) { - return nullptr; + ZLOGE("write param failed"); + return RDB_ERROR; } - + if (!data.WriteRemoteObject(notifier)) { + ZLOGE("write notifier failed"); + return RDB_ERROR; + } + MessageParcel reply; MessageOption option; - if (Remote()->SendRequest(RDB_SERVICE_CMD_GET_SYNCER, data, reply, option) != 0) { + if (Remote()->SendRequest(RDB_SERVICE_CMD_INIT_NOTIFIER, data, reply, option) != 0) { + ZLOGE("send request failed"); + return RDB_ERROR; + } + + int32_t res = RDB_ERROR; + return reply.ReadInt32(res) ? res : RDB_ERROR; +} + +uint32_t RdbServiceProxy::GetSeqNum() +{ + return seqNum_++; +} + +int32_t RdbServiceProxy::DoSync(const RdbSyncerParam& param, const SyncOption &option, + const RdbPredicates &predicates, SyncResult& result) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(IRdbService::GetDescriptor())) { + ZLOGE("write descriptor failed"); + return RDB_ERROR; + } + if (!DistributedKv::ITypesUtil::Marshalling(param, data)) { + ZLOGE("write param failed"); + return RDB_ERROR; + } + if (!DistributedKv::ITypesUtil::Marshalling(option, data)) { + ZLOGE("write option failed"); + return RDB_ERROR; + } + if (!DistributedKv::ITypesUtil::Marshalling(predicates, data)) { + ZLOGE("write predicates failed"); + } + + MessageParcel reply; + MessageOption opt; + if (Remote()->SendRequest(RDB_SERVICE_CMD_SYNC, data, reply, opt) != 0) { ZLOGE("send request failed"); - return nullptr; + return RDB_ERROR; + } + + if (!DistributedKv::ITypesUtil::UnMarshalling(reply, result)) { + ZLOGE("read result failed"); + return RDB_ERROR; + } + return RDB_OK; +} + +int32_t RdbServiceProxy::DoSync(const RdbSyncerParam& param, const SyncOption &option, + const RdbPredicates &predicates, const SyncCallback& callback) +{ + SyncResult result; + if (DoSync(param, option, predicates, result) != RDB_OK) { + ZLOGI("failed"); + return RDB_ERROR; + } + ZLOGI("success"); + + if (callback != nullptr) { + callback(result); + } + return RDB_OK; +} + +int32_t RdbServiceProxy::DoAsync(const RdbSyncerParam& param, uint32_t seqNum, const SyncOption &option, + const RdbPredicates &predicates) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(IRdbService::GetDescriptor())) { + ZLOGE("write descriptor failed"); + return RDB_ERROR; + } + if (!DistributedKv::ITypesUtil::Marshalling(param, data)) { + ZLOGE("write param failed"); + return RDB_ERROR; + } + if (!data.WriteInt32(seqNum)) { + ZLOGE("write seq num failed"); + return RDB_ERROR; + } + if (!DistributedKv::ITypesUtil::Marshalling(option, data)) { + ZLOGE("write option failed"); + return RDB_ERROR; + } + if (!DistributedKv::ITypesUtil::Marshalling(predicates, data)) { + ZLOGE("write predicates failed"); + } + + MessageParcel reply; + MessageOption opt; + if (Remote()->SendRequest(RDB_SERVICE_CMD_ASYNC, data, reply, opt) != 0) { + ZLOGE("send request failed"); + return RDB_ERROR; + } + + int32_t res = RDB_ERROR; + return reply.ReadInt32(res) ? res : RDB_ERROR; +} + +int32_t RdbServiceProxy::DoAsync(const RdbSyncerParam& param, const SyncOption &option, + const RdbPredicates &predicates, const SyncCallback& callback) +{ + uint32_t num = GetSeqNum(); + if (!syncCallbacks_.Insert(num, callback)) { + ZLOGI("insert callback failed"); + return RDB_ERROR; + } + ZLOGI("num=%{public}u", num); + + if (DoAsync(param, num, option, predicates) != RDB_OK) { + ZLOGE("failed"); + syncCallbacks_.Erase(num); + return RDB_ERROR; } - auto remoteObject = reply.ReadRemoteObject(); - auto syncer = iface_cast(remoteObject); - return std::shared_ptr(syncer.GetRefPtr(), [holder = syncer] (const auto*) {}); + ZLOGI("success"); + return RDB_OK; +} + +std::vector RdbServiceProxy::GetConnectDevices() +{ + MessageParcel data; + if (!data.WriteInterfaceToken(IRdbService::GetDescriptor())) { + ZLOGE("write descriptor failed"); + return {}; + } + + MessageParcel reply; + MessageOption option; + if (Remote()->SendRequest(RDB_SERVICE_CMD_GET_DEVICES, data, reply, option) != 0) { + ZLOGE("send request failed"); + return {}; + } + + std::vector devices; + if (!reply.ReadStringVector(&devices)) { + ZLOGE("read devices failed"); + return {}; + } + + ZLOGI("success"); + return devices; +} + +int32_t RdbServiceProxy::SetDistributedTables(const RdbSyncerParam& param, const std::vector &tables) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(IRdbService::GetDescriptor())) { + ZLOGE("write descriptor failed"); + return RDB_ERROR; + } + if (!DistributedKv::ITypesUtil::Marshalling(param, data)) { + ZLOGE("write param failed"); + return RDB_ERROR; + } + if (!data.WriteStringVector(tables)) { + ZLOGE("write tables failed"); + return RDB_ERROR; + } + + MessageParcel reply; + MessageOption option; + if (Remote()->SendRequest(RDB_SERVICE_CMD_SET_DIST_TABLE, data, reply, option) != 0) { + ZLOGE("send request failed"); + return RDB_ERROR; + } + + int32_t res = RDB_ERROR; + return reply.ReadInt32(res) ? res : RDB_ERROR; } -int RdbServiceProxy::RegisterClientDeathRecipient(const std::string& bundleName, sptr object) +int32_t RdbServiceProxy::Sync(const RdbSyncerParam& param, const SyncOption &option, + const RdbPredicates &predicates, const SyncCallback &callback) +{ + if (option.isBlock) { + return DoSync(param, option, predicates, callback); + } + return DoAsync(param, option, predicates, callback); +} + +int32_t RdbServiceProxy::Subscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, + RdbStoreObserver *observer) +{ + if (option.mode != SubscribeMode::REMOTE) { + ZLOGE("subscribe mode invalid"); + return RDB_ERROR; + } + if (DoSubscribe(param) != RDB_OK) { + ZLOGI("communicate to server failed"); + return RDB_ERROR; + } + observers_.Compute( + param.storeName_, [observer] (const auto& key, ObserverMapValue& value) { + for (const auto& element : value.first) { + if (element == observer) { + ZLOGE("duplicate observer"); + return false; + } + } + value.first.push_back(observer); + return true; + }); + return RDB_OK; +} + +int32_t RdbServiceProxy::DoSubscribe(const RdbSyncerParam ¶m) { MessageParcel data; if (!data.WriteInterfaceToken(IRdbService::GetDescriptor())) { ZLOGE("write descriptor failed"); - return -1; + return RDB_ERROR; } - if (!data.WriteString(bundleName)) { - ZLOGE("write bundle name failed"); - return -1; + if (!DistributedKv::ITypesUtil::Marshalling(param, data)) { + ZLOGE("write param failed"); + return RDB_ERROR; } - if (!data.WriteRemoteObject(object)) { - ZLOGE("write remote object failed"); - return -1; + + MessageParcel reply; + MessageOption option; + if (Remote()->SendRequest(RDB_SERVICE_CMD_SUBSCRIBE, data, reply, option) != 0) { + ZLOGE("send request failed"); + return RDB_ERROR; } + + int32_t res = RDB_ERROR; + return reply.ReadInt32(res) ? res : RDB_ERROR; +} + +int32_t RdbServiceProxy::UnSubscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, + RdbStoreObserver *observer) +{ + DoUnSubscribe(param); + bool canErase = false; + observers_.ComputeIfPresent( + param.storeName_, [observer, &canErase](const auto& key, ObserverMapValue& value) { + ZLOGI("before remove size=%{public}d", static_cast(value.first.size())); + value.first.remove(observer); + ZLOGI("after remove size=%{public}d", static_cast(value.first.size())); + if (value.first.empty()) { + canErase = true; + } + }); + + if (canErase) { + observers_.Erase(param.storeName_); + } + return RDB_OK; +} + +int32_t RdbServiceProxy::DoUnSubscribe(const RdbSyncerParam ¶m) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(IRdbService::GetDescriptor())) { + ZLOGE("write descriptor failed"); + return RDB_ERROR; + } + if (!DistributedKv::ITypesUtil::Marshalling(param, data)) { + ZLOGE("write param failed"); + return RDB_ERROR; + } + MessageParcel reply; MessageOption option; - if (Remote()->SendRequest(RDB_SERVICE_CMD_REGISTER_CLIENT_DEATH, data, reply, option) != 0) { + if (Remote()->SendRequest(RDB_SERVICE_CMD_UNSUBSCRIBE, data, reply, option) != 0) { ZLOGE("send request failed"); - return -1; + return RDB_ERROR; } - int32_t res = -1; - return reply.ReadInt32(res) ? res : -1; + + int32_t res = RDB_ERROR; + return reply.ReadInt32(res) ? res : RDB_ERROR; +} + +RdbServiceProxy::ObserverMap RdbServiceProxy::ExportObservers() +{ + return observers_; +} + +void RdbServiceProxy::ImportObservers(ObserverMap &observers) +{ + ZLOGI("enter"); + SubscribeOption option {SubscribeMode::REMOTE}; + observers.ForEach([this, &option](const std::string& key, const ObserverMapValue& value) { + for (auto& observer : value.first) { + Subscribe(value.second, option, observer); + } + return false; + }); } } \ No newline at end of file diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_service_proxy.h b/frameworks/innerkitsimpl/rdb/src/rdb_service_proxy.h index 5dab528a8c0894abd6c69de7316efdbc6d35dce1..29dab88f95b4d6e1addd630189b1c7058d473980 100644 --- a/frameworks/innerkitsimpl/rdb/src/rdb_service_proxy.h +++ b/frameworks/innerkitsimpl/rdb/src/rdb_service_proxy.h @@ -16,20 +16,73 @@ #ifndef DISTRIBUTED_RDB_SERVICE_PROXY_H #define DISTRIBUTED_RDB_SERVICE_PROXY_H +#include +#include #include #include "irdb_service.h" +#include "rdb_notifier.h" +#include "concurrent_map.h" namespace OHOS::DistributedRdb { class RdbServiceProxy : public IRemoteProxy { public: + using ObserverMapValue = std::pair, RdbSyncerParam>; + using ObserverMap = ConcurrentMap; + explicit RdbServiceProxy(const sptr& object); + + std::string ObtainDistributedTableName(const std::string& device, const std::string& table) override; + + std::vector GetConnectDevices() override; + + int32_t InitNotifier(const RdbSyncerParam& param); + int32_t InitNotifier(const RdbSyncerParam& param, const sptr notifier) override; - std::shared_ptr GetRdbSyncer(const RdbSyncerParam& param) override; + int32_t SetDistributedTables(const RdbSyncerParam& param, const std::vector& tables) override; - int RegisterClientDeathRecipient(const std::string& bundleName, sptr object) override; + int32_t Sync(const RdbSyncerParam& param, const SyncOption& option, + const RdbPredicates& predicates, const SyncCallback& callback) override; + + int32_t Subscribe(const RdbSyncerParam& param, const SubscribeOption& option, + RdbStoreObserver *observer) override; + + int32_t UnSubscribe(const RdbSyncerParam& param, const SubscribeOption& option, + RdbStoreObserver *observer) override; + + ObserverMap ExportObservers(); + + void ImportObservers(ObserverMap& observers); + +protected: + int32_t DoSync(const RdbSyncerParam& param, const SyncOption& option, + const RdbPredicates& predicates, SyncResult& result) override; + + int32_t DoAsync(const RdbSyncerParam& param, uint32_t seqNum, const SyncOption& option, + const RdbPredicates& predicates) override; + + int32_t DoSubscribe(const RdbSyncerParam& param) override; + + int32_t DoUnSubscribe(const RdbSyncerParam& param) override; private: + uint32_t GetSeqNum(); + int32_t DoSync(const RdbSyncerParam& param, const SyncOption& option, + const RdbPredicates& predicates, const SyncCallback& callback); + + int32_t DoAsync(const RdbSyncerParam& param, const SyncOption& option, + const RdbPredicates& predicates, const SyncCallback& callback); + + void OnSyncComplete(uint32_t seqNum, const SyncResult& result); + + void OnDataChange(const std::string& storeName, const std::vector& devices); + + std::atomic seqNum_ {}; + + ConcurrentMap syncCallbacks_; + ObserverMap observers_; + sptr notifier_; + static inline BrokerDelegator delegator_; }; } diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_service_stub.cpp b/frameworks/innerkitsimpl/rdb/src/rdb_service_stub.cpp deleted file mode 100644 index 17808369ff7a0595f074e94bf1274dffbeb0a7a8..0000000000000000000000000000000000000000 --- a/frameworks/innerkitsimpl/rdb/src/rdb_service_stub.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2022 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 "RdbServiceStub" - -#include "rdb_service_stub.h" -#include "log_print.h" -#include "irdb_syncer.h" -#include "itypes_util.h" - -namespace OHOS::DistributedRdb { -int RdbServiceStub::OnRemoteGetRdbSyncer(MessageParcel& data, MessageParcel& reply) -{ - RdbSyncerParam param; - sptr store; - if (DistributedKv::ITypesUtil::UnMarshalling(data, param)) { - store = GetRdbSyncerInner(param); - } - reply.WriteRemoteObject(store->AsObject().GetRefPtr()); - return 0; -} - -int RdbServiceStub::OnRemoteRegisterClientDeathRecipient(MessageParcel &data, MessageParcel &reply) -{ - std::string bundleName = data.ReadString(); - auto remoteObject = data.ReadRemoteObject(); - reply.WriteInt32(RegisterClientDeathRecipient(bundleName, remoteObject)); - return 0; -} - -bool RdbServiceStub::CheckInterfaceToken(MessageParcel& data) -{ - auto localDescriptor = IRdbService::GetDescriptor(); - auto remoteDescriptor = data.ReadInterfaceToken(); - if (remoteDescriptor != localDescriptor) { - ZLOGE("interface token is not equal"); - return false; - } - return true; -} -int RdbServiceStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) -{ - ZLOGI("code=%{public}d", code); - if (!CheckInterfaceToken(data)) { - return -1; - } - if (code >= 0 && code < RDB_SERVICE_CMD_MAX) { - return (this->*HANDLES[code])(data, reply); - } - return IPCObjectStub::OnRemoteRequest(code, data, reply, option); -} -} \ No newline at end of file diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_syncer_proxy.cpp b/frameworks/innerkitsimpl/rdb/src/rdb_syncer_proxy.cpp deleted file mode 100644 index ede9735a84ae6a842af7beb86da5ddd27a7bbd56..0000000000000000000000000000000000000000 --- a/frameworks/innerkitsimpl/rdb/src/rdb_syncer_proxy.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2022 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 "rdb_syncer_proxy.h" - -#define LOG_TAG "RdbSyncerProxy" -#include "log_print.h" - -namespace OHOS::DistributedRdb { -RdbSyncerProxy::RdbSyncerProxy(const sptr &object) - : IRemoteProxy(object) -{ -} - -int RdbSyncerProxy::SetDistributedTables(const std::vector &tables) -{ - MessageParcel data; - if (!data.WriteInterfaceToken(IRdbSyncer::GetDescriptor())) { - ZLOGE("write descriptor failed"); - return -1; - } - if (!data.WriteStringVector(tables)) { - ZLOGE("write tables failed"); - return -1; - } - - MessageParcel reply; - MessageOption option; - if (Remote()->SendRequest(RDB_SYNCER_CMD_SET_DIST_TABLES, data, reply, option) != 0) { - ZLOGE("send request failed"); - return -1; - } - - int32_t res = -1; - return reply.ReadInt32(res) ? res : -1; -} -} - diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_syncer_stub.cpp b/frameworks/innerkitsimpl/rdb/src/rdb_syncer_stub.cpp deleted file mode 100644 index 001a4cc5fa616505d2318840d4b4fb694529b444..0000000000000000000000000000000000000000 --- a/frameworks/innerkitsimpl/rdb/src/rdb_syncer_stub.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2022 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 "RdbSyncerStub" - -#include "rdb_syncer_stub.h" -#include "log_print.h" - -namespace OHOS::DistributedRdb { -int RdbSyncerStub::OnRemoteSetDistributedTables(MessageParcel &data, MessageParcel &reply) -{ - std::vector tables; - data.ReadStringVector(&tables); - reply.WriteInt32(SetDistributedTables(tables)); - return 0; -} - -bool RdbSyncerStub::CheckInterfaceToken(MessageParcel& data) -{ - auto localDescriptor = IRdbSyncer::GetDescriptor(); - auto remoteDescriptor = data.ReadInterfaceToken(); - if (remoteDescriptor != localDescriptor) { - ZLOGE("interface token is not equal"); - return false; - } - return true; -} - -int RdbSyncerStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) -{ - ZLOGI("%{public}d", code); - if (!CheckInterfaceToken(data)) { - return -1; - } - if (code >= 0 && code < RDB_SYNCER_CMD_MAX) { - return (this->*HANDLERS[code])(data, reply); - } - return IPCObjectStub::OnRemoteRequest(code, data, reply, option); -} -} - diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_syncer_stub.h b/frameworks/innerkitsimpl/rdb/src/rdb_syncer_stub.h deleted file mode 100644 index 8c72560fc78829f7a09b0319f016cdf9418aac5f..0000000000000000000000000000000000000000 --- a/frameworks/innerkitsimpl/rdb/src/rdb_syncer_stub.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2022 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 DISTRIBUTED_RDB_SYNCER_STUB_H -#define DISTRIBUTED_RDB_SYNCER_STUB_H - -#include -#include "irdb_syncer.h" - -namespace OHOS::DistributedRdb { -class RdbSyncerStub : public IRemoteStub { -public: - int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; - -private: - static bool CheckInterfaceToken(MessageParcel& data); - - int OnRemoteSetDistributedTables(MessageParcel &data, MessageParcel &reply); - - using RequestHandle = int (RdbSyncerStub::*)(MessageParcel &, MessageParcel &); - static constexpr RequestHandle HANDLERS[RDB_SYNCER_CMD_MAX] = { - [RDB_SYNCER_CMD_SET_DIST_TABLES] = &RdbSyncerStub::OnRemoteSetDistributedTables, - }; -}; -} -#endif diff --git a/interfaces/innerkits/distributeddata/BUILD.gn b/interfaces/innerkits/distributeddata/BUILD.gn index b53e0e84edfbc339ca7c4166b8ab3761c4b1712c..b2163c61c4aa35b5f7c210b52b4da1a4478ca35c 100755 --- a/interfaces/innerkits/distributeddata/BUILD.gn +++ b/interfaces/innerkits/distributeddata/BUILD.gn @@ -77,13 +77,10 @@ ohos_shared_library("distributeddata_inner") { ] rdb_sources = [ - "../../../frameworks/innerkitsimpl/rdb/src/rdb_client_death_recipient.cpp", "../../../frameworks/innerkitsimpl/rdb/src/rdb_manager.cpp", "../../../frameworks/innerkitsimpl/rdb/src/rdb_manager_impl.cpp", + "../../../frameworks/innerkitsimpl/rdb/src/rdb_notifier.cpp", "../../../frameworks/innerkitsimpl/rdb/src/rdb_service_proxy.cpp", - "../../../frameworks/innerkitsimpl/rdb/src/rdb_service_stub.cpp", - "../../../frameworks/innerkitsimpl/rdb/src/rdb_syncer_proxy.cpp", - "../../../frameworks/innerkitsimpl/rdb/src/rdb_syncer_stub.cpp", ] sources = kvdb_sources + rdb_sources diff --git a/services/distributeddataservice/adapter/BUILD.gn b/services/distributeddataservice/adapter/BUILD.gn index 99ed4c66222d61b122bd140b8afc671413f9bb96..e770a62d1a2182144412ccf7a09b832f41a7bd56 100755 --- a/services/distributeddataservice/adapter/BUILD.gn +++ b/services/distributeddataservice/adapter/BUILD.gn @@ -32,7 +32,6 @@ config("distributeddata_adapter_public_config") { "include/autils", "include/utils", "include", - "include/security", "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/app_distributeddata/include", "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata/include/", "//foundation/distributeddatamgr/distributeddatamgr/frameworks/common", @@ -48,7 +47,6 @@ ohos_shared_library("distributeddata_adapter") { "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/autils:distributeddata_autils_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/communicator:distributeddata_communicator_static", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/dfx:distributeddata_dfx_static", - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/security:distributeddata_security_static", ] external_deps = [ "hiviewdfx_hilog_native:libhilog" ] diff --git a/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp b/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp index ab041e915f2f9e67e459fa085f67b5e0220faa0b..26778960e2ec2865f399b14a0d3fe87ad6f5a5d8 100755 --- a/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp +++ b/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp @@ -404,6 +404,7 @@ std::string SoftBusAdapter::ToUUID(const std::string& id) const return ""; } +// id is return of default value std::string SoftBusAdapter::ToNodeID(const std::string& id, const std::string &nodeId) const { { @@ -413,7 +414,7 @@ std::string SoftBusAdapter::ToNodeID(const std::string& id, const std::string &n if (nodeId == (std::get<0>(tup))) { // id is uuid return e.first; } - if (id == (std::get<1>(tup))) { // id is udid + if (nodeId == (std::get<1>(tup))) { // id is udid return e.first; } } @@ -423,7 +424,7 @@ std::string SoftBusAdapter::ToNodeID(const std::string& id, const std::string &n std::vector devices; NodeBasicInfo *info = nullptr; int32_t infoNum = 0; - std::string networkId; + std::string networkId = id; int32_t ret = GetAllNodeDeviceInfo("ohos.distributeddata", &info, &infoNum); if (ret == SOFTBUS_OK) { lock_guard lock(networkMutex_); diff --git a/services/distributeddataservice/adapter/include/security/security_adapter.h b/services/distributeddataservice/adapter/include/security/security_adapter.h deleted file mode 100755 index 08ab9d4d9f9677cc4a4c6d21f43bc4e1e1cc444d..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/adapter/include/security/security_adapter.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2021 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_SECURITY_ADAPTER_H -#define OHOS_SECURITY_ADAPTER_H - -#include "visibility.h" -namespace OHOS::DistributedKv { -KVSTORE_API void InitSecurityAdapter(); -} -#endif // OHOS_SECURITY_ADAPTER_H diff --git a/services/distributeddataservice/adapter/security/BUILD.gn b/services/distributeddataservice/adapter/security/BUILD.gn deleted file mode 100755 index 5b0f6a3a272286cabe598da297913226313bdad3..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/adapter/security/BUILD.gn +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (c) 2021 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. - -import("//build/ohos.gni") - -ohos_static_library("distributeddata_security_static") { - sources = [ - "src/security.cpp", - "src/security_adapter.cpp", - "src/sensitive.cpp", - ] - - cflags_cc = [ "-fvisibility=hidden" ] - - include_dirs = [ - "../include/autils", - "../include/log", - "../include/security", - "../include/communicator", - "//foundation/distributeddatamgr/distributeddatamgr/frameworks/common", - "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/app_distributeddata/include", - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework/include", - ] - - deps = [ - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework:distributeddatasvcfwk", - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/libs/distributeddb:distributeddb", - "//utils/native/base:utils", - ] - - external_deps = [ - "dsoftbus_standard:softbus_client", - "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_core", - "os_account_standard:libaccountkits", - ] -} diff --git a/services/distributeddataservice/adapter/security/src/security_adapter.cpp b/services/distributeddataservice/adapter/security/src/security_adapter.cpp deleted file mode 100755 index 377dc1917c0515cc584019a78c3edbd844c38505..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/adapter/security/src/security_adapter.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2021 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 "security_adapter.h" -#include "log_print.h" -#include "security.h" -#undef LOG_TAG -#define LOG_TAG "SecurityAdapter" - -namespace OHOS::DistributedKv { -namespace { -class InstallDevsl { -public: - InstallDevsl(); - ~InstallDevsl(); - void Initialize(); -private: - std::shared_ptr security_ = nullptr; -}; - -InstallDevsl::InstallDevsl() -{ - security_ = std::make_shared("distributeddata", "default", "/data/misc_de/0/mdds/Meta"); - if (security_ == nullptr) { - ZLOGD("Security is nullptr."); - return; - } - - auto status = DistributedDB::KvStoreDelegateManager::SetProcessSystemAPIAdapter(security_); - ZLOGD("set distributed db system api adapter: %d.", static_cast(status)); -} - -InstallDevsl::~InstallDevsl() -{ -} - -void InstallDevsl::Initialize() -{ - return; -} -__attribute__((used)) InstallDevsl g_installDevsl; -} - -KVSTORE_API void InitSecurityAdapter() -{ - if (!Security::IsFirstInit()) { - ZLOGD("Security is already inited."); - return; - } - - g_installDevsl.Initialize(); - ZLOGD("Security init finished!"); -} -} diff --git a/services/distributeddataservice/app/BUILD.gn b/services/distributeddataservice/app/BUILD.gn index 6e830702acfa4e9b49fbe3174706508724b8cc7d..bd096dbe86458899118a2d00f9f877e7068ae0a6 100755 --- a/services/distributeddataservice/app/BUILD.gn +++ b/services/distributeddataservice/app/BUILD.gn @@ -45,21 +45,22 @@ config("module_private_config") { "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework/include", "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/rdb/include", "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/rdb/src", - "//foundation/distributeddatamgr/distributeddatamgr/services/rdb", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/rdb", "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/app_distributeddata/include", + "//foundation/filemanagement/file_api/interfaces/innerkits/include", "//utils/system/safwk/native/include", "../adapter/include/account", "../adapter/include/permission", "../adapter/include/uninstaller", "../adapter/include/broadcaster", "../adapter/include/utils", - "../adapter/include/security", "../adapter/include", # for ipc_core interfaces. "//utils/native/base/include", "include", "src", + "src/security", "//third_party/json/single_include", "//base/security/permission/interfaces/innerkits/permission_standard/permissionsdk/main/cpp/include", "//base/security/huks/interfaces/innerkits/huks_standard/main/include", @@ -89,14 +90,16 @@ ohos_shared_library("distributeddataservice") { "src/kvstore_sync_manager.cpp", "src/kvstore_user_manager.cpp", "src/query_helper.cpp", + "src/security/security.cpp", + "src/security/sensitive.cpp", "src/single_kvstore_impl.cpp", ] rdb_sources = [ - "../../rdb/rdb_device_syncer.cpp", - "../../rdb/rdb_service_impl.cpp", - "../../rdb/rdb_syncer_factory.cpp", - "../../rdb/rdb_syncer_impl.cpp", + "../service/rdb/rdb_service_impl.cpp", + "../service/rdb/rdb_service_stub.cpp", + "../service/rdb/rdb_store_observer_impl.cpp", + "../service/rdb/rdb_syncer.cpp", ] sources += rdb_sources @@ -124,6 +127,7 @@ ohos_shared_library("distributeddataservice") { "battery_manager_native:batterysrv_client", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", + "dataclassification:data_transit_mgr", "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", diff --git a/services/distributeddataservice/app/src/kvstore_data_service.cpp b/services/distributeddataservice/app/src/kvstore_data_service.cpp index 98135ed8e223d85228cd59941ea5fa146c09ebff..41ee80e4aeaffe23ba9a30ef65ab9bca0e53aed2 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -93,6 +93,7 @@ void KvStoreDataService::Initialize() #ifndef UT_TEST KvStoreDelegateManager::SetProcessLabel(Bootstrap::GetInstance().GetProcessLabel(), "default"); #endif + InitSecurityAdapter(); KvStoreMetaManager::GetInstance().InitMetaParameter(); std::thread th = std::thread([]() { auto communicator = std::make_shared(); @@ -871,8 +872,7 @@ void KvStoreDataService::StartService() ZLOGI("autoLaunchRequestCallback start"); auto autoLaunchRequestCallback = [this](const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) -> bool { - ResolveAutoLaunchParamByIdentifier(identifier, param); - return true; + return ResolveAutoLaunchParamByIdentifier(identifier, param); }; KvStoreDelegateManager::SetAutoLaunchRequestCallback(autoLaunchRequestCallback); @@ -887,7 +887,7 @@ void KvStoreDataService::StartService() ZLOGI("Publish ret: %d", static_cast(ret)); } -void KvStoreDataService::ResolveAutoLaunchParamByIdentifier(const std::string &identifier, +bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) { ZLOGI("start"); @@ -918,16 +918,19 @@ void KvStoreDataService::ResolveAutoLaunchParamByIdentifier(const std::string &i param.appId = entry.second.kvStoreMetaData.appId; param.storeId = entry.second.kvStoreMetaData.storeId; param.option = option; + return true; } } } + ZLOGI("not find identifier"); + return false; } bool KvStoreDataService::CheckPermissions(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) const { - ZLOGI("userId=%.6s appId=%s storeId=%s flag=%d deviceId=%.4s", userId.c_str(), appId.c_str(), storeId.c_str(), flag, - deviceId.c_str()); // only print 4 chars of device id + ZLOGI("userId=%{public}.6s appId=%{public}s storeId=%{public}s flag=%{public}d deviceId=%{public}.4s", + userId.c_str(), appId.c_str(), storeId.c_str(), flag, deviceId.c_str()); // only print 4 chars of device id auto &instance = KvStoreMetaManager::GetInstance(); KvStoreMetaData metaData; auto localDevId = DeviceKvStoreImpl::GetLocalDeviceId(); @@ -1125,6 +1128,25 @@ Status KvStoreDataService::GetDeviceList(std::vector &deviceInfoList return Status::SUCCESS; } +void KvStoreDataService::InitSecurityAdapter() +{ + auto ret = DATASL_OnStart(); + ZLOGI("datasl on start ret:%d", ret); + security_ = std::make_shared(); + if (security_ == nullptr) { + ZLOGD("Security is nullptr."); + return; + } + + auto dbStatus = DistributedDB::KvStoreDelegateManager::SetProcessSystemAPIAdapter(security_); + ZLOGD("set distributed db system api adapter: %d.", static_cast(dbStatus)); + + auto status = KvStoreUtils::GetProviderInstance().StartWatchDeviceChange(security_.get(), {"security"}); + if (status != AppDistributedKv::Status::SUCCESS) { + ZLOGD("security register device change failed, status:%d", static_cast(status)); + } +} + Status KvStoreDataService::StartWatchDeviceChange(sptr observer, DeviceFilterStrategy strategy) { diff --git a/services/distributeddataservice/app/src/kvstore_data_service.h b/services/distributeddataservice/app/src/kvstore_data_service.h index 0ec6dcdaf03fc99147af03f91b6c67529a256cd3..ad981ff9f9fa56c55600fd537942e93cebed3689 100755 --- a/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/services/distributeddataservice/app/src/kvstore_data_service.h @@ -30,6 +30,7 @@ #include "account_delegate.h" #include "backup_handler.h" #include "device_change_listener_impl.h" +#include "security/security.h" namespace OHOS::DistributedRdb { class IRdbService; @@ -134,6 +135,8 @@ private: void StartService(); + void InitSecurityAdapter(); + Status DeleteKvStore(const std::string &bundleName, const StoreId &storeId); template @@ -157,7 +160,7 @@ private: bool CheckPermissions(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) const; - void ResolveAutoLaunchParamByIdentifier(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); + bool ResolveAutoLaunchParamByIdentifier(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); bool CheckOptions(const Options &options, const std::vector &metaKey) const; @@ -174,7 +177,8 @@ private: std::map> deviceListeners_; std::mutex deviceListenerMutex_; std::shared_ptr deviceListener_; - + + std::shared_ptr security_; sptr rdbService_; }; diff --git a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp index 046808d08cf05cc1ecded12f02fbc78634682e05..5cba848d37ed69940e6942f2605ab67e7246169c 100755 --- a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -21,7 +21,6 @@ #include #include #include -#include "security_adapter.h" #include "hks_api.h" #include "hks_param.h" #include "account_delegate.h" @@ -34,6 +33,7 @@ #include "directory_utils.h" #include "kvstore_app_manager.h" #include "utils/crypto.h" +#include "rdb_types.h" namespace OHOS { namespace DistributedKv { @@ -1032,7 +1032,7 @@ Status KvStoreMetaManager::QueryKvStoreMetaDataByDeviceIdAndAppId(const std::str } } - ZLOGW("find meta failed id:%s.", appId.c_str()); + ZLOGW("find meta failed id: %{public}s", appId.c_str()); return Status::ERROR; } @@ -1155,7 +1155,7 @@ void SecretKeyMetaData::Unmarshal(const nlohmann::json &jObject) kvStoreType = Serializable::GetVal(jObject, KVSTORE_TYPE, json::value_t::number_unsigned, kvStoreType); } -bool KvStoreMetaManager::GetFullMetaData(std::map &entries) +bool KvStoreMetaManager::GetFullMetaData(std::map &entries, enum DatabaseType type) { ZLOGI("start"); auto &metaDelegate = GetMetaKvStore(); @@ -1177,8 +1177,8 @@ bool KvStoreMetaManager::GetFullMetaData(std::map &entrie auto metaObj = Serializable::ToJson(jsonStr); MetaData metaData {0}; metaData.kvStoreType = MetaData::GetKvStoreType(metaObj); - if (metaData.kvStoreType == KvStoreType::INVALID_TYPE) { - ZLOGE("Failed to find KVSTORE_TYPE in jsonStr."); + if (!(type == KVDB && metaData.kvStoreType < KvStoreType::INVALID_TYPE) && + !(type == RDB && metaData.kvStoreType >= DistributedRdb::RdbDistributedType::RDB_DEVICE_COLLABORATION)) { continue; } diff --git a/services/distributeddataservice/app/src/kvstore_meta_manager.h b/services/distributeddataservice/app/src/kvstore_meta_manager.h index 413910b6cdb13cfc97808863b577eb25fb6d1ddb..c67d6b70cfe92e9831b4372e533f02a9d69b1c24 100755 --- a/services/distributeddataservice/app/src/kvstore_meta_manager.h +++ b/services/distributeddataservice/app/src/kvstore_meta_manager.h @@ -146,6 +146,10 @@ private: class KvStoreMetaManager { public: static constexpr uint32_t META_STORE_VERSION = 0x03000001; + enum DatabaseType { + KVDB, + RDB, + }; using NbDelegate = std::unique_ptr>; @@ -228,7 +232,7 @@ public: bool GetKvStoreMetaDataByAppId(const std::string &appId, KvStoreMetaData &metaData); - bool GetFullMetaData(std::map &entries); + bool GetFullMetaData(std::map &entries, enum DatabaseType type = KVDB); private: NbDelegate CreateMetaKvStore(); diff --git a/services/distributeddataservice/adapter/security/src/security.cpp b/services/distributeddataservice/app/src/security/security.cpp old mode 100755 new mode 100644 similarity index 52% rename from services/distributeddataservice/adapter/security/src/security.cpp rename to services/distributeddataservice/app/src/security/security.cpp index 7ab087ff89f2b3066784a83f41d7e6c8d48e1242..e22d4703fbb0d8b2e2af6fecb3dbbdb088b3d046 --- a/services/distributeddataservice/adapter/security/src/security.cpp +++ b/services/distributeddataservice/app/src/security/security.cpp @@ -1,263 +1,261 @@ -/* - * Copyright (c) 2021 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 "security.h" - -#include -#include - -#include "communication_provider.h" -#include "constant.h" -#include "log_print.h" -#include "ohos_account_kits.h" -#include "sensitive.h" -#include "utils/block_integer.h" - -#undef LOG_TAG -#define LOG_TAG "SecurityAdapter" -namespace OHOS::DistributedKv { -using namespace DistributedDB; -using BlockInteger = OHOS::DistributedData::BlockInteger; -std::atomic_bool Security::isInitialized_ = true; -const char * const Security::LABEL_VALUES[S4 + 1] = {}; -const char * const Security::DATA_DE[] = { nullptr }; -const char * const Security::DATA_CE[] = { nullptr }; - -Security::Security(const std::string &appId, const std::string &userId, const std::string &dir) -{ - ZLOGD("constructor kvStore_ is %s", dir.c_str()); -} - -Security::~Security() -{ - ZLOGD("destructor kvStore_"); -} - -DBStatus Security::RegOnAccessControlledEvent(const OnAccessControlledEvent &callback) -{ - ZLOGD("add new lock status observer! current size: %d", static_cast(observers_.size())); - if (callback == nullptr) { - return INVALID_ARGS; - } - - if (!IsSupportSecurity()) { - ZLOGI("Not support lock status!"); - return NOT_SUPPORT; - } - - if (observers_.empty()) { - observers_.insert(std::pair(GetCurrentUserId(), callback)); - std::thread th = std::thread([this] { - ZLOGI("Start to subscribe lock status!"); - bool result = false; - std::function observer = [this](int32_t userId, int32_t state) -> int32_t { - auto observer = observers_.find(userId); - if (observer == observers_.end() || observer->second == nullptr) { - return DB_ERROR; - } - observer->second(!(state == UNLOCK || state == NO_PWD)); - return OK; - }; - // retry after 10 second, 10 * 1000 * 1000 mains 1 second - BlockInteger retry(10 * 1000 * 1000); - for (; retry < RETRY_MAX_TIMES && !result; ++retry) { - result = SubscribeUserStatus(observer); - } - - ZLOGI("Subscribe lock status! retry:%d, result: %d", static_cast(retry), result); - }); - th.detach(); - } else { - observers_.insert(std::pair(GetCurrentUserId(), callback)); - } - return OK; -} - -bool Security::IsAccessControlled() const -{ - int curStatus = GetCurrentUserStatus(); - return !(curStatus == UNLOCK || curStatus == NO_PWD); -} - -DBStatus Security::SetSecurityOption(const std::string &filePath, const SecurityOption &option) -{ - if (filePath.empty()) { - return INVALID_ARGS; - } - - if (!InPathsBox(filePath, DATA_DE) && !InPathsBox(filePath, DATA_CE)) { - return NOT_SUPPORT; - } - - struct stat curStat; - stat(filePath.c_str(), &curStat); - if (S_ISDIR(curStat.st_mode)) { - return SetDirSecurityOption(filePath, option); - } else { - return SetFileSecurityOption(filePath, option); - } -} - -DBStatus Security::GetSecurityOption(const std::string &filePath, SecurityOption &option) const -{ - if (filePath.empty()) { - return INVALID_ARGS; - } - - if (!InPathsBox(filePath, DATA_DE) && !InPathsBox(filePath, DATA_CE)) { - return NOT_SUPPORT; - } - - struct stat curStat; - stat(filePath.c_str(), &curStat); - if (S_ISDIR(curStat.st_mode)) { - return GetDirSecurityOption(filePath, option); - } else { - return GetFileSecurityOption(filePath, option); - } -} - -DBStatus Security::GetDirSecurityOption(const std::string &filePath, SecurityOption &option) const -{ - return NOT_SUPPORT; -} - -DBStatus Security::GetFileSecurityOption(const std::string &filePath, SecurityOption &option) const -{ - return NOT_SUPPORT; -} - -DBStatus Security::SetDirSecurityOption(const std::string &filePath, const SecurityOption &option) -{ - return NOT_SUPPORT; -} - -DBStatus Security::SetFileSecurityOption(const std::string &filePath, const SecurityOption &option) -{ - if (option.securityLabel == NOT_SET) { - return OK; - } - return NOT_SUPPORT; -} - -bool Security::CheckDeviceSecurityAbility(const std::string &devId, const SecurityOption &option) const -{ - ZLOGD("The kv store is null, label:%d", option.securityLabel); - return GetDeviceNodeByUuid(devId, nullptr) >= option; -} - -int32_t Security::GetCurrentUserId() const -{ - std::int32_t uid = getuid(); - return AccountSA::OhosAccountKits::GetInstance().GetDeviceAccountIdByUID(uid); -} - -int32_t Security::GetCurrentUserStatus() const -{ - if (!IsSupportSecurity()) { - return NO_PWD; - } - return NO_PWD; -} - -bool Security::SubscribeUserStatus(std::function &observer) const -{ - return false; -} - -const char *Security::Convert2Name(const SecurityOption &option, bool isCE) -{ - if (option.securityLabel <= NOT_SET || option.securityLabel > S4) { - return nullptr; - } - - return nullptr; -} - -int Security::Convert2Security(const std::string &name) -{ - return NOT_SET; -} - -bool Security::IsSupportSecurity() -{ - return false; -} - -bool Security::IsFirstInit() -{ - return isInitialized_.exchange(false); -} - -bool Security::IsExits(const std::string &file) const -{ - return access(file.c_str(), F_OK) == 0; -} - -bool Security::InPathsBox(const std::string &file, const char * const pathsBox[]) const -{ - auto curPath = pathsBox; - if (curPath == nullptr) { - return false; - } - while ((*curPath) != nullptr) { - if (file.find(*curPath) == 0) { - return true; - } - curPath++; - } - return false; -} - -Sensitive Security::GetDeviceNodeByUuid(const std::string &uuid, - const std::function(void)> &getValue) -{ - static std::mutex mutex; - static std::map devicesUdid; - std::lock_guard guard(mutex); - auto it = devicesUdid.find(uuid); - if (devicesUdid.find(uuid) != devicesUdid.end()) { - return it->second; - } - - auto &network = AppDistributedKv::CommunicationProvider::GetInstance(); - auto devices = network.GetRemoteNodesBasicInfo(); - devices.push_back(network.GetLocalBasicInfo()); - for (auto &device : devices) { - auto deviceUuid = network.GetUuidByNodeId(device.deviceId); - ZLOGD("GetDeviceNodeByUuid(%.10s) peer device is %.10s", uuid.c_str(), deviceUuid.c_str()); - if (uuid != deviceUuid) { - continue; - } - - Sensitive sensitive(network.GetUdidByNodeId(device.deviceId), 0); - if (getValue == nullptr) { - devicesUdid.insert({uuid, std::move(sensitive)}); - return devicesUdid[uuid]; - } - - auto value = getValue(); - sensitive.Unmarshal(value); - if (!value.empty()) { - devicesUdid.insert({uuid, std::move(sensitive)}); - return devicesUdid[uuid]; - } - - return sensitive; - } - - return Sensitive(); -} -} +/* + * Copyright (c) 2021 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 "security.h" +#include +#include +#include +#include +#include "constant.h" +#include "log_print.h" +#include "kvstore_utils.h" +#include "communication_provider.h" +#include "dev_slinfo_mgr.h" +#include "security_label.h" + +#undef LOG_TAG +#define LOG_TAG "Security" +namespace OHOS::DistributedKv { +namespace { + const std::string SECURITY_VALUE_XATTR_PARRERN = "s([01234])"; + const std::string EMPTY_STRING = ""; +} +using namespace DistributedDB; +const std::string Security::LABEL_VALUES[S4 + 1] = { + "", "s0", "s1", "s2", "s3", "s4" +}; + +Security::Security() +{ + ZLOGD("construct"); +} + +Security::~Security() +{ + ZLOGD("destructor"); +} + +DBStatus Security::RegOnAccessControlledEvent(const OnAccessControlledEvent &callback) +{ + ZLOGD("add new lock status observer!"); + return NOT_SUPPORT; +} + +bool Security::IsAccessControlled() const +{ + auto curStatus = GetCurrentUserStatus(); + return !(curStatus == UNLOCK || curStatus == NO_PWD); +} + +DBStatus Security::SetSecurityOption(const std::string &filePath, const SecurityOption &option) +{ + if (filePath.empty()) { + return INVALID_ARGS; + } + + struct stat curStat; + stat(filePath.c_str(), &curStat); + if (S_ISDIR(curStat.st_mode)) { + return SetDirSecurityOption(filePath, option); + } else { + return SetFileSecurityOption(filePath, option); + } +} + +DBStatus Security::GetSecurityOption(const std::string &filePath, SecurityOption &option) const +{ + if (filePath.empty()) { + return INVALID_ARGS; + } + + struct stat curStat; + stat(filePath.c_str(), &curStat); + if (S_ISDIR(curStat.st_mode)) { + return GetDirSecurityOption(filePath, option); + } else { + return GetFileSecurityOption(filePath, option); + } +} + +bool Security::CheckDeviceSecurityAbility(const std::string &deviceId, const SecurityOption &option) const +{ + ZLOGD("The kvstore security level: label:%d", option.securityLabel); + Sensitive sensitive = GetDeviceNodeByUuid(deviceId, true, nullptr); + return (sensitive >= option); +} + +int Security::Convert2Security(const std::string &name) +{ + for (int i = 0; i <= S4; i++) { + if (name == LABEL_VALUES[i]) { + return i; + } + } + return NOT_SET; +} + +const std::string Security::Convert2Name(const SecurityOption &option) +{ + if (option.securityLabel <= NOT_SET || option.securityLabel > S4) { + return EMPTY_STRING; + } + + return LABEL_VALUES[option.securityLabel]; +} + +bool Security::IsXattrValueValid(const std::string& value) const +{ + if (value.empty()) { + ZLOGD("value is empty"); + return false; + } + + return std::regex_match(value, std::regex(SECURITY_VALUE_XATTR_PARRERN)); +} + +bool Security::IsSupportSecurity() +{ + return false; +} + +void Security::OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, + const AppDistributedKv::DeviceChangeType &type) const +{ + if (info.deviceId.empty()) { + ZLOGD("deviceId is empty"); + return; + } + + bool isOnline = type == AppDistributedKv::DeviceChangeType::DEVICE_ONLINE; + Sensitive sensitive = GetDeviceNodeByUuid(info.deviceId, isOnline, nullptr); + ZLOGD("device is online:%d, deviceId:%{public}s", isOnline, KvStoreUtils::ToBeAnonymous(info.deviceId).c_str()); + if (isOnline) { + auto secuiryLevel = sensitive.GetDeviceSecurityLevel(); + ZLOGI("device is online, secuiry Level:%d", secuiryLevel); + } +} + +bool Security::IsExits(const std::string &file) const +{ + return access(file.c_str(), F_OK) == 0; +} + +Sensitive Security::GetDeviceNodeByUuid(const std::string &uuid, bool isOnline, + const std::function(void)> &getValue) +{ + static std::mutex mutex; + static std::map devicesUdid; + std::lock_guard guard(mutex); + auto it = devicesUdid.find(uuid); + if (!isOnline) { + if (it != devicesUdid.end()) { + devicesUdid.erase(uuid); + } + return Sensitive(); + } + if (it != devicesUdid.end()) { + return it->second; + } + + auto &network = AppDistributedKv::CommunicationProvider::GetInstance(); + auto devices = network.GetRemoteNodesBasicInfo(); + devices.push_back(network.GetLocalBasicInfo()); + for (auto &device : devices) { + auto deviceUuid = network.GetUuidByNodeId(device.deviceId); + ZLOGD("GetDeviceNodeByUuid(%.10s) peer device is %.10s", uuid.c_str(), deviceUuid.c_str()); + if (uuid != deviceUuid) { + continue; + } + + Sensitive sensitive(network.GetUdidByNodeId(device.deviceId)); + if (getValue == nullptr) { + devicesUdid.insert(std::pair(uuid, std::move(sensitive))); + return devicesUdid[uuid]; + } + + auto value = getValue(); + ZLOGI("getValue is not nullptr!"); + return sensitive; + } + + return Sensitive(); +} + +int32_t Security::GetCurrentUserStatus() const +{ + if (!IsSupportSecurity()) { + return NO_PWD; + } + return NO_PWD; +} + +DBStatus Security::SetFileSecurityOption(const std::string &filePath, const SecurityOption &option) +{ + ZLOGI("set security option %d", option.securityLabel); + if (!IsExits(filePath)) { + return INVALID_ARGS; + } + if (option.securityLabel == NOT_SET) { + return OK; + } + auto dataLevel = Convert2Name(option); + if (dataLevel.empty()) { + ZLOGE("Invalid label args! label:%d, flag:%d path:%s", + option.securityLabel, option.securityFlag, filePath.c_str()); + return INVALID_ARGS; + } + + bool result = FileIO::SecurityLabel::SetSecurityLabel(filePath, dataLevel); + if (!result) { + ZLOGE("set security label failed!, result:%d, datalevel:%s", result, dataLevel.c_str()); + return DB_ERROR; + } + + return OK; +} + +DBStatus Security::SetDirSecurityOption(const std::string &filePath, const SecurityOption &option) +{ + ZLOGI("the filePath is a directory!"); + return NOT_SUPPORT; +} + +DBStatus Security::GetFileSecurityOption(const std::string &filePath, SecurityOption &option) const +{ + if (!IsExits(filePath)) { + option = {NOT_SET, ECE}; + return OK; + } + + std::string value = FileIO::SecurityLabel::GetSecurityLabel(filePath); + if (!IsXattrValueValid(value)) { + option = {NOT_SET, ECE}; + return OK; + } + ZLOGI("get security option %s", value.c_str()); + if (value == "s3") { + option = { Convert2Security(value), SECE }; + } else { + option = { Convert2Security(value), ECE }; + } + return OK; +} + +DBStatus Security::GetDirSecurityOption(const std::string &filePath, SecurityOption &option) const +{ + ZLOGI("the filePath is a directory!"); + return NOT_SUPPORT; +} +} diff --git a/services/distributeddataservice/adapter/security/src/security.h b/services/distributeddataservice/app/src/security/security.h similarity index 67% rename from services/distributeddataservice/adapter/security/src/security.h rename to services/distributeddataservice/app/src/security/security.h index 074192551de330d861359d98857d48ae155c9c0b..ab858c225c7ab1d5f3572612087c9e4df4c0485a 100644 --- a/services/distributeddataservice/adapter/security/src/security.h +++ b/services/distributeddataservice/app/src/security/security.h @@ -1,89 +1,80 @@ -/* - * Copyright (c) 2021 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_SECURITY_H -#define OHOS_SECURITY_H - -#include -#include -#include -#include -#include "iprocess_system_api_adapter.h" -#include "kv_store_delegate_manager.h" -#include "visibility.h" -#include "sensitive.h" - -namespace OHOS::DistributedKv { -class Security - : public DistributedDB::IProcessSystemApiAdapter, public std::enable_shared_from_this { -public: - using DBStatus = DistributedDB::DBStatus; - using OnAccessControlledEvent = DistributedDB::OnAccessControlledEvent; - using SecurityOption = DistributedDB::SecurityOption; - Security(const std::string &appId, const std::string &userId, const std::string &dir); - ~Security() override; - - static bool IsFirstInit(); - static bool IsSupportSecurity(); - - DBStatus RegOnAccessControlledEvent(const OnAccessControlledEvent &callback) override; - - // Check is the access of this device in locked state - bool IsAccessControlled() const override; - - // Set the SecurityOption to the targe filepath. - // If the filePath is a directory, All the files and directories in the filePath should be effective. - DBStatus SetSecurityOption(const std::string &filePath, const SecurityOption &option) override; - - // Get the SecurityOption of the targe filepath. - DBStatus GetSecurityOption(const std::string &filePath, SecurityOption &option) const override; - - // Check if the target device can save the data at the give sensitive class. - bool CheckDeviceSecurityAbility(const std::string &devId, const SecurityOption &option) const override; - - static const char *Convert2Name(const SecurityOption &option, bool isCE); - static int Convert2Security(const std::string &name); -private: - enum { - NO_PWD = -1, - UNLOCK, - LOCKED, - UNINITIALIZED, - }; - - // the key is security_chain/{deviceId} - static const char * const LABEL_VALUES[DistributedDB::S4 + 1]; - static const char * const DATA_DE[]; // = "/data/misc_de/", "/data/user_de/"; - static const char * const DATA_CE[]; - static constexpr int LABEL_VALUE_LEN = 10; - static constexpr int RETRY_MAX_TIMES = 10; - int32_t GetCurrentUserId() const; - int32_t GetCurrentUserStatus() const; - bool SubscribeUserStatus(std::function &observer) const; - bool IsExits(const std::string &file) const; - bool InPathsBox(const std::string &file, const char * const pathsBox[]) const; - static Sensitive GetDeviceNodeByUuid(const std::string &uuid, - const std::function(void)> &getValue); - DBStatus GetDirSecurityOption(const std::string &filePath, SecurityOption &option) const; - DBStatus GetFileSecurityOption(const std::string &filePath, SecurityOption &option) const; - DBStatus SetDirSecurityOption(const std::string &filePath, const SecurityOption &option); - DBStatus SetFileSecurityOption(const std::string &filePath, const SecurityOption &option); - - std::map observers_ {}; - static std::atomic_bool isInitialized_; -}; -} - -#endif // OHOS_SECURITY_H +/* + * Copyright (c) 2021 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_SECURITY_H +#define OHOS_SECURITY_H + +#include +#include +#include +#include "iprocess_system_api_adapter.h" +#include "kv_store_delegate_manager.h" +#include "app_device_status_change_listener.h" +#include "visibility.h" +#include "sensitive.h" + +namespace OHOS::DistributedKv { +class Security + : public DistributedDB::IProcessSystemApiAdapter, + public AppDistributedKv::AppDeviceStatusChangeListener { +public: + using DBStatus = DistributedDB::DBStatus; + using OnAccessControlledEvent = DistributedDB::OnAccessControlledEvent; + using SecurityOption = DistributedDB::SecurityOption; + Security(); + ~Security() override; + static bool IsSupportSecurity(); + + DBStatus RegOnAccessControlledEvent(const OnAccessControlledEvent &callback) override; + + // Check is the access of this device in locked state + bool IsAccessControlled() const override; + + // Set the SecurityOption to the targe filepath. + // If the filePath is a directory, the function would not effective. + DBStatus SetSecurityOption(const std::string &filePath, const SecurityOption &option) override; + + // Get the SecurityOption of the targe filepath. + DBStatus GetSecurityOption(const std::string &filePath, SecurityOption &option) const override; + + // Check if the target device can save the data at the give sensitive class. + bool CheckDeviceSecurityAbility(const std::string &deviceId, const SecurityOption &option) const override; + +private: + enum { + NO_PWD = -1, + UNLOCK, + LOCKED, + UNINITIALIZED, + }; + static constexpr int RETRY_MAX_TIMES = 10; + static const std::string LABEL_VALUES[DistributedDB::S4 + 1]; + static const std::string Convert2Name(const SecurityOption &option); + static int Convert2Security(const std::string &name); + bool IsExits(const std::string &file) const; + void OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, + const AppDistributedKv::DeviceChangeType &type) const override; + static Sensitive GetDeviceNodeByUuid(const std::string &uuid, bool isOnline, + const std::function(void)> &getValue); + bool IsXattrValueValid(const std::string& value) const; + int32_t GetCurrentUserStatus() const; + DBStatus SetFileSecurityOption(const std::string &filePath, const SecurityOption &option); + DBStatus SetDirSecurityOption(const std::string &filePath, const SecurityOption &option); + DBStatus GetFileSecurityOption(const std::string &filePath, SecurityOption &option) const; + DBStatus GetDirSecurityOption(const std::string &filePath, SecurityOption &option) const; +}; +} // namespace OHOS::DistributedKv + +#endif // OHOS_SECURITY_H diff --git a/services/distributeddataservice/adapter/security/src/sensitive.cpp b/services/distributeddataservice/app/src/security/sensitive.cpp old mode 100755 new mode 100644 similarity index 40% rename from services/distributeddataservice/adapter/security/src/sensitive.cpp rename to services/distributeddataservice/app/src/security/sensitive.cpp index 1d9e1834f24282797f6c239444eba156170bcc6c..3f7af35566ded1e2ea94cb3655dc8d0675d9531c --- a/services/distributeddataservice/adapter/security/src/sensitive.cpp +++ b/services/distributeddataservice/app/src/security/sensitive.cpp @@ -1,97 +1,125 @@ -/* - * Copyright (c) 2021 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 "sensitive.h" -#include -#include "iprocess_system_api_adapter.h" -#include "log_print.h" -#undef LOG_TAG -#define LOG_TAG "Sensitive" - -namespace OHOS::DistributedKv { -Sensitive::Sensitive(std::string deviceId, uint32_t type) - : deviceId(std::move(deviceId)), securityLevel(0), deviceType(type) -{ -} - -Sensitive::Sensitive(const std::vector &value) - : securityLevel(0), deviceType(0) -{ - Unmarshal(value); -} - -std::vector Sensitive::Marshal() const -{ - return {}; -} - -void Sensitive::Unmarshal(const std::vector &value) -{ -} - -uint32_t Sensitive::GetSensitiveLevel() -{ - return securityLevel; -} - -bool Sensitive::operator >= (const DistributedDB::SecurityOption &option) -{ - return true; -} - -bool Sensitive::LoadData() -{ - return true; -} - -Sensitive::Sensitive(Sensitive &&sensitive) noexcept -{ - this->operator=(std::move(sensitive)); -} - -Sensitive &Sensitive::operator=(Sensitive &&sensitive) noexcept -{ - if (this == &sensitive) { - return *this; - } - deviceId = std::move(sensitive.deviceId); - dataBase64 = std::move(sensitive.dataBase64); - securityLevel = sensitive.securityLevel; - deviceType = sensitive.deviceType; - return *this; -} - -Sensitive::Sensitive(const Sensitive &sensitive) -{ - this->operator=(sensitive); -} - -Sensitive &Sensitive::operator=(const Sensitive &sensitive) -{ - if (this == &sensitive) { - return *this; - } - deviceId = sensitive.deviceId; - dataBase64 = sensitive.dataBase64; - securityLevel = sensitive.securityLevel; - deviceType = sensitive.deviceType; - return *this; -} - -uint32_t Sensitive::GetDevslDeviceType() const -{ - return deviceType; -} -} +/* + * Copyright (c) 2022 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 "sensitive.h" +#include +#include +#include "log_print.h" +#include "app_types.h" +#include "kvstore_utils.h" +#undef LOG_TAG +#define LOG_TAG "Sensitive" + +namespace OHOS { +namespace DistributedKv { +Sensitive::Sensitive(std::string deviceId) + : deviceId(std::move(deviceId)), securityLevel(DATA_SEC_LEVEL1) +{ +} + +Sensitive::Sensitive() + : deviceId(""), securityLevel(DATA_SEC_LEVEL1) +{ +} + +uint32_t Sensitive::GetDeviceSecurityLevel() +{ + if (securityLevel > DATA_SEC_LEVEL1) { + ZLOGI("the device security level had gotten"); + return securityLevel; + } + return GetSensitiveLevel(deviceId); +} + +bool Sensitive::InitDEVSLQueryParams(DEVSLQueryParams *params, const std::string &udid) +{ + ZLOGI("udid is [%{public}s]", KvStoreUtils::ToBeAnonymous(udid).c_str()); + if (params == nullptr || udid.empty()) { + return false; + } + std::vector vec(udid.begin(), udid.end()); + for (size_t i = 0; i < MAX_UDID_LENGTH && i < vec.size(); i++) { + params->udid[i] = vec[i]; + } + params->udidLen = uint32_t(udid.size()); + return true; +} + +bool Sensitive::operator >= (const DistributedDB::SecurityOption &option) +{ + if (option.securityLabel == DistributedDB::NOT_SET) { + return true; + } + + uint32_t level = securityLevel; + if (level <= DATA_SEC_LEVEL1) { + ZLOGI("the device security level hadn't gotten"); + level = GetSensitiveLevel(deviceId); + } + return (level >= static_cast(option.securityLabel - 1)); +} + +Sensitive::Sensitive(const Sensitive &sensitive) +{ + this->operator=(sensitive); +} + +Sensitive &Sensitive::operator=(const Sensitive &sensitive) +{ + if (this == &sensitive) { + return *this; + } + deviceId = sensitive.deviceId; + securityLevel = sensitive.securityLevel; + return *this; +} + +Sensitive::Sensitive(Sensitive &&sensitive) noexcept +{ + this->operator=(std::move(sensitive)); +} + +Sensitive &Sensitive::operator=(Sensitive &&sensitive) noexcept +{ + if (this == &sensitive) { + return *this; + } + deviceId = std::move(sensitive.deviceId); + securityLevel = sensitive.securityLevel; + return *this; +} + +uint32_t Sensitive::GetSensitiveLevel(const std::string &udid) +{ + DEVSLQueryParams query; + if (!InitDEVSLQueryParams(&query, udid)) { + ZLOGE("init query params failed! udid:[%{public}s]", KvStoreUtils::ToBeAnonymous(udid).c_str()); + return DATA_SEC_LEVEL1; + } + + uint32_t level = DATA_SEC_LEVEL1; + int32_t result = DATASL_GetHighestSecLevel(&query, &level); + if (result != DEVSL_SUCCESS) { + ZLOGE("get highest level failed(%{public}s)! level: %d, error: %d", + KvStoreUtils::ToBeAnonymous(udid).c_str(), securityLevel, result); + return DATA_SEC_LEVEL1; + } + securityLevel = level; + ZLOGI("get highest level success(%{public}s)! level: %d, error: %d", + KvStoreUtils::ToBeAnonymous(udid).c_str(), securityLevel, result); + return securityLevel; +} +} // namespace DistributedKv +} // namespace OHOS diff --git a/services/distributeddataservice/adapter/security/src/sensitive.h b/services/distributeddataservice/app/src/security/sensitive.h old mode 100755 new mode 100644 similarity index 61% rename from services/distributeddataservice/adapter/security/src/sensitive.h rename to services/distributeddataservice/app/src/security/sensitive.h index 2aba82b705a169bd82c30a05b0e44a02478f6fcf..250ad76120f89d2ed7e9299586510d09cd0c8ede --- a/services/distributeddataservice/adapter/security/src/sensitive.h +++ b/services/distributeddataservice/app/src/security/sensitive.h @@ -1,52 +1,47 @@ -/* - * Copyright (c) 2021 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_SENSITIVE_H -#define OHOS_SENSITIVE_H - -#include -#include -#include - -namespace OHOS::DistributedKv { -class Sensitive final { -public: - static constexpr uint32_t MAX_DATA_LEN = 16 * 1024; - Sensitive(std::string deviceId, uint32_t type); - explicit Sensitive(const std::vector &value = {}); - Sensitive(const Sensitive &sensitive); - Sensitive &operator=(const Sensitive &sensitive); - Sensitive(Sensitive &&sensitive) noexcept; - Sensitive &operator=(Sensitive &&sensitive) noexcept; - ~Sensitive() = default; - - std::vector Marshal() const; - void Unmarshal(const std::vector &value); - - bool operator >= (const DistributedDB::SecurityOption &option); - - bool LoadData(); -private: - uint32_t GetSensitiveLevel(); - uint32_t GetDevslDeviceType() const; - - std::string deviceId {}; - std::string dataBase64 {}; - uint32_t securityLevel = 0; - uint32_t deviceType = 0; -}; -} - -#endif // OHOS_SENSITIVE_H +/* + * Copyright (c) 2022 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_SENSITIVE_H +#define OHOS_SENSITIVE_H + +#include +#include "visibility.h" +#include "iprocess_system_api_adapter.h" +#include "dev_slinfo_mgr.h" + +namespace OHOS { +namespace DistributedKv { +class Sensitive final { +public: + explicit Sensitive(std::string deviceId); + explicit Sensitive(); + Sensitive(const Sensitive &sensitive); + Sensitive &operator=(const Sensitive &sensitive); + Sensitive(Sensitive &&sensitive) noexcept; + Sensitive &operator=(Sensitive &&sensitive) noexcept; + ~Sensitive() = default; + + bool operator >= (const DistributedDB::SecurityOption &option); + uint32_t GetDeviceSecurityLevel(); + +private: + uint32_t GetSensitiveLevel(const std::string &udid); + bool InitDEVSLQueryParams(DEVSLQueryParams *params, const std::string &udid); + std::string deviceId {}; + uint32_t securityLevel = 0; +}; +} // namespace DistributedKv +} // namespace OHOS +#endif // OHOS_SENSITIVE_H \ No newline at end of file diff --git a/services/distributeddataservice/app/src/uninstaller/BUILD.gn b/services/distributeddataservice/app/src/uninstaller/BUILD.gn index ca0b860852d6076c21b87bd2f25860943aff1d99..3532513ca0fd974e3c7b1b0c64c1903d06eadc8a 100755 --- a/services/distributeddataservice/app/src/uninstaller/BUILD.gn +++ b/services/distributeddataservice/app/src/uninstaller/BUILD.gn @@ -44,6 +44,7 @@ ohos_static_library("distributeddata_uninstaller_static") { # "ces:libcommonevent", "ability_base:want", "ces_standard:cesfwk_innerkits", + "dataclassification:data_transit_mgr", "dmsfwk_standard:zuri", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", diff --git a/services/distributeddataservice/app/test/BUILD.gn b/services/distributeddataservice/app/test/BUILD.gn index 5083a0a6f34c804d3d57fdc49f3eae8b4ee4decd..70982a4ea593150e378bf75e214ba85d2382fcc7 100755 --- a/services/distributeddataservice/app/test/BUILD.gn +++ b/services/distributeddataservice/app/test/BUILD.gn @@ -31,10 +31,12 @@ config("module_private_config") { "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/bootstrap/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/config/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/directory/include", + "//foundation/filemanagement/file_api/interfaces/innerkits/include", "//utils/native/base/include", "//utils/system/safwk/native/include", "../include", "../src", + "../src/security", "unittest", "../src/uninstaller", "../src/flowctrl_manager", @@ -64,6 +66,8 @@ ohos_unittest("KvStoreImplLogicalIsolationTest") { "../src/kvstore_sync_manager.cpp", "../src/kvstore_user_manager.cpp", "../src/query_helper.cpp", + "../src/security/security.cpp", + "../src/security/sensitive.cpp", "../src/single_kvstore_impl.cpp", "unittest/kvstore_impl_logical_isolation_test.cpp", ] @@ -72,6 +76,7 @@ ohos_unittest("KvStoreImplLogicalIsolationTest") { external_deps = [ "battery_manager_native:batterysrv_client", + "dataclassification:data_transit_mgr", "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", @@ -119,6 +124,8 @@ ohos_unittest("KvStoreImplPhysicalIsolationTest") { "../src/kvstore_sync_manager.cpp", "../src/kvstore_user_manager.cpp", "../src/query_helper.cpp", + "../src/security/security.cpp", + "../src/security/sensitive.cpp", "../src/single_kvstore_impl.cpp", "unittest/kvstore_impl_physical_isolation_test.cpp", ] @@ -127,6 +134,7 @@ ohos_unittest("KvStoreImplPhysicalIsolationTest") { external_deps = [ "battery_manager_native:batterysrv_client", + "dataclassification:data_transit_mgr", "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", @@ -174,6 +182,8 @@ ohos_unittest("KvStoreDataServiceTest") { "../src/kvstore_sync_manager.cpp", "../src/kvstore_user_manager.cpp", "../src/query_helper.cpp", + "../src/security/security.cpp", + "../src/security/sensitive.cpp", "../src/single_kvstore_impl.cpp", "unittest/kvstore_data_service_test.cpp", ] @@ -182,6 +192,7 @@ ohos_unittest("KvStoreDataServiceTest") { external_deps = [ "battery_manager_native:batterysrv_client", + "dataclassification:data_transit_mgr", "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", @@ -229,6 +240,8 @@ ohos_unittest("KvStoreBackupTest") { "../src/kvstore_sync_manager.cpp", "../src/kvstore_user_manager.cpp", "../src/query_helper.cpp", + "../src/security/security.cpp", + "../src/security/sensitive.cpp", "../src/single_kvstore_impl.cpp", "unittest/kvstore_backup_test.cpp", ] @@ -238,6 +251,7 @@ ohos_unittest("KvStoreBackupTest") { external_deps = [ "battery_manager_native:batterysrv_client", + "dataclassification:data_transit_mgr", "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", @@ -275,6 +289,7 @@ ohos_unittest("KvStoreFlowCtrlManagerTest") { external_deps = [ "battery_manager_native:batterysrv_client", + "dataclassification:data_transit_mgr", "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", @@ -316,6 +331,8 @@ ohos_unittest("KvStoreSyncManagerTest") { "../src/kvstore_sync_manager.cpp", "../src/kvstore_user_manager.cpp", "../src/query_helper.cpp", + "../src/security/security.cpp", + "../src/security/sensitive.cpp", "../src/single_kvstore_impl.cpp", ] @@ -323,6 +340,7 @@ ohos_unittest("KvStoreSyncManagerTest") { external_deps = [ "battery_manager_native:batterysrv_client", + "dataclassification:data_transit_mgr", "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", @@ -370,6 +388,8 @@ ohos_unittest("KvStoreUninstallerTest") { "../src/kvstore_sync_manager.cpp", "../src/kvstore_user_manager.cpp", "../src/query_helper.cpp", + "../src/security/security.cpp", + "../src/security/sensitive.cpp", "../src/single_kvstore_impl.cpp", "unittest/uninstaller_test.cpp", ] @@ -396,6 +416,7 @@ ohos_unittest("KvStoreUninstallerTest") { "ability_base:base", "ability_runtime:intent", "battery_manager_native:batterysrv_client", + "dataclassification:data_transit_mgr", "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp index a3d48fbd84f94a886e2ed43931e7ed34f734e5b0..c10ad103c495481b45bf6406f91849965f60a5c5 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp @@ -1189,9 +1189,18 @@ int SQLiteSingleVerRelationalStorageExecutor::CheckQueryObjectLegal(const TableI return errCode; } - errCode = SQLiteUtils::CheckSchemaChanged(stmt, table, DBConstant::RELATIONAL_LOG_TABLE_FIELD_NUM); + TableInfo newTable; + SQLiteUtils::AnalysisSchema(dbHandle_, table.GetTableName(), newTable); if (errCode != E_OK) { - LOGE("Check schema failed, schema was changed. %d", errCode); + LOGE("Check new schema failed. %d", errCode); + } else { + errCode = table.CompareWithTable(newTable); + if (errCode != -E_RELATIONAL_TABLE_EQUAL && errCode != -E_RELATIONAL_TABLE_COMPATIBLE) { + LOGE("Check schema failed, schema was changed. %d", errCode); + errCode = -E_DISTRIBUTED_SCHEMA_CHANGED; + } else { + errCode = E_OK; + } } SQLiteUtils::ResetStatement(stmt, true, errCode); diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/ability_sync.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/ability_sync.cpp index 9e03dfef46e2fb339f1d8dd694be6a2f4f4c759e..1b0509eedd20ec1fc93cdb52c263a6183fa0da67 100755 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/ability_sync.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/ability_sync.cpp @@ -417,6 +417,7 @@ int AbilitySync::AckRecv(const Message *message, ISyncTaskContext *context) errCode = metadata_->SetDbCreateTime(deviceId_, packet->GetDbCreateTime(), true); if (errCode != E_OK) { LOGE("[AbilitySync][AckRecv] set db create time failed,errCode=%d", errCode); + context->SetTaskErrCode(errCode); return errCode; } } @@ -1033,9 +1034,7 @@ int AbilitySync::AckMsgCheck(const Message *message, ISyncTaskContext *context) int ackCode = packet->GetAckCode(); if (ackCode != E_OK) { LOGE("[AbilitySync][AckMsgCheck] received a errCode %d", ackCode); - if (ackCode == -E_SECURITY_OPTION_CHECK_ERROR) { - context->SetTaskErrCode(-E_SECURITY_OPTION_CHECK_ERROR); - } + context->SetTaskErrCode(ackCode); return ackCode; } return E_OK; diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp index cc920a9ed95f1d15f6ad245e05fca5398640072c..5af8e14fadd1ee6c6cc519c6ba32d193487bcf6c 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp @@ -272,4 +272,63 @@ HWTEST_F(DistributedDBMockSyncModuleTest, SyncDataSync002, TestSize.Level1) EXPECT_CALL(dataSync, RemoveDeviceDataIfNeed(_)).WillRepeatedly(Return(-E_BUSY)); EXPECT_EQ(dataSync.CallPullRequestStart(&syncTaskContext), -E_BUSY); EXPECT_EQ(syncTaskContext.GetTaskErrCode(), -E_BUSY); +} + +/** + * @tc.name: AbilitySync001 + * @tc.desc: Test abilitySync abort when recv error. + * @tc.type: FUNC + * @tc.require: AR000CCPOM + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBMockSyncModuleTest, AbilitySync001, TestSize.Level1) +{ + MockSyncTaskContext syncTaskContext; + AbilitySync abilitySync; + + DistributedDB::Message *message = new(std::nothrow) DistributedDB::Message(); + ASSERT_TRUE(message != nullptr); + AbilitySyncAckPacket packet; + packet.SetAckCode(-E_BUSY); + message->SetCopiedObject(&packet); + EXPECT_EQ(abilitySync.AckRecv(message, &syncTaskContext), -E_BUSY); + delete message; + EXPECT_EQ(syncTaskContext.GetTaskErrCode(), -E_BUSY); +} + +/** + * @tc.name: AbilitySync002 + * @tc.desc: Test abilitySync abort when save meta failed. + * @tc.type: FUNC + * @tc.require: AR000CCPOM + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBMockSyncModuleTest, AbilitySync002, TestSize.Level1) +{ + MockSyncTaskContext syncTaskContext; + AbilitySync abilitySync; + MockCommunicator comunicator; + VirtualSingleVerSyncDBInterface syncDBInterface; + std::shared_ptr metaData = std::make_shared(); + metaData->Initialize(&syncDBInterface); + abilitySync.Initialize(&comunicator, &syncDBInterface, metaData, "deviceId"); + + /** + * @tc.steps: step1. set AbilitySyncAckPacket ackCode is E_OK for pass the ack check + */ + DistributedDB::Message *message = new(std::nothrow) DistributedDB::Message(); + ASSERT_TRUE(message != nullptr); + AbilitySyncAckPacket packet; + packet.SetAckCode(E_OK); + packet.SetSoftwareVersion(SOFTWARE_VERSION_CURRENT); + message->SetCopiedObject(&packet); + /** + * @tc.steps: step1. set syncDBInterface busy for save data return -E_BUSY + */ + syncDBInterface.SetBusy(true); + SyncStrategy mockStrategy = {true, false, false}; + EXPECT_CALL(syncTaskContext, GetSyncStrategy(_)).WillOnce(Return(mockStrategy)); + EXPECT_EQ(abilitySync.AckRecv(message, &syncTaskContext), -E_BUSY); + delete message; + EXPECT_EQ(syncTaskContext.GetTaskErrCode(), -E_BUSY); } \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp index ab5c039a285fc8c5b0b493e52cc52706f8e71078..2b45522f0444436f955d3c4a75a63fe980175a60 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp @@ -979,6 +979,53 @@ HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AbilitySync002, TestSize.Level1) BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, SCHEMA_MISMATCH, {DEVICE_B}); } +/** +* @tc.name: Ability Sync 003 +* @tc.desc: Test ability sync failed when has different schema. +* @tc.type: FUNC +* @tc.require: AR000GK58N +* @tc.author: zhangqiquan +*/ +HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AbilitySync003, TestSize.Level1) +{ + /** + * @tc.steps: step1. set local and remote schema is (BOOL, INTEGER, REAL, TEXT, BLOB) + */ + std::map dataMap; + std::vector schema; + std::vector localStorageType = g_storageType; + GetFieldInfo(schema, localStorageType); + + /** + * @tc.steps: step2. create table and insert data + */ + PrepareEnvironment(dataMap, schema, schema, {g_deviceB}); + + /** + * @tc.steps: step3. change local table to (BOOL, INTEGER, REAL, TEXT, BLOB) + * @tc.expected: sync fail + */ + g_communicatorAggregator->RegOnDispatch([](const std::string &target, Message *inMsg) { + if (target != "real_device") { + return; + } + if (inMsg->GetMessageType() != TYPE_NOTIFY || inMsg->GetMessageId() != ABILITY_SYNC_MESSAGE) { + return; + } + sqlite3 *db = nullptr; + EXPECT_EQ(GetDB(db), SQLITE_OK); + ASSERT_NE(db, nullptr); + std::string alterSql = "ALTER TABLE " + g_tableName + " ADD COLUMN NEW_COLUMN TEXT DEFAULT 'DEFAULT_TEXT'"; + EXPECT_EQ(sqlite3_exec(db, alterSql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); + + EXPECT_EQ(g_rdbDelegatePtr->CreateDistributedTable(g_tableName), OK); + }); + + BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B}); + + g_communicatorAggregator->RegOnDispatch(nullptr); +} + /** * @tc.name: WaterMark 001 * @tc.desc: Test sync success after erase waterMark. diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_sync_task_context.h b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_sync_task_context.h index b5a41503cb10b54a7c614f0cb45fb99594ea1358..5b650bc635468bd6f1266cf53af2feda5f18987e 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_sync_task_context.h +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_sync_task_context.h @@ -37,6 +37,8 @@ public: MOCK_METHOD0(Clear, void(void)); MOCK_CONST_METHOD0(GetRequestSessionId, uint32_t(void)); + + MOCK_CONST_METHOD1(GetSyncStrategy, SyncStrategy(QuerySyncObject &)); }; } // namespace DistributedDB #endif // #define MOCK_SINGLE_VER_STATE_MACHINE_H \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.cpp index d38a326bff022649b405e6b2c8b929fff13046cb..cd9a0fa63b1f2bfeb03a0f17ce383e06545d68eb 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.cpp @@ -89,8 +89,11 @@ int VirtualRelationalVerSyncDBInterface::PutSyncDataWithQuery(const QueryObject for (const auto &optRowDataWithLog : optTableDataWithLog.dataList) { VirtualRowData virtualRowData; virtualRowData.logInfo = optRowDataWithLog.logInfo; - int index = 0; + size_t index = 0; for (const auto &optItem : optRowDataWithLog.optionalData) { + if (index >= localFieldInfo_.size()) { + break; + } DataValue dataValue = std::move(optItem); LOGD("type:%d", optItem.GetType()); virtualRowData.objectData.PutDataValue(localFieldInfo_[index].GetFieldName(), dataValue); diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.cpp index 810ede8db5fb268030c77a09e34f9998960f3f37..c6590ad8e5b2a1267fbb3bc1c7d1d8505c52b843 100755 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.cpp @@ -88,6 +88,9 @@ int VirtualSingleVerSyncDBInterface::GetMetaData(const Key &key, Value &value) c int VirtualSingleVerSyncDBInterface::PutMetaData(const Key &key, const Value &value) { + if (busy_) { + return -E_BUSY; + } metadata_[key] = value; return E_OK; } @@ -408,4 +411,9 @@ int VirtualSingleVerSyncDBInterface::RemoveSubscribe(const std::vector &subscribeIds) override; + + void SetBusy(bool busy); private: int GetSyncData(TimeStamp begin, TimeStamp end, uint32_t blockSize, std::vector& dataItems, ContinueToken& continueStmtToken) const; @@ -134,6 +136,7 @@ private: KvDBProperties properties_; uint64_t saveDataDelayTime_ = 0; SecurityOption secOption_; + bool busy_ = false; }; } // namespace DistributedDB diff --git a/services/distributeddataservice/service/bootstrap/CMakeLists.txt b/services/distributeddataservice/service/bootstrap/CMakeLists.txt deleted file mode 100644 index 72d567cdcf03813c9bff06ed0e096ce4102a2697..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/bootstrap/CMakeLists.txt +++ /dev/null @@ -1,87 +0,0 @@ -cmake_minimum_required(VERSION 3.10.2) -project(bootstrap) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -fno-rtti -fvisibility=hidden -D_GNU_SOURCE") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -fPIC -fpic -ffunction-sections -D_GLIBC_MOCK") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-as-needed -ldl") -#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") -#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") -set(MOCK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../mock") -aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src bootstrapSrc) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../frameworks/common) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../config/include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../directory/include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../framework/include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/innerkits/distributeddata/include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../utils_native/base/include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../utils_native/safwk/native/include) -include_directories(${MOCK_DIR}) -include_directories(${MOCK_DIR}/uapi) -include_directories(${MOCK_DIR}/innerkits/sensor/sensor_interface_native/include) -include_directories(${MOCK_DIR}/innerkits/miscdevice/vibrator_interface_native/include) -include_directories(${MOCK_DIR}/innerkits/aafwk_standard/want/include/ohos/aafwk/content) -include_directories(${MOCK_DIR}/innerkits/aafwk_standard/intent/include) -include_directories(${MOCK_DIR}/innerkits/aafwk_standard/ability_manager/include) -include_directories(${MOCK_DIR}/innerkits/aafwk_standard/base/include) -include_directories(${MOCK_DIR}/innerkits/jsapi_worker/worker_init/include) -include_directories(${MOCK_DIR}/innerkits/os_account_standard/libaccountkits/include) -include_directories(${MOCK_DIR}/innerkits/deviceauth_standard/deviceauth_sdk/include) -include_directories(${MOCK_DIR}/innerkits/samgr_standard/samgr_proxy/include) -include_directories(${MOCK_DIR}/innerkits/ipc/ipc_core/include) -include_directories(${MOCK_DIR}/innerkits/ipc/ipc_single/include) -include_directories(${MOCK_DIR}/innerkits/ipc/libdbinder/include) -include_directories(${MOCK_DIR}/innerkits/resmgr_standard/global_resmgr/include) -include_directories(${MOCK_DIR}/innerkits/power_manager_native/powermgr_client/include) -include_directories(${MOCK_DIR}/innerkits/napi/ace_napi/include) -include_directories(${MOCK_DIR}/innerkits/hisysevent_native/libhisysevent/include) -include_directories(${MOCK_DIR}/innerkits/appverify/libhapverify/include) -include_directories(${MOCK_DIR}/innerkits/huks_standard/libhukssdk/include) -include_directories(${MOCK_DIR}/innerkits/inputmethod_native/inputmethod_ability/include) -include_directories(${MOCK_DIR}/innerkits/inputmethod_native/inputmethod_client/include) -include_directories(${MOCK_DIR}/innerkits/safwk/system_ability_fwk/include) -include_directories(${MOCK_DIR}/innerkits/ipc_js/rpc/include) -include_directories(${MOCK_DIR}/innerkits/dataclassification/fbe_iudf_xattr/include) -include_directories(${MOCK_DIR}/innerkits/dataclassification/hwdsl/include) -include_directories(${MOCK_DIR}/innerkits/battery_manager_native/batterysrv_client/include) -include_directories(${MOCK_DIR}/innerkits/permission_standard/libpermissionsdk_standard/include) -include_directories(${MOCK_DIR}/innerkits/hilog_native/libhilog/include) -include_directories(${MOCK_DIR}/innerkits/display_manager_native/displaymgr/include) -include_directories(${MOCK_DIR}/innerkits/i18n_standard/phonenumber_standard/include) -include_directories(${MOCK_DIR}/innerkits/i18n_standard/zone_util/include) -include_directories(${MOCK_DIR}/innerkits/bytrace_standard/bytrace_core/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libmmi-client/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libmmi-client/include/proxy/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libmmi-client/include/event/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libmmi-client/include/common/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libmmi-server/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libmmi-server/include/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libinput-third-mmi/include) -include_directories(${MOCK_DIR}/innerkits/appexecfwk_standard/appexecfwk_base/include) -include_directories(${MOCK_DIR}/innerkits/appexecfwk_standard/eventhandler_native/include) -include_directories(${MOCK_DIR}/innerkits/appexecfwk_standard/fmskit_native/include) -include_directories(${MOCK_DIR}/innerkits/appexecfwk_standard/libeventhandler/include) -include_directories(${MOCK_DIR}/innerkits/appexecfwk_standard/appexecfwk_core/include) -include_directories(${MOCK_DIR}/innerkits/hitrace_native/libhitrace/include) -include_directories(${MOCK_DIR}/innerkits/dmsfwk_standard/zuri/include) -include_directories(${MOCK_DIR}/innerkits/ces_standard/cesfwk_services/include) -include_directories(${MOCK_DIR}/innerkits/ces_standard/cesfwk_core/include) -include_directories(${MOCK_DIR}/innerkits/ces_standard/cesfwk_innerkits/include) -include_directories(${MOCK_DIR}/innerkits/multimedia_image_standard/image/include) -include_directories(${MOCK_DIR}/innerkits/ril_adapter/hril/include) -include_directories(${MOCK_DIR}/innerkits/native_appdatamgr/native_dataability/include) -include_directories(${MOCK_DIR}/innerkits/native_appdatamgr/native_preferences/include) -include_directories(${MOCK_DIR}/innerkits/native_appdatamgr/native_rdb/include) -include_directories(${MOCK_DIR}/innerkits/native_appdatamgr/native_appdatafwk/include) -include_directories(${MOCK_DIR}/innerkits/startup_l2/syspara/include) -include_directories(${MOCK_DIR}/innerkits/hicollie_native/libhicollie/include) -include_directories(${MOCK_DIR}/innerkits/dsoftbus_standard/softbus_client/include) -include_directories(${MOCK_DIR}/innerkits/device_manager_base/devicemanagersdk/include) -include_directories(${MOCK_DIR}/innerkits/distributeddatamgr/app_distributeddata/include) -include_directories(${MOCK_DIR}/innerkits/distributeddatamgr/distributeddata_inner/include) -#include_directories(${MOCK_DIR}/innerkits/utils_base/utils/include/include) -set(links secure mock frameworks config svcFwk directory) -set(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/../../../../") -add_library(bootstrap SHARED ${bootstrapSrc}) -target_link_libraries(bootstrap ${links}) diff --git a/services/distributeddataservice/service/config/CMakeLists.txt b/services/distributeddataservice/service/config/CMakeLists.txt deleted file mode 100644 index af844568a5f02b0c02aacda8333d3ef72f7b680f..0000000000000000000000000000000000000000 --- a/services/distributeddataservice/service/config/CMakeLists.txt +++ /dev/null @@ -1,88 +0,0 @@ -cmake_minimum_required(VERSION 3.10.2) -project(config) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -fno-rtti -fvisibility=hidden -D_GNU_SOURCE") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -fPIC -fpic -ffunction-sections -D_GLIBC_MOCK") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-as-needed -ldl") -#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") -#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") -set(MOCK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../mock") -aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src configSrc) -aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src/model configSrc) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/model) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../frameworks/common) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../framework/include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../directory/include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/innerkits/distributeddata/include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../utils_native/base/include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../utils_native/safwk/native/include) -include_directories(${MOCK_DIR}) -include_directories(${MOCK_DIR}/uapi) -include_directories(${MOCK_DIR}/innerkits/sensor/sensor_interface_native/include) -include_directories(${MOCK_DIR}/innerkits/miscdevice/vibrator_interface_native/include) -include_directories(${MOCK_DIR}/innerkits/aafwk_standard/want/include/ohos/aafwk/content) -include_directories(${MOCK_DIR}/innerkits/aafwk_standard/intent/include) -include_directories(${MOCK_DIR}/innerkits/aafwk_standard/ability_manager/include) -include_directories(${MOCK_DIR}/innerkits/aafwk_standard/base/include) -include_directories(${MOCK_DIR}/innerkits/jsapi_worker/worker_init/include) -include_directories(${MOCK_DIR}/innerkits/os_account_standard/libaccountkits/include) -include_directories(${MOCK_DIR}/innerkits/deviceauth_standard/deviceauth_sdk/include) -include_directories(${MOCK_DIR}/innerkits/samgr_standard/samgr_proxy/include) -include_directories(${MOCK_DIR}/innerkits/ipc/ipc_core/include) -include_directories(${MOCK_DIR}/innerkits/ipc/ipc_single/include) -include_directories(${MOCK_DIR}/innerkits/ipc/libdbinder/include) -include_directories(${MOCK_DIR}/innerkits/resmgr_standard/global_resmgr/include) -include_directories(${MOCK_DIR}/innerkits/power_manager_native/powermgr_client/include) -include_directories(${MOCK_DIR}/innerkits/napi/ace_napi/include) -include_directories(${MOCK_DIR}/innerkits/hisysevent_native/libhisysevent/include) -include_directories(${MOCK_DIR}/innerkits/appverify/libhapverify/include) -include_directories(${MOCK_DIR}/innerkits/huks_standard/libhukssdk/include) -include_directories(${MOCK_DIR}/innerkits/inputmethod_native/inputmethod_ability/include) -include_directories(${MOCK_DIR}/innerkits/inputmethod_native/inputmethod_client/include) -include_directories(${MOCK_DIR}/innerkits/safwk/system_ability_fwk/include) -include_directories(${MOCK_DIR}/innerkits/ipc_js/rpc/include) -include_directories(${MOCK_DIR}/innerkits/dataclassification/fbe_iudf_xattr/include) -include_directories(${MOCK_DIR}/innerkits/dataclassification/hwdsl/include) -include_directories(${MOCK_DIR}/innerkits/battery_manager_native/batterysrv_client/include) -include_directories(${MOCK_DIR}/innerkits/permission_standard/libpermissionsdk_standard/include) -include_directories(${MOCK_DIR}/innerkits/hilog_native/libhilog/include) -include_directories(${MOCK_DIR}/innerkits/display_manager_native/displaymgr/include) -include_directories(${MOCK_DIR}/innerkits/i18n_standard/phonenumber_standard/include) -include_directories(${MOCK_DIR}/innerkits/i18n_standard/zone_util/include) -include_directories(${MOCK_DIR}/innerkits/bytrace_standard/bytrace_core/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libmmi-client/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libmmi-client/include/proxy/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libmmi-client/include/event/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libmmi-client/include/common/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libmmi-server/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libmmi-server/include/include) -include_directories(${MOCK_DIR}/innerkits/multimodalinput_base/libinput-third-mmi/include) -include_directories(${MOCK_DIR}/innerkits/appexecfwk_standard/appexecfwk_base/include) -include_directories(${MOCK_DIR}/innerkits/appexecfwk_standard/eventhandler_native/include) -include_directories(${MOCK_DIR}/innerkits/appexecfwk_standard/fmskit_native/include) -include_directories(${MOCK_DIR}/innerkits/appexecfwk_standard/libeventhandler/include) -include_directories(${MOCK_DIR}/innerkits/appexecfwk_standard/appexecfwk_core/include) -include_directories(${MOCK_DIR}/innerkits/hitrace_native/libhitrace/include) -include_directories(${MOCK_DIR}/innerkits/dmsfwk_standard/zuri/include) -include_directories(${MOCK_DIR}/innerkits/ces_standard/cesfwk_services/include) -include_directories(${MOCK_DIR}/innerkits/ces_standard/cesfwk_core/include) -include_directories(${MOCK_DIR}/innerkits/ces_standard/cesfwk_innerkits/include) -include_directories(${MOCK_DIR}/innerkits/multimedia_image_standard/image/include) -include_directories(${MOCK_DIR}/innerkits/ril_adapter/hril/include) -include_directories(${MOCK_DIR}/innerkits/native_appdatamgr/native_dataability/include) -include_directories(${MOCK_DIR}/innerkits/native_appdatamgr/native_preferences/include) -include_directories(${MOCK_DIR}/innerkits/native_appdatamgr/native_rdb/include) -include_directories(${MOCK_DIR}/innerkits/native_appdatamgr/native_appdatafwk/include) -include_directories(${MOCK_DIR}/innerkits/startup_l2/syspara/include) -include_directories(${MOCK_DIR}/innerkits/hicollie_native/libhicollie/include) -include_directories(${MOCK_DIR}/innerkits/dsoftbus_standard/softbus_client/include) -include_directories(${MOCK_DIR}/innerkits/device_manager_base/devicemanagersdk/include) -include_directories(${MOCK_DIR}/innerkits/distributeddatamgr/app_distributeddata/include) -include_directories(${MOCK_DIR}/innerkits/distributeddatamgr/distributeddata_inner/include) -#include_directories(${MOCK_DIR}/innerkits/utils_base/utils/include/include) -set(links secure mock frameworks svcFwk directory) -set(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/../../../../") -add_library(config SHARED ${configSrc}) -target_link_libraries(config ${links}) diff --git a/services/distributeddataservice/service/rdb/rdb_service_impl.cpp b/services/distributeddataservice/service/rdb/rdb_service_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb74d2077b05e844705fe153ca8eec89a45807e8 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2022 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 "RdbServiceImpl" + +#include "rdb_service_impl.h" +#include "account_delegate.h" +#include "checker/checker_manager.h" +#include "communication_provider.h" +#include "kvstore_utils.h" +#include "log_print.h" +#include "kvstore_meta_manager.h" + +using OHOS::DistributedKv::AccountDelegate; +using OHOS::DistributedKv::KvStoreMetaManager; +using OHOS::DistributedKv::MetaData; +using OHOS::AppDistributedKv::CommunicationProvider; +using OHOS::DistributedData::CheckerManager; +using DistributedDB::RelationalStoreManager; + +namespace OHOS::DistributedRdb { +RdbServiceImpl::DeathRecipientImpl::DeathRecipientImpl(const DeathCallback& callback) + : callback_(callback) +{ + ZLOGI("construct"); +} + +RdbServiceImpl::DeathRecipientImpl::~DeathRecipientImpl() +{ + ZLOGI("destroy"); +} + +void RdbServiceImpl::DeathRecipientImpl::OnRemoteDied(const wptr &object) +{ + ZLOGI("enter"); + if (callback_) { + callback_(); + } +} + +RdbServiceImpl::RdbServiceImpl() + : timer_("SyncerTimer", -1), autoLaunchObserver_(this) +{ + ZLOGI("construct"); + timer_.Setup(); + DistributedDB::RelationalStoreManager::SetAutoLaunchRequestCallback( + [this](const std::string& identifier, DistributedDB::AutoLaunchParam ¶m) { + return ResolveAutoLaunch(identifier, param); + }); +} + +bool RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) +{ + std::string identifierHex = TransferStringToHex(identifier); + ZLOGI("%{public}.6s", identifierHex.c_str()); + std::map entries; + if (!KvStoreMetaManager::GetInstance().GetFullMetaData(entries, KvStoreMetaManager::RDB)) { + ZLOGE("get meta failed"); + return false; + } + ZLOGI("size=%{public}d", static_cast(entries.size())); + + for (const auto& [key, entry] : entries) { + auto aIdentifier = DistributedDB::RelationalStoreManager::GetRelationalStoreIdentifier( + entry.kvStoreMetaData.deviceAccountId, entry.kvStoreMetaData.appId, entry.kvStoreMetaData.storeId); + ZLOGI("%{public}s %{public}s %{public}s", entry.kvStoreMetaData.deviceAccountId.c_str(), + entry.kvStoreMetaData.appId.c_str(), entry.kvStoreMetaData.storeId.c_str()); + if (aIdentifier != identifier) { + continue; + } + ZLOGI("find identifier %{public}s", entry.kvStoreMetaData.storeId.c_str()); + param.userId = entry.kvStoreMetaData.deviceAccountId; + param.appId = entry.kvStoreMetaData.appId; + param.storeId = entry.kvStoreMetaData.storeId; + param.path = entry.kvStoreMetaData.dataDir; + param.option.storeObserver = &autoLaunchObserver_; + return true; + } + + ZLOGE("not find identifier"); + return false; +} + +void RdbServiceImpl::OnClientDied(pid_t pid) +{ + ZLOGI("client dead pid=%{public}d", pid); + syncers_.ComputeIfPresent(pid, [this](const auto& key, StoreSyncersType& syncers) { + syncerNum_ -= static_cast(syncers.size()); + for (const auto& [name, syncer] : syncers) { + timer_.Unregister(syncer->GetTimerId()); + } + syncers_.Erase(key); + }); + notifiers_.Erase(pid); + identifiers_.EraseIf([pid](const auto& key, pid_t& value) { + return pid == value; + }); +} + +bool RdbServiceImpl::CheckAccess(const RdbSyncerParam ¶m) +{ + return !CheckerManager::GetInstance().GetAppId(param.bundleName_, GetCallingUid()).empty(); +} + +std::string RdbServiceImpl::ObtainDistributedTableName(const std::string &device, const std::string &table) +{ + ZLOGI("device=%{public}.6s table=%{public}s", device.c_str(), table.c_str()); + auto uuid = AppDistributedKv::CommunicationProvider::GetInstance().GetUuidByNodeId(device); + if (uuid.empty()) { + ZLOGE("get uuid failed"); + return ""; + } + return DistributedDB::RelationalStoreManager::GetDistributedTableName(uuid, table); +} + +std::vector RdbServiceImpl::GetConnectDevices() +{ + auto deviceInfos = AppDistributedKv::CommunicationProvider::GetInstance().GetRemoteNodesBasicInfo(); + std::vector devices; + for (const auto& deviceInfo : deviceInfos) { + devices.push_back(deviceInfo.deviceId); + } + ZLOGI("size=%{public}u", static_cast(devices.size())); + for (const auto& device: devices) { + ZLOGI("%{public}.6s", device.c_str()); + } + return devices; +} + +int32_t RdbServiceImpl::InitNotifier(const RdbSyncerParam& param, const sptr notifier) +{ + if (!CheckAccess(param)) { + ZLOGE("permission error"); + return RDB_ERROR; + } + + pid_t pid = GetCallingPid(); + auto recipient = new(std::nothrow) DeathRecipientImpl([this, pid] { + OnClientDied(pid); + }); + if (recipient == nullptr) { + ZLOGE("malloc recipient failed"); + return RDB_ERROR; + } + + if (!notifier->AddDeathRecipient(recipient)) { + ZLOGE("link to death failed"); + return RDB_ERROR; + } + notifiers_.Insert(pid, iface_cast(notifier)); + ZLOGI("success pid=%{public}d", pid); + + return RDB_OK; +} + +void RdbServiceImpl::OnDataChange(pid_t pid, const DistributedDB::StoreChangedData &data) +{ + DistributedDB::StoreProperty property; + data.GetStoreProperty(property); + ZLOGI("%{public}d %{public}s", pid, property.storeId.c_str()); + if (pid == 0) { + auto identifier = RelationalStoreManager::GetRelationalStoreIdentifier(property.userId, property.appId, + property.storeId); + auto pair = identifiers_.Find(TransferStringToHex(identifier)); + if (!pair.first) { + ZLOGI("client doesn't subscribe"); + return; + } + pid = pair.second; + ZLOGI("fixed pid=%{public}d", pid); + } + notifiers_.ComputeIfPresent(pid, [&data, &property] (const auto& key, const sptr& value) { + std::string device = data.GetDataChangeDevice(); + auto networkId = CommunicationProvider::GetInstance().ToNodeId(device); + value->OnChange(property.storeId, { networkId }); + }); +} + +void RdbServiceImpl::SyncerTimeout(std::shared_ptr syncer) +{ + ZLOGI("%{public}s", syncer->GetStoreId().c_str()); + syncers_.ComputeIfPresent(syncer->GetPid(), [this, &syncer](const auto& key, StoreSyncersType& syncers) { + syncers.erase(syncer->GetStoreId()); + syncerNum_--; + }); +} + +std::shared_ptr RdbServiceImpl::GetRdbSyncer(const RdbSyncerParam ¶m) +{ + if (!CheckAccess(param)) { + ZLOGE("permission error"); + return nullptr; + } + + pid_t pid = GetCallingPid(); + pid_t uid = GetCallingUid(); + std::shared_ptr syncer; + + syncers_.Compute(pid, [this, ¶m, pid, uid, &syncer] (const auto& key, StoreSyncersType& syncers) { + auto it = syncers.find(param.storeName_); + if (it != syncers.end()) { + syncer = it->second; + timer_.Unregister(syncer->GetTimerId()); + uint32_t timerId = timer_.Register([this, syncer]() { SyncerTimeout(syncer); }, SYNCER_TIMEOUT, true); + syncer->SetTimerId(timerId); + return true; + } + if (syncers.size() >= MAX_SYNCER_PER_PROCESS) { + ZLOGE("%{public}d exceed MAX_PROCESS_SYNCER_NUM", pid); + return false; + } + if (syncerNum_ >= MAX_SYNCER_NUM) { + ZLOGE("no available syncer"); + return false; + } + auto syncer_ = std::make_shared(param, new (std::nothrow) RdbStoreObserverImpl(this, pid)); + if (syncer_->Init(pid, uid) != 0) { + return false; + } + syncers[param.storeName_] = syncer_; + syncer = syncer_; + syncerNum_++; + uint32_t timerId = timer_.Register([this, syncer]() { SyncerTimeout(syncer); }, SYNCER_TIMEOUT, true); + syncer->SetTimerId(timerId); + return true; + }); + + if (syncer != nullptr) { + identifiers_.Insert(syncer->GetIdentifier(), pid); + } else { + ZLOGE("syncer is nullptr"); + } + return syncer; +} + +int32_t RdbServiceImpl::SetDistributedTables(const RdbSyncerParam ¶m, const std::vector &tables) +{ + ZLOGI("enter"); + auto syncer = GetRdbSyncer(param); + if (syncer == nullptr) { + return RDB_ERROR; + } + return syncer->SetDistributedTables(tables); +} + +int32_t RdbServiceImpl::DoSync(const RdbSyncerParam ¶m, const SyncOption &option, + const RdbPredicates &predicates, SyncResult &result) +{ + auto syncer = GetRdbSyncer(param); + if (syncer == nullptr) { + return RDB_ERROR; + } + return syncer->DoSync(option, predicates, result); +} + +void RdbServiceImpl::OnAsyncComplete(pid_t pid, uint32_t seqNum, const SyncResult &result) +{ + ZLOGI("pid=%{public}d seqnum=%{public}u", pid, seqNum); + notifiers_.ComputeIfPresent(pid, [seqNum, &result] (const auto& key, const sptr& value) { + value->OnComplete(seqNum, result); + }); +} + +int32_t RdbServiceImpl::DoAsync(const RdbSyncerParam ¶m, uint32_t seqNum, const SyncOption &option, + const RdbPredicates &predicates) +{ + pid_t pid = GetCallingPid(); + ZLOGI("seq num=%{public}u", seqNum); + auto syncer = GetRdbSyncer(param); + if (syncer == nullptr) { + return RDB_ERROR; + } + return syncer->DoAsync(option, predicates, [this, pid, seqNum] (const SyncResult& result) { + OnAsyncComplete(pid, seqNum, result); + }); +} + +std::string RdbServiceImpl::TransferStringToHex(const std::string &origStr) +{ + if (origStr.empty()) { + return ""; + } + const char *hex = "0123456789abcdef"; + std::string tmp; + for (auto item : origStr) { + auto currentByte = static_cast(item); + tmp.push_back(hex[currentByte >> 4]); // high 4 bit to one hex. + tmp.push_back(hex[currentByte & 0x0F]); // low 4 bit to one hex. + } + return tmp; +} + +std::string RdbServiceImpl::GenIdentifier(const RdbSyncerParam ¶m) +{ + pid_t uid = GetCallingUid(); + std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); + std::string appId = CheckerManager::GetInstance().GetAppId(param.bundleName_, uid); + std::string identifier = RelationalStoreManager::GetRelationalStoreIdentifier(userId, appId, param.storeName_); + return TransferStringToHex(identifier); +} + +int32_t RdbServiceImpl::DoSubscribe(const RdbSyncerParam& param) +{ + pid_t pid = GetCallingPid(); + auto identifier = GenIdentifier(param); + ZLOGI("%{public}s %{public}.6s %{public}d", param.storeName_.c_str(), identifier.c_str(), pid); + identifiers_.Insert(identifier, pid); + return RDB_OK; +} + +int32_t RdbServiceImpl::DoUnSubscribe(const RdbSyncerParam& param) +{ + auto identifier = GenIdentifier(param); + ZLOGI("%{public}s %{public}.6s", param.storeName_.c_str(), identifier.c_str()); + identifiers_.Erase(identifier); + return RDB_OK; +} +} \ No newline at end of file diff --git a/services/rdb/rdb_service_impl.h b/services/distributeddataservice/service/rdb/rdb_service_impl.h similarity index 30% rename from services/rdb/rdb_service_impl.h rename to services/distributeddataservice/service/rdb/rdb_service_impl.h index 42b9bf1ef096746b374a99426b2dac0cf91ecbb2..31a96de64acd2b22a384d75bdb257977de25f4ba 100644 --- a/services/rdb/rdb_service_impl.h +++ b/services/distributeddataservice/service/rdb/rdb_service_impl.h @@ -21,36 +21,76 @@ #include #include #include -#include "rdb_syncer_impl.h" +#include "rdb_syncer.h" #include "concurrent_map.h" +#include "store_observer.h" +#include "timer.h" namespace OHOS::DistributedRdb { class RdbServiceImpl : public RdbServiceStub { public: - sptr GetRdbSyncerInner(const RdbSyncerParam& param) override; - - int RegisterClientDeathRecipient(const std::string& bundleName, sptr proxy) override; - - void OnClientDied(pid_t pid, sptr& proxy); + RdbServiceImpl(); -private: - sptr CreateSyncer(const RdbSyncerParam& param, pid_t uid, pid_t pid); + void OnClientDied(pid_t pid); - void ClearClientRecipient(sptr& proxy); + /* IPC interface */ + std::string ObtainDistributedTableName(const std::string& device, const std::string& table) override; + + std::vector GetConnectDevices() override; + + int32_t InitNotifier(const RdbSyncerParam& param, const sptr notifier) override; - void ClearClientSyncers(pid_t pid); + int32_t SetDistributedTables(const RdbSyncerParam& param, const std::vector& tables) override; - class ClientDeathRecipient : public DeathRecipient { + void OnDataChange(pid_t pid, const DistributedDB::StoreChangedData& data); + +protected: + int32_t DoSync(const RdbSyncerParam& param, const SyncOption& option, + const RdbPredicates& predicates, SyncResult& result) override; + + int32_t DoAsync(const RdbSyncerParam& param, uint32_t seqNum, const SyncOption& option, + const RdbPredicates& predicates) override; + + int32_t DoSubscribe(const RdbSyncerParam& param) override; + + int32_t DoUnSubscribe(const RdbSyncerParam& param) override; + +private: + std::string GenIdentifier(const RdbSyncerParam& param); + + bool CheckAccess(const RdbSyncerParam& param); + + bool ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); + + void SyncerTimeout(std::shared_ptr syncer); + + std::shared_ptr GetRdbSyncer(const RdbSyncerParam& param); + + void OnAsyncComplete(pid_t pid, uint32_t seqNum, const SyncResult& result); + + class DeathRecipientImpl : public DeathRecipient { public: - explicit ClientDeathRecipient(std::function&)> callback); - ~ClientDeathRecipient() override; + using DeathCallback = std::function; + explicit DeathRecipientImpl(const DeathCallback& callback); + ~DeathRecipientImpl() override; void OnRemoteDied(const wptr &object) override; private: - std::function&)> callback_; + const DeathCallback callback_; }; - - ConcurrentMap>> syncers_; // identifier - ConcurrentMap, sptr> recipients_; + + using StoreSyncersType = std::map>; + int32_t syncerNum_ {}; + ConcurrentMap syncers_; + ConcurrentMap> notifiers_; + ConcurrentMap identifiers_; + Utils::Timer timer_; + RdbStoreObserverImpl autoLaunchObserver_; + + static std::string TransferStringToHex(const std::string& origStr); + + static constexpr int32_t MAX_SYNCER_NUM = 50; + static constexpr int32_t MAX_SYNCER_PER_PROCESS = 10; + static constexpr int32_t SYNCER_TIMEOUT = 60 * 1000; // ms }; } #endif diff --git a/services/distributeddataservice/service/rdb/rdb_service_stub.cpp b/services/distributeddataservice/service/rdb/rdb_service_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..797d532f890aeed9e4abb6428dc48ba611d00918 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_service_stub.cpp @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2022 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 "RdbServiceStub" + +#include "rdb_service_stub.h" +#include "log_print.h" +#include "itypes_util.h" + +namespace OHOS::DistributedRdb { +int32_t RdbServiceStub::OnRemoteObtainDistributedTableName(MessageParcel &data, MessageParcel &reply) +{ + std::string device; + if (!data.ReadString(device)) { + ZLOGE("read device failed"); + reply.WriteString(""); + return RDB_OK; + } + + std::string table; + if (!data.ReadString(table)) { + ZLOGE("read table failed"); + reply.WriteString(""); + return RDB_OK; + } + + reply.WriteString(ObtainDistributedTableName(device, table)); + return RDB_OK; +} + +int32_t RdbServiceStub::OnRemoteGetConnectDevices(MessageParcel& data, MessageParcel& reply) +{ + std::vector devices = GetConnectDevices(); + if (!reply.WriteStringVector(devices)) { + ZLOGE("write devices failed"); + } + + return RDB_OK; +} + +int32_t RdbServiceStub::OnRemoteInitNotifier(MessageParcel &data, MessageParcel &reply) +{ + int32_t error = RDB_ERROR; + RdbSyncerParam param; + if (!DistributedKv::ITypesUtil::UnMarshalling(data, param)) { + ZLOGE("read param failed"); + reply.WriteInt32(RDB_ERROR); + return RDB_OK; + } + auto notifier = data.ReadRemoteObject(); + if (notifier == nullptr) { + ZLOGE("read object failed"); + reply.WriteInt32(error); + return RDB_OK; + } + if (InitNotifier(param, notifier) != RDB_OK) { + ZLOGE("init notifier failed"); + reply.WriteInt32(error); + return RDB_OK; + } + ZLOGI("success"); + reply.WriteInt32(RDB_OK); + return RDB_OK; +} + +int32_t RdbServiceStub::OnRemoteSetDistributedTables(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + if (!DistributedKv::ITypesUtil::UnMarshalling(data, param)) { + ZLOGE("read param failed"); + reply.WriteInt32(RDB_ERROR); + return RDB_OK; + } + std::vector tables; + data.ReadStringVector(&tables); + reply.WriteInt32(SetDistributedTables(param, tables)); + return RDB_OK; +} + +int32_t RdbServiceStub::OnRemoteDoSync(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + if (!DistributedKv::ITypesUtil::UnMarshalling(data, param)) { + ZLOGE("read param failed"); + reply.WriteInt32(RDB_ERROR); + return RDB_OK; + } + SyncOption option {}; + if (!DistributedKv::ITypesUtil::UnMarshalling(data, option)) { + ZLOGE("read option failed"); + reply.WriteInt32(RDB_ERROR); + return RDB_OK; + } + RdbPredicates predicates; + if (!DistributedKv::ITypesUtil::UnMarshalling(data, predicates)) { + ZLOGE("read predicates failed"); + reply.WriteInt32(RDB_ERROR); + return RDB_OK; + } + + SyncResult result; + if (DoSync(param, option, predicates, result) != RDB_OK) { + reply.WriteInt32(RDB_ERROR); + return RDB_OK; + } + if (!DistributedKv::ITypesUtil::Marshalling(result, reply)) { + reply.WriteInt32(RDB_ERROR); + return RDB_OK; + } + return RDB_OK; +} + +int32_t RdbServiceStub::OnRemoteDoAsync(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + if (!DistributedKv::ITypesUtil::UnMarshalling(data, param)) { + ZLOGE("read param failed"); + reply.WriteInt32(RDB_ERROR); + return RDB_OK; + } + uint32_t seqNum; + if (!data.ReadUint32(seqNum)) { + ZLOGI("read seq num failed"); + reply.WriteInt32(RDB_ERROR); + return RDB_OK; + } + SyncOption option {}; + if (!DistributedKv::ITypesUtil::UnMarshalling(data, option)) { + ZLOGE("read option failed"); + reply.WriteInt32(RDB_ERROR); + return RDB_OK; + } + RdbPredicates predicates; + if (!DistributedKv::ITypesUtil::UnMarshalling(data, predicates)) { + ZLOGE("read predicates failed"); + reply.WriteInt32(RDB_ERROR); + return RDB_OK; + } + + reply.WriteInt32(DoAsync(param, seqNum, option, predicates)); + return RDB_OK; +} + +int32_t RdbServiceStub::OnRemoteDoSubscribe(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + if (!DistributedKv::ITypesUtil::UnMarshalling(data, param)) { + ZLOGE("read param failed"); + reply.WriteInt32(RDB_ERROR); + return RDB_OK; + } + reply.WriteInt32(DoSubscribe(param)); + return RDB_OK; +} + +int32_t RdbServiceStub::OnRemoteDoUnSubscribe(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + if (!DistributedKv::ITypesUtil::UnMarshalling(data, param)) { + ZLOGE("read param failed"); + reply.WriteInt32(RDB_ERROR); + return RDB_OK; + } + reply.WriteInt32(DoUnSubscribe(param)); + return RDB_OK; +} + +bool RdbServiceStub::CheckInterfaceToken(MessageParcel& data) +{ + auto localDescriptor = IRdbService::GetDescriptor(); + auto remoteDescriptor = data.ReadInterfaceToken(); + if (remoteDescriptor != localDescriptor) { + ZLOGE("interface token is not equal"); + return false; + } + return true; +} + +int RdbServiceStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) +{ + ZLOGI("code=%{public}d", code); + if (!CheckInterfaceToken(data)) { + return RDB_ERROR; + } + if (code >= 0 && code < RDB_SERVICE_CMD_MAX) { + return (this->*HANDLERS[code])(data, reply); + } + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} +} \ No newline at end of file diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_service_stub.h b/services/distributeddataservice/service/rdb/rdb_service_stub.h similarity index 34% rename from frameworks/innerkitsimpl/rdb/src/rdb_service_stub.h rename to services/distributeddataservice/service/rdb/rdb_service_stub.h index 3eeab5ce43ea0c34c192edf3d7f3c4dd5ac7d335..c520bc4904b8cc1c18a3a39dd745e4364baef20e 100644 --- a/frameworks/innerkitsimpl/rdb/src/rdb_service_stub.h +++ b/services/distributeddataservice/service/rdb/rdb_service_stub.h @@ -18,26 +18,60 @@ #include #include "irdb_service.h" +#include "rdb_notifier.h" namespace OHOS::DistributedRdb { class RdbServiceStub : public IRemoteStub { public: int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; - - std::shared_ptr GetRdbSyncer(const RdbSyncerParam& param) override { return nullptr; }; - virtual sptr GetRdbSyncerInner(const RdbSyncerParam& param) = 0; - + + int32_t Sync(const RdbSyncerParam& param, const SyncOption& option, + const RdbPredicates& predicates, const SyncCallback& callback) override + { + return 0; + } + + int32_t Subscribe(const RdbSyncerParam& param, const SubscribeOption& option, + RdbStoreObserver *observer) override + { + return 0; + } + + int32_t UnSubscribe(const RdbSyncerParam& param, const SubscribeOption& option, + RdbStoreObserver *observer) override + { + return 0; + } + private: static bool CheckInterfaceToken(MessageParcel& data); + + int32_t OnRemoteObtainDistributedTableName(MessageParcel& data, MessageParcel& reply); + + int32_t OnRemoteGetConnectDevices(MessageParcel& data, MessageParcel& reply); + + int32_t OnRemoteInitNotifier(MessageParcel&data, MessageParcel& reply); - int OnRemoteGetRdbSyncer(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteSetDistributedTables(MessageParcel &data, MessageParcel &reply); - int OnRemoteRegisterClientDeathRecipient(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteDoSync(MessageParcel& data, MessageParcel& reply); - using RequestHandle = int (RdbServiceStub::*)(MessageParcel&, MessageParcel&); - static constexpr RequestHandle HANDLES[RDB_SERVICE_CMD_MAX] = { - [RDB_SERVICE_CMD_GET_SYNCER] = &RdbServiceStub::OnRemoteGetRdbSyncer, - [RDB_SERVICE_CMD_REGISTER_CLIENT_DEATH] = &RdbServiceStub::OnRemoteRegisterClientDeathRecipient, + int32_t OnRemoteDoAsync(MessageParcel& data, MessageParcel& reply); + + int32_t OnRemoteDoSubscribe(MessageParcel& data, MessageParcel& reply); + + int32_t OnRemoteDoUnSubscribe(MessageParcel& data, MessageParcel& reply); + + using RequestHandle = int (RdbServiceStub::*)(MessageParcel &, MessageParcel &); + static constexpr RequestHandle HANDLERS[RDB_SERVICE_CMD_MAX] = { + [RDB_SERVICE_CMD_OBTAIN_TABLE] = &RdbServiceStub::OnRemoteObtainDistributedTableName, + [RDB_SERVICE_CMD_GET_DEVICES] = &RdbServiceStub::OnRemoteGetConnectDevices, + [RDB_SERVICE_CMD_INIT_NOTIFIER] = &RdbServiceStub::OnRemoteInitNotifier, + [RDB_SERVICE_CMD_SET_DIST_TABLE] = &RdbServiceStub::OnRemoteSetDistributedTables, + [RDB_SERVICE_CMD_SYNC] = &RdbServiceStub::OnRemoteDoSync, + [RDB_SERVICE_CMD_ASYNC] = &RdbServiceStub::OnRemoteDoAsync, + [RDB_SERVICE_CMD_SUBSCRIBE] = &RdbServiceStub::OnRemoteDoSubscribe, + [RDB_SERVICE_CMD_UNSUBSCRIBE] = &RdbServiceStub::OnRemoteDoUnSubscribe, }; }; } diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_service.h b/services/distributeddataservice/service/rdb/rdb_store_observer_impl.cpp similarity index 55% rename from frameworks/innerkitsimpl/rdb/src/rdb_service.h rename to services/distributeddataservice/service/rdb/rdb_store_observer_impl.cpp index 7168c9b747b13bf3ece8becc6ea3bb3f3b39d5bf..bc5a16f560ed4da9c14bf85cf36c8a665cdf7e66 100644 --- a/frameworks/innerkitsimpl/rdb/src/rdb_service.h +++ b/services/distributeddataservice/service/rdb/rdb_store_observer_impl.cpp @@ -13,23 +13,29 @@ * limitations under the License. */ -#ifndef DISTRIBUTED_RDB_SERVICE_H -#define DISTRIBUTED_RDB_SERVICE_H +#define LOG_TAG "RdbStoreObserverImpl" -#include -#include - -#include +#include "rdb_store_observer_impl.h" +#include "rdb_service_impl.h" +#include "log_print.h" namespace OHOS::DistributedRdb { -struct RdbSyncerParam; -class RdbSyncer; +RdbStoreObserverImpl::RdbStoreObserverImpl(RdbServiceImpl* owner, pid_t pid) + : pid_(pid), owner_(owner) +{ + ZLOGI("construct"); +} -class RdbService { -public: - virtual std::shared_ptr GetRdbSyncer(const RdbSyncerParam& param) = 0; - - virtual int RegisterClientDeathRecipient(const std::string& bundleName, sptr object) = 0; -}; +RdbStoreObserverImpl::~RdbStoreObserverImpl() +{ + ZLOGI("destroy"); +} + +void RdbStoreObserverImpl::OnChange(const DistributedDB::StoreChangedData &data) +{ + ZLOGI("enter"); + if (owner_ != nullptr) { + owner_->OnDataChange(pid_, data); + } +} } -#endif diff --git a/frameworks/innerkitsimpl/rdb/src/rdb_syncer_proxy.h b/services/distributeddataservice/service/rdb/rdb_store_observer_impl.h similarity index 59% rename from frameworks/innerkitsimpl/rdb/src/rdb_syncer_proxy.h rename to services/distributeddataservice/service/rdb/rdb_store_observer_impl.h index eff2a15aed48461fa8730b6873b994bda3b2243e..87615d1d52178b6bc17df0d7ad9fc823ebc929dc 100644 --- a/frameworks/innerkitsimpl/rdb/src/rdb_syncer_proxy.h +++ b/services/distributeddataservice/service/rdb/rdb_store_observer_impl.h @@ -13,21 +13,25 @@ * limitations under the License. */ -#ifndef DISTRIBUTED_RDB_STORE_PROXY_H -#define DISTRIBUTED_RDB_STORE_PROXY_H +#ifndef DISTRIBUTED_RDB_STORE_OBSERVER_H +#define DISTRIBUTED_RDB_STORE_OBSERVER_H -#include -#include "irdb_syncer.h" +#include +#include "store_observer.h" namespace OHOS::DistributedRdb { -class RdbSyncerProxy : public IRemoteProxy { +class RdbServiceImpl; +class RdbStoreObserverImpl : public DistributedDB::StoreObserver { public: - explicit RdbSyncerProxy(const sptr& object); - - int SetDistributedTables(const std::vector& tables) override; + explicit RdbStoreObserverImpl(RdbServiceImpl* owner, pid_t pid = 0); + + ~RdbStoreObserverImpl() override; + + void OnChange(const DistributedDB::StoreChangedData &data) override; private: - static inline BrokerDelegator delegator_; + pid_t pid_ {}; + RdbServiceImpl* owner_ {}; }; } #endif diff --git a/services/distributeddataservice/service/rdb/rdb_syncer.cpp b/services/distributeddataservice/service/rdb/rdb_syncer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1c48d44cbb0e958f6f28011d849a6970c8e501ed --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_syncer.cpp @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2022 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 "RdbSyncer" + +#include "rdb_syncer.h" + +#include "account_delegate.h" +#include "checker/checker_manager.h" +#include "log_print.h" +#include "kvstore_utils.h" +#include "kvstore_meta_manager.h" + +using OHOS::DistributedKv::AccountDelegate; +using OHOS::DistributedKv::KvStoreMetaManager; +using OHOS::AppDistributedKv::CommunicationProvider; + +namespace OHOS::DistributedRdb { +RdbSyncer::RdbSyncer(const RdbSyncerParam& param, RdbStoreObserverImpl* observer) + : param_(param), observer_(observer) +{ + ZLOGI("construct %{public}s", param_.storeName_.c_str()); +} + +RdbSyncer::~RdbSyncer() noexcept +{ + ZLOGI("destroy %{public}s", param_.storeName_.c_str()); + if ((manager_ != nullptr) && (delegate_ != nullptr)) { + manager_->CloseStore(delegate_); + } + delete manager_; + if (observer_ != nullptr) { + delete observer_; + } +} + +void RdbSyncer::SetTimerId(uint32_t timerId) +{ + timerId_ = timerId; +} + +uint32_t RdbSyncer::GetTimerId() const +{ + return timerId_; +} + +pid_t RdbSyncer::GetPid() const +{ + return pid_; +} + +std::string RdbSyncer::GetIdentifier() const +{ + return DistributedDB::RelationalStoreManager::GetRelationalStoreIdentifier(GetUserId(), GetAppId(), GetStoreId()); +} + +std::string RdbSyncer::GetUserId() const +{ + return AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid_); +} + +std::string RdbSyncer::GetBundleName() const +{ + return param_.bundleName_; +} + +std::string RdbSyncer::GetAppId() const +{ + return DistributedData::CheckerManager::GetInstance().GetAppId(param_.bundleName_, uid_); +} + +std::string RdbSyncer::GetPath() const +{ + return param_.path_; +} + +std::string RdbSyncer::GetStoreId() const +{ + return param_.storeName_; +} + +int32_t RdbSyncer::Init(pid_t pid, pid_t uid) +{ + ZLOGI("enter"); + pid_ = pid; + uid_ = uid; + if (CreateMetaData() != RDB_OK) { + ZLOGE("create meta data failed"); + return RDB_ERROR; + } + ZLOGI("success"); + return RDB_OK; +} + +int32_t RdbSyncer::CreateMetaData() +{ + DistributedKv::KvStoreMetaData meta; + meta.kvStoreType =static_cast(RDB_DEVICE_COLLABORATION); + meta.appId = GetAppId(); + meta.appType = "harmony"; + meta.bundleName = GetBundleName(); + meta.deviceId = CommunicationProvider::GetInstance().GetLocalDevice().deviceId; + meta.storeId = GetStoreId(); + meta.userId = AccountDelegate::GetInstance()->GetCurrentAccountId(GetBundleName()); + meta.uid = uid_; + meta.deviceAccountId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid_); + meta.dataDir = GetPath(); + + std::string metaString = meta.Marshal(); + std::vector metaValue(metaString.begin(), metaString.end()); + auto metaKey = KvStoreMetaManager::GetMetaKey(meta.deviceAccountId, "default", meta.bundleName, meta.storeId); + DistributedKv::KvStoreMetaData oldMeta; + if (KvStoreMetaManager::GetInstance().GetKvStoreMeta(metaKey, oldMeta) == DistributedKv::Status::SUCCESS) { + if (metaString == oldMeta.Marshal()) { + ZLOGI("ignore same meta"); + return RDB_OK; + } + } + auto status = KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(metaKey, DistributedKv::UPDATE, metaValue); + return static_cast(status); +} + +DistributedDB::RelationalStoreDelegate* RdbSyncer::GetDelegate() +{ + std::lock_guard lock(mutex_); + if (manager_ == nullptr) { + manager_ = new(std::nothrow) DistributedDB::RelationalStoreManager(GetAppId(), GetUserId()); + } + if (manager_ == nullptr) { + ZLOGE("malloc manager failed"); + return nullptr; + } + + if (delegate_ == nullptr) { + DistributedDB::RelationalStoreDelegate::Option option; + option.observer = observer_; + ZLOGI("path=%{public}s storeId=%{public}s", GetPath().c_str(), GetStoreId().c_str()); + DistributedDB::DBStatus status = manager_->OpenStore(GetPath(), GetStoreId(), option, delegate_); + if (status != DistributedDB::DBStatus::OK) { + ZLOGE("open store failed status=%{public}d", status); + return nullptr; + } + ZLOGI("open store success"); + } + + return delegate_; +} + +int32_t RdbSyncer::SetDistributedTables(const std::vector &tables) +{ + auto* delegate = GetDelegate(); + if (delegate == nullptr) { + ZLOGE("delegate is nullptr"); + return RDB_ERROR; + } + + for (const auto& table : tables) { + ZLOGI("%{public}s", table.c_str()); + if (delegate->CreateDistributedTable(table) != DistributedDB::DBStatus::OK) { + ZLOGE("create distributed table failed"); + return RDB_ERROR; + } + } + ZLOGE("create distributed table success"); + return RDB_OK; +} + +std::vector RdbSyncer::NetworkIdToUUID(const std::vector &networkIds) +{ + std::vector uuids; + for (const auto& networkId : networkIds) { + auto uuid = CommunicationProvider::GetInstance().GetUuidByNodeId(networkId); + if (uuid.empty()) { + ZLOGE("%{public}.6s failed", networkId.c_str()); + continue; + } + uuids.push_back(uuid); + } + return uuids; +} + +void RdbSyncer::HandleSyncStatus(const std::map> &syncStatus, + SyncResult &result) +{ + for (const auto& status : syncStatus) { + auto res = DistributedDB::DBStatus::OK; + for (const auto& tableStatus : status.second) { + if (tableStatus.status != DistributedDB::DBStatus::OK) { + res = tableStatus.status; + break; + } + } + std::string uuid = CommunicationProvider::GetInstance().ToNodeId(status.first); + if (uuid.empty()) { + ZLOGE("%{public}.6s failed", status.first.c_str()); + continue; + } + ZLOGI("%{public}.6s=%{public}d", uuid.c_str(), res); + result[uuid] = res; + } +} +void RdbSyncer::EqualTo(const RdbPredicateOperation &operation, DistributedDB::Query &query) +{ + query.EqualTo(operation.field_, operation.values_[0]); + ZLOGI("field=%{public}s value=%{public}s", operation.field_.c_str(), operation.values_[0].c_str()); +} + +void RdbSyncer::NotEqualTo(const RdbPredicateOperation &operation, DistributedDB::Query &query) +{ + query.NotEqualTo(operation.field_, operation.values_[0]); + ZLOGI("field=%{public}s value=%{public}s", operation.field_.c_str(), operation.values_[0].c_str()); +} + +void RdbSyncer::And(const RdbPredicateOperation &operation, DistributedDB::Query &query) +{ + query.And(); + ZLOGI(""); +} + +void RdbSyncer::Or(const RdbPredicateOperation &operation, DistributedDB::Query &query) +{ + query.Or(); + ZLOGI(""); +} + +void RdbSyncer::OrderBy(const RdbPredicateOperation &operation, DistributedDB::Query &query) +{ + bool isAsc = operation.values_[0] == "true"; + query.OrderBy(operation.field_, isAsc); + ZLOGI("field=%{public}s isAsc=%{public}s", operation.field_.c_str(), operation.values_[0].c_str()); +} + +void RdbSyncer::Limit(const RdbPredicateOperation &operation, DistributedDB::Query &query) +{ + char *end = nullptr; + int limit = static_cast(strtol(operation.field_.c_str(), &end, DECIMAL_BASE)); + int offset = static_cast(strtol(operation.values_[0].c_str(), &end, DECIMAL_BASE)); + if (limit < 0) { + limit = 0; + } + if (offset < 0) { + offset = 0; + } + query.Limit(limit, offset); + ZLOGI("limit=%{public}d offset=%{public}d", limit, offset); +} + +DistributedDB::Query RdbSyncer::MakeQuery(const RdbPredicates &predicates) +{ + ZLOGI("table=%{public}s", predicates.table_.c_str()); + auto query = DistributedDB::Query::Select(predicates.table_); + for (const auto& device : predicates.devices_) { + ZLOGI("device=%{public}.6s", device.c_str()); + } + for (const auto& operation : predicates.operations_) { + if (operation.operator_ >= 0 && operation.operator_ < OPERATOR_MAX) { + HANDLES[operation.operator_](operation, query); + } + } + return query; +} + +int32_t RdbSyncer::DoSync(const SyncOption &option, const RdbPredicates &predicates, SyncResult &result) +{ + ZLOGI("enter"); + auto* delegate = GetDelegate(); + if (delegate == nullptr) { + ZLOGE("delegate is nullptr"); + return RDB_ERROR; + } + + auto devices = NetworkIdToUUID(predicates.devices_); + ZLOGI("delegate sync"); + return delegate->Sync(devices, static_cast(option.mode), + MakeQuery(predicates), [&result] (const auto& syncStatus) { + HandleSyncStatus(syncStatus, result); + }, true); +} + +int32_t RdbSyncer::DoAsync(const SyncOption &option, const RdbPredicates &predicates, const SyncCallback& callback) +{ + auto* delegate = GetDelegate(); + if (delegate == nullptr) { + ZLOGE("delegate is nullptr"); + return RDB_ERROR; + } + auto devices = NetworkIdToUUID(predicates.devices_); + ZLOGI("delegate sync"); + return delegate->Sync(devices, static_cast(option.mode), + MakeQuery(predicates), [callback] (const auto& syncStatus) { + SyncResult result; + HandleSyncStatus(syncStatus, result); + callback(result); + }, false); +} +} \ No newline at end of file diff --git a/services/distributeddataservice/service/rdb/rdb_syncer.h b/services/distributeddataservice/service/rdb/rdb_syncer.h new file mode 100644 index 0000000000000000000000000000000000000000..b31adfb86ba1794754de3530242f7680eeeecde3 --- /dev/null +++ b/services/distributeddataservice/service/rdb/rdb_syncer.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2022 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 DISTRIBUTED_RDB_SYNCER_H +#define DISTRIBUTED_RDB_SYNCER_H + +#include +#include + +#include "rdb_types.h" +#include "rdb_notifier.h" +#include "rdb_store_observer_impl.h" +#include "relational_store_manager.h" +#include "relational_store_delegate.h" + +namespace OHOS::DistributedRdb { +class RdbSyncer { +public: + RdbSyncer(const RdbSyncerParam& param, RdbStoreObserverImpl* observer); + ~RdbSyncer() noexcept; + + int32_t Init(pid_t pid, pid_t uid); + + pid_t GetPid() const ; + + void SetTimerId(uint32_t timerId); + + uint32_t GetTimerId() const; + + std::string GetStoreId() const; + + std::string GetIdentifier() const; + + int32_t SetDistributedTables(const std::vector& tables); + + int32_t DoSync(const SyncOption& option, const RdbPredicates& predicates, SyncResult& result); + + int32_t DoAsync(const SyncOption& option, const RdbPredicates& predicates, const SyncCallback& callback); + +private: + std::string GetUserId() const; + + std::string GetBundleName() const; + + std::string GetAppId() const; + + std::string GetPath() const; + + int32_t CreateMetaData(); + + DistributedDB::RelationalStoreDelegate* GetDelegate(); + + std::mutex mutex_; + DistributedDB::RelationalStoreManager* manager_ {}; + DistributedDB::RelationalStoreDelegate* delegate_ {}; + RdbSyncerParam param_; + RdbStoreObserverImpl *observer_ {}; + pid_t pid_ {}; + pid_t uid_ {}; + uint32_t timerId_ {}; + + static std::vector NetworkIdToUUID(const std::vector& networkIds); + + static void HandleSyncStatus(const std::map>& SyncStatus, + SyncResult& result); + static DistributedDB::Query MakeQuery(const RdbPredicates& predicates); + static void EqualTo(const RdbPredicateOperation& operation, DistributedDB::Query& query); + static void NotEqualTo(const RdbPredicateOperation& operation, DistributedDB::Query& query); + static void And(const RdbPredicateOperation& operation, DistributedDB::Query& query); + static void Or(const RdbPredicateOperation& operation, DistributedDB::Query& query); + static void OrderBy(const RdbPredicateOperation& operation, DistributedDB::Query& query); + static void Limit(const RdbPredicateOperation& operation, DistributedDB::Query& query); + + using PredicateHandle = void(*)(const RdbPredicateOperation& operation, DistributedDB::Query& query); + static inline PredicateHandle HANDLES[OPERATOR_MAX] = { + [EQUAL_TO] = &RdbSyncer::EqualTo, + [NOT_EQUAL_TO] = &RdbSyncer::NotEqualTo, + [AND] = &RdbSyncer::And, + [OR] = &RdbSyncer::Or, + [ORDER_BY] = &RdbSyncer::OrderBy, + [LIMIT] = &RdbSyncer::Limit, + }; + + static constexpr int DECIMAL_BASE = 10; +}; +} +#endif diff --git a/services/rdb/rdb_device_syncer.cpp b/services/rdb/rdb_device_syncer.cpp deleted file mode 100644 index 8a5da35db2198f498785c16456b9f6f3e2c68db8..0000000000000000000000000000000000000000 --- a/services/rdb/rdb_device_syncer.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2022 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 "RdbDeviceSyncer" - -#include "rdb_device_syncer.h" -#include "log_print.h" -#include "rdb_syncer_factory.h" -#include "relational_store_manager.h" -#include "relational_store_delegate.h" - -namespace OHOS::DistributedRdb { -RdbDeviceSyncer::RdbDeviceSyncer(const RdbSyncerParam ¶m, pid_t uid) - : RdbSyncerImpl(param, uid), isInit_(false), manager_(nullptr), delegate_(nullptr) -{ - ZLOGI("construct %{public}s", param.storeName_.c_str()); -} - -RdbDeviceSyncer::~RdbDeviceSyncer() -{ - ZLOGI("destroy"); - if (manager_ != nullptr & delegate_ != nullptr) { - manager_->CloseStore(delegate_); - } - delete manager_; -} - -int RdbDeviceSyncer::Init() -{ - ZLOGI("enter"); - if (isInit_) { - return 0; - } - manager_ = new(std::nothrow) DistributedDB::RelationalStoreManager(GetAppId(), GetUserId()); - if (manager_ == nullptr) { - ZLOGE("malloc manager failed"); - return -1; - } - if (CreateMetaData() != 0) { - ZLOGE("create meta data failed"); - return -1; - } - isInit_ = true; - ZLOGI("success"); - return 0; -} - -int RdbDeviceSyncer::CreateMetaData() -{ - ZLOGI("enter"); - return 0; -} - -int RdbDeviceSyncer::SetDistributedTables(const std::vector &tables) -{ - auto delegate = GetDelegate(); - if (delegate == nullptr) { - return -1; - } - - for (const auto& table : tables) { - ZLOGI("%{public}s", table.c_str()); - if (delegate->CreateDistributedTable(table) != DistributedDB::DBStatus::OK) { - ZLOGE("create distributed table failed"); - return -1; - } - } - ZLOGE("create distributed table success"); - return 0; -} - -DistributedDB::RelationalStoreDelegate* RdbDeviceSyncer::GetDelegate() -{ - if (manager_ == nullptr) { - ZLOGE("manager_ is nullptr"); - return nullptr; - } - - std::lock_guard lock(mutex_); - if (delegate_ == nullptr) { - ZLOGI("create delegate"); - DistributedDB::RelationalStoreDelegate::Option option; - DistributedDB::DBStatus status = manager_->OpenStore(GetPath(), GetStoreId(), option, delegate_); - if (status != DistributedDB::DBStatus::OK) { - ZLOGE("open store failed status=%{public}d", status); - return nullptr; - } - ZLOGI("open store success"); - } - return delegate_; -} -} - diff --git a/services/rdb/rdb_device_syncer.h b/services/rdb/rdb_device_syncer.h deleted file mode 100644 index aa5f37eb4aad89ed8d818588a96538eae7aec74d..0000000000000000000000000000000000000000 --- a/services/rdb/rdb_device_syncer.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2022 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 DISTRIBUTED_RDB_DEVICE_SYNCER_H -#define DISTRIBUTED_RDB_DEVICE_SYNCER_H - -#include "rdb_syncer_impl.h" -#include "rdb_syncer_stub.h" -#include "rdb_types.h" -#include "rdb_syncer_factory.h" - -namespace DistributedDB { -class RelationalStoreManager; -class RelationalStoreDelegate; -} - -namespace OHOS::DistributedRdb { -class RdbDeviceSyncer : public RdbSyncerImpl { -public: - explicit RdbDeviceSyncer(const RdbSyncerParam& param, pid_t uid); - - ~RdbDeviceSyncer() override; - - /* IPC interface */ - int SetDistributedTables(const std::vector& tables) override; - - /* RdbStore interface */ - int Init() override; - -private: - int CreateMetaData(); - - DistributedDB::RelationalStoreDelegate* GetDelegate(); - - std::mutex mutex_; - bool isInit_; - DistributedDB::RelationalStoreManager* manager_; - DistributedDB::RelationalStoreDelegate* delegate_; - - static inline RdbSyncerRegistration registration_; -}; -} -#endif diff --git a/services/rdb/rdb_service_impl.cpp b/services/rdb/rdb_service_impl.cpp deleted file mode 100644 index 7cae2f86019cafaa86ce2cd5571a67d050cd505e..0000000000000000000000000000000000000000 --- a/services/rdb/rdb_service_impl.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2022 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 "RdbServiceImpl" - -#include "rdb_service_impl.h" -#include "checker/checker_manager.h" -#include "ipc_skeleton.h" -#include "log_print.h" -#include "rdb_syncer_impl.h" -#include "rdb_syncer_factory.h" - -namespace OHOS::DistributedRdb { -using namespace OHOS::DistributedData; -RdbServiceImpl::ClientDeathRecipient::ClientDeathRecipient(std::function&)> callback) - : callback_(std::move(callback)) -{ - ZLOGI("construct"); -} - -RdbServiceImpl::ClientDeathRecipient::~ClientDeathRecipient() -{ - ZLOGI("deconstruct"); -} - -void RdbServiceImpl::ClientDeathRecipient::OnRemoteDied(const wptr& object) -{ - auto objectSptr = object.promote(); - if (objectSptr != nullptr && callback_ != nullptr) { - callback_(objectSptr); - } -} - -void RdbServiceImpl::ClearClientRecipient(sptr& proxy) -{ - recipients_.Erase(proxy); -} - -void RdbServiceImpl::ClearClientSyncers(pid_t pid) -{ - ZLOGI("enter"); - auto count = syncers_.Erase(pid); - ZLOGI("remove %{public}d", static_cast(count)); -} - -void RdbServiceImpl::OnClientDied(pid_t pid, sptr& proxy) -{ - ClearClientRecipient(proxy); - ClearClientSyncers(pid); -} - -sptr RdbServiceImpl::CreateSyncer(const RdbSyncerParam& param, pid_t uid, pid_t pid) -{ - sptr syncer; - syncers_.Compute(pid, [¶m, uid, &syncer] (const auto &key, auto &syncers) -> bool { - ZLOGI("create new syncer %{public}d", key); - auto it = syncers.find(param.storeName_); - if (it != syncers.end()) { - syncer = it->second; - return true; - } - syncer = RdbSyncerFactory::GetInstance().CreateSyncer(param, uid); - if (syncer == nullptr) { - return false; - } - syncer->Init(); - syncers.insert({param.storeName_, syncer}); - return true; - }); - return syncer; -} - -sptr RdbServiceImpl::GetRdbSyncerInner(const RdbSyncerParam& param) -{ - pid_t uid = IPCSkeleton::GetCallingUid(); - pid_t pid = IPCSkeleton::GetCallingPid(); - ZLOGI("%{public}s %{public}s %{public}s", param.bundleName_.c_str(), - param.path_.c_str(), param.storeName_.c_str()); - if (!CheckerManager::GetInstance().IsValid(param.bundleName_, uid)) { - ZLOGI("check access failed"); - return nullptr; - } - return CreateSyncer(param, uid, pid); -} - -int RdbServiceImpl::RegisterClientDeathRecipient(const std::string& bundleName, sptr proxy) -{ - if (proxy == nullptr) { - ZLOGE("recipient is nullptr"); - return -1; - } - - pid_t pid = IPCSkeleton::GetCallingPid(); - sptr recipient = new(std::nothrow) ClientDeathRecipient( - [this, pid](sptr& object) { - OnClientDied(pid, object); - }); - if (recipient == nullptr) { - ZLOGE("malloc failed"); - return -1; - } - if (!proxy->AddDeathRecipient(recipient)) { - ZLOGE("add death recipient failed"); - return -1; - } - if (!recipients_.Insert(proxy, recipient)) { - ZLOGE("insert failed"); - return -1; - } - ZLOGI("success"); - return 0; -} -} diff --git a/services/rdb/rdb_syncer_factory.cpp b/services/rdb/rdb_syncer_factory.cpp deleted file mode 100644 index dd57b7d30539bc8bd065b2ca2cd3c7fedb73bb21..0000000000000000000000000000000000000000 --- a/services/rdb/rdb_syncer_factory.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2022 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 "RdbSyncerFactory" - -#include "rdb_syncer_factory.h" -#include "log_print.h" -#include "rdb_types.h" - -namespace OHOS::DistributedRdb { -RdbSyncerFactory& RdbSyncerFactory::GetInstance() -{ - static RdbSyncerFactory factory; - return factory; -} - -void RdbSyncerFactory::Register(int type, const Creator &creator) -{ - if (creator == nullptr) { - ZLOGE("creator is empty"); - return; - } - ZLOGI("add creator for store type %{public}d", type); - creators_.insert({ type, creator }); -} - -void RdbSyncerFactory::UnRegister(int type) -{ - creators_.erase(type); -} - -RdbSyncerImpl* RdbSyncerFactory::CreateSyncer(const RdbSyncerParam& param, pid_t uid) -{ - auto it = creators_.find(param.type_); - if (it == creators_.end()) { - return nullptr; - } - return it->second(param, uid); -} -} - diff --git a/services/rdb/rdb_syncer_factory.h b/services/rdb/rdb_syncer_factory.h deleted file mode 100644 index ba47258ad755549b5c3a0c15c4191319fb197773..0000000000000000000000000000000000000000 --- a/services/rdb/rdb_syncer_factory.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2022 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 DISTRIBUTED_RDB_STORE_FACTORY_H -#define DISTRIBUTED_RDB_STORE_FACTORY_H - -#include -#include -#include -#include -namespace OHOS::DistributedRdb { -class RdbSyncerImpl; -struct RdbSyncerParam; -class RdbSyncerFactory { -public: - using Creator = std::function; - - static RdbSyncerFactory& GetInstance(); - - void Register(int type, const Creator& creator); - - void UnRegister(int type); - - RdbSyncerImpl* CreateSyncer(const RdbSyncerParam& param, pid_t uid); - -private: - std::map creators_; -}; - -template -class RdbSyncerCreator { -public: - RdbSyncerImpl* operator()(const RdbSyncerParam& param, pid_t uid) - { - return static_cast(new(std::nothrow) T(param, uid)); - } -}; - -template -class RdbSyncerRegistration { -public: - RdbSyncerRegistration(); - - ~RdbSyncerRegistration(); - - RdbSyncerRegistration(const RdbSyncerRegistration&) = delete; - RdbSyncerRegistration(RdbSyncerRegistration&&) = delete; - RdbSyncerRegistration& operator=(const RdbSyncerRegistration&) = delete; - RdbSyncerRegistration& operator=(RdbSyncerRegistration&&) = delete; -}; - -template -RdbSyncerRegistration::RdbSyncerRegistration() -{ - RdbSyncerFactory::GetInstance().Register(type, RdbSyncerCreator()); -} - -template -RdbSyncerRegistration::~RdbSyncerRegistration() -{ - RdbSyncerFactory::GetInstance().UnRegister(type); -} -} -#endif diff --git a/services/rdb/rdb_syncer_impl.cpp b/services/rdb/rdb_syncer_impl.cpp deleted file mode 100644 index 062c4c1f8f4d0739b1952295117ad8e43447ed02..0000000000000000000000000000000000000000 --- a/services/rdb/rdb_syncer_impl.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2022 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 "RdbSyncerImpl" - -#include "rdb_syncer_impl.h" -#include "account_delegate.h" -#include "checker/checker_manager.h" -#include "log_print.h" - -namespace OHOS::DistributedRdb { -using namespace OHOS::DistributedData; -using namespace OHOS::DistributedKv; -RdbSyncerImpl::RdbSyncerImpl(const RdbSyncerParam ¶m, pid_t uid) - : type_(param.type_), bundleName_(param.bundleName_), path_(param.path_), - storeId_(param.storeName_) -{ - ZLOGI("construct %{public}s %{public}s %{public}s %{public}d", - bundleName_.c_str(), userId_.c_str(), storeId_.c_str(), type_); - appId_ = CheckerManager::GetInstance().GetAppId(param.bundleName_, uid); - userId_ = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); - identifier_ = std::to_string(type_) + "-" + appId_ + "-" + userId_ + "-" + storeId_; -} - -RdbSyncerImpl::~RdbSyncerImpl() -{ - ZLOGI("destroy %{public}s", storeId_.c_str()); -} - -bool RdbSyncerImpl::operator==(const RdbSyncerImpl& rhs) const -{ - return identifier_ == rhs.identifier_; -} - -std::string RdbSyncerImpl::GetBundleName() const -{ - return bundleName_; -} - -std::string RdbSyncerImpl::GetAppId() const -{ - return appId_; -} - -std::string RdbSyncerImpl::GetUserId() const -{ - return userId_; -} - -std::string RdbSyncerImpl::GetStoreId() const -{ - return storeId_; -} - -std::string RdbSyncerImpl::GetIdentifier() const -{ - return identifier_; -} - -std::string RdbSyncerImpl::GetPath() const -{ - return path_; -} -} \ No newline at end of file diff --git a/services/rdb/rdb_syncer_impl.h b/services/rdb/rdb_syncer_impl.h deleted file mode 100644 index 76ec6e7a44ab39a4eee2b1897591ce492664aa43..0000000000000000000000000000000000000000 --- a/services/rdb/rdb_syncer_impl.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2022 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 DISTRIBUTED_RDB_SYNCER_IMPL_H -#define DISTRIBUTED_RDB_SYNCER_IMPL_H - -#include "rdb_syncer_stub.h" -#include "rdb_types.h" - -namespace OHOS::DistributedRdb { -class RdbSyncerImpl : public RdbSyncerStub { -public: - explicit RdbSyncerImpl(const RdbSyncerParam& param, pid_t uid); - - RdbSyncerImpl() = delete; - RdbSyncerImpl(const RdbSyncerImpl&) = delete; - RdbSyncerImpl& operator=(const RdbSyncerImpl&) = delete; - - virtual ~RdbSyncerImpl(); - - virtual int Init() = 0; - - bool operator==(const RdbSyncerImpl& rhs) const; - - std::string GetBundleName() const; - - std::string GetAppId() const; - - std::string GetUserId() const; - - std::string GetStoreId() const; - - std::string GetIdentifier() const; - - std::string GetPath() const; - -private: - int type_; - std::string bundleName_; - std::string path_; - std::string storeId_; - std::string appId_; - std::string userId_; - std::string identifier_; -}; -} -#endif