diff --git a/common/include/device_profile_errors.h b/common/include/device_profile_errors.h index b37f31a..cd0824a 100755 --- a/common/include/device_profile_errors.h +++ b/common/include/device_profile_errors.h @@ -30,6 +30,9 @@ enum { // DEVICE_PROFILE_ERR_OFFSET(98566143) ERR_DP_INVALID_PARAMS = 98566144, ERR_DP_INTERFACE_CHECK_FAILED = 98566145, + ERR_DP_GET_LOCAL_UDID_FAILED = 98566146, + ERR_DP_GET_SERVICE_FAILED = 98566147, + ERR_DP_INIT_DB_FAILED = 98566148, }; } // namespace DeviceProfile } // namespace OHOS diff --git a/common/include/parcel_helper.h b/common/include/parcel_helper.h new file mode 100755 index 0000000..5e4dfd7 --- /dev/null +++ b/common/include/parcel_helper.h @@ -0,0 +1,110 @@ +/* + * 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_DEVICE_PROFILE_PARCEL_HELPER_H +#define OHOS_DEVICE_PROFILE_PARCEL_HELPER_H + +#include "ipc_types.h" +#include "device_profile_log.h" + +namespace OHOS { +namespace DeviceProfile { +#define PARCEL_WRITE_HELPER(parcel, type, value) \ + do { \ + bool ret = parcel.Write##type((value)); \ + if (!ret) { \ + HILOGE("write value failed!"); \ + return ERR_FLATTEN_OBJECT; \ + } \ + } while (0) + +#define PARCEL_WRITE_HELPER_NORET(parcel, type, value) \ + do { \ + bool ret = parcel.Write##type((value)); \ + if (!ret) { \ + HILOGE("write value failed!"); \ + return; \ + } \ + } while (0) + +#define PARCEL_WRITE_HELPER_RET(parcel, type, value, failRet) \ + do { \ + bool ret = parcel.Write##type((value)); \ + if (!ret) { \ + HILOGE("write value failed!"); \ + return failRet; \ + } \ + } while (0) + +#define PARCEL_READ_HELPER(parcel, type, out) \ + do { \ + bool ret = parcel.Read##type((out)); \ + if (!ret) { \ + HILOGE("read value failed!"); \ + return ERR_FLATTEN_OBJECT; \ + } \ + } while (0) + +#define PARCEL_READ_HELPER_RET(parcel, type, out, failRet) \ + do { \ + bool ret = parcel.Read##type((out)); \ + if (!ret) { \ + HILOGE("read value failed!"); \ + return failRet; \ + } \ + } while (0) + +#define PARCEL_READ_HELPER_NORET(parcel, type, out) \ + do { \ + bool ret = parcel.Read##type((out)); \ + if (!ret) { \ + HILOGW("read value failed!"); \ + } \ + } while (0) + +#define PARCEL_WRITE_REPLY_NOERROR(reply, type, result) \ + do { \ + bool ret = reply.Write##type(result); \ + if (!ret) { \ + HILOGW("write reply failed!"); \ + } \ + return ERR_OK; \ + } while (0) + +#define PARCEL_TRANSACT_SYNC_RET_INT(remote, code, data, reply) \ + do { \ + MessageOption option; \ + int32_t errCode = remote->SendRequest(code, data, reply, option); \ + if (errCode != ERR_OK) { \ + HILOGE("transact failed, errCode = %{public}d", errCode); \ + return errCode; \ + } \ + HILOGI("transact succeeded"); \ + return ERR_OK; \ + } while (0) + +#define PARCEL_TRANSACT_SYNC_NORET(remote, code, data, reply) \ + do { \ + MessageOption option; \ + int32_t errCode = remote->SendRequest(code, data, reply, option); \ + if (errCode != ERR_OK) { \ + HILOGE("transact failed, errCode = %{public}d", errCode); \ + return; \ + } \ + HILOGI("transact succeeded"); \ + } while (0) +} // namespace DeviceProfile +} // namespace OHOS +#endif // OHOS_DEVICE_PROFILE_PARCEL_HELPER_H diff --git a/interfaces/innerkits/core/BUILD.gn b/interfaces/innerkits/core/BUILD.gn index 553c421..07d3ca5 100755 --- a/interfaces/innerkits/core/BUILD.gn +++ b/interfaces/innerkits/core/BUILD.gn @@ -15,6 +15,7 @@ import("//build/ohos.gni") import("//build/ohos_var.gni") device_profile_path = "//foundation/deviceprofile/device_profile_core" +device_profile_service = "${device_profile_path}/services/core" config("distributed_device_profile_client_config") { visibility = [ ":*" ] @@ -29,6 +30,7 @@ config("distributed_device_profile_client_config") { ohos_shared_library("distributed_device_profile_client") { install_enable = true sources = [ + "${device_profile_service}/src/service_characteristic_profile.cpp", "src/distributed_device_profile_client.cpp", "src/distributed_device_profile_proxy.cpp", ] diff --git a/interfaces/innerkits/core/include/distributed_device_profile_client.h b/interfaces/innerkits/core/include/distributed_device_profile_client.h index 9aac39f..2060f21 100755 --- a/interfaces/innerkits/core/include/distributed_device_profile_client.h +++ b/interfaces/innerkits/core/include/distributed_device_profile_client.h @@ -27,6 +27,8 @@ namespace DeviceProfile { class DistributedDeviceProfileClient { DECLARE_SINGLE_INSTANCE(DistributedDeviceProfileClient); +public: + int32_t PutDeviceProfile(const ServiceCharacteristicProfile& profile); private: class DeviceProfileDeathRecipient : public IRemoteObject::DeathRecipient { public: @@ -34,6 +36,7 @@ private: }; sptr GetDeviceProfileService(); + bool CheckProfileInvalidity(const ServiceCharacteristicProfile& profile); void OnServiceDied(const sptr& remote); std::mutex serviceLock_; sptr dpProxy_; diff --git a/interfaces/innerkits/core/include/distributed_device_profile_proxy.h b/interfaces/innerkits/core/include/distributed_device_profile_proxy.h index 25ac52a..7257579 100755 --- a/interfaces/innerkits/core/include/distributed_device_profile_proxy.h +++ b/interfaces/innerkits/core/include/distributed_device_profile_proxy.h @@ -26,6 +26,7 @@ public: explicit DistributedDeviceProfileProxy(const sptr& impl) : IRemoteProxy(impl) {} ~DistributedDeviceProfileProxy() = default; + int32_t PutDeviceProfile(const ServiceCharacteristicProfile& profile) override; private: static inline BrokerDelegator delegator_; diff --git a/interfaces/innerkits/core/include/idistributed_device_profile.h b/interfaces/innerkits/core/include/idistributed_device_profile.h index c41bca3..39d0861 100755 --- a/interfaces/innerkits/core/include/idistributed_device_profile.h +++ b/interfaces/innerkits/core/include/idistributed_device_profile.h @@ -17,13 +17,17 @@ #define OHOS_I_DISTRIBUTED_DEVICE_PROFILE_H #include "iremote_broker.h" - +#include "service_characteristic_profile.h" namespace OHOS { namespace DeviceProfile { class IDistributedDeviceProfile : public IRemoteBroker { public: + enum { + PUT_DEVICE_PROFILE = 1, + }; + virtual int32_t PutDeviceProfile(const ServiceCharacteristicProfile& profile) = 0; DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DeviceProfile.IDistributedDeviceProfile"); }; } // namespace DeviceProfile diff --git a/interfaces/innerkits/core/include/service_characteristic_profile.h b/interfaces/innerkits/core/include/service_characteristic_profile.h new file mode 100755 index 0000000..009fc8d --- /dev/null +++ b/interfaces/innerkits/core/include/service_characteristic_profile.h @@ -0,0 +1,50 @@ +/* + * 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_DEVICE_SERVICE_PROFILE_CHARACTERISTIC_PROFILE_H +#define OHOS_DEVICE_SERVICE_PROFILE_CHARACTERISTIC_PROFILE_H + +#include "parcel.h" + +namespace OHOS { +namespace DeviceProfile { +class ServiceCharacteristicProfile : public Parcelable { +public: + ServiceCharacteristicProfile() = default; + ~ServiceCharacteristicProfile() = default; + + void SetServiceId(const std::string& serviceId); + void SetServiceType(const std::string& serviceType); + void SetServiceProfileJson(const std::string& profileJson); + void SetCharacteristicProfileJson(const std::string& profileJson); + + const std::string& GetServiceId() const; + const std::string& GetServiceType() const; + const std::string& GetServiceProfileJson() const; + const std::string& GetCharacteristicProfileJson() const; + + bool Marshalling(Parcel& parcel) const override; + bool Unmarshalling(Parcel& parcel); + +private: + std::string serviceId_; + std::string serviceType_; + // reserved, not used currently + std::string serviceProfileJson_; + std::string characteristicProfileJson_; +}; +} // namespace DeviceProfile +} // namespace OHOS +#endif // OHOS_DEVICE_SERVICE_PROFILE_CHARACTERISTIC_PROFILE_H \ No newline at end of file diff --git a/interfaces/innerkits/core/src/distributed_device_profile_client.cpp b/interfaces/innerkits/core/src/distributed_device_profile_client.cpp index 7836130..70772b4 100755 --- a/interfaces/innerkits/core/src/distributed_device_profile_client.cpp +++ b/interfaces/innerkits/core/src/distributed_device_profile_client.cpp @@ -26,9 +26,22 @@ namespace OHOS { namespace DeviceProfile { namespace { const std::string TAG = "DistributedDeviceProfileClient"; +const std::string JSON_NULL = "null"; } IMPLEMENT_SINGLE_INSTANCE(DistributedDeviceProfileClient); +int32_t DistributedDeviceProfileClient::PutDeviceProfile(const ServiceCharacteristicProfile& profile) +{ + if (CheckProfileInvalidity(profile)) { + return ERR_DP_INVALID_PARAMS; + } + + auto dps = GetDeviceProfileService(); + if (dps == nullptr) { + return ERR_DP_GET_SERVICE_FAILED; + } + return dps->PutDeviceProfile(profile); +} sptr DistributedDeviceProfileClient::GetDeviceProfileService() { @@ -57,6 +70,13 @@ sptr DistributedDeviceProfileClient::GetDeviceProfile return dpProxy_; } +bool DistributedDeviceProfileClient::CheckProfileInvalidity(const ServiceCharacteristicProfile& profile) +{ + return profile.GetServiceId().empty() || + profile.GetServiceType().empty() || + profile.GetCharacteristicProfileJson().empty() || + profile.GetCharacteristicProfileJson() == JSON_NULL; +} void DistributedDeviceProfileClient::OnServiceDied(const sptr& remote) { HILOGI("called"); diff --git a/interfaces/innerkits/core/src/distributed_device_profile_proxy.cpp b/interfaces/innerkits/core/src/distributed_device_profile_proxy.cpp index d74599c..17680c0 100755 --- a/interfaces/innerkits/core/src/distributed_device_profile_proxy.cpp +++ b/interfaces/innerkits/core/src/distributed_device_profile_proxy.cpp @@ -16,11 +16,27 @@ #include "distributed_device_profile_proxy.h" #include "device_profile_log.h" +#include "parcel_helper.h" namespace OHOS { namespace DeviceProfile { namespace { const std::string TAG = "DistributedDeviceProfileProxy"; } +int32_t DistributedDeviceProfileProxy::PutDeviceProfile(const ServiceCharacteristicProfile& profile) +{ + sptr remote = Remote(); + MessageParcel data; + if (!data.WriteInterfaceToken(IDistributedDeviceProfile::GetDescriptor())) { + HILOGE("write interface token failed"); + return ERR_FLATTEN_OBJECT; + } + if (!profile.Marshalling(data)) { + HILOGE("marshall profile failed"); + return ERR_FLATTEN_OBJECT; + } + MessageParcel reply; + PARCEL_TRANSACT_SYNC_RET_INT(remote, PUT_DEVICE_PROFILE, data, reply); +} } // namespace DeviceProfile } // namespace OHOS \ No newline at end of file diff --git a/ohos.build b/ohos.build index 42d7236..0ed323f 100755 --- a/ohos.build +++ b/ohos.build @@ -9,8 +9,9 @@ "header_files": [ "distributed_device_profile_client.h", "distributed_device_profile_proxy.h", - "idistributed_device_profile.h" + "idistributed_device_profile.h", + "service_characteristic_profile.h" ] }, "name": "//foundation/deviceprofile/device_profile_core/interfaces/innerkits/core:distributed_device_profile_client" @@ -20,7 +21,10 @@ "//foundation/deviceprofile/device_profile_core/sa_profile:dps_sa_profile", "//foundation/deviceprofile/device_profile_core/services/core:distributed_device_profile" ], - "system_kits": [] + "system_kits": [], + "test_list": [ + "//foundation/deviceprofile/device_profile_core/services/core:unittest" + ] } }, "subsystem": "deviceprofile" diff --git a/services/core/BUILD.gn b/services/core/BUILD.gn index 4b280c4..aad0bea 100755 --- a/services/core/BUILD.gn +++ b/services/core/BUILD.gn @@ -20,8 +20,11 @@ config("device_profile_core_config") { visibility = [ ":*" ] include_dirs = [ "include", + "include/devicemanager", + "include/dbstorage", "${device_profile_path}/common/include", "${device_profile_innerkits}/core/include", + "//third_party/json/include", ] } @@ -30,8 +33,14 @@ dp_common_sources = [] ohos_shared_library("distributed_device_profile") { install_enable = true sources = [ + "src/dbstorage/device_profile_storage.cpp", + "src/dbstorage/device_profile_storage_manager.cpp", + "src/dbstorage/kvstore_death_recipient.cpp", + "src/dbstorage/online_sync_table.cpp", + "src/devicemanager/device_manager.cpp", "src/distributed_device_profile_service.cpp", "src/distributed_device_profile_stub.cpp", + "src/service_characteristic_profile.cpp", ] sources += dp_common_sources @@ -40,12 +49,16 @@ ohos_shared_library("distributed_device_profile") { deps = [ "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara", + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler", + "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata:distributeddata_inner", "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", "//utils/native/base:utils", ] external_deps = [ + "dsoftbus_standard:softbus_client", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", ] @@ -53,3 +66,8 @@ ohos_shared_library("distributed_device_profile") { part_name = "device_profile_core" subsystem_name = "deviceprofile" } + +group("unittest") { + testonly = true + deps = [ "test:unittest" ] +} diff --git a/services/core/include/dbstorage/device_profile_storage.h b/services/core/include/dbstorage/device_profile_storage.h new file mode 100755 index 0000000..2c88ec1 --- /dev/null +++ b/services/core/include/dbstorage/device_profile_storage.h @@ -0,0 +1,69 @@ +/* + * 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_DISTRIBUTED_DEVICE_PROFILE_STORAGE_H +#define OHOS_DISTRIBUTED_DEVICE_PROFILE_STORAGE_H + +#include +#include + +#include "distributed_kv_data_manager.h" +#include "event_handler.h" + +namespace OHOS { +namespace DeviceProfile { +enum StorageInitStatus { + UNINITED = 1, + INIT_FAILED = 2, + INIT_SUCCEED = 3 +}; + +class DeviceProfileStorage { +public: + using KvStoreInitCallback = std::function; + + DeviceProfileStorage(const std::string& appId, const std::string& storeId); + virtual ~DeviceProfileStorage() = default; + + virtual void Init(); + virtual int32_t GetDeviceProfile(const std::string& key, std::string& value); + virtual int32_t PutDeviceProfile(const std::string& key, const std::string& value); + virtual int32_t PutDeviceProfileBatch(const std::vector& keys, + const std::vector& values); + + void SetOptions(const DistributedKv::Options& options); + StorageInitStatus GetInitStatus(); + bool RegisterKvStoreInitCallback(const KvStoreInitCallback& callback); + +private: + bool TryGetKvStore(); + bool InitKvStore(); + DistributedKv::Status GetKvStore(); + void DeleteKvStore(); + +private: + DistributedKv::Options options_; + DistributedKv::AppId appId_; + DistributedKv::StoreId storeId_; + DistributedKv::DistributedKvDataManager dataManager_; + + std::shared_ptr kvStorePtr_; + std::atomic initStatus_ {StorageInitStatus::UNINITED}; + KvStoreInitCallback kvStoreInitCallback_; + std::shared_mutex storageLock_; +}; +} // namespace DeviceProfile +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_DEVICE_PROFILE_STORAGE_H diff --git a/services/core/include/dbstorage/device_profile_storage_manager.h b/services/core/include/dbstorage/device_profile_storage_manager.h new file mode 100755 index 0000000..263551f --- /dev/null +++ b/services/core/include/dbstorage/device_profile_storage_manager.h @@ -0,0 +1,69 @@ +/* + * 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_DISTRIBUTED_DEVICE_PROFILE_STORAGE_MANAGER_H +#define OHOS_DISTRIBUTED_DEVICE_PROFILE_STORAGE_MANAGER_H + +#include +#include + +#include "device_profile_storage.h" +#include "event_handler.h" +#include "kvstore_death_recipient.h" +#include "online_sync_table.h" +#include "service_characteristic_profile.h" +#include "single_instance.h" + +#include "nlohmann/json.hpp" + +namespace OHOS { +namespace DeviceProfile { +enum KeyType { + UNKNOWN = -1, + SERVICE = 0, + SERVICE_LIST = 1, + DEVICE_INFO = 2 +}; + +class DeviceProfileStorageManager { + DECLARE_SINGLE_INSTANCE(DeviceProfileStorageManager); + +public: + bool Init(); + void OnKvStoreInitDone(); + + int32_t PutDeviceProfile(const ServiceCharacteristicProfile& profile); + +private: + bool WaitKvDataService(); + void RestoreServiceItemLocked(const std::string& value); + void FlushProfileItems(); + std::string GenerateKey(const std::string& udid, const std::string& key, KeyType keyType); + + +private: + std::mutex serviceLock_; + nlohmann::json servicesJson_; + std::unique_ptr onlineSyncTbl_; + std::shared_ptr storageHandler_; + sptr kvStoreDeathRecipient_; + std::string localUdid_; + std::map profileItems_; + std::atomic kvDataServiceFailed_ {false}; + std::atomic inited_ {false}; +}; +} // namespace DeviceProfile +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_DEVICE_PROFILE_STORAGE_MANAGER_H \ No newline at end of file diff --git a/services/core/include/dbstorage/kvstore_death_recipient.h b/services/core/include/dbstorage/kvstore_death_recipient.h new file mode 100755 index 0000000..a8c8cec --- /dev/null +++ b/services/core/include/dbstorage/kvstore_death_recipient.h @@ -0,0 +1,29 @@ +/* + * 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_KVSTORE_DEATH_RECIPIENT_H +#define OHOS_KVSTORE_DEATH_RECIPIENT_H + +#include "iremote_object.h" + +namespace OHOS { +namespace DeviceProfile { +class KvStoreDeathRecipient : public IRemoteObject::DeathRecipient { +public: + void OnRemoteDied(const wptr& remote) override; +}; +} // namespace DeviceProfile +} // namespace OHOS +#endif // OHOS_KVSTORE_DEATH_RECIPIENT_H \ No newline at end of file diff --git a/services/core/include/dbstorage/online_sync_table.h b/services/core/include/dbstorage/online_sync_table.h new file mode 100755 index 0000000..b08c065 --- /dev/null +++ b/services/core/include/dbstorage/online_sync_table.h @@ -0,0 +1,32 @@ +/* + * 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_DISTRIBUTED_DEVICE_PROFILE_ONLINE_SYNC_TABLE_H +#define OHOS_DISTRIBUTED_DEVICE_PROFILE_ONLINE_SYNC_TABLE_H + +#include "device_profile_storage.h" + +namespace OHOS { +namespace DeviceProfile { +class OnlineSyncTable : public DeviceProfileStorage { +public: + OnlineSyncTable(); + ~OnlineSyncTable() = default; + + void Init() override; +}; +} // namespace DeviceProfile +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_DEVICE_PROFILE_ONLINE_SYNC_TABLE_H \ No newline at end of file diff --git a/services/core/include/devicemanager/device_manager.h b/services/core/include/devicemanager/device_manager.h new file mode 100755 index 0000000..333d706 --- /dev/null +++ b/services/core/include/devicemanager/device_manager.h @@ -0,0 +1,34 @@ +/* + * 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_DEVICE_PROFILE_DEVICE_MANAGER_H +#define OHOS_DEVICE_PROFILE_DEVICE_MANAGER_H + +#include + + +#include "single_instance.h" + +namespace OHOS { +namespace DeviceProfile { +class DeviceManager { + DECLARE_SINGLE_INSTANCE(DeviceManager); +public: + bool Init(); + void GetLocalDeviceUdid(std::string& udid); +}; +} // namespace DeviceProfile +} // namespace OHOS +#endif // OHOS_DEVICE_PROFILE_DEVICE_MANAGER_H diff --git a/services/core/include/distributed_device_profile_service.h b/services/core/include/distributed_device_profile_service.h index 8c78322..9a19fa7 100755 --- a/services/core/include/distributed_device_profile_service.h +++ b/services/core/include/distributed_device_profile_service.h @@ -31,6 +31,7 @@ public: DistributedDeviceProfileService(); ~DistributedDeviceProfileService() = default; + int32_t PutDeviceProfile(const ServiceCharacteristicProfile& profile) override; protected: void OnStart() override; void OnStop() override; diff --git a/services/core/include/distributed_device_profile_stub.h b/services/core/include/distributed_device_profile_stub.h index 4d6a016..7d95a12 100755 --- a/services/core/include/distributed_device_profile_stub.h +++ b/services/core/include/distributed_device_profile_stub.h @@ -32,6 +32,7 @@ public: int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) override; + int32_t PutDeviceProfileInner(MessageParcel& data, MessageParcel& reply); private: using Func = int32_t(DistributedDeviceProfileStub::*)(MessageParcel& data, MessageParcel& reply); diff --git a/services/core/src/dbstorage/device_profile_storage.cpp b/services/core/src/dbstorage/device_profile_storage.cpp new file mode 100755 index 0000000..a5acb8d --- /dev/null +++ b/services/core/src/dbstorage/device_profile_storage.cpp @@ -0,0 +1,189 @@ +/* + * 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 "device_profile_storage.h" + +#include +#include + +#include "device_profile_errors.h" +#include "device_profile_log.h" +#include "device_profile_storage_manager.h" +#include "service_characteristic_profile.h" + +#include "datetime_ex.h" + +namespace OHOS { +namespace DeviceProfile { +using namespace OHOS::DistributedKv; +using namespace std::chrono_literals; + +namespace { +const std::string TAG = "DeviceProfileStorage"; + +constexpr int32_t RETRY_TIMES_GET_KVSTORE = 10; +} + +DeviceProfileStorage::DeviceProfileStorage(const std::string& appId, const std::string& storeId) +{ + appId_.appId = appId, + storeId_.storeId = storeId; +} + +void DeviceProfileStorage::SetOptions(const Options& options) +{ + options_ = options; +} + +bool DeviceProfileStorage::RegisterKvStoreInitCallback(const KvStoreInitCallback& callback) +{ + if (kvStoreInitCallback_ != nullptr) { + HILOGE("callback is not null"); + return false; + } + kvStoreInitCallback_ = callback; + return true; +} + +void DeviceProfileStorage::Init() +{ + int64_t begin = GetTickCount(); + std::unique_lock writeLock(storageLock_); + bool result = TryGetKvStore(); + writeLock.unlock(); + int64_t end = GetTickCount(); + HILOGI("TryGetKvStore %{public}s, spend %{public}" PRId64 " ms", + result ? "succeeded" : "failed", end - begin); + // must call callback before set init status + if (kvStoreInitCallback_ != nullptr) { + kvStoreInitCallback_(); + } + initStatus_ = StorageInitStatus::INIT_SUCCEED; +} + +StorageInitStatus DeviceProfileStorage::GetInitStatus() +{ + return initStatus_; +} + +bool DeviceProfileStorage::TryGetKvStore() +{ + int32_t retryTimes = 0; + while (retryTimes < RETRY_TIMES_GET_KVSTORE) { + if (GetKvStore() == Status::SUCCESS && kvStorePtr_ != nullptr) { + return true; + } + HILOGD("retry get kvstore..."); + std::this_thread::sleep_for(500ms); + retryTimes++; + } + if (kvStorePtr_ == nullptr) { + initStatus_ = StorageInitStatus::INIT_FAILED; + return false; + } + return true; +} + +Status DeviceProfileStorage::GetKvStore() +{ + HILOGD("called"); + Status status = dataManager_.GetSingleKvStore(options_, appId_, storeId_, kvStorePtr_); + if (status != Status::SUCCESS) { + HILOGI("get failed, error = %{public}d", status); + } else { + HILOGI("get succeeded"); + } + return status; +} + +void DeviceProfileStorage::DeleteKvStore() +{ + Status status = dataManager_.DeleteKvStore(appId_, storeId_); + if (status != Status::SUCCESS) { + HILOGE("delete failed, error = %{public}d", status); + } +} + +int32_t DeviceProfileStorage::GetDeviceProfile(const std::string& key, std::string& value) +{ + std::shared_lock readLock(storageLock_); + if (kvStorePtr_ == nullptr) { + HILOGE("null kvstore"); + return ERR_DP_INVALID_PARAMS; + } + + Key k(key); + Value v; + Status status = kvStorePtr_->Get(k, v); + if (status != Status::SUCCESS) { + HILOGE("get failed, %{public}d", status); + return static_cast(status); + } + value = v.ToString(); + HILOGI("get succeeded"); + return static_cast(status); +} + +int32_t DeviceProfileStorage::PutDeviceProfile(const std::string& key, const std::string& value) +{ + std::unique_lock writeLock(storageLock_); + if (kvStorePtr_ == nullptr) { + HILOGE("null kvstore"); + return ERR_DP_INVALID_PARAMS; + } + + Key k(key); + Value v(value); + Status status = kvStorePtr_->Put(k, v); + if (status != Status::SUCCESS) { + HILOGE("put failed, error = %{public}d", status); + } + return static_cast(status); +} + +int32_t DeviceProfileStorage::PutDeviceProfileBatch(const std::vector& keys, + const std::vector& values) +{ + std::unique_lock writeLock(storageLock_); + if (kvStorePtr_ == nullptr) { + HILOGE("null kvstore"); + return ERR_DP_INVALID_PARAMS; + } + + const size_t keySize = keys.size(); + const size_t valSize = values.size(); + HILOGI("keySize = %{public}zu, valSize = %{public}zu", keySize, valSize); + if (keySize != valSize) { + HILOGE("diff key-value size"); + return ERR_DP_INVALID_PARAMS; + } + + std::vector entries; + entries.reserve(keySize); + for (uint32_t i = 0; i < keySize; i++) { + Entry entry; + entry.key = keys[i]; + entry.value = values[i]; + entries.emplace_back(entry); + } + + Status status = kvStorePtr_->PutBatch(entries); + if (status != Status::SUCCESS) { + HILOGE("put batch failed, error = %{public}d", status); + } + return static_cast(status); +} +} // namespace DeviceProfile +} // namespace OHOS diff --git a/services/core/src/dbstorage/device_profile_storage_manager.cpp b/services/core/src/dbstorage/device_profile_storage_manager.cpp new file mode 100755 index 0000000..c9804e4 --- /dev/null +++ b/services/core/src/dbstorage/device_profile_storage_manager.cpp @@ -0,0 +1,213 @@ +/* + * 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 "device_profile_storage_manager.h" + +#include +#include + +#include "device_manager.h" +#include "device_profile_errors.h" +#include "device_profile_log.h" + +#include "ipc_object_proxy.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" + +namespace OHOS { +namespace DeviceProfile { +using namespace std::chrono_literals; +using namespace OHOS::DistributedKv; + +namespace { +const std::string TAG = "DeviceProfileStorageManager"; + +const std::string SERVICE_TYPE = "type"; +const std::string SERVICES = "services"; +constexpr int32_t RETRY_TIMES_WAIT_KV_DATA = 30; +} + +IMPLEMENT_SINGLE_INSTANCE(DeviceProfileStorageManager); + +bool DeviceProfileStorageManager::Init() +{ + if (!inited_) { + DeviceManager::GetInstance().GetLocalDeviceUdid(localUdid_); + if (localUdid_.empty()) { + HILOGE("get local udid failed"); + return false; + } + onlineSyncTbl_ = std::make_unique(); + if (onlineSyncTbl_ == nullptr) { + return false; + } + + kvStoreDeathRecipient_ = sptr(new KvStoreDeathRecipient()); + auto runner = AppExecFwk::EventRunner::Create("dpstorage"); + storageHandler_ = std::make_shared(runner); + if (storageHandler_ == nullptr) { + return false; + } + inited_ = true; + } + + auto waitTask = [this]() { + if (!WaitKvDataService()) { + std::lock_guard autoLock(serviceLock_); + profileItems_.clear(); + kvDataServiceFailed_ = true; + return; + } + auto callback = std::bind(&DeviceProfileStorageManager::OnKvStoreInitDone, this); + onlineSyncTbl_->RegisterKvStoreInitCallback(callback); + onlineSyncTbl_->Init(); + }; + if (!storageHandler_->PostTask(waitTask)) { + HILOGE("post task failed"); + return false; + } + HILOGI("init succeeded"); + return true; +} + +bool DeviceProfileStorageManager::WaitKvDataService() +{ + auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgrProxy == nullptr) { + HILOGE("get samgrProxy failed"); + return false; + } + int32_t retryTimes = RETRY_TIMES_WAIT_KV_DATA; + do { + auto kvDataSvr = samgrProxy->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID); + if (kvDataSvr != nullptr) { + IPCObjectProxy* proxy = reinterpret_cast(kvDataSvr.GetRefPtr()); + if (proxy != nullptr && !proxy->IsObjectDead()) { + HILOGI("get service succeed"); + proxy->AddDeathRecipient(kvStoreDeathRecipient_); + return true; + } + } + HILOGD("waiting for service..."); + std::this_thread::sleep_for(1s); + if (--retryTimes <= 0) { + HILOGE("waiting service timeout(30)s"); + return false; + } + } while (true); + return false; +} + +std::string DeviceProfileStorageManager::GenerateKey(const std::string& udid, + const std::string& key, KeyType keyType) +{ + std::string tmp; + tmp.append(udid).append("/").append(std::to_string(keyType)).append("/").append(key); + return tmp; +} + +int32_t DeviceProfileStorageManager::PutDeviceProfile(const ServiceCharacteristicProfile& profile) +{ + if (kvDataServiceFailed_ || onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_FAILED) { + HILOGE("kvstore init failed"); + return ERR_DP_INIT_DB_FAILED; + } + + std::vector keys; + std::vector values; + std::string serviceId = profile.GetServiceId(); + keys.emplace_back(GenerateKey(localUdid_, serviceId, KeyType::SERVICE)); + values.emplace_back(profile.GetCharacteristicProfileJson()); + std::unique_lock autoLock(serviceLock_); + if (servicesJson_[serviceId] == nullptr) { + nlohmann::json j; + j[SERVICE_TYPE] = profile.GetServiceType(); + servicesJson_[serviceId] = j; + keys.emplace_back(GenerateKey(localUdid_, SERVICES, KeyType::SERVICE_LIST)); + values.emplace_back(servicesJson_.dump()); + } + + int32_t errCode = ERR_OK; + if (onlineSyncTbl_->GetInitStatus() == StorageInitStatus::INIT_SUCCEED) { + autoLock.unlock(); + if (keys.size() > 1) { + errCode = onlineSyncTbl_->PutDeviceProfileBatch(keys, values); + } else { + errCode = onlineSyncTbl_->PutDeviceProfile(keys[0], values[0]); + } + } else { + for (size_t i = 0; i < keys.size(); i++) { + profileItems_[keys[i]] = values[i]; + } + } + return errCode; +} + +void DeviceProfileStorageManager::RestoreServiceItemLocked(const std::string& value) +{ + auto restoreItems = nlohmann::json::parse(value, nullptr, false); + if (restoreItems.is_discarded()) { + HILOGE("parse error"); + return; + } + for (const auto& [key, value] : servicesJson_.items()) { + restoreItems[key] = value; + } + servicesJson_ = std::move(restoreItems); +} + +void DeviceProfileStorageManager::FlushProfileItems() +{ + std::string services; + std::string servicesKey = GenerateKey(localUdid_, SERVICES, KeyType::SERVICE_LIST); + int32_t errCode = onlineSyncTbl_->GetDeviceProfile(servicesKey, services); + std::unique_lock autoLock(serviceLock_); + if (errCode == ERR_OK) { + RestoreServiceItemLocked(services); + } + + std::vector keys; + std::vector values; + size_t itemSize = profileItems_.size(); + HILOGI("profile item size = %{public}zu", itemSize); + if (itemSize == 0) { + return; + } + keys.reserve(itemSize); + values.reserve(itemSize); + // update service list to avoid overwriting the value in db storage + profileItems_[servicesKey] = servicesJson_.dump(); + for (const auto& [key, value] : profileItems_) { + keys.emplace_back(key); + values.emplace_back(value); + HILOGD("key = %{public}s, value = %{public}s", key.c_str(), value.c_str()); + } + profileItems_.clear(); + autoLock.unlock(); + + errCode = onlineSyncTbl_->PutDeviceProfileBatch(keys, values); + if (errCode != ERR_OK) { + HILOGE("put failed, errCode = %{public}d", errCode); + } +} + +void DeviceProfileStorageManager::OnKvStoreInitDone() +{ + FlushProfileItems(); +} + +} // namespace DeviceProfile +} // namespace OHOS diff --git a/services/core/src/dbstorage/kvstore_death_recipient.cpp b/services/core/src/dbstorage/kvstore_death_recipient.cpp new file mode 100755 index 0000000..f40f8a8 --- /dev/null +++ b/services/core/src/dbstorage/kvstore_death_recipient.cpp @@ -0,0 +1,33 @@ +/* + * 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 "kvstore_death_recipient.h" + +#include "device_profile_log.h" +#include "device_profile_storage_manager.h" + +namespace OHOS { +namespace DeviceProfile { +namespace { +const std::string TAG = "KvStoreDeathRecipient"; +} + +void KvStoreDeathRecipient::OnRemoteDied(const wptr& remote) +{ + HILOGI("called"); + DeviceProfileStorageManager::GetInstance().Init(); +} +} // namespace DeviceProfile +} // namespace OHOS \ No newline at end of file diff --git a/services/core/src/dbstorage/online_sync_table.cpp b/services/core/src/dbstorage/online_sync_table.cpp new file mode 100755 index 0000000..5a7bf45 --- /dev/null +++ b/services/core/src/dbstorage/online_sync_table.cpp @@ -0,0 +1,48 @@ +/* + * 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 "online_sync_table.h" + +#include "device_profile_log.h" + +namespace OHOS { +namespace DeviceProfile { +using namespace OHOS::DistributedKv; + +namespace { +const std::string TAG = "OnlineSyncTable"; + +const std::string APP_ID = "distributed_device_profile_service"; +const std::string STORE_ID = "online_sync_storage"; +} + +OnlineSyncTable::OnlineSyncTable() : DeviceProfileStorage(APP_ID, STORE_ID) +{ +} + +void OnlineSyncTable::Init() +{ + HILOGD("called"); + Options options = { + .createIfMissing = true, + .encrypt = false, + .autoSync = false, + .kvStoreType = KvStoreType::SINGLE_VERSION, + }; + SetOptions(options); + DeviceProfileStorage::Init(); +} +} // namespace DeviceProfile +} // namespace OHOS diff --git a/services/core/src/devicemanager/device_manager.cpp b/services/core/src/devicemanager/device_manager.cpp new file mode 100755 index 0000000..a011800 --- /dev/null +++ b/services/core/src/devicemanager/device_manager.cpp @@ -0,0 +1,44 @@ +/* + * 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 "device_manager.h" + +#include "parameter.h" + +#include "device_profile_log.h" + +namespace OHOS { +namespace DeviceProfile { +namespace { +const std::string TAG = "DeviceManager"; + +constexpr int32_t DEVICE_ID_SIZE = 65; +} + +IMPLEMENT_SINGLE_INSTANCE(DeviceManager); + +bool DeviceManager::Init() +{ + return true; +} + +void DeviceManager::GetLocalDeviceUdid(std::string& udid) +{ + char localDeviceId[DEVICE_ID_SIZE] = {0}; + GetDevUdid(localDeviceId, DEVICE_ID_SIZE); + udid = localDeviceId; +} +} // namespace DeviceProfile +} // namespace OHOS diff --git a/services/core/src/distributed_device_profile_service.cpp b/services/core/src/distributed_device_profile_service.cpp index c5c098e..34c768e 100755 --- a/services/core/src/distributed_device_profile_service.cpp +++ b/services/core/src/distributed_device_profile_service.cpp @@ -15,8 +15,10 @@ #include "distributed_device_profile_service.h" +#include "device_manager.h" #include "device_profile_log.h" - +#include "device_profile_storage_manager.h" +#include "service_characteristic_profile.h" #include "system_ability_definition.h" @@ -36,10 +38,23 @@ DistributedDeviceProfileService::DistributedDeviceProfileService() bool DistributedDeviceProfileService::Init() { + if (!DeviceManager::GetInstance().Init()) { + HILOGE("DeviceManager init failed"); + return false; + } + if (!DeviceProfileStorageManager::GetInstance().Init()) { + HILOGE("DeviceProfileStorageManager init failed"); + return false; + } HILOGI("init succeeded"); return true; } +int32_t DistributedDeviceProfileService::PutDeviceProfile(const ServiceCharacteristicProfile& profile) +{ + return DeviceProfileStorageManager::GetInstance().PutDeviceProfile(profile); +} + void DistributedDeviceProfileService::OnStart() { HILOGI("called"); diff --git a/services/core/src/distributed_device_profile_stub.cpp b/services/core/src/distributed_device_profile_stub.cpp index c6d8182..cbe65f1 100755 --- a/services/core/src/distributed_device_profile_stub.cpp +++ b/services/core/src/distributed_device_profile_stub.cpp @@ -19,6 +19,7 @@ #include "device_profile_errors.h" #include "device_profile_log.h" +#include "device_profile_storage.h" namespace OHOS { namespace DeviceProfile { @@ -28,6 +29,7 @@ const std::string TAG = "DistributedDeviceProfileStub"; DistributedDeviceProfileStub::DistributedDeviceProfileStub() { + funcsMap_[PUT_DEVICE_PROFILE] = &DistributedDeviceProfileStub::PutDeviceProfileInner; } bool DistributedDeviceProfileStub::EnforceInterfaceToken(MessageParcel& data) @@ -54,5 +56,14 @@ int32_t DistributedDeviceProfileStub::OnRemoteRequest(uint32_t code, MessageParc HILOGW("unknown request code, please check"); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } +int32_t DistributedDeviceProfileStub::PutDeviceProfileInner(MessageParcel& data, MessageParcel& reply) +{ + HILOGI("called"); + ServiceCharacteristicProfile profile; + if (!profile.Unmarshalling(data)) { + return ERR_NULL_OBJECT; + } + return PutDeviceProfile(profile); +} } // namespace DeviceProfile } // namespace OHOS \ No newline at end of file diff --git a/services/core/src/service_characteristic_profile.cpp b/services/core/src/service_characteristic_profile.cpp new file mode 100755 index 0000000..10f7843 --- /dev/null +++ b/services/core/src/service_characteristic_profile.cpp @@ -0,0 +1,85 @@ +/* + * 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 "service_characteristic_profile.h" + +#include "device_profile_log.h" +#include "parcel_helper.h" + +namespace OHOS { +namespace DeviceProfile { +namespace { +const std::string TAG = "ServiceCharacteristicProfile"; +} + +void ServiceCharacteristicProfile::SetServiceId(const std::string& serviceId) +{ + serviceId_ = serviceId; +} + +void ServiceCharacteristicProfile::SetServiceType(const std::string& serviceType) +{ + serviceType_ = serviceType; +} + +void ServiceCharacteristicProfile::SetServiceProfileJson(const std::string& profileJson) +{ + serviceProfileJson_ = profileJson; +} + +void ServiceCharacteristicProfile::SetCharacteristicProfileJson(const std::string& profileJson) +{ + characteristicProfileJson_ = profileJson; +} + +const std::string& ServiceCharacteristicProfile::GetServiceId() const +{ + return serviceId_; +} + +const std::string& ServiceCharacteristicProfile::GetServiceType() const +{ + return serviceType_; +} + +const std::string& ServiceCharacteristicProfile::GetServiceProfileJson() const +{ + return serviceProfileJson_; +} + +const std::string& ServiceCharacteristicProfile::GetCharacteristicProfileJson() const +{ + return characteristicProfileJson_; +} + +bool ServiceCharacteristicProfile::Marshalling(Parcel& parcel) const +{ + PARCEL_WRITE_HELPER_RET(parcel, String, serviceId_, false); + PARCEL_WRITE_HELPER_RET(parcel, String, serviceType_, false); + PARCEL_WRITE_HELPER_RET(parcel, String, characteristicProfileJson_, false); + PARCEL_WRITE_HELPER_RET(parcel, String, serviceProfileJson_, false); + return true; +} + +bool ServiceCharacteristicProfile::Unmarshalling(Parcel& parcel) +{ + PARCEL_READ_HELPER_RET(parcel, String, serviceId_, false); + PARCEL_READ_HELPER_RET(parcel, String, serviceType_, false); + PARCEL_READ_HELPER_RET(parcel, String, characteristicProfileJson_, false); + PARCEL_READ_HELPER_RET(parcel, String, serviceProfileJson_, false); + return true; +} +} // namespace DeviceProfile +} // namespace OHOS diff --git a/services/core/test/BUILD.gn b/services/core/test/BUILD.gn new file mode 100755 index 0000000..ef68cce --- /dev/null +++ b/services/core/test/BUILD.gn @@ -0,0 +1,55 @@ +# 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") +import("//build/ohos_var.gni") +import("//build/test.gni") + +module_output_path = "deviceprofile/deviceprofiletest" + +device_profile_path = "//foundation/deviceprofile/device_profile_core" +device_profile_innerkits = "${device_profile_path}/interfaces/innerkits" +device_profile_service = "${device_profile_path}/services" + +device_profile_configs = + [ "${device_profile_service}/core:device_profile_core_config" ] + +device_profile_deps = [ + "${device_profile_innerkits}/core:distributed_device_profile_client", + "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler", + "//utils/native/base:utils", +] + +device_profile_external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", +] + +device_profile_public_deps = [ "//third_party/googletest:gtest_main" ] + +ohos_unittest("profile_crud_test") { + module_out_path = module_output_path + + sources = [ "unittest/profile_crud_test.cpp" ] + configs = device_profile_configs + deps = device_profile_deps + if (is_standard_system) { + external_deps = device_profile_external_deps + public_deps = device_profile_public_deps + } +} +group("unittest") { + testonly = true + deps = [ ":profile_crud_test" ] +} diff --git a/services/core/test/unittest/profile_crud_test.cpp b/services/core/test/unittest/profile_crud_test.cpp new file mode 100755 index 0000000..9db6eaa --- /dev/null +++ b/services/core/test/unittest/profile_crud_test.cpp @@ -0,0 +1,172 @@ +/* + * 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 "gtest/gtest.h" + +#include "utils.h" + +#define private public +#define protected public +#include "device_profile_errors.h" +#include "distributed_device_profile_client.h" +#include "nlohmann/json.hpp" +#undef private +#undef protected + +namespace OHOS { +namespace DeviceProfile { +using namespace testing; +using namespace testing::ext; + +class ProfileCrudTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void ProfileCrudTest::SetUpTestCase() +{ +} + +void ProfileCrudTest::TearDownTestCase() +{ +} + +void ProfileCrudTest::SetUp() +{ +} + +void ProfileCrudTest::TearDown() +{ +} + +/** + * @tc.name: PutDeviceProfile_001 + * @tc.desc: put device profile with empty service id + * @tc.type: FUNC + */ +HWTEST_F(ProfileCrudTest, PutDeviceProfile_001, TestSize.Level1) +{ + auto dps = DistributedDeviceProfileClient::GetInstance().GetDeviceProfileService(); + if (dps == nullptr) { + DTEST_LOG << "device profile service is nullptr" << std::endl; + return; + } + + ServiceCharacteristicProfile profile; + profile.SetServiceId(""); + profile.SetServiceType("test"); + nlohmann::json j; + j["testVersion"] = "3.0.0"; + j["testApiLevel"] = 7; + profile.SetCharacteristicProfileJson(j.dump()); + int32_t result = DistributedDeviceProfileClient::GetInstance().PutDeviceProfile(profile); + EXPECT_TRUE(result == ERR_DP_INVALID_PARAMS); +} + +/** + * @tc.name: PutDeviceProfile_002 + * @tc.desc: put device profile with empty service type + * @tc.type: FUNC + */ +HWTEST_F(ProfileCrudTest, PutDeviceProfile_002, TestSize.Level1) +{ + auto dps = DistributedDeviceProfileClient::GetInstance().GetDeviceProfileService(); + if (dps == nullptr) { + DTEST_LOG << "device profile service is nullptr" << std::endl; + return; + } + + ServiceCharacteristicProfile profile; + profile.SetServiceId("test"); + profile.SetServiceType(""); + nlohmann::json j; + j["testVersion"] = "3.0.0"; + j["testApiLevel"] = 7; + profile.SetCharacteristicProfileJson(j.dump()); + int32_t result = DistributedDeviceProfileClient::GetInstance().PutDeviceProfile(profile); + EXPECT_TRUE(result == ERR_DP_INVALID_PARAMS); +} + +/** + * @tc.name: PutDeviceProfile_003 + * @tc.desc: put device profile with empty characteristics + * @tc.type: FUNC + */ +HWTEST_F(ProfileCrudTest, PutDeviceProfile_003, TestSize.Level1) +{ + auto dps = DistributedDeviceProfileClient::GetInstance().GetDeviceProfileService(); + if (dps == nullptr) { + DTEST_LOG << "device profile service is nullptr" << std::endl; + return; + } + + ServiceCharacteristicProfile profile; + profile.SetServiceId("test"); + profile.SetServiceType("test"); + nlohmann::json j; + // the result string is "null" + profile.SetCharacteristicProfileJson(j.dump()); + int32_t result = DistributedDeviceProfileClient::GetInstance().PutDeviceProfile(profile); + EXPECT_TRUE(result == ERR_DP_INVALID_PARAMS); +} + +/** + * @tc.name: PutDeviceProfile_004 + * @tc.desc: put device profile without set characteristics + * @tc.type: FUNC + */ +HWTEST_F(ProfileCrudTest, PutDeviceProfile_004, TestSize.Level1) +{ + auto dps = DistributedDeviceProfileClient::GetInstance().GetDeviceProfileService(); + if (dps == nullptr) { + DTEST_LOG << "device profile service is nullptr" << std::endl; + return; + } + + ServiceCharacteristicProfile profile; + profile.SetServiceId("test"); + profile.SetServiceType("test"); + int32_t result = DistributedDeviceProfileClient::GetInstance().PutDeviceProfile(profile); + EXPECT_TRUE(result == ERR_DP_INVALID_PARAMS); +} + +/** + * @tc.name: PutDeviceProfile_005 + * @tc.desc: put device profile with normal value + * @tc.type: FUNC + */ +HWTEST_F(ProfileCrudTest, PutDeviceProfile_005, TestSize.Level1) +{ + auto dps = DistributedDeviceProfileClient::GetInstance().GetDeviceProfileService(); + if (dps == nullptr) { + DTEST_LOG << "device profile service is nullptr" << std::endl; + return; + } + + ServiceCharacteristicProfile profile; + profile.SetServiceId("test"); + profile.SetServiceType("test"); + nlohmann::json j; + j["testVersion"] = "3.0.0"; + j["testApiLevel"] = 7; + profile.SetCharacteristicProfileJson(j.dump()); + int32_t result = DistributedDeviceProfileClient::GetInstance().PutDeviceProfile(profile); + EXPECT_TRUE(result == ERR_OK); +} +} +} \ No newline at end of file diff --git a/services/core/test/unittest/utils.h b/services/core/test/unittest/utils.h new file mode 100755 index 0000000..b452d68 --- /dev/null +++ b/services/core/test/unittest/utils.h @@ -0,0 +1,25 @@ +/* + * 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_DEVICE_PROFILE_UNITTEST_UTILS_H +#define OHOS_DEVICE_PROFILE_UNITTEST_UTILS_H + +namespace OHOS { +namespace DeviceProfile { +#define DTEST_LOG std::cout << __FILE__ << ":" << __LINE__ << ":" +} // namespace DeviceProfile +} // namespace OHOS + +#endif // OHOS_DEVICE_PROFILE_UNITTEST_UTILS_H \ No newline at end of file