From df8e7ef3cda5a1307a77f09b4a95894ce64212ed Mon Sep 17 00:00:00 2001 From: htt1997 Date: Tue, 10 Sep 2024 21:33:59 +0800 Subject: [PATCH] update Signed-off-by: htt1997 --- data_object/CMakeLists.txt | 1 + data_object/bundle.json | 5 +- .../adaptor/flat_object_storage_engine.h | 1 + .../include/common/common_types.h | 53 + .../innerkitsimpl/include/common/logger.h | 11 +- .../include/common/object_radar_reporter.h | 38 +- .../include/communicator/softbus_adapter.h | 2 +- .../src/adaptor/distributed_object_impl.cpp | 1 - .../adaptor/distributed_object_store_impl.cpp | 10 +- .../adaptor/flat_object_storage_engine.cpp | 41 +- .../src/adaptor/flat_object_store.cpp | 36 +- .../communicator/softbus_adapter_standard.cpp | 10 +- .../src/object_radar_reporter.cpp | 211 + .../test/fuzztest/objectstore_fuzzer/BUILD.gn | 1 - .../include/adaptor/js_object_wrapper.h | 6 +- .../jskitsimpl/include/common/uv_queue.h | 2 +- .../src/adaptor/js_distributedobject.cpp | 2 +- .../src/adaptor/js_distributedobjectstore.cpp | 1 + .../src/adaptor/js_object_wrapper.cpp | 6 +- data_object/interfaces/innerkits/BUILD.gn | 3 +- data_object/interfaces/jskits/BUILD.gn | 3 +- .../jskits/distributed_data_object.js | 21 +- data_share/OAT.xml | 10 +- .../include/datashare_predicates_proxy.h | 1 + .../common/src/datashare_predicates_proxy.cpp | 22 + .../js/napi/dataShare/src/async_call.cpp | 4 +- .../dataShare/src/napi_datashare_helper.cpp | 7 + .../native_datashare_predicates_module.cpp | 5 +- .../js/napi/datashare_ext_ability/BUILD.gn | 2 +- .../datashare_ext_ability.js | 1 + .../datashare_ext_ability_context/BUILD.gn | 2 +- .../native/common/include/call_reporter.h | 39 + .../include/datashare_block_writer_impl.h | 4 +- .../native/common/include/datashare_log.h | 13 +- .../common/include/datashare_string_utils.h | 2 + ...ibuteddata_data_share_ipc_interface_code.h | 9 +- .../common/include/idata_share_service.h | 28 +- .../native/common/include/idatashare.h | 7 + .../common/include/ikvstore_data_service.h | 6 +- .../native/common/src/call_reporter.cpp | 60 + .../src/datashare_block_writer_impl.cpp | 54 +- .../common/src/datashare_result_set.cpp | 138 +- .../common/src/datashare_string_utils.cpp | 10 + .../controller/common/general_controller.h | 8 + .../general_controller_provider_impl.h | 8 + .../src/general_controller_provider_impl.cpp | 61 +- .../include/general_controller_service_impl.h | 18 +- .../src/general_controller_service_impl.cpp | 109 +- .../consumer/include/datashare_connection.h | 23 +- .../consumer/include/datashare_helper_impl.h | 9 +- .../native/consumer/include/datashare_proxy.h | 7 + .../consumer/src/datashare_connection.cpp | 95 +- .../native/consumer/src/datashare_helper.cpp | 80 +- .../consumer/src/datashare_helper_impl.cpp | 77 +- .../native/consumer/src/datashare_proxy.cpp | 122 +- .../native/provider/include/datashare_stub.h | 8 + .../provider/include/datashare_stub_impl.h | 7 + .../native/provider/src/datashare_stub.cpp | 125 +- .../provider/src/datashare_stub_impl.cpp | 103 +- .../native/proxy/include/ams_mgr_proxy.h | 7 +- .../proxy/include/data_share_manager_impl.h | 13 +- .../proxy/include/data_share_service_proxy.h | 17 +- .../native/proxy/src/ams_mgr_proxy.cpp | 5 +- .../proxy/src/data_share_manager_impl.cpp | 28 +- .../proxy/src/data_share_service_proxy.cpp | 112 +- data_share/interfaces/inner_api/BUILD.gn | 1 + .../common/include/datashare_errno.h | 38 + .../consumer/include/datashare_helper.h | 60 +- .../consumer/include/datashare_result_set.h | 11 +- .../include/datashare_shared_result_set.h | 2 +- data_share/test/native/BUILD.gn | 1 + .../DataShareExtAbility.ts | 22 +- .../proxydatas_with_permission_test.cpp | 4 +- .../src/mediadatashare_unit_test.cpp | 111 +- .../src/slientaccess_test.cpp | 121 + datamgr_service/bundle.json | 3 + .../distributeddataservice/adapter/BUILD.gn | 13 +- .../adapter/CMakeLists.txt | 2 + .../adapter/account/BUILD.gn | 7 +- .../src/account_delegate_default_impl.cpp | 18 +- .../src/account_delegate_default_impl.h | 2 +- .../src/account_delegate_normal_impl.cpp | 25 +- .../src/account_delegate_normal_impl.h | 2 +- .../adapter/account/test/BUILD.gn | 14 +- .../src/device_manager_adapter.cpp | 10 + .../communicator/src/softbus_adapter.h | 4 + .../src/softbus_adapter_standard.cpp | 117 +- .../communicator/src/softbus_client.cpp | 27 +- .../adapter/communicator/src/softbus_client.h | 5 +- .../fuzztest/softbusadapter_fuzzer/BUILD.gn | 1 + .../softbus_adapter_standard_test.cpp | 1 - .../adapter/dfx/src/radar_reporter.cpp | 4 +- .../communicator/device_manager_adapter.h | 1 + .../adapter/include/dfx/radar_reporter.h | 4 + .../adapter/include/screenlock/screen_lock.h | 29 + .../adapter/include/utils/visibility.h | 29 + .../adapter/screenlock/BUILD.gn | 42 + .../adapter/screenlock/src/screen_lock.cpp | 31 + .../distributeddataservice/app/BUILD.gn | 1 + .../app/distributed_data.cfg | 3 +- .../app/src/installer/installer_impl.cpp | 10 - .../app/src/installer/installer_impl.h | 1 - .../app/src/kvstore_data_service.cpp | 100 +- .../app/src/kvstore_data_service.h | 7 +- .../app/src/security/security.cpp | 6 + .../app/src/security/security.h | 2 + .../route_head_handler_impl.cpp | 4 + .../src/session_manager/session_manager.cpp | 41 +- .../app/src/session_manager/session_manager.h | 2 + .../src/session_manager/upgrade_manager.cpp | 27 +- .../app/src/session_manager/upgrade_manager.h | 2 +- .../kvstore_data_service_clear_test.cpp | 98 +- .../test/unittest/session_manager_test.cpp | 7 +- .../distributeddataservice/framework/BUILD.gn | 6 + .../framework/CMakeLists.txt | 13 +- .../framework/account/account_delegate.cpp | 36 + .../app_id_mapping_config_manager.cpp | 43 + .../framework/cloud/cloud_db.cpp | 2 +- .../framework/cloud/cloud_event.cpp | 7 +- .../framework/cloud/cloud_info.cpp | 8 +- .../framework/cloud/cloud_lock_event.cpp | 27 + .../framework/cloud/schema_meta.cpp | 2 +- .../framework/cloud/sharing_center.cpp | 32 +- .../framework/cloud/subscription.cpp | 1 + .../framework/cloud/sync_event.cpp | 8 +- .../communication/connect_manager.cpp | 137 + .../framework/directory/directory_manager.cpp | 52 +- .../include/account/account_delegate.h | 23 +- .../app_id_mapping_config_manager.h | 40 + .../include/changeevent/remote_change_event.h | 1 + .../framework/include/cloud/cloud_db.h | 2 +- .../framework/include/cloud/cloud_event.h | 6 + .../include/cloud/cloud_lock_event.h | 34 + .../framework/include/cloud/sync_event.h | 3 +- .../include/commonevent/data_change_event.h | 6 + .../include/commonevent/data_sync_event.h | 19 +- .../commonevent/set_searchable_event.h | 43 + .../include/communication/connect_manager.h | 65 + .../include/directory/directory_manager.h | 1 + .../framework/include/error/general_error.h | 13 + .../include/metadata/auto_launch_meta_data.h | 1 + .../include/metadata/matrix_meta_data.h | 2 +- .../include/metadata/store_meta_data.h | 2 + .../framework/include/screen/screen_manager.h | 38 + .../framework/include/store/auto_cache.h | 12 +- .../framework/include/store/general_store.h | 27 +- .../framework/include/store/general_value.h | 11 + .../framework/include/utils/constant.h | 2 + .../metadata/auto_launch_meta_data.cpp | 2 + .../framework/metadata/meta_data_manager.cpp | 33 +- .../framework/metadata/store_meta_data.cpp | 11 +- .../framework/screen/screen_manager.cpp | 46 + .../framework/store/auto_cache.cpp | 145 +- .../framework/test/BUILD.gn | 5 + .../framework/test/checker_manager_test.cpp | 32 + .../framework/test/cloud_test.cpp | 77 +- .../framework/test/constant_test.cpp | 139 +- .../framework/test/feature_test.cpp | 15 + .../framework/test/meta_data_test.cpp | 24 +- .../test/store_meta_data_local_test.cpp | 44 +- .../framework/test/store_test.cpp | 1 - .../framework/test/utils_test.cpp | 37 + .../framework/utils/constant.cpp | 19 + .../rust/extension/BUILD.gn | 1 + .../rust/extension/cloud_cursor_impl.cpp | 1 + .../rust/extension/cloud_db_impl.cpp | 11 +- .../rust/extension/cloud_db_impl.h | 2 +- .../rust/ylong_cloud_extension/BUILD.gn | 34 +- .../src/ipc_conn/function.rs | 2 +- .../distributeddataservice/service/BUILD.gn | 3 +- .../service/CMakeLists.txt | 2 +- .../service/backup/src/backup_manager.cpp | 18 +- .../service/bootstrap/include/bootstrap.h | 1 + .../service/bootstrap/src/bootstrap.cpp | 14 + .../service/cloud/cloud_service_impl.cpp | 95 +- .../service/cloud/cloud_service_impl.h | 6 +- .../service/cloud/cloud_service_stub.cpp | 10 +- .../service/cloud/cloud_types_util.h | 3 +- .../service/cloud/cloud_value_util.h | 4 +- .../service/cloud/sync_manager.cpp | 166 +- .../service/cloud/sync_manager.h | 26 +- .../sync_strategies/network_sync_strategy.cpp | 18 +- .../sync_strategies/network_sync_strategy.h | 12 +- .../service/config/include/config_factory.h | 1 + .../include/model/app_id_mapping_config.h | 30 + .../config/include/model/global_config.h | 2 + .../service/config/src/config_factory.cpp | 5 + .../src/model/app_id_mapping_config.cpp | 32 + .../config/src/model/global_config.cpp | 3 + .../data_share/common/bundle_mgr_proxy.cpp | 113 +- .../data_share/common/bundle_mgr_proxy.h | 47 +- .../service/data_share/common/context.h | 4 +- .../service/data_share/common/db_delegate.cpp | 84 +- .../service/data_share/common/db_delegate.h | 29 +- .../common/extension_ability_manager.cpp | 34 +- .../common/extension_ability_manager.h | 5 +- .../common/extension_connect_adaptor.cpp | 12 +- .../common/extension_connect_adaptor.h | 5 +- .../data_share/common/extension_mgr_proxy.cpp | 4 +- .../data_share/common/extension_mgr_proxy.h | 4 +- .../service/data_share/common/kv_delegate.cpp | 150 +- .../service/data_share/common/kv_delegate.h | 9 +- .../data_share/common/rdb_delegate.cpp | 137 +- .../service/data_share/common/rdb_delegate.h | 28 +- .../service/data_share/common/uri_utils.cpp | 4 +- .../service/data_share/data/template_data.cpp | 3 + .../data_share/data_provider_config.cpp | 46 +- .../service/data_share/data_provider_config.h | 6 +- .../data_share/data_share_db_config.cpp | 16 +- .../service/data_share/data_share_db_config.h | 13 +- .../data_share/data_share_profile_config.cpp | 19 +- .../data_share/data_share_profile_config.h | 5 +- .../data_share/data_share_service_impl.cpp | 223 +- .../data_share/data_share_service_impl.h | 30 +- .../data_share/data_share_service_stub.cpp | 40 +- .../data_share/data_share_service_stub.h | 14 +- .../service/data_share/idata_share_service.h | 20 +- ...d_config_from_data_proxy_node_strategy.cpp | 16 +- ...g_from_data_share_bundle_info_strategy.cpp | 16 +- .../load_config_data_info_strategy.cpp | 6 +- .../rdb_subscriber_manager.cpp | 9 +- .../data_share/sys_event_subscriber.cpp | 4 +- .../service/kvdb/auth_delegate.cpp | 133 +- .../service/kvdb/auth_delegate.h | 52 +- .../service/kvdb/kvdb_general_store.cpp | 169 +- .../service/kvdb/kvdb_general_store.h | 23 +- .../service/kvdb/kvdb_service_impl.cpp | 330 +- .../service/kvdb/kvdb_service_impl.h | 16 +- .../service/kvdb/kvdb_service_stub.cpp | 46 +- .../service/kvdb/kvdb_service_stub.h | 2 +- .../service/matrix/include/auto_sync_matrix.h | 1 + .../service/matrix/include/device_matrix.h | 11 +- .../service/matrix/src/auto_sync_matrix.cpp | 5 +- .../service/matrix/src/device_matrix.cpp | 83 +- .../service/object/object_asset_loader.cpp | 24 +- .../service/object/object_asset_machine.cpp | 6 +- .../service/object/object_data_listener.cpp | 11 +- .../service/object/object_manager.cpp | 411 +- .../service/object/object_manager.h | 33 +- .../service/object/object_service_impl.cpp | 14 +- .../service/rdb/rdb_cloud.cpp | 71 +- .../service/rdb/rdb_cloud.h | 16 + .../service/rdb/rdb_cloud_data_translate.cpp | 2 +- .../service/rdb/rdb_general_store.cpp | 379 +- .../service/rdb/rdb_general_store.h | 57 +- .../service/rdb/rdb_notifier_proxy.cpp | 2 +- .../service/rdb/rdb_service_impl.cpp | 421 +- .../service/rdb/rdb_service_impl.h | 30 +- .../service/rdb/rdb_service_stub.cpp | 72 +- .../service/rdb/rdb_service_stub.h | 17 +- .../service/test/BUILD.gn | 332 +- .../service/test/auto_sync_matrix_test.cpp | 230 - .../service/test/cloud_data_test.cpp | 1576 ++++- .../service/test/cloud_service_impl_test.cpp | 488 ++ .../service/test/cloud_test.cpp | 21 +- .../test/data_share_profile_config_test.cpp | 19 +- .../test/data_share_service_impl_test.cpp | 27 +- .../test/data_share_service_stub_test.cpp | 11 +- .../data_share_subscriber_managers_test.cpp | 2 +- .../service/test/device_matrix_test.cpp | 122 +- .../service/test/dump_helper_test.cpp | 99 + .../fuzztest/cloudservicestub_fuzzer/BUILD.gn | 1 + .../customutdinstaller_fuzzer/BUILD.gn | 1 + .../fuzztest/kvdbservicestub_fuzzer/BUILD.gn | 2 +- .../objectservicestub_fuzzer/BUILD.gn | 1 + .../fuzztest/rdbservicestub_fuzzer/BUILD.gn | 1 + .../test/fuzztest/udmfservice_fuzzer/BUILD.gn | 1 - .../service/test/kvdb_general_store_test.cpp | 492 +- .../service/test/kvdb_service_impl_test.cpp | 290 +- .../service/test/kvdb_service_test.cpp | 685 ++ .../service/test/mock/BUILD.gn | 1 + .../service/test/mock/db_store_mock.cpp | 21 +- .../service/test/mock/db_store_mock.h | 11 +- .../service/test/mock/general_store_mock.cpp | 45 +- .../service/test/mock/general_store_mock.h | 14 +- .../test/mock/general_watcher_mock.cpp | 37 + .../service/test/mock/general_watcher_mock.h | 40 + .../test/mock/kv_store_nb_delegate_mock.cpp | 333 + .../test/mock/kv_store_nb_delegate_mock.h | 111 + .../service/test/object_asset_loader_test.cpp | 207 + .../test/object_asset_machine_test.cpp | 123 +- .../service/test/object_manager_test.cpp | 893 +++ .../service/test/object_snapshot_test.cpp | 371 + .../service/test/rdb_asset_loader_test.cpp | 33 +- .../service/test/rdb_cloud_test.cpp | 11 +- .../service/test/rdb_cursor_test.cpp | 1 - .../service/test/rdb_general_store_test.cpp | 97 +- .../service/test/value_proxy_test.cpp | 143 +- .../service/udmf/BUILD.gn | 4 +- .../udmf/lifecycle/lifecycle_manager.cpp | 1 + .../permission/uri_permission_manager.cpp | 8 +- .../udmf/permission/uri_permission_manager.h | 3 +- .../udmf/preprocess/preprocess_utils.cpp | 31 +- .../udmf/preprocess/preprocess_utils.h | 1 + .../service/udmf/store/runtime_store.cpp | 76 +- .../service/udmf/store/runtime_store.h | 5 + .../service/udmf/store/store.h | 2 + .../udmf/store/store_account_observer.cpp | 49 + .../udmf/store/store_account_observer.h | 38 + .../service/udmf/store/store_cache.cpp | 6 +- .../service/udmf/udmf_service_impl.cpp | 99 +- .../service/udmf/udmf_service_impl.h | 6 + .../service/udmf/udmf_service_stub.cpp | 24 + .../service/udmf/udmf_service_stub.h | 6 +- .../waterversion/water_version_manager.cpp | 22 +- .../waterversion/water_version_manager.h | 3 +- googletest/BUILD.bazel | 32 +- googletest/BUILD.gn | 179 +- googletest/CMakeLists.txt | 19 +- googletest/CONTRIBUTING.md | 11 +- googletest/CONTRIBUTORS | 2 + googletest/OAT.xml | 9 +- googletest/README.OpenSource | 10 +- googletest/README.md | 59 +- googletest/WORKSPACE | 40 +- googletest/bundle.json | 29 +- googletest/ci/linux-presubmit.sh | 16 +- googletest/ci/macos-presubmit.sh | 6 +- googletest/ci/windows-presubmit.bat | 71 + googletest/docs/_layouts/default.html | 2 +- googletest/docs/advanced.md | 177 +- googletest/docs/faq.md | 63 +- googletest/docs/gmock_cheat_sheet.md | 12 +- googletest/docs/gmock_cook_book.md | 148 +- googletest/docs/gmock_faq.md | 4 +- googletest/docs/gmock_for_dummies.md | 12 +- googletest/docs/pkgconfig.md | 2 +- googletest/docs/primer.md | 19 +- googletest/docs/quickstart-bazel.md | 39 +- googletest/docs/quickstart-cmake.md | 12 +- googletest/docs/reference/actions.md | 14 +- googletest/docs/reference/matchers.md | 37 +- googletest/docs/reference/mocking.md | 4 +- googletest/docs/reference/testing.md | 6 +- googletest/docs/samples.md | 2 +- googletest/googlemock/CMakeLists.txt | 11 +- googletest/googlemock/README.md | 4 - .../googlemock/include/gmock/gmock-actions.h | 1081 ++- .../include/gmock/gmock-cardinalities.h | 8 +- .../include/gmock/gmock-function-mocker.h | 138 +- .../googlemock/include/gmock/gmock-matchers.h | 776 ++- .../include/gmock/gmock-more-actions.h | 603 +- .../include/gmock/gmock-more-matchers.h | 60 +- .../include/gmock/gmock-nice-strict.h | 38 +- .../include/gmock/gmock-spec-builders.h | 621 +- googletest/googlemock/include/gmock/gmock.h | 8 +- .../include/gmock/internal/custom/README.md | 2 + .../internal/custom/gmock-generated-actions.h | 3 +- .../gmock/internal/custom/gmock-matchers.h | 7 +- .../gmock/internal/custom/gmock-port.h | 5 +- .../gmock/internal/gmock-internal-utils.h | 129 +- .../include/gmock/internal/gmock-port.h | 86 +- .../googlemock/src/gmock-cardinalities.cc | 12 +- .../googlemock/src/gmock-internal-utils.cc | 113 +- googletest/googlemock/src/gmock-matchers.cc | 30 +- .../googlemock/src/gmock-spec-builders.cc | 243 +- googletest/googlemock/src/gmock.cc | 62 +- googletest/googlemock/src/gmock_main.cc | 4 +- googletest/googlemock/test/BUILD.bazel | 4 +- .../googlemock/test/gmock-actions_test.cc | 906 ++- .../test/gmock-cardinalities_test.cc | 111 +- .../test/gmock-function-mocker_test.cc | 140 +- .../test/gmock-internal-utils_test.cc | 243 +- .../test/gmock-matchers-arithmetic_test.cc | 1517 ++++ .../test/gmock-matchers-comparisons_test.cc | 2359 +++++++ ...t.cc => gmock-matchers-containers_test.cc} | 6085 +---------------- .../test/gmock-matchers-misc_test.cc | 1819 +++++ .../googlemock/test/gmock-matchers_test.h | 192 + .../test/gmock-more-actions_test.cc | 39 +- .../googlemock/test/gmock-nice-strict_test.cc | 72 +- googletest/googlemock/test/gmock-port_test.cc | 2 +- .../googlemock/test/gmock-pp-string_test.cc | 3 +- .../test/gmock-spec-builders_test.cc | 1091 ++- googletest/googlemock/test/gmock_all_test.cc | 5 +- googletest/googlemock/test/gmock_ex_test.cc | 2 - googletest/googlemock/test/gmock_leak_test.py | 2 +- .../googlemock/test/gmock_leak_test_.cc | 4 +- .../googlemock/test/gmock_link2_test.cc | 1 - googletest/googlemock/test/gmock_link_test.cc | 1 - googletest/googlemock/test/gmock_link_test.h | 37 +- .../googlemock/test/gmock_output_test.py | 13 +- .../googlemock/test/gmock_output_test_.cc | 78 +- .../test/gmock_output_test_golden.txt | 10 +- .../googlemock/test/gmock_stress_test.cc | 53 +- googletest/googlemock/test/gmock_test.cc | 38 +- .../googlemock/test/gmock_test_utils.py | 14 +- googletest/googletest/CMakeLists.txt | 24 +- googletest/googletest/README.md | 18 +- .../googletest/cmake/internal_utils.cmake | 34 +- .../include/gtest/gtest-assertion-result.h | 237 + .../include/gtest/gtest-death-test.h | 89 +- .../googletest/include/gtest/gtest-matchers.h | 78 +- .../googletest/include/gtest/gtest-message.h | 29 +- .../include/gtest/gtest-param-test.h | 124 +- .../googletest/include/gtest/gtest-printers.h | 152 +- .../googletest/include/gtest/gtest-spi.h | 134 +- .../include/gtest/gtest-test-part.h | 16 +- .../include/gtest/gtest-typed-test.h | 38 +- googletest/googletest/include/gtest/gtest.h | 574 +- .../include/gtest/gtest_pred_impl.h | 200 +- .../googletest/include/gtest/gtest_prod.h | 9 +- .../include/gtest/hwext/gtest-multithread.h | 117 + .../include/gtest/hwext/gtest-tag.h | 1 + .../include/gtest/internal/custom/README.md | 12 - .../internal/gtest-death-test-internal.h | 77 +- .../include/gtest/internal/gtest-filepath.h | 34 +- .../include/gtest/internal/gtest-internal.h | 335 +- .../include/gtest/internal/gtest-param-util.h | 220 +- .../include/gtest/internal/gtest-port-arch.h | 102 +- .../include/gtest/internal/gtest-port.h | 1155 ++-- .../include/gtest/internal/gtest-string.h | 19 +- .../include/gtest/internal/gtest-type-util.h | 25 +- googletest/googletest/samples/prime_tables.h | 8 +- googletest/googletest/samples/sample1.cc | 4 +- .../googletest/samples/sample10_unittest.cc | 8 +- .../googletest/samples/sample1_unittest.cc | 11 +- googletest/googletest/samples/sample2.cc | 2 +- googletest/googletest/samples/sample2.h | 1 - .../googletest/samples/sample2_unittest.cc | 4 +- googletest/googletest/samples/sample3-inl.h | 9 +- .../googletest/samples/sample3_unittest.cc | 11 +- googletest/googletest/samples/sample4.cc | 14 +- .../googletest/samples/sample4_unittest.cc | 2 +- .../googletest/samples/sample5_unittest.cc | 13 +- .../googletest/samples/sample6_unittest.cc | 5 +- .../googletest/samples/sample7_unittest.cc | 6 +- .../googletest/samples/sample8_unittest.cc | 6 +- .../googletest/samples/sample9_unittest.cc | 29 +- googletest/googletest/src/gtest-all.cc | 5 +- .../googletest/src/gtest-assertion-result.cc | 77 + googletest/googletest/src/gtest-death-test.cc | 524 +- googletest/googletest/src/gtest-filepath.cc | 155 +- .../googletest/src/gtest-internal-inl.h | 230 +- googletest/googletest/src/gtest-matchers.cc | 5 +- googletest/googletest/src/gtest-port.cc | 349 +- googletest/googletest/src/gtest-printers.cc | 124 +- googletest/googletest/src/gtest-test-part.cc | 19 +- googletest/googletest/src/gtest-typed-test.cc | 7 +- googletest/googletest/src/gtest.cc | 1690 ++--- googletest/googletest/src/gtest_main.cc | 17 +- .../googletest/src/hwext/gtest-filter.cc | 6 +- .../src/hwext/gtest-multithread.cpp | 96 + googletest/googletest/test/BUILD.bazel | 6 +- .../googletest-break-on-failure-unittest.py | 2 +- .../googletest-break-on-failure-unittest_.cc | 19 +- .../test/googletest-catch-exceptions-test.py | 12 +- .../test/googletest-catch-exceptions-test_.cc | 16 +- .../googletest/test/googletest-color-test.py | 3 +- .../googletest/test/googletest-color-test_.cc | 4 +- .../test/googletest-death-test-test.cc | 428 +- .../test/googletest-death-test_ex_test.cc | 27 +- .../test/googletest-env-var-test.py | 2 +- .../test/googletest-env-var-test_.cc | 30 +- .../test/googletest-failfast-unittest.py | 2 +- .../test/googletest-failfast-unittest_.cc | 3 +- .../test/googletest-filepath-test.cc | 200 +- .../test/googletest-filter-unittest.py | 33 +- .../test/googletest-filter-unittest_.cc | 71 +- .../googletest-global-environment-unittest.py | 64 +- .../test/googletest-json-outfiles-test.py | 8 +- .../test/googletest-json-output-unittest.py | 68 +- .../test/googletest-list-tests-unittest.py | 2 +- .../test/googletest-list-tests-unittest_.cc | 90 +- .../test/googletest-listener-test.cc | 38 +- .../test/googletest-message-test.cc | 21 +- .../test/googletest-options-test.cc | 69 +- .../googletest-output-test-golden-lin.txt | 20 +- .../googletest/test/googletest-output-test.py | 2 +- .../test/googletest-output-test_.cc | 259 +- ...oogletest-param-test-invalid-name1-test.py | 2 +- ...ogletest-param-test-invalid-name1-test_.cc | 8 +- ...oogletest-param-test-invalid-name2-test.py | 2 +- ...ogletest-param-test-invalid-name2-test_.cc | 11 +- .../test/googletest-param-test-test.cc | 216 +- .../test/googletest-param-test-test.h | 6 +- .../test/googletest-param-test2-test.cc | 9 +- .../googletest/test/googletest-port-test.cc | 191 +- .../test/googletest-printers-test.cc | 435 +- .../test/googletest-setuptestsuite-test.py | 2 +- .../test/googletest-setuptestsuite-test_.cc | 9 +- .../test/googletest-shuffle-test.py | 2 +- .../test/googletest-shuffle-test_.cc | 3 +- .../test/googletest-test-part-test.cc | 22 +- .../test/googletest-throw-on-failure-test.py | 2 +- .../test/googletest-throw-on-failure-test_.cc | 10 +- .../test/googletest-uninitialized-test.py | 2 +- .../test/googletest-uninitialized-test_.cc | 5 +- .../googletest/test/gtest-typed-test2_test.cc | 3 +- .../googletest/test/gtest-typed-test_test.cc | 56 +- .../googletest/test/gtest-typed-test_test.h | 11 +- .../test/gtest-unittest-api_test.cc | 24 +- .../test/gtest_assert_by_exception_test.cc | 24 +- googletest/googletest/test/gtest_dirs_test.cc | 97 + .../googletest/test/gtest_environment_test.cc | 23 +- googletest/googletest/test/gtest_help_test.py | 73 +- .../googletest/test/gtest_help_test_.cc | 1 - .../googletest/test/gtest_json_test_utils.py | 2 + .../test/gtest_list_output_unittest.py | 2 +- .../googletest/test/gtest_main_unittest.cc | 4 +- .../test/gtest_pred_impl_unittest.cc | 1728 ++--- .../test/gtest_premature_exit_test.cc | 22 +- .../googletest/test/gtest_repeat_test.cc | 67 +- .../test/gtest_skip_check_output_test.py | 2 +- ...test_skip_environment_check_output_test.py | 2 +- .../gtest_skip_in_environment_setup_test.cc | 1 + googletest/googletest/test/gtest_skip_test.cc | 8 +- .../googletest/test/gtest_sole_header_test.cc | 4 +- .../googletest/test/gtest_stress_test.cc | 26 +- .../gtest_test_macro_stack_footprint_test.cc | 58 +- .../googletest/test/gtest_test_utils.py | 83 +- .../googletest/test/gtest_testbridge_test.py | 2 +- .../googletest/test/gtest_testbridge_test_.cc | 1 - .../test/gtest_throw_on_failure_ex_test.cc | 16 +- googletest/googletest/test/gtest_unittest.cc | 1984 +++--- .../test/gtest_xml_outfile2_test_.cc | 4 +- .../test/gtest_xml_outfiles_test.py | 8 +- .../test/gtest_xml_output_unittest.py | 64 +- .../test/gtest_xml_output_unittest_.cc | 8 +- .../googletest/test/gtest_xml_test_utils.py | 6 +- googletest/googletest/test/production.h | 1 + ...application.DataShareExtensionAbility.d.ts | 1 + .../api/@ohos.data.DataShareResultSet.d.ts | 4 + .../api/@ohos.data.ValuesBucket.d.ts | 10 + .../api/@ohos.data.cloudExtension.d.ts | 2 + interface_sdk/api/@ohos.data.commonType.d.ts | 72 +- interface_sdk/api/@ohos.data.dataAbility.d.ts | 1 + interface_sdk/api/@ohos.data.dataShare.d.ts | 19 + .../api/@ohos.data.dataSharePredicates.d.ts | 85 + .../api/@ohos.data.distributedData.d.ts | 478 ++ .../api/@ohos.data.distributedDataObject.d.ts | 30 + .../api/@ohos.data.distributedKVStore.d.ts | 32 +- interface_sdk/api/@ohos.data.preferences.d.ts | 11 +- interface_sdk/api/@ohos.data.rdb.d.ts | 21 + .../api/@ohos.data.relationalStore.d.ts | 278 +- .../api/@ohos.data.sendablePreferences.d.ets | 4 +- .../@ohos.data.sendableRelationalStore.d.ets | 200 + interface_sdk/api/@ohos.data.storage.d.ts | 263 +- .../api/@ohos.data.unifiedDataChannel.d.ts | 431 +- .../api/@ohos.data.uniformDataStruct.d.ts | 14 +- .../api/@ohos.data.uniformTypeDescriptor.d.ts | 144 +- kv_store/bundle.json | 2 + kv_store/frameworks/CMakeLists.txt | 2 + .../cj/include/distributed_kv_store_ffi.h | 126 +- .../cj/include/distributed_kv_store_impl.h | 255 +- .../cj/src/distributed_kv_store_ffi.cpp | 523 +- .../cj/src/distributed_kv_store_impl.cpp | 731 +- kv_store/frameworks/common/concurrent_map.h | 6 - .../include/ikvstore_observer.h | 4 +- .../src/kvstore_service_death_notifier.cpp | 105 +- .../src/kvstore_service_death_notifier.h | 2 +- .../distributeddatafwk/test/BUILD.gn | 91 +- .../unittest/distributed_data_mgr_test.cpp | 79 +- .../distributed_kv_data_manager_test.cpp | 28 + .../single_kvstore_async_get_test.cpp | 4 +- ...ta_change_notifier.h => auto_sync_timer.h} | 29 +- .../innerkitsimpl/kvdb/include/dev_manager.h | 2 + .../distributeddata_kvdb_ipc_interface_code.h | 2 +- .../kvdb/include/kv_hiview_reporter.h | 51 + .../kvdb/include/kv_types_util.h | 6 + .../innerkitsimpl/kvdb/include/kvdb_service.h | 5 +- .../kvdb/include/kvdb_service_client.h | 5 +- .../kvdb/include/single_store_impl.h | 25 +- .../kvdb/src/auto_sync_timer.cpp | 150 + ..._notifier.cpp => auto_sync_timer_mock.cpp} | 102 +- .../innerkitsimpl/kvdb/src/dev_manager.cpp | 30 + .../kvdb/src/kv_hiview_reporter.cpp | 117 + .../kvdb/src/kv_hiview_reporter_mock.cpp | 68 + .../innerkitsimpl/kvdb/src/kv_types_util.cpp | 21 +- .../kvdb/src/kvdb_service_client.cpp | 28 +- .../kvdb/src/observer_bridge.cpp | 3 +- .../src/process_system_api_adapter_impl.cpp | 2 +- .../kvdb/src/single_store_impl.cpp | 171 +- .../innerkitsimpl/kvdb/src/store_factory.cpp | 2 +- .../innerkitsimpl/kvdb/src/store_manager.cpp | 11 +- .../innerkitsimpl/kvdb/test/BUILD.gn | 69 +- .../kvdb/test/data_change_notifier_test.cpp | 336 - .../kvdb/test/single_store_impl_test.cpp | 28 +- .../kvdb/test/store_factory_test.cpp | 1 + .../distributeddata/include/js_schema.h | 2 +- .../distributedkvstore/include/js_schema.h | 2 +- .../common/include/cloud/cloud_db_constant.h | 4 + .../common/include/cloud/cloud_db_types.h | 3 +- .../common/include/db_base64_utils.h | 3 + .../distributeddb/common/include/db_common.h | 27 + .../common/include/db_constant.h | 89 +- .../distributeddb/common/include/db_errno.h | 1 + .../distributeddb/common/include/db_types.h | 1 + .../distributeddb/common/include/log_print.h | 2 +- .../common/include/param_check_utils.h | 5 +- .../common/include/query_utils.h | 5 +- .../common/include/relational/tracker_table.h | 10 +- .../distributeddb/common/include/version.h | 10 +- .../distributeddb/common/src/auto_launch.cpp | 61 +- .../common/src/db_base64_utils.cpp | 62 +- .../distributeddb/common/src/db_common.cpp | 164 +- .../distributeddb/common/src/db_constant.cpp | 67 +- .../common/src/db_dfx_adapter.cpp | 51 +- .../src/evloop/src/event_loop_epoll.cpp | 34 +- .../common/src/param_check_utils.cpp | 17 +- .../common/src/performance_analysis.cpp | 31 +- .../distributeddb/common/src/query_utils.cpp | 28 +- .../relational/relational_schema_object.cpp | 34 +- .../common/src/relational/table_info.cpp | 27 +- .../common/src/relational/tracker_table.cpp | 120 +- .../common/src/runtime_context.cpp | 6 +- .../common/src/runtime_context_impl.cpp | 20 +- .../common/src/schema_object.cpp | 20 +- .../common/src/semaphore_utils.cpp | 4 +- .../common/src/time_tick_monitor.cpp | 3 +- .../distributeddb/common/src/value_object.cpp | 16 +- .../src/communicator_aggregator.cpp | 18 +- .../communicator/src/communicator_linker.cpp | 2 +- .../communicator/src/db_status_adapter.cpp | 2 +- .../communicator/src/network_adapter.cpp | 14 +- .../communicator/src/protocol_proto.cpp | 3 + .../libs/distributeddb/distributeddb.gni | 2 + .../gaussdb_rd/include/grd_base/grd_db_api.h | 7 +- .../gaussdb_rd/include/grd_base/grd_error.h | 5 + .../src/common/include/grd_api_manager.h | 7 +- .../src/common/src/grd_api_manager.cpp | 10 +- .../src/executor/base/grd_db_api.cpp | 31 +- .../test/unittest/api/documentdb_api_test.cpp | 15 - .../include/auto_launch_export.h | 1 + .../libs/distributeddb/include/types_export.h | 5 + .../interfaces/include/cloud/iAssetLoader.h | 6 + .../interfaces/include/kv_store_errno.h | 2 +- .../interfaces/include/kv_store_nb_delegate.h | 6 + .../relational/relational_store_delegate.h | 12 + .../interfaces/include/store_types.h | 33 +- .../src/kv_store_delegate_manager.cpp | 21 +- .../interfaces/src/kv_store_errno.cpp | 6 +- .../src/kv_store_nb_delegate_impl.cpp | 160 +- .../src/kv_store_nb_delegate_impl.h | 9 + .../relational_store_delegate_impl.cpp | 51 +- .../relational_store_delegate_impl.h | 4 + .../relational/relational_store_instance.h | 6 +- .../relational/relational_store_manager.cpp | 2 +- .../relational_store_sqlite_ext.cpp | 84 +- .../relational/relational_sync_able_storage.h | 28 +- .../include/cloud/cloud_storage_utils.h | 15 +- .../include/cloud/cloud_upload_recorder.h | 46 + .../storage/include/db_properties.h | 27 +- .../include/icloud_sync_storage_interface.h | 31 +- .../storage/include/kvdb_pragma.h | 25 + .../include/relational_db_sync_interface.h | 2 + .../include/relational_store_connection.h | 6 +- .../storage/include/storage_proxy.h | 10 +- .../storage/include/sync_generic_interface.h | 10 + .../storage/src/cloud/cloud_meta_data.cpp | 10 +- .../storage/src/cloud/cloud_storage_utils.cpp | 137 +- .../src/cloud/cloud_upload_recorder.cpp | 65 + .../storage/src/cloud/schema_mgr.cpp | 10 +- .../storage/src/data_transformer.h | 6 +- .../storage/src/db_properties.cpp | 15 - .../rd_single_ver_natural_store.cpp | 129 +- .../gaussdb_rd/rd_single_ver_natural_store.h | 3 + ...rd_single_ver_natural_store_connection.cpp | 87 +- .../rd_single_ver_natural_store_connection.h | 9 + .../rd_single_ver_storage_engine.cpp | 12 +- .../rd_single_ver_storage_executor.cpp | 47 +- .../rd_single_ver_storage_executor.h | 2 + .../storage/src/gaussdb_rd/rd_utils.cpp | 46 +- .../storage/src/gaussdb_rd/rd_utils.h | 16 +- .../storage/src/kv/generic_kvdb.cpp | 4 +- .../storage/src/kv/kvdb_manager.cpp | 21 +- .../storage/src/kv/sync_able_kvdb.cpp | 57 +- .../storage/src/kv/sync_able_kvdb.h | 9 +- .../src/kv/sync_able_kvdb_connection.cpp | 61 +- .../src/kv/sync_able_kvdb_connection.h | 4 + .../multiver/multi_ver_storage_executor.cpp | 2 +- .../storage/src/operation/database_oper.cpp | 20 +- .../storage/src/package_file.cpp | 8 +- .../relational/relational_store_instance.cpp | 14 +- .../relational_sync_able_storage.cpp | 193 +- .../storage/src/single_ver_utils.cpp | 32 + .../storage/src/single_ver_utils.h | 2 + .../storage/src/sqlite/query_sync_object.cpp | 4 + .../cloud_sync_log_table_manager.cpp | 30 +- .../simple_tracker_log_table_manager.cpp | 20 +- .../sqlite_relational_database_upgrader.cpp | 19 +- .../sqlite_relational_database_upgrader.h | 2 +- .../relational/sqlite_relational_store.cpp | 34 +- .../relational/sqlite_relational_store.h | 6 +- .../sqlite_relational_store_connection.cpp | 86 +- .../sqlite_relational_store_connection.h | 6 +- .../relational/sqlite_relational_utils.cpp | 18 +- ...qlite_single_relational_storage_engine.cpp | 19 +- ...e_single_ver_relational_continue_token.cpp | 4 +- ...single_ver_relational_storage_executor.cpp | 163 +- ...e_single_ver_relational_storage_executor.h | 49 +- ...ver_relational_storage_executor_extend.cpp | 198 +- ...ver_relational_storage_extend_executor.cpp | 244 +- .../sqlite/sqlite_cloud_kv_executor_utils.cpp | 420 +- .../sqlite/sqlite_cloud_kv_executor_utils.h | 44 +- .../src/sqlite/sqlite_cloud_kv_store.cpp | 114 +- .../src/sqlite/sqlite_cloud_kv_store.h | 10 + .../sqlite/sqlite_local_storage_executor.cpp | 44 +- .../src/sqlite/sqlite_log_table_manager.cpp | 34 +- .../src/sqlite/sqlite_log_table_manager.h | 3 + .../src/sqlite/sqlite_query_helper.cpp | 156 +- .../storage/src/sqlite/sqlite_query_helper.h | 17 +- .../sqlite_single_ver_continue_token.cpp | 15 +- .../sqlite_single_ver_database_upgrader.cpp | 7 +- .../sqlite_single_ver_natural_store.cpp | 128 +- .../sqlite/sqlite_single_ver_natural_store.h | 12 + ...te_single_ver_natural_store_connection.cpp | 88 +- ...sqlite_single_ver_natural_store_extend.cpp | 37 +- .../sqlite_single_ver_storage_engine.cpp | 86 +- .../sqlite_single_ver_storage_executor.cpp | 43 +- .../sqlite_single_ver_storage_executor.h | 14 + ...lite_single_ver_storage_executor_cache.cpp | 4 +- ...ite_single_ver_storage_executor_extend.cpp | 180 +- .../sqlite_single_ver_storage_executor_sql.h | 247 +- .../src/sqlite/sqlite_storage_engine.cpp | 10 +- .../storage/src/sqlite/sqlite_utils.cpp | 50 +- .../storage/src/storage_engine.cpp | 29 +- .../storage/src/storage_engine.h | 7 + .../storage/src/storage_engine_manager.cpp | 5 +- .../storage/src/storage_proxy.cpp | 46 +- .../storage/src/sync_able_engine.cpp | 6 +- .../distributeddb/syncer/include/isyncer.h | 4 + .../syncer/include/syncer_proxy.h | 3 + .../syncer/src/cloud/cloud_db_proxy.cpp | 147 +- .../syncer/src/cloud/cloud_db_proxy.h | 15 +- .../src/cloud/cloud_force_pull_strategy.cpp | 3 +- .../src/cloud/cloud_force_pull_strategy.h | 3 +- .../src/cloud/cloud_force_push_strategy.cpp | 3 +- .../src/cloud/cloud_force_push_strategy.h | 3 +- .../syncer/src/cloud/cloud_merge_strategy.cpp | 43 +- .../syncer/src/cloud/cloud_merge_strategy.h | 8 +- .../syncer/src/cloud/cloud_sync_strategy.cpp | 23 +- .../syncer/src/cloud/cloud_sync_strategy.h | 8 +- .../src/cloud/cloud_sync_tag_assets.cpp | 26 +- .../syncer/src/cloud/cloud_sync_tag_assets.h | 2 +- .../syncer/src/cloud/cloud_sync_utils.cpp | 103 +- .../syncer/src/cloud/cloud_sync_utils.h | 16 +- .../syncer/src/cloud/cloud_syncer.cpp | 125 +- .../syncer/src/cloud/cloud_syncer.h | 36 +- .../syncer/src/cloud/cloud_syncer_extend.cpp | 349 +- .../syncer/src/cloud/process_notifier.cpp | 53 +- .../syncer/src/cloud/process_notifier.h | 5 +- .../syncer/src/cloud/process_recorder.cpp | 65 + .../syncer/src/cloud/process_recorder.h | 47 + .../syncer/src/device/ability_sync.cpp | 36 +- .../syncer/src/device/commit_history_sync.cpp | 12 +- .../syncer/src/device/generic_syncer.cpp | 64 +- .../syncer/src/device/generic_syncer.h | 3 + .../syncer/src/device/isync_engine.h | 4 +- .../syncer/src/device/meta_data.cpp | 8 +- .../syncer/src/device/meta_data.h | 3 +- .../device/multiver/multi_ver_data_sync.cpp | 12 +- .../device/multiver/multi_ver_sync_engine.cpp | 2 +- .../device/multiver/multi_ver_sync_engine.h | 2 +- .../multiver/multi_ver_sync_state_machine.cpp | 6 +- .../multiver/multi_ver_sync_task_context.cpp | 5 +- .../src/device/multiver/value_slice_sync.cpp | 12 +- .../syncer/src/device/remote_executor.cpp | 14 +- .../single_ver_data_message_schedule.cpp | 2 +- .../singlever/single_ver_data_packet.cpp | 26 +- .../device/singlever/single_ver_data_packet.h | 4 + .../device/singlever/single_ver_data_sync.cpp | 40 +- .../device/singlever/single_ver_data_sync.h | 14 +- .../singlever/single_ver_data_sync_utils.cpp | 71 +- .../singlever/single_ver_data_sync_utils.h | 13 + .../device/singlever/single_ver_kv_syncer.cpp | 6 +- .../single_ver_relational_syncer.cpp | 7 +- .../single_ver_serialize_manager.cpp | 35 +- .../singlever/single_ver_sync_engine.cpp | 16 +- .../device/singlever/single_ver_sync_engine.h | 4 +- .../single_ver_sync_state_machine.cpp | 39 +- .../single_ver_sync_task_context.cpp | 54 +- .../singlever/single_ver_sync_task_context.h | 14 + .../syncer/src/device/sync_engine.cpp | 133 +- .../syncer/src/device/sync_engine.h | 17 +- .../syncer/src/device/sync_state_machine.cpp | 6 +- .../syncer/src/device/sync_task_context.cpp | 15 +- .../syncer/src/device/syncer_proxy.cpp | 12 +- .../syncer/src/device/time_sync.cpp | 24 +- .../syncer/src/sync_operation.cpp | 140 +- .../distributeddb/syncer/src/sync_operation.h | 21 + .../distributeddb/syncer/src/time_helper.cpp | 2 +- .../libs/distributeddb/test/BUILD.gn | 7 + .../test/fuzztest/cloudsync_fuzzer/BUILD.gn | 6 + .../cloudsync_fuzzer/cloudsync_fuzzer.cpp | 122 +- .../fuzztest/cloudsync_fuzzer/project.xml | 2 +- .../test/fuzztest/common/fuzzer_data.cpp | 9 + .../test/fuzztest/common/fuzzer_data.h | 2 + .../test/fuzztest/delegate_fuzzer/BUILD.gn | 6 + .../delegate_fuzzer/delegate_fuzzer.cpp | 45 +- .../test/fuzztest/fileoper_fuzzer/BUILD.gn | 6 + .../test/fuzztest/importfile_fuzzer/BUILD.gn | 6 + .../iprocesscommunicator_fuzzer/BUILD.gn | 6 + .../iprocesscommunicator_fuzzer.cpp | 61 +- .../test/fuzztest/json_fuzzer/BUILD.gn | 148 + .../test/fuzztest/json_fuzzer/corpus/init | 14 + .../test/fuzztest/json_fuzzer/json_fuzzer.cpp | 1688 +++++ .../test/fuzztest/json_fuzzer/json_fuzzer.h | 19 +- .../test/fuzztest/json_fuzzer/project.xml | 25 + .../test/fuzztest/jsoninner_fuzzer/BUILD.gn | 148 + .../fuzztest/jsoninner_fuzzer/corpus/init | 14 + .../jsoninner_fuzzer/jsoninner_fuzzer.cpp | 1697 +++++ .../jsoninner_fuzzer/jsoninner_fuzzer.h | 21 + .../fuzztest/jsoninner_fuzzer/project.xml | 25 + .../kvdelegatemanager_fuzzer/BUILD.gn | 6 + .../kvdelegatemanager_fuzzer.cpp | 59 +- .../fuzztest/kvstoreresultset_fuzzer/BUILD.gn | 6 + .../kvstoreresultset_fuzzer.cpp | 2 +- .../kvstoreresultset_fuzzer.h | 15 +- .../test/fuzztest/nbdelegate_fuzzer/BUILD.gn | 7 + .../nbdelegate_fuzzer/nbdelegate_fuzzer.cpp | 69 +- .../test/fuzztest/parseckeck_fuzzer/BUILD.gn | 6 + .../test/fuzztest/query_fuzzer/BUILD.gn | 6 + .../fuzztest/query_fuzzer/query_fuzzer.cpp | 6 +- .../test/fuzztest/query_fuzzer/query_fuzzer.h | 15 +- .../test/fuzztest/rekey_fuzzer/BUILD.gn | 6 + .../relationalstoredelegate_fuzzer/BUILD.gn | 6 + .../relationalstoredelegate_fuzzer.cpp | 64 +- .../relationalstoremanager_fuzzer/BUILD.gn | 6 + .../relationalstoremanager_fuzzer.cpp | 84 +- .../fuzztest/schemadelegate_fuzzer/BUILD.gn | 7 + .../test/fuzztest/storage_fuzzer/BUILD.gn | 6 + .../storage_fuzzer/storage_fuzzer.cpp | 156 +- .../test/fuzztest/sync_fuzzer/BUILD.gn | 5 + .../src/distributeddb_nb_observer_test.cpp | 2 +- .../common/distributeddb_common_test.cpp | 256 + .../distributeddb_data_generate_unit_test.cpp | 14 + .../distributeddb_data_generate_unit_test.h | 2 + .../common/distributeddb_parcel_unit_test.cpp | 75 + ...ibuteddb_relational_schema_object_test.cpp | 106 + .../distributeddb_schema_object_test.cpp | 84 + .../common/distributeddb_schema_unit_test.cpp | 36 + .../common/distributeddb_tools_unit_test.cpp | 38 + .../common/distributeddb_tools_unit_test.h | 4 + .../distributeddb_communicator_deep_test.cpp | 6 +- .../distributeddb_communicator_test.cpp | 6 +- ...uteddb_cloud_interfaces_reference_test.cpp | 2 +- ...b_cloud_interfaces_relational_ext_test.cpp | 130 +- ...ces_relational_remove_device_data_test.cpp | 277 +- ...cloud_interfaces_set_cloud_schema_test.cpp | 26 + ...stributeddb_interfaces_data_value_test.cpp | 2 +- ...ddb_interfaces_database_rd_kernel_test.cpp | 115 +- ...distributeddb_interfaces_database_test.cpp | 2 +- ...b_interfaces_import_and_export_rd_test.cpp | 1298 ++++ ...eddb_interfaces_import_and_export_test.cpp | 59 +- ...nterfaces_nb_delegate_local_batch_test.cpp | 44 + ...buteddb_interfaces_nb_delegate_rd_test.cpp | 96 +- ...tributeddb_interfaces_nb_delegate_test.cpp | 304 + ...stributeddb_interfaces_nb_publish_test.cpp | 39 + .../distributeddb_interfaces_query_test.cpp | 56 + ...uteddb_interfaces_relational_sync_test.cpp | 61 + ...terfaces_relational_tracker_table_test.cpp | 21 +- ...erfaces_single_version_result_set_test.cpp | 8 +- ...teddb_cloud_assets_operation_sync_test.cpp | 226 +- .../distributeddb_cloud_check_sync_test.cpp | 85 +- ..._cloud_interfaces_relational_sync_test.cpp | 17 +- .../distributeddb_cloud_meta_data_test.cpp | 188 + ...istributeddb_cloud_reference_sync_test.cpp | 45 + ...stributeddb_cloud_save_cloud_data_test.cpp | 18 +- ...relational_cloud_syncable_storage_test.cpp | 59 +- ...distributeddb_relational_get_data_test.cpp | 5 + ...stributeddb_relational_result_set_test.cpp | 10 +- .../distributeddb_sqlite_utils_test.cpp | 23 + ...mory_rd_single_ver_naturall_store_test.cpp | 236 - ...storage_rd_resultset_and_json_optimize.cpp | 370 - ...ge_rd_single_ver_natural_executor_test.cpp | 4 +- ...orage_rd_single_ver_natural_store_test.cpp | 2 +- ...e_rd_single_ver_natural_store_testcase.cpp | 9 +- ...buteddb_storage_register_conflict_test.cpp | 4 +- ...db_storage_resultset_and_json_optimize.cpp | 4 +- ...uteddb_storage_single_ver_upgrade_test.cpp | 2 +- ...qlite_single_ver_natural_executor_test.cpp | 112 +- .../common/syncer/cloud/cloud_syncer_test.h | 20 +- .../distributeddb_cloud_db_proxy_test.cpp | 188 +- .../distributeddb_cloud_kv_syncer_test.cpp | 519 ++ .../cloud/distributeddb_cloud_kv_test.cpp | 587 +- .../distributeddb_cloud_strategy_test.cpp | 98 +- ...eddb_cloud_syncer_download_assets_test.cpp | 373 +- ...stributeddb_cloud_syncer_download_test.cpp | 10 +- .../distributeddb_cloud_syncer_lock_test.cpp | 186 +- ...distributeddb_cloud_syncer_upload_test.cpp | 104 +- .../syncer/cloud/virtual_asset_loader.cpp | 21 + .../syncer/cloud/virtual_asset_loader.h | 9 +- .../common/syncer/cloud/virtual_cloud_db.cpp | 15 +- .../distributeddb_ability_sync_test.cpp | 2 +- .../distributeddb_mock_sync_module_test.cpp | 24 +- ...stributeddb_relational_multi_user_test.cpp | 8 +- ...ributeddb_relational_ver_p2p_sync_test.cpp | 12 +- ...stributeddb_single_ver_multi_user_test.cpp | 4 +- ...db_single_ver_p2p_permission_sync_test.cpp | 2 +- ...uteddb_single_ver_p2p_simple_sync_test.cpp | 4 +- ...ddb_single_ver_p2p_subscribe_sync_test.cpp | 1 + ...buteddb_single_ver_p2p_sync_check_test.cpp | 238 +- .../common/syncer/generic_virtual_device.cpp | 44 + .../common/syncer/generic_virtual_device.h | 3 + .../unittest/common/syncer/mock_sync_engine.h | 7 +- .../virtual_communicator_aggregator.cpp | 20 +- .../syncer/virtual_communicator_aggregator.h | 3 + ...rtual_relational_ver_sync_db_interface.cpp | 5 + ...virtual_relational_ver_sync_db_interface.h | 2 + .../virtual_single_ver_sync_db_Interface.cpp | 51 + .../virtual_single_ver_sync_db_Interface.h | 4 + .../innerkits/distributeddata/BUILD.gn | 16 +- .../innerkits/distributeddata/include/types.h | 24 + kv_store/kv_store.gni | 15 + .../KvManagerDataPromiseJsTest.js | 57 - .../SingleKvStoreDataPromiseJsTest.js | 50 + mock/CMakeLists.txt | 2 + .../ability_base/base/include/int_wrapper.h | 6 +- .../include/common_event_publish_info.h | 180 +- .../devicemanagersdk/include/device_manager.h | 2 + .../include/device_manager_impl.h | 2 +- .../hilog_native/libhilog/include/hilog/log.h | 2 +- .../memmgrclient/include/bundle_priority.h | 2 +- .../image_native/include/pixel_map.h | 2 + .../include/image_format_convert_mdk_kits.h | 60 + .../image_native/ndk/include/image_mdk_kits.h | 54 + .../ndk/include/image_packer_mdk_kits.h | 53 + .../ndk/include/image_packer_native_impl.h | 67 + .../ndk/include/image_receiver_mdk_kits.h | 63 + .../include/image_receiver_napi_listener.h | 40 + .../ndk/include/image_source_mdk_kits.h | 83 + .../ndk/include/image_source_native_impl.h | 57 + .../ndk/include/pixelmap_native_impl.h | 42 + mock/innerkits/napi/common.h | 39 + mock/innerkits/napi/native_api.h | 216 + mock/innerkits/napi/native_common.h | 148 +- .../include/screenlock_callback_interface.h | 36 + .../inner_api/include/screenlock_common.h | 139 + .../inner_api/include/screenlock_manager.h | 57 + .../include/screenlock_manager_interface.h | 49 + .../screenlock_system_ability_interface.h | 44 + .../interfaces/inner_api/include/visibility.h | 23 + mock/napi/src/js_native_api_types.h | 218 +- mock/src/mock_device_manager.cpp | 5 + mock/src/mock_image..cpp | 76 +- mock/src/mock_js_napi.cpp | 630 +- mock/src/mock_mem_mgr.cpp | 3 +- mock/src/mock_notification.cpp | 89 + mock/src/mock_screenlock_mgr.cpp | 49 + preferences/OAT.xml | 66 + preferences/bundle.json | 16 + .../frameworks/cj/src/preferences_ffi.cpp | 13 +- .../frameworks/cj/src/preferences_ffi.h | 5 +- .../frameworks/cj/src/preferences_impl.cpp | 163 +- .../frameworks/common/include/log_print.h | 8 + .../frameworks/js/napi/common/BUILD.gn | 1 + .../js/napi/common/src/js_common_utils.cpp | 5 - .../js/napi/common/src/napi_async_call.cpp | 2 +- .../napi/preferences/src/napi_preferences.cpp | 5 +- .../src/napi_preferences_helper.cpp | 1 - .../src/napi_preferences.cpp | 3 +- .../src/napi_preferences_helper.cpp | 1 - .../js/napi/storage/src/napi_storage.cpp | 1 - .../napi/storage/src/napi_storage_helper.cpp | 1 - .../native/include/concurrent_map.h | 346 + .../native/include/preferences_base.h | 9 +- .../native/include/preferences_enhance_impl.h | 10 + .../native/include/preferences_impl.h | 49 +- .../native/include/preferences_xml_utils.h | 8 +- .../platform/include/preferences_anonymous.h | 46 + .../platform/include/preferences_db_adapter.h | 55 +- .../include/preferences_dfx_adapter.h | 47 + .../include/preferences_file_operation.h | 18 +- .../platform/src/preferences_db_adapter.cpp | 244 +- .../platform/src/preferences_dfx_adapter.cpp | 129 + .../platform/src/preferences_file_lock.cpp | 11 +- .../native/src/preferences_base.cpp | 21 +- .../native/src/preferences_enhance_impl.cpp | 184 +- .../native/src/preferences_helper.cpp | 66 +- .../native/src/preferences_impl.cpp | 276 +- .../native/src/preferences_value_parcel.cpp | 28 +- .../native/src/preferences_xml_utils.cpp | 38 +- .../ndk/include/convertor_error_code.h | 30 + .../ndk/include/oh_preferences_impl.h | 84 + .../ndk/include/oh_preferences_value_impl.h | 45 + .../ndk/src/convertor_error_code.cpp | 44 + .../frameworks/ndk/src/oh_preferences.cpp | 405 ++ .../ndk/src/oh_preferences_option.cpp | 51 + .../ndk/src/oh_preferences_value.cpp | 124 + preferences/interfaces/inner_api/BUILD.gn | 20 +- .../inner_api/include/preferences.h | 36 +- .../inner_api/include/preferences_errno.h | 5 + preferences/interfaces/ndk/BUILD.gn | 95 + .../interfaces/ndk/include/oh_preferences.h | 271 + .../ndk/include/oh_preferences_err_code.h | 77 + .../ndk/include/oh_preferences_option.h | 118 + .../ndk/include/oh_preferences_value.h | 174 + preferences/preferences.gni | 2 + .../native/unittest/preferences_file_test.cpp | 2 +- .../unittest/preferences_xml_utils_test.cpp | 38 +- relational_store/bundle.json | 6 +- .../cj/include/relational_store_ffi.h | 32 +- .../include/relational_store_impl_rdbstore.h | 92 +- .../cj/include/relational_store_utils.h | 92 +- .../cj/src/relational_store_ffi.cpp | 124 +- .../cj/src/relational_store_impl_rdbstore.cpp | 241 +- .../relational_store_impl_resultsetproxy.cpp | 4 + .../cj/src/relational_store_utils.cpp | 186 + .../frameworks/common/include/logger.h | 7 + .../frameworks/js/napi/cloud_data/BUILD.gn | 9 - .../js/napi/cloud_data/src/js_config.cpp | 2 +- .../js/napi/cloud_data/src/napi_queue.cpp | 12 +- .../js/napi/cloud_extension/BUILD.gn | 2 +- .../js/napi/common/include/js_ability.h | 1 + .../napi/common/include/js_sendable_utils.h | 98 + .../js/napi/common/include/js_utils.h | 26 +- .../js/napi/common/mock/include/js_ability.h | 1 + .../js/napi/common/mock/src/js_ability.cpp | 6 + .../js/napi/common/src/js_ability.cpp | 17 + .../js/napi/common/src/js_sendable_utils.cpp | 220 + .../js/napi/common/src/js_utils.cpp | 176 +- .../js/napi/common/src/js_uv_queue.cpp | 29 +- .../frameworks/js/napi/dataability/BUILD.gn | 9 - .../src/napi_data_ability_predicates.cpp | 2 +- .../frameworks/js/napi/rdb/BUILD.gn | 25 +- .../js/napi/rdb/src/napi_rdb_predicates.cpp | 6 + .../js/napi/rdb/src/napi_rdb_store.cpp | 202 +- .../js/napi/rdb/src/napi_rdb_store_helper.cpp | 20 +- .../napi/rdb/src/napi_rdb_store_observer.cpp | 4 +- .../js/napi/rdb/src/napi_result_set.cpp | 28 +- .../js/napi/relationalstore/BUILD.gn | 23 +- .../include/napi_rdb_context.h | 78 + .../relationalstore/include/napi_rdb_error.h | 8 - .../include/napi_rdb_js_utils.h | 22 +- .../include/napi_rdb_sendable_utils.h | 35 + .../relationalstore/include/napi_rdb_store.h | 5 +- .../relationalstore/include/napi_result_set.h | 1 + .../mock/include/napi_rdb_store.h | 2 +- .../mock/include/napi_result_set.h | 1 + .../relationalstore/src/napi_async_call.cpp | 10 +- .../src/napi_rdb_const_properties.cpp | 13 + .../relationalstore/src/napi_rdb_error.cpp | 1 + .../relationalstore/src/napi_rdb_js_utils.cpp | 191 +- .../src/napi_rdb_predicates.cpp | 12 +- .../src/napi_rdb_sendable_utils.cpp | 72 + .../relationalstore/src/napi_rdb_store.cpp | 621 +- .../relationalstore/src/napi_result_set.cpp | 28 +- .../js/napi/sendablerelationalstore/BUILD.gn | 60 + .../include/napi_rdb_store_convert_utils.h | 29 + .../src/entry_point.cpp | 51 + .../src/napi_rdb_store_convert_utils.cpp | 157 + .../native/appdatafwk/src/shared_block.cpp | 4 +- .../native/cloud_data/src/cloud_manager.cpp | 14 +- .../src/ishared_result_set_proxy.cpp | 6 +- .../src/ishared_result_set_stub.cpp | 46 +- .../dataability/src/ishared_result_set_stub.h | 18 - .../dfx/include/rdb_fault_hiview_reporter.h | 55 + .../native/dfx/include/rdb_radar_reporter.h | 23 +- .../dfx/src/rdb_fault_hiview_reporter.cpp | 87 + .../native/dfx/src/rdb_radar_reporter.cpp | 54 +- .../native/rdb/include/connection.h | 14 +- .../connection_pool.h} | 277 +- .../native/rdb/include/delay_notify.h | 11 +- .../native/rdb/include/grd_api_manager.h | 2 +- .../native/rdb/include/grd_type_export.h | 12 +- .../native/rdb/include/rd_connection.h | 15 +- .../native/rdb/include/rd_statement.h | 7 + .../native/rdb/include/rdb_security_manager.h | 59 +- .../native/rdb/include/rdb_service_proxy.h | 14 +- .../native/rdb/include/rdb_sql_statistic.h | 7 +- .../native/rdb/include/rdb_store_impl.h | 28 +- .../native/rdb/include/rdb_store_manager.h | 1 + .../native/rdb/include/rdb_types_util.h | 5 + .../native/rdb/include/sqlite_connection.h | 59 +- .../native/rdb/include/sqlite_errno.h | 1 + .../native/rdb/include/sqlite_global_config.h | 7 +- .../rdb/include/sqlite_shared_result_set.h | 4 +- .../native/rdb/include/sqlite_sql_builder.h | 2 + .../native/rdb/include/sqlite_statement.h | 15 + .../native/rdb/include/sqlite_utils.h | 13 +- .../frameworks/native/rdb/include/statement.h | 3 + .../native/rdb/include/step_result_set.h | 6 +- .../native/rdb/mock/include/connection.h | 15 +- .../include/connection_pool.h} | 278 +- .../native/rdb/mock/include/rdb_store_impl.h | 20 +- .../rdb/mock/include/sqlite_connection.h | 62 +- .../native/rdb/mock/include/step_result_set.h | 6 +- .../mock/src/rdb_fault_hiview_reporter.cpp | 36 + .../rdb/mock/src/rdb_radar_reporter.cpp | 9 +- .../native/rdb/src/abs_predicates.cpp | 12 +- .../native/rdb/src/abs_rdb_predicates.cpp | 4 +- .../native/rdb/src/abs_result_set.cpp | 11 +- .../native/rdb/src/abs_shared_result_set.cpp | 52 +- .../frameworks/native/rdb/src/connection.cpp | 24 +- ...onnection_pool.cpp => connection_pool.cpp} | 184 +- .../native/rdb/src/delay_notify.cpp | 93 +- .../native/rdb/src/grd_api_manager.cpp | 2 +- .../native/rdb/src/raw_data_parser.cpp | 27 +- .../native/rdb/src/rd_connection.cpp | 39 +- .../native/rdb/src/rd_statement.cpp | 67 +- .../frameworks/native/rdb/src/rd_utils.cpp | 12 +- .../frameworks/native/rdb/src/rdb_helper.cpp | 37 +- .../native/rdb/src/rdb_manager_impl.cpp | 30 +- .../native/rdb/src/rdb_notifier_stub.cpp | 8 +- .../native/rdb/src/rdb_security_manager.cpp | 237 +- .../native/rdb/src/rdb_service_proxy.cpp | 82 +- .../native/rdb/src/rdb_sql_statistic.cpp | 10 +- .../native/rdb/src/rdb_store_config.cpp | 182 +- .../native/rdb/src/rdb_store_impl.cpp | 404 +- .../native/rdb/src/rdb_store_manager.cpp | 8 +- .../native/rdb/src/rdb_types_util.cpp | 15 +- .../native/rdb/src/security_policy.cpp | 17 +- .../frameworks/native/rdb/src/share_block.cpp | 4 +- .../native/rdb/src/sqlite_connection.cpp | 821 ++- .../native/rdb/src/sqlite_global_config.cpp | 6 +- .../rdb/src/sqlite_shared_result_set.cpp | 39 +- .../native/rdb/src/sqlite_sql_builder.cpp | 72 +- .../native/rdb/src/sqlite_statement.cpp | 231 +- .../native/rdb/src/sqlite_utils.cpp | 121 +- .../native/rdb/src/step_result_set.cpp | 82 +- .../rdb_data_share_adapter/src/rdb_utils.cpp | 2 +- .../interfaces/inner_api/rdb/BUILD.gn | 11 +- .../inner_api/rdb/include/abs_result_set.h | 2 + .../rdb/include/abs_shared_result_set.h | 2 + ...data_relational_store_ipc_interface_code.h | 4 + .../inner_api/rdb/include/rdb_common.h | 14 + .../inner_api/rdb/include/rdb_errno.h | 15 + .../inner_api/rdb/include/rdb_helper.h | 2 + .../inner_api/rdb/include/rdb_service.h | 10 +- .../inner_api/rdb/include/rdb_store.h | 38 + .../inner_api/rdb/include/rdb_store_config.h | 93 +- .../inner_api/rdb/include/rdb_types.h | 7 + .../inner_api/rdb/include/value_object.h | 7 +- .../rdb/mock/include/abs_result_set.h | 5 +- .../inner_api/rdb/mock/include/rdb_common.h | 14 + .../inner_api/rdb/mock/include/rdb_helper.h | 1 + .../inner_api/rdb/mock/include/rdb_store.h | 16 + .../rdb/mock/include/rdb_store_config.h | 130 +- .../inner_api/rdb/mock/include/value_object.h | 2 +- .../interfaces/ndk/include/relational_store.h | 6 + .../interfaces/ndk/src/relational_asset.cpp | 6 +- .../interfaces/ndk/src/relational_store.cpp | 28 +- .../frameworks/native/rdb/concurrent_map.h | 6 - .../rdbmock/frameworks/native/rdb/file_ex.h | 14 + .../rdbmock/frameworks/native/rdb/mock.h | 4 +- .../frameworks/native/win32/sys/ioctl.h | 34 + relational_store/relational_store.gni | 4 + .../src/RdbstorePredicatesJsunit.test.js | 34 + .../src/RdbStoreAssetResultSetJsunit.test.js | 327 + .../unittest/src/RdbStoreDataChange.test.js | 2 +- .../src/RdbStoreDistributedJsunit.test.js | 34 + .../src/RdbStoreQueryByCursor.test.js | 5 +- .../unittest/src/RdbStoreQueryByStep.test.js | 4 +- .../src/RdbStoreResultSetGetRow.test.js | 70 +- .../src/RdbStoreResultSetGetValue.test.js | 354 + .../unittest/src/RdbStoreValueType.test.js | 2 +- .../src/RdbstoreAfterCloseJsunit.test.js | 683 ++ .../src/RdbstoreAfterCloseSyncJsunit.test.js | 146 + ...reBackupRestoreWithFAContextJsunit.test.js | 76 + .../unittest/src/RdbstoreDeleteJsunit.test.js | 102 + .../src/RdbstoreDeleteSyncJsunit.test.js | 53 + .../unittest/src/RdbstoreInsertJsunit.test.js | 47 +- .../src/RdbstoreInsertSyncJsUnit.test.js | 46 +- .../src/RdbstorePluginLibsJsunit.test.js | 159 + .../src/RdbstoreRdbstoreJsunit.test.js | 5 +- .../src/RdbstoreStoreExcuteJsunit.test.js | 26 +- .../src/RdbstoreStoreExcuteSqlJsunit.test.js | 88 +- .../src/RdbstoreStoreExcuteSyncJsunit.test.js | 150 +- .../unittest/src/RdbstoreUpdateJsunit.test.js | 67 + .../src/RdbstoreUpdateSyncJsunit.test.js | 65 + .../appdatafwk/unittest/serializable_test.cpp | 66 +- .../unittest/data_ability_predicates_test.cpp | 24 +- relational_store/test/native/rdb/BUILD.gn | 18 +- .../rdb_store_impl_test/distributed_test.cpp | 60 +- .../distributed_test_agent.cpp | 33 +- .../rdb/fuzztest/rdbimpl_fuzzer/BUILD.gn | 17 +- .../rdb/fuzztest/rdbimpl_fuzzer/project.xml | 2 +- .../rdb/fuzztest/rdbrdutils_fuzzer/BUILD.gn | 27 + .../rddbopen_fuzzer/BUILD.gn | 78 + .../rddbopen_fuzzer/corpus/init | 14 + .../rddbopen_fuzzer/project.xml | 25 + .../rddbopen_fuzzer/rddbopen_fuzzer.cpp | 118 + .../rddbopen_fuzzer/rddbopen_fuzzer.h | 21 + .../rddbrepair_fuzzer/BUILD.gn | 78 + .../rddbrepair_fuzzer/corpus/init | 14 + .../rddbrepair_fuzzer/project.xml | 25 + .../rddbrepair_fuzzer/rddbrepair_fuzzer.cpp | 37 + .../rddbrepair_fuzzer/rddbrepair_fuzzer.h | 21 + .../transfergrderrno_fuzzer/BUILD.gn | 78 + .../transfergrderrno_fuzzer/corpus/init | 14 + .../transfergrderrno_fuzzer/project.xml | 25 + .../transfergrderrno_fuzzer.cpp | 46 + .../transfergrderrno_fuzzer.h | 21 + .../transfergrdtypetocoltype_fuzzer/BUILD.gn | 78 + .../corpus/init | 14 + .../project.xml | 25 + .../transfergrdtypetocoltype_fuzzer.cpp | 46 + .../transfergrdtypetocoltype_fuzzer.h | 21 + .../rdbstore_fuzzer/rdbstore_fuzzer.cpp | 40 +- .../rdb/fuzztest/rdstatement_fuzzer/BUILD.gn | 78 + .../fuzztest/rdstatement_fuzzer/corpus/init | 14 + .../fuzztest/rdstatement_fuzzer/project.xml | 25 + .../rdstatement_fuzzer/rdstatement_fuzzer.cpp | 38 + .../rdstatement_fuzzer/rdstatement_fuzzer.h | 21 + .../native/rdb/unittest/big_integer_test.cpp | 60 + .../native/rdb/unittest/connection_test.cpp | 82 + .../multiThread/rdb_connection_rd_test.cpp | 178 + .../multiThread/rdb_connection_test.cpp | 18 +- .../rdb/unittest/raw_data_parser_test.cpp | 151 + .../native/rdb/unittest/rd_utils_test.cpp | 68 + .../native/rdb/unittest/rdb_attach_test.cpp | 12 +- .../native/rdb/unittest/rdb_bigint_test.cpp | 30 +- .../native/rdb/unittest/rdb_delete_test.cpp | 8 +- .../rdb/unittest/rdb_distributed_test.cpp | 21 +- .../rdb/unittest/rdb_double_write_test.cpp | 1143 ++++ .../rdb/unittest/rdb_encrypt_decrypt_test.cpp | 4 +- .../native/rdb/unittest/rdb_execute_test.cpp | 6 +- .../rdb/unittest/rdb_get_store_test.cpp | 109 +- .../native/rdb/unittest/rdb_insert_test.cpp | 8 +- .../rdb/unittest/rdb_open_callback_test.cpp | 8 +- .../unittest/rdb_predicates_join_b_test.cpp | 47 +- .../rdb/unittest/rdb_predicates_join_test.cpp | 24 +- .../rdb/unittest/rdb_predicates_test.cpp | 143 +- .../rdb/unittest/rdb_read_only_test.cpp | 4 +- .../unittest/rdb_security_manager_test.cpp | 102 + .../rdb/unittest/rdb_sql_utils_test.cpp | 59 + .../rdb_sqlite_shared_result_set_test.cpp | 46 +- .../unittest/rdb_step_result_get_row_test.cpp | 2 +- .../rdb/unittest/rdb_step_result_set_test.cpp | 76 +- .../unittest/rdb_store_concurrent_test.cpp | 10 +- .../rdb/unittest/rdb_store_config_test.cpp | 14 +- .../rdb/unittest/rdb_store_impl_test.cpp | 147 +- .../rdb/unittest/rdb_store_interface_test.cpp | 8 +- .../rdb/unittest/rdb_store_rekey_test.cpp | 131 +- .../rdb/unittest/rdb_store_subscribe_test.cpp | 97 +- .../rdb/unittest/rdb_transaction_test.cpp | 18 +- .../native/rdb/unittest/rdb_update_test.cpp | 115 +- .../native/rdb/unittest/rdb_upgrade_test.cpp | 8 +- .../native/rdb/unittest/rdb_utils_test.cpp | 49 +- .../rdb/unittest/rdb_value_bucket_test.cpp | 8 +- .../rdb/unittest/rdb_wal_limit_test.cpp | 23 +- .../native/rdb/unittest/value_object_test.cpp | 111 + .../unittest/data_ability_utils_test.cpp | 17 +- .../unittest/rdb_data_share_adapter_test.cpp | 36 +- relational_store/test/ndk/unittest/common.h | 2 +- .../test/ndk/unittest/rdb_asset_test.cpp | 11 +- .../test/ndk/unittest/rdb_cursor_test.cpp | 13 +- .../test/ndk/unittest/rdb_predicates_test.cpp | 35 +- .../test/ndk/unittest/rdb_store_test.cpp | 70 +- test/CMakeLists.txt | 9 +- udmf/BUILD.gn | 3 + udmf/CMakeLists.txt | 12 +- udmf/adapter/BUILD.gn | 305 + udmf/adapter/arkui_x_udmf.gni | 31 + .../innerkitsimpl/client/concurrent_map.h | 27 + .../innerkitsimpl/client/udmf_client.cpp | 91 + .../innerkitsimpl/client/utd_client.cpp | 74 + udmf/bundle.json | 24 + udmf/framework/common/base32_utils.cpp | 2 - .../common/custom_utd_json_parser.cpp | 3 - udmf/framework/common/endian_converter.cpp | 84 + udmf/framework/common/endian_converter.h | 20 +- udmf/framework/common/graph.cpp | 12 + udmf/framework/common/graph.h | 1 + udmf/framework/common/logger.h | 1 + udmf/framework/common/tlv_object.cpp | 606 +- udmf/framework/common/tlv_object.h | 28 +- udmf/framework/common/tlv_util.cpp | 112 +- udmf/framework/common/tlv_util.h | 5 + udmf/framework/common/udmf_radar_reporter.cpp | 140 + udmf/framework/common/udmf_radar_reporter.h | 38 +- udmf/framework/common/udmf_types_util.cpp | 31 +- udmf/framework/common/udmf_types_util.h | 6 + udmf/framework/common/udmf_utils.cpp | 18 +- udmf/framework/common/udmf_utils.h | 2 +- udmf/framework/common/unittest/BUILD.gn | 82 + .../common/unittest/udmf_types_util_test.cpp | 204 + .../common/unittest/utd_cfgs_checker_test.cpp | 281 + udmf/framework/common/utd_cfgs_checker.cpp | 1 - udmf/framework/common/utd_common.h | 2 + udmf/framework/common/utd_graph.cpp | 8 +- udmf/framework/common/utd_graph.h | 3 +- .../client/async_obtain_data.cpp | 224 + .../innerkitsimpl/client/async_obtain_data.h | 61 + .../innerkitsimpl/client/getter_system.cpp | 49 + .../innerkitsimpl/client/udmf_client.cpp | 68 +- .../innerkitsimpl/client/utd_client.cpp | 312 +- .../innerkitsimpl/common/unified_key.cpp | 14 +- .../innerkitsimpl/common/unified_meta.cpp | 90 +- .../convert/ndk_data_conversion.cpp | 37 + .../data/application_defined_record.cpp | 4 +- udmf/framework/innerkitsimpl/data/audio.cpp | 5 +- udmf/framework/innerkitsimpl/data/file.cpp | 1 + .../innerkitsimpl/data/flexible_type.cpp | 19 +- udmf/framework/innerkitsimpl/data/folder.cpp | 5 +- udmf/framework/innerkitsimpl/data/html.cpp | 35 +- udmf/framework/innerkitsimpl/data/image.cpp | 5 +- udmf/framework/innerkitsimpl/data/link.cpp | 33 +- .../innerkitsimpl/data/plain_text.cpp | 33 +- .../data/preset_type_descriptors.cpp | 296 +- .../data/system_defined_appitem.cpp | 53 +- .../data/system_defined_form.cpp | 5 +- .../data/system_defined_pixelmap.cpp | 45 +- .../data/system_defined_record.cpp | 15 +- udmf/framework/innerkitsimpl/data/text.cpp | 14 +- .../innerkitsimpl/data/unified_data.cpp | 57 +- .../data/unified_data_helper.cpp | 16 +- .../innerkitsimpl/data/unified_record.cpp | 136 +- udmf/framework/innerkitsimpl/data/video.cpp | 5 +- .../distributeddata_udmf_ipc_interface_code.h | 2 + .../innerkitsimpl/service/udmf_service.h | 2 + .../service/udmf_service_client.cpp | 10 + .../service/udmf_service_client.h | 2 + .../service/udmf_service_proxy.cpp | 34 +- .../service/udmf_service_proxy.h | 2 + .../innerkitsimpl/test/fuzztest/BUILD.gn | 5 +- .../udmfclient_fuzzer/udmf_client_fuzzer.cpp | 41 + .../test/fuzztest/utdclient_fuzzer/BUILD.gn | 51 + .../fuzztest/utdclient_fuzzer/corpus/init | 16 + .../fuzztest/utdclient_fuzzer/project.xml | 25 + .../utdclient_fuzzer/utd_client_fuzzer.cpp | 122 + .../utdclient_fuzzer/utd_client_fuzzer.h | 21 + .../innerkitsimpl/test/unittest/BUILD.gn | 405 +- .../application_defined_record_test.cpp | 113 + .../test/unittest/audio_test.cpp | 68 + .../innerkitsimpl/test/unittest/file_test.cpp | 87 + .../test/unittest/flexible_type_test.cpp | 212 + .../test/unittest/folder_test.cpp | 68 + .../innerkitsimpl/test/unittest/html_test.cpp | 189 + .../test/unittest/image_test.cpp | 68 + .../innerkitsimpl/test/unittest/link_test.cpp | 187 + .../mock/include/udmf_service_client_mock.h | 70 + .../mock/system_defined_pixelmap_mock.cpp | 57 + .../test/unittest/mock/tlv_object_mock.cpp | 262 + .../mock/udmf_service_client_mock.cpp | 155 + .../test/unittest/plain_text_test.cpp | 123 + .../unittest/system_defined_appitem_test.cpp | 223 + .../unittest/system_defined_form_test.cpp | 68 + .../unittest/system_defined_pixelmap_test.cpp | 100 + .../unittest/system_defined_record_test.cpp | 128 + .../innerkitsimpl/test/unittest/text_test.cpp | 87 + .../unittest/udmf_client_abnormal_test.cpp | 272 + .../test/unittest/udmf_client_test.cpp | 442 ++ .../unittest/unified_data_helper_test.cpp | 167 + .../test/unittest/unified_data_test.cpp | 162 + .../test/unittest/unified_meta_test.cpp | 509 ++ .../test/unittest/unified_record_test.cpp | 169 + .../test/unittest/utd_client_test.cpp | 572 ++ .../test/unittest/video_test.cpp | 69 + .../jskitsimpl/common/napi_data_utils.cpp | 121 +- .../jskitsimpl/common/napi_error_utils.cpp | 8 +- .../jskitsimpl/common/napi_queue.cpp | 2 - .../data/application_defined_record_napi.cpp | 3 - udmf/framework/jskitsimpl/data/audio_napi.cpp | 3 - udmf/framework/jskitsimpl/data/file_napi.cpp | 3 - .../framework/jskitsimpl/data/folder_napi.cpp | 3 - udmf/framework/jskitsimpl/data/html_napi.cpp | 3 - udmf/framework/jskitsimpl/data/image_napi.cpp | 3 - udmf/framework/jskitsimpl/data/link_napi.cpp | 3 - .../jskitsimpl/data/plain_text_napi.cpp | 3 - .../jskitsimpl/data/summary_napi.cpp | 2 - .../data/system_defined_appitem_napi.cpp | 3 - .../data/system_defined_form_napi.cpp | 3 - .../data/system_defined_pixelmap_napi.cpp | 3 - .../data/system_defined_record_napi.cpp | 3 - udmf/framework/jskitsimpl/data/text_napi.cpp | 3 - .../jskitsimpl/data/type_descriptor_napi.cpp | 2 - .../data/unified_data_channel_napi.cpp | 3 - .../jskitsimpl/data/unified_data_napi.cpp | 2 - .../data/unified_data_properties_napi.cpp | 2 - .../jskitsimpl/data/unified_record_napi.cpp | 21 +- .../data/uniform_type_descriptor_napi.cpp | 79 +- udmf/framework/jskitsimpl/data/video_napi.cpp | 3 - .../jskitsimpl/unittest/UdmfJsTest.js | 385 ++ .../jskitsimpl/unittest/UdmfUtdJsTest.js | 206 +- .../ndkimpl/data/data_provider_impl.cpp | 55 + udmf/framework/ndkimpl/data/udmf.cpp | 826 +++ .../framework/ndkimpl/data/udmf_capi_common.h | 119 + udmf/framework/ndkimpl/data/uds.cpp | 529 ++ udmf/framework/ndkimpl/data/utd.cpp | 290 + udmf/framework/ndkimpl/unittest/BUILD.gn | 93 + .../unittest/ndk_data_conversion_test.cpp | 145 + udmf/framework/ndkimpl/unittest/udmf_test.cpp | 1888 +++++ udmf/framework/ndkimpl/unittest/uds_test.cpp | 1084 +++ udmf/framework/ndkimpl/unittest/utd_test.cpp | 588 ++ udmf/interfaces/innerkits/BUILD.gn | 48 +- .../innerkits/client/entry_getter.h | 32 + .../innerkits/client/getter_system.h | 47 + .../interfaces/innerkits/client/udmf_client.h | 3 + udmf/interfaces/innerkits/client/utd_client.h | 15 + udmf/interfaces/innerkits/common/error_code.h | 5 +- .../innerkits/common/unified_meta.h | 103 +- .../innerkits/common/unified_types.h | 24 + .../innerkits/convert/ndk_data_conversion.h | 31 + .../interfaces/innerkits/data/flexible_type.h | 2 + udmf/interfaces/innerkits/data/html.h | 5 + udmf/interfaces/innerkits/data/link.h | 6 + udmf/interfaces/innerkits/data/plain_text.h | 5 + .../innerkits/data/system_defined_appitem.h | 3 + .../innerkits/data/system_defined_pixelmap.h | 4 + .../innerkits/data/system_defined_record.h | 2 + udmf/interfaces/innerkits/data/text.h | 2 + udmf/interfaces/innerkits/data/unified_data.h | 10 +- .../innerkits/data/unified_data_properties.h | 1 + .../innerkits/data/unified_record.h | 34 +- udmf/interfaces/jskits/BUILD.gn | 1 + .../jskits/common/napi_data_utils.h | 15 + .../data/uniform_type_descriptor_napi.h | 2 + .../unified_data_channel_napi_module.cpp | 1 - .../uniform_type_descriptor_napi_module.cpp | 1 - udmf/interfaces/ndk/BUILD.gn | 61 + udmf/interfaces/ndk/data/data_provider_impl.h | 42 + udmf/interfaces/ndk/data/udmf.h | 731 ++ udmf/interfaces/ndk/data/udmf_err_code.h | 74 + udmf/interfaces/ndk/data/udmf_meta.h | 1005 +++ udmf/interfaces/ndk/data/uds.h | 677 ++ udmf/interfaces/ndk/data/utd.h | 231 + udmf/udmf.gni | 6 +- 1408 files changed, 88164 insertions(+), 26265 deletions(-) create mode 100644 data_object/frameworks/innerkitsimpl/include/common/common_types.h create mode 100644 data_object/frameworks/innerkitsimpl/src/object_radar_reporter.cpp create mode 100644 data_share/frameworks/native/common/include/call_reporter.h create mode 100644 data_share/frameworks/native/common/src/call_reporter.cpp create mode 100644 datamgr_service/services/distributeddataservice/adapter/include/screenlock/screen_lock.h create mode 100644 datamgr_service/services/distributeddataservice/adapter/include/utils/visibility.h create mode 100644 datamgr_service/services/distributeddataservice/adapter/screenlock/BUILD.gn create mode 100644 datamgr_service/services/distributeddataservice/adapter/screenlock/src/screen_lock.cpp create mode 100644 datamgr_service/services/distributeddataservice/framework/account/account_delegate.cpp create mode 100644 datamgr_service/services/distributeddataservice/framework/app_id_mapping/app_id_mapping_config_manager.cpp create mode 100644 datamgr_service/services/distributeddataservice/framework/cloud/cloud_lock_event.cpp create mode 100644 datamgr_service/services/distributeddataservice/framework/communication/connect_manager.cpp rename datamgr_service/services/distributeddataservice/{adapter => framework}/include/account/account_delegate.h (80%) create mode 100644 datamgr_service/services/distributeddataservice/framework/include/app_id_mapping/app_id_mapping_config_manager.h create mode 100644 datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_lock_event.h create mode 100644 datamgr_service/services/distributeddataservice/framework/include/commonevent/set_searchable_event.h create mode 100644 datamgr_service/services/distributeddataservice/framework/include/communication/connect_manager.h create mode 100644 datamgr_service/services/distributeddataservice/framework/include/screen/screen_manager.h create mode 100644 datamgr_service/services/distributeddataservice/framework/screen/screen_manager.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/config/include/model/app_id_mapping_config.h create mode 100644 datamgr_service/services/distributeddataservice/service/config/src/model/app_id_mapping_config.cpp delete mode 100644 datamgr_service/services/distributeddataservice/service/test/auto_sync_matrix_test.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/cloud_service_impl_test.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/dump_helper_test.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/kvdb_service_test.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/mock/general_watcher_mock.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/mock/general_watcher_mock.h create mode 100644 datamgr_service/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.h create mode 100644 datamgr_service/services/distributeddataservice/service/test/object_asset_loader_test.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/object_manager_test.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/object_snapshot_test.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/udmf/store/store_account_observer.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/udmf/store/store_account_observer.h create mode 100644 googletest/ci/windows-presubmit.bat create mode 100644 googletest/googlemock/test/gmock-matchers-arithmetic_test.cc create mode 100644 googletest/googlemock/test/gmock-matchers-comparisons_test.cc rename googletest/googlemock/test/{gmock-matchers_test.cc => gmock-matchers-containers_test.cc} (31%) create mode 100644 googletest/googlemock/test/gmock-matchers-misc_test.cc create mode 100644 googletest/googlemock/test/gmock-matchers_test.h create mode 100644 googletest/googletest/include/gtest/gtest-assertion-result.h create mode 100644 googletest/googletest/include/gtest/hwext/gtest-multithread.h create mode 100644 googletest/googletest/src/gtest-assertion-result.cc create mode 100644 googletest/googletest/src/hwext/gtest-multithread.cpp create mode 100644 googletest/googletest/test/gtest_dirs_test.cc create mode 100644 interface_sdk/api/@ohos.data.sendableRelationalStore.d.ets rename kv_store/frameworks/innerkitsimpl/kvdb/include/{data_change_notifier.h => auto_sync_timer.h} (56%) create mode 100644 kv_store/frameworks/innerkitsimpl/kvdb/include/kv_hiview_reporter.h create mode 100644 kv_store/frameworks/innerkitsimpl/kvdb/src/auto_sync_timer.cpp rename kv_store/frameworks/innerkitsimpl/kvdb/src/{data_change_notifier.cpp => auto_sync_timer_mock.cpp} (35%) create mode 100644 kv_store/frameworks/innerkitsimpl/kvdb/src/kv_hiview_reporter.cpp create mode 100644 kv_store/frameworks/innerkitsimpl/kvdb/src/kv_hiview_reporter_mock.cpp delete mode 100644 kv_store/frameworks/innerkitsimpl/kvdb/test/data_change_notifier_test.cpp create mode 100644 kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_upload_recorder.h create mode 100644 kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_upload_recorder.cpp create mode 100644 kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_recorder.cpp create mode 100644 kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_recorder.h create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/json_fuzzer/BUILD.gn create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/json_fuzzer/corpus/init create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/json_fuzzer/json_fuzzer.cpp rename datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate.cpp => kv_store/frameworks/libs/distributeddb/test/fuzztest/json_fuzzer/json_fuzzer.h (63%) create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/json_fuzzer/project.xml create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/jsoninner_fuzzer/BUILD.gn create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/jsoninner_fuzzer/corpus/init create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/jsoninner_fuzzer/jsoninner_fuzzer.cpp create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/jsoninner_fuzzer/jsoninner_fuzzer.h create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/jsoninner_fuzzer/project.xml create mode 100644 kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_import_and_export_rd_test.cpp delete mode 100644 kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_memory_rd_single_ver_naturall_store_test.cpp delete mode 100644 kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_rd_resultset_and_json_optimize.cpp create mode 100644 kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_kv_syncer_test.cpp create mode 100644 mock/innerkits/multimedia_image_standard/image_native/ndk/include/image_format_convert_mdk_kits.h create mode 100644 mock/innerkits/multimedia_image_standard/image_native/ndk/include/image_mdk_kits.h create mode 100644 mock/innerkits/multimedia_image_standard/image_native/ndk/include/image_packer_mdk_kits.h create mode 100644 mock/innerkits/multimedia_image_standard/image_native/ndk/include/image_packer_native_impl.h create mode 100644 mock/innerkits/multimedia_image_standard/image_native/ndk/include/image_receiver_mdk_kits.h create mode 100644 mock/innerkits/multimedia_image_standard/image_native/ndk/include/image_receiver_napi_listener.h create mode 100644 mock/innerkits/multimedia_image_standard/image_native/ndk/include/image_source_mdk_kits.h create mode 100644 mock/innerkits/multimedia_image_standard/image_native/ndk/include/image_source_native_impl.h create mode 100644 mock/innerkits/multimedia_image_standard/image_native/ndk/include/pixelmap_native_impl.h create mode 100644 mock/innerkits/napi/common.h create mode 100644 mock/innerkits/napi/native_api.h create mode 100644 mock/innerkits/screenlock_mgr/interfaces/inner_api/include/screenlock_callback_interface.h create mode 100644 mock/innerkits/screenlock_mgr/interfaces/inner_api/include/screenlock_common.h create mode 100644 mock/innerkits/screenlock_mgr/interfaces/inner_api/include/screenlock_manager.h create mode 100644 mock/innerkits/screenlock_mgr/interfaces/inner_api/include/screenlock_manager_interface.h create mode 100644 mock/innerkits/screenlock_mgr/interfaces/inner_api/include/screenlock_system_ability_interface.h create mode 100644 mock/innerkits/screenlock_mgr/interfaces/inner_api/include/visibility.h create mode 100644 mock/src/mock_screenlock_mgr.cpp create mode 100644 preferences/OAT.xml create mode 100644 preferences/frameworks/native/include/concurrent_map.h create mode 100644 preferences/frameworks/native/platform/include/preferences_anonymous.h create mode 100644 preferences/frameworks/native/platform/include/preferences_dfx_adapter.h create mode 100644 preferences/frameworks/native/platform/src/preferences_dfx_adapter.cpp create mode 100644 preferences/frameworks/ndk/include/convertor_error_code.h create mode 100644 preferences/frameworks/ndk/include/oh_preferences_impl.h create mode 100644 preferences/frameworks/ndk/include/oh_preferences_value_impl.h create mode 100644 preferences/frameworks/ndk/src/convertor_error_code.cpp create mode 100644 preferences/frameworks/ndk/src/oh_preferences.cpp create mode 100644 preferences/frameworks/ndk/src/oh_preferences_option.cpp create mode 100644 preferences/frameworks/ndk/src/oh_preferences_value.cpp create mode 100644 preferences/interfaces/ndk/BUILD.gn create mode 100644 preferences/interfaces/ndk/include/oh_preferences.h create mode 100644 preferences/interfaces/ndk/include/oh_preferences_err_code.h create mode 100644 preferences/interfaces/ndk/include/oh_preferences_option.h create mode 100644 preferences/interfaces/ndk/include/oh_preferences_value.h create mode 100644 relational_store/frameworks/js/napi/common/include/js_sendable_utils.h create mode 100644 relational_store/frameworks/js/napi/common/src/js_sendable_utils.cpp create mode 100644 relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_context.h create mode 100644 relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_sendable_utils.h create mode 100644 relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_sendable_utils.cpp create mode 100644 relational_store/frameworks/js/napi/sendablerelationalstore/BUILD.gn create mode 100644 relational_store/frameworks/js/napi/sendablerelationalstore/include/napi_rdb_store_convert_utils.h create mode 100644 relational_store/frameworks/js/napi/sendablerelationalstore/src/entry_point.cpp create mode 100644 relational_store/frameworks/js/napi/sendablerelationalstore/src/napi_rdb_store_convert_utils.cpp create mode 100644 relational_store/frameworks/native/dfx/include/rdb_fault_hiview_reporter.h create mode 100644 relational_store/frameworks/native/dfx/src/rdb_fault_hiview_reporter.cpp rename relational_store/frameworks/native/rdb/{mock/include/sqlite_connection_pool.h => include/connection_pool.h} (85%) rename relational_store/frameworks/native/rdb/{include/sqlite_connection_pool.h => mock/include/connection_pool.h} (85%) create mode 100644 relational_store/frameworks/native/rdb/mock/src/rdb_fault_hiview_reporter.cpp rename relational_store/frameworks/native/rdb/src/{sqlite_connection_pool.cpp => connection_pool.cpp} (76%) create mode 100644 relational_store/rdbmock/frameworks/native/win32/sys/ioctl.h create mode 100644 relational_store/test/js/relationalstore/unittest/src/RdbStoreResultSetGetValue.test.js create mode 100644 relational_store/test/js/relationalstore/unittest/src/RdbstoreAfterCloseJsunit.test.js create mode 100644 relational_store/test/js/relationalstore/unittest/src/RdbstoreAfterCloseSyncJsunit.test.js create mode 100644 relational_store/test/js/relationalstore/unittest/src/RdbstorePluginLibsJsunit.test.js create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/BUILD.gn create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/rddbopen_fuzzer/BUILD.gn create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/rddbopen_fuzzer/corpus/init create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/rddbopen_fuzzer/project.xml create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/rddbopen_fuzzer/rddbopen_fuzzer.cpp create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/rddbopen_fuzzer/rddbopen_fuzzer.h create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/rddbrepair_fuzzer/BUILD.gn create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/rddbrepair_fuzzer/corpus/init create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/rddbrepair_fuzzer/project.xml create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/rddbrepair_fuzzer/rddbrepair_fuzzer.cpp create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/rddbrepair_fuzzer/rddbrepair_fuzzer.h create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/transfergrderrno_fuzzer/BUILD.gn create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/transfergrderrno_fuzzer/corpus/init create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/transfergrderrno_fuzzer/project.xml create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/transfergrderrno_fuzzer/transfergrderrno_fuzzer.cpp create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/transfergrderrno_fuzzer/transfergrderrno_fuzzer.h create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/transfergrdtypetocoltype_fuzzer/BUILD.gn create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/transfergrdtypetocoltype_fuzzer/corpus/init create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/transfergrdtypetocoltype_fuzzer/project.xml create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/transfergrdtypetocoltype_fuzzer/transfergrdtypetocoltype_fuzzer.cpp create mode 100644 relational_store/test/native/rdb/fuzztest/rdbrdutils_fuzzer/transfergrdtypetocoltype_fuzzer/transfergrdtypetocoltype_fuzzer.h create mode 100644 relational_store/test/native/rdb/fuzztest/rdstatement_fuzzer/BUILD.gn create mode 100644 relational_store/test/native/rdb/fuzztest/rdstatement_fuzzer/corpus/init create mode 100644 relational_store/test/native/rdb/fuzztest/rdstatement_fuzzer/project.xml create mode 100644 relational_store/test/native/rdb/fuzztest/rdstatement_fuzzer/rdstatement_fuzzer.cpp create mode 100644 relational_store/test/native/rdb/fuzztest/rdstatement_fuzzer/rdstatement_fuzzer.h create mode 100644 relational_store/test/native/rdb/unittest/big_integer_test.cpp create mode 100644 relational_store/test/native/rdb/unittest/connection_test.cpp create mode 100644 relational_store/test/native/rdb/unittest/multiThread/rdb_connection_rd_test.cpp create mode 100644 relational_store/test/native/rdb/unittest/raw_data_parser_test.cpp create mode 100644 relational_store/test/native/rdb/unittest/rd_utils_test.cpp create mode 100644 relational_store/test/native/rdb/unittest/rdb_double_write_test.cpp create mode 100644 relational_store/test/native/rdb/unittest/rdb_security_manager_test.cpp create mode 100644 relational_store/test/native/rdb/unittest/rdb_sql_utils_test.cpp create mode 100644 relational_store/test/native/rdb/unittest/value_object_test.cpp create mode 100644 udmf/adapter/BUILD.gn create mode 100644 udmf/adapter/arkui_x_udmf.gni create mode 100644 udmf/adapter/framework/innerkitsimpl/client/concurrent_map.h create mode 100644 udmf/adapter/framework/innerkitsimpl/client/udmf_client.cpp create mode 100644 udmf/adapter/framework/innerkitsimpl/client/utd_client.cpp create mode 100644 udmf/framework/common/endian_converter.cpp create mode 100644 udmf/framework/common/udmf_radar_reporter.cpp create mode 100644 udmf/framework/common/unittest/BUILD.gn create mode 100644 udmf/framework/common/unittest/udmf_types_util_test.cpp create mode 100644 udmf/framework/common/unittest/utd_cfgs_checker_test.cpp create mode 100644 udmf/framework/innerkitsimpl/client/async_obtain_data.cpp create mode 100644 udmf/framework/innerkitsimpl/client/async_obtain_data.h create mode 100644 udmf/framework/innerkitsimpl/client/getter_system.cpp create mode 100644 udmf/framework/innerkitsimpl/convert/ndk_data_conversion.cpp create mode 100644 udmf/framework/innerkitsimpl/test/fuzztest/utdclient_fuzzer/BUILD.gn create mode 100644 udmf/framework/innerkitsimpl/test/fuzztest/utdclient_fuzzer/corpus/init create mode 100644 udmf/framework/innerkitsimpl/test/fuzztest/utdclient_fuzzer/project.xml create mode 100644 udmf/framework/innerkitsimpl/test/fuzztest/utdclient_fuzzer/utd_client_fuzzer.cpp create mode 100644 udmf/framework/innerkitsimpl/test/fuzztest/utdclient_fuzzer/utd_client_fuzzer.h create mode 100644 udmf/framework/innerkitsimpl/test/unittest/application_defined_record_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/audio_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/file_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/flexible_type_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/folder_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/html_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/image_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/link_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/mock/include/udmf_service_client_mock.h create mode 100644 udmf/framework/innerkitsimpl/test/unittest/mock/system_defined_pixelmap_mock.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/mock/tlv_object_mock.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/mock/udmf_service_client_mock.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/plain_text_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/system_defined_appitem_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/system_defined_form_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/system_defined_pixelmap_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/system_defined_record_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/text_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/udmf_client_abnormal_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/unified_data_helper_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/unified_data_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/unified_meta_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/unified_record_test.cpp create mode 100644 udmf/framework/innerkitsimpl/test/unittest/video_test.cpp create mode 100644 udmf/framework/ndkimpl/data/data_provider_impl.cpp create mode 100644 udmf/framework/ndkimpl/data/udmf.cpp create mode 100644 udmf/framework/ndkimpl/data/udmf_capi_common.h create mode 100644 udmf/framework/ndkimpl/data/uds.cpp create mode 100644 udmf/framework/ndkimpl/data/utd.cpp create mode 100644 udmf/framework/ndkimpl/unittest/BUILD.gn create mode 100644 udmf/framework/ndkimpl/unittest/ndk_data_conversion_test.cpp create mode 100644 udmf/framework/ndkimpl/unittest/udmf_test.cpp create mode 100644 udmf/framework/ndkimpl/unittest/uds_test.cpp create mode 100644 udmf/framework/ndkimpl/unittest/utd_test.cpp create mode 100644 udmf/interfaces/innerkits/client/entry_getter.h create mode 100644 udmf/interfaces/innerkits/client/getter_system.h create mode 100644 udmf/interfaces/innerkits/convert/ndk_data_conversion.h create mode 100644 udmf/interfaces/ndk/BUILD.gn create mode 100644 udmf/interfaces/ndk/data/data_provider_impl.h create mode 100644 udmf/interfaces/ndk/data/udmf.h create mode 100644 udmf/interfaces/ndk/data/udmf_err_code.h create mode 100644 udmf/interfaces/ndk/data/udmf_meta.h create mode 100644 udmf/interfaces/ndk/data/uds.h create mode 100644 udmf/interfaces/ndk/data/utd.h diff --git a/data_object/CMakeLists.txt b/data_object/CMakeLists.txt index 318c5f41..117034f6 100644 --- a/data_object/CMakeLists.txt +++ b/data_object/CMakeLists.txt @@ -35,6 +35,7 @@ include(${KV_STORE_DIR}/interfaces/CMakeLists.txt OPTIONAL) set(links secure mock adapter distributeddb kvdb) add_library(data_object SHARED ${data_object_src}) target_link_libraries(data_object ${links}) +target_include_directories(data_object PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/frameworks/innerkitsimpl/include) target_include_directories(data_object PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/frameworks/innerkitsimpl/include/common) target_include_directories(data_object PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/innerkits) target_include_directories(data_object PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../relational_store/interfaces/inner_api/common_type/include) \ No newline at end of file diff --git a/data_object/bundle.json b/data_object/bundle.json index 146b70fc..26237616 100644 --- a/data_object/bundle.json +++ b/data_object/bundle.json @@ -61,10 +61,7 @@ "dmsfwk", "hisysevent" ], - "third_party": [ - "libuv", - "bounds_checking_function" - ] + "third_party": [] }, "build": { "sub_component": [ diff --git a/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_storage_engine.h b/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_storage_engine.h index e549a1c3..d94ee1f1 100644 --- a/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_storage_engine.h +++ b/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_storage_engine.h @@ -49,6 +49,7 @@ public: void NotifyStatus(const std::string &sessionId, const std::string &deviceId, const std::string &status); void NotifyChange(const std::string &sessionId, const std::map> &changedData); private: + constexpr static const char *DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC"; std::mutex operationMutex_{}; std::shared_ptr storeManager_; std::map delegates_; diff --git a/data_object/frameworks/innerkitsimpl/include/common/common_types.h b/data_object/frameworks/innerkitsimpl/include/common/common_types.h new file mode 100644 index 00000000..67d4e2e7 --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/include/common/common_types.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 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_DATA_OBJECT_COMMON_TYPES_H +#define OHOS_DATA_OBJECT_COMMON_TYPES_H +#include +#include +#include +#include +namespace OHOS::CommonType { +struct AssetValue { + enum Status : int32_t { + STATUS_UNKNOWN, + STATUS_NORMAL, + STATUS_INSERT, + STATUS_UPDATE, + STATUS_DELETE, + STATUS_ABNORMAL, + STATUS_DOWNLOADING, + STATUS_BUTT + }; + static constexpr uint64_t NO_EXPIRES_TIME = 0; + uint32_t version = 0; + mutable uint32_t status = STATUS_UNKNOWN; + uint64_t expiresTime = NO_EXPIRES_TIME; + std::string id; + std::string name; + std::string uri; + std::string createTime; + std::string modifyTime; + std::string size; + std::string hash; + std::string path; +}; +using Bytes = std::vector; +using Asset = AssetValue; +using Assets = std::vector; +using Value = std::variant; +using ValuesBucket = std::map; +} +#endif // OHOS_DATA_OBJECT_COMMON_TYPES_H \ No newline at end of file diff --git a/data_object/frameworks/innerkitsimpl/include/common/logger.h b/data_object/frameworks/innerkitsimpl/include/common/logger.h index 2d591b0f..63f2a1e7 100644 --- a/data_object/frameworks/innerkitsimpl/include/common/logger.h +++ b/data_object/frameworks/innerkitsimpl/include/common/logger.h @@ -60,7 +60,7 @@ static inline OHOS::HiviewDFX::HiLogLabel LogLabel() } \ } while (0) -#define LOG_FATAL(fmt, ...) \ +#define LOG_FATAL(fmt, ...) \ do { \ auto lable = LogLabel(); \ if (HiLogIsLoggable(lable.domain, lable.tag, LogLevel::LOG_FATAL)) { \ @@ -73,14 +73,15 @@ static inline OHOS::HiviewDFX::HiLogLabel LogLabel() #else #include #include +#define __FILE_NAME__ __FILE__ #define LOG_DEBUG(fmt, ...) \ - printf("[D][ObjectStore]%s:%d %s: " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) + printf("[D][ObjectStore]%s:%d %s: " fmt "\n", __FILE_NAME__, __LINE__, __FUNCTION__, ##__VA_ARGS__) #define LOG_ERROR(fmt, ...) \ - printf("[E][ObjectStore]%s:%d %s: " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) + printf("[E][ObjectStore]%s:%d %s: " fmt "\n", __FILE_NAME__, __LINE__, __FUNCTION__, ##__VA_ARGS__) #define LOG_INFO(fmt, ...) \ - printf("[I][ObjectStore]%s:%d %s: " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) + printf("[I][ObjectStore]%s:%d %s: " fmt "\n", __FILE_NAME__, __LINE__, __FUNCTION__, ##__VA_ARGS__) #define LOG_WARN(fmt, ...) \ - printf("[W][ObjectStore]%s:%d %s: " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) + printf("[W][ObjectStore]%s:%d %s: " fmt "\n", __FILE_NAME__, __LINE__, __FUNCTION__, ##__VA_ARGS__) #endif // #ifdef HILOG_ENABLE #endif // OBJECT_STORE_LOGGER_H diff --git a/data_object/frameworks/innerkitsimpl/include/common/object_radar_reporter.h b/data_object/frameworks/innerkitsimpl/include/common/object_radar_reporter.h index 95181502..8c87673d 100644 --- a/data_object/frameworks/innerkitsimpl/include/common/object_radar_reporter.h +++ b/data_object/frameworks/innerkitsimpl/include/common/object_radar_reporter.h @@ -16,12 +16,15 @@ #ifndef OBJECT_RADAR_REPORTER_H #define OBJECT_RADAR_REPORTER_H -#include "hisysevent.h" +#include "hisysevent_c.h" +#include +#include "visibility.h" namespace OHOS::ObjectStore { enum BizScene { CREATE = 1, SAVE = 2, + DATA_RESTORE = 3, }; enum CreateStage { INIT_STORE = 1, @@ -33,6 +36,12 @@ enum SaveStage { SAVE_TO_SERVICE = 1, SAVE_TO_STORE = 2, PUSH_ASSETS = 3, + SYNC_DATA = 4, +}; +enum DataRestoreStage { + DATA_RECV = 1, + ASSETS_RECV = 2, + NOTIFY = 3, }; enum StageRes { IDLE = 0, @@ -55,18 +64,21 @@ enum ErrorCode { GETKV_FAILED = OFFSET + 6, DB_NOT_INIT = OFFSET + 7, }; -static constexpr char DOMAIN[] = "DISTDATAMGR"; -const std::string EVENT_NAME = "DISTRIBUTED_DATA_OBJECT_BEHAVIOR"; -static constexpr HiviewDFX::HiSysEvent::EventType TYPE = HiviewDFX::HiSysEvent::EventType::BEHAVIOR; -const std::string ORG_PKG = "distributeddata"; -const std::string ERROR_CODE = "ERROR_CODE"; -const std::string BIZ_STATE = "BIZ_STATE"; +constexpr char DOMAIN[] = "DISTDATAMGR"; +constexpr char EVENT_NAME[] = "DISTRIBUTED_DATA_OBJECT_BEHAVIOR"; +constexpr char ORG_PKG[] = "distributeddata"; -#define RADAR_REPORT(bizScene, bizStage, stageRes, ...) \ -({ \ - HiSysEventWrite(ObjectStore::DOMAIN, ObjectStore::EVENT_NAME, ObjectStore::TYPE, \ - "ORG_PKG", ObjectStore::ORG_PKG, "FUNC", __FUNCTION__, \ - "BIZ_SCENE", bizScene, "BIZ_STAGE", bizStage, "STAGE_RES", stageRes, ##__VA_ARGS__); \ -}) +class API_EXPORT RadarReporter { +public: + static void ReportStateStart(std::string func, int32_t scene, int32_t stage, int32_t stageRes, + int32_t state, std::string appCaller); + static void ReportStateFinished(std::string func, int32_t scene, int32_t stage, + int32_t stageRes, int32_t state); + static void ReportStateError(std::string func, int32_t scene, int32_t stage, int32_t stageRes, + int32_t errCode, int32_t state); + static void ReportStage(std::string func, int32_t scene, int32_t stage, int32_t stageRes); + static void ReportStageError(std::string func, int32_t scene, int32_t stage, + int32_t stageRes, int32_t errCode); +}; } // namespace OHOS::ObjectStore #endif // OBJECT_RADAR_REPORTER_H diff --git a/data_object/frameworks/innerkitsimpl/include/communicator/softbus_adapter.h b/data_object/frameworks/innerkitsimpl/include/communicator/softbus_adapter.h index 74869706..bb3961e5 100644 --- a/data_object/frameworks/innerkitsimpl/include/communicator/softbus_adapter.h +++ b/data_object/frameworks/innerkitsimpl/include/communicator/softbus_adapter.h @@ -67,7 +67,7 @@ public: int RemoveSessionServerAdapter(const std::string &sessionName) const; - void UpdateRelationship(const std::string &networkid, const DeviceChangeType &type); + void UpdateRelationship(const std::string &networkId, const DeviceChangeType &type); void NotifyDataListeners(const uint8_t *ptr, const int size, const std::string &deviceId, const PipeInfo &pipeInfo); diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_impl.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_impl.cpp index 17b7c15b..9bc4246e 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_impl.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_impl.cpp @@ -91,7 +91,6 @@ uint32_t DistributedObjectImpl::GetComplex(const std::string &key, std::vectorSave(sessionId_, deviceId); if (status != SUCCESS) { LOG_ERROR("DistributedObjectImpl:Save failed. status = %{public}d", status); diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp index 8abff6e4..5904e831 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp @@ -257,17 +257,18 @@ void WatcherProxy::SetAssetChangeCallBack(const AssetChangeCallback &assetChange DistributedObjectStore *DistributedObjectStore::GetInstance(const std::string &bundleName) { - RADAR_REPORT(CREATE, INIT_STORE, IDLE, BIZ_STATE, START); static std::mutex instLock_; static DistributedObjectStore *instPtr = nullptr; if (instPtr == nullptr) { std::lock_guard lock(instLock_); if (instPtr == nullptr && !bundleName.empty()) { + RadarReporter::ReportStateStart(std::string(__FUNCTION__), CREATE, INIT_STORE, IDLE, START, bundleName); LOG_INFO("new objectstore %{public}s", bundleName.c_str()); FlatObjectStore *flatObjectStore = new (std::nothrow) FlatObjectStore(bundleName); if (flatObjectStore == nullptr) { LOG_ERROR("no memory for FlatObjectStore malloc!"); - RADAR_REPORT(CREATE, INIT_STORE, RADAR_FAILED, ERROR_CODE, NO_MEMORY, BIZ_STATE, FINISHED); + RadarReporter::ReportStateError(std::string(__FUNCTION__), CREATE, INIT_STORE, + RADAR_FAILED, NO_MEMORY, FINISHED); return nullptr; } // Use instMemory to make sure this singleton not free before other object. @@ -276,12 +277,13 @@ DistributedObjectStore *DistributedObjectStore::GetInstance(const std::string &b if (instPtr == nullptr) { delete flatObjectStore; LOG_ERROR("no memory for DistributedObjectStoreImpl malloc!"); - RADAR_REPORT(CREATE, INIT_STORE, RADAR_FAILED, ERROR_CODE, NO_MEMORY, BIZ_STATE, FINISHED); + RadarReporter::ReportStateError(std::string(__FUNCTION__), CREATE, INIT_STORE, + RADAR_FAILED, NO_MEMORY, FINISHED); return nullptr; } + RadarReporter::ReportStage(std::string(__FUNCTION__), CREATE, INIT_STORE, RADAR_SUCCESS); } } - RADAR_REPORT(CREATE, INIT_STORE, RADAR_SUCCESS); return instPtr; } diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp index 77fdee13..8f51a161 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp @@ -14,6 +14,8 @@ */ #include "flat_object_storage_engine.h" +#include "accesstoken_kit.h" +#include "ipc_skeleton.h" #include "logger.h" #include "objectstore_errors.h" #include "process_communicator_impl.h" @@ -39,18 +41,21 @@ uint32_t FlatObjectStorageEngine::Open(const std::string &bundleName) LOG_INFO("FlatObjectDatabase: No need to reopen it"); return SUCCESS; } - auto status = DistributedDB::KvStoreDelegateManager::SetProcessLabel("objectstoreDB", bundleName); - if (status != DistributedDB::DBStatus::OK) { - LOG_ERROR("delegate SetProcessLabel failed: %{public}d.", static_cast(status)); - } - - auto communicator = std::make_shared(); - auto commStatus = DistributedDB::KvStoreDelegateManager::SetProcessCommunicator(communicator); - if (commStatus != DistributedDB::DBStatus::OK) { - LOG_ERROR("set distributed db communicator failed."); + auto tokenId = IPCSkeleton::GetSelfTokenID(); + int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, DISTRIBUTED_DATASYNC); + LOG_INFO("bundleName:%{public}s, permission :%{public}d", bundleName.c_str(), ret); + if (ret == Security::AccessToken::PermissionState::PERMISSION_GRANTED) { + auto status = DistributedDB::KvStoreDelegateManager::SetProcessLabel("objectstoreDB", bundleName); + if (status != DistributedDB::DBStatus::OK) { + LOG_ERROR("delegate SetProcessLabel failed: %{public}d.", static_cast(status)); + } + status = DistributedDB::KvStoreDelegateManager::SetProcessCommunicator( + std::make_shared()); + if (status != DistributedDB::DBStatus::OK) { + LOG_ERROR("set distributed db communicator failed: %{public}d.", static_cast(status)); + } } storeManager_ = std::make_shared(bundleName, "default"); - DistributedDB::KvStoreConfig config; config.dataDir = "/data/log"; storeManager_->SetKvStoreConfig(config); @@ -85,16 +90,18 @@ void FlatObjectStorageEngine::OnComplete(const std::string &key, uint32_t FlatObjectStorageEngine::CreateTable(const std::string &key) { - RADAR_REPORT(CREATE, CREATE_TABLE, IDLE); + RadarReporter::ReportStage(std::string(__FUNCTION__), CREATE, CREATE_TABLE, IDLE); if (!isOpened_) { - RADAR_REPORT(CREATE, CREATE_TABLE, RADAR_FAILED, ERROR_CODE, DB_NOT_INIT, BIZ_STATE, FINISHED); + RadarReporter::ReportStateError(std::string(__FUNCTION__), CREATE, CREATE_TABLE, + RADAR_FAILED, DB_NOT_INIT, FINISHED); return ERR_DB_NOT_INIT; } { std::lock_guard lock(operationMutex_); if (delegates_.count(key) != 0) { LOG_ERROR("FlatObjectStorageEngine::CreateTable %{public}s already created", key.c_str()); - RADAR_REPORT(CREATE, CREATE_TABLE, RADAR_FAILED, ERROR_CODE, DUPLICATE_CREATE, BIZ_STATE, FINISHED); + RadarReporter::ReportStateError(std::string(__FUNCTION__), CREATE, CREATE_TABLE, RADAR_FAILED, + DUPLICATE_CREATE, FINISHED); return ERR_EXIST; } } @@ -110,7 +117,8 @@ uint32_t FlatObjectStorageEngine::CreateTable(const std::string &key) }); if (status != DistributedDB::DBStatus::OK || kvStore == nullptr) { LOG_ERROR("FlatObjectStorageEngine::CreateTable %{public}s getkvstore fail[%{public}d]", key.c_str(), status); - RADAR_REPORT(CREATE, CREATE_TABLE, RADAR_FAILED, ERROR_CODE, status, BIZ_STATE, FINISHED); + RadarReporter::ReportStateError(std::string(__FUNCTION__), CREATE, CREATE_TABLE, + RADAR_FAILED, status, FINISHED); return ERR_DB_GETKV_FAIL; } bool autoSync = true; @@ -119,7 +127,8 @@ uint32_t FlatObjectStorageEngine::CreateTable(const std::string &key) status = kvStore->Pragma(DistributedDB::AUTO_SYNC, data); if (status != DistributedDB::DBStatus::OK) { LOG_ERROR("FlatObjectStorageEngine::CreateTable %{public}s Pragma fail[%{public}d]", key.c_str(), status); - RADAR_REPORT(CREATE, CREATE_TABLE, RADAR_FAILED, ERROR_CODE, status, BIZ_STATE, FINISHED); + RadarReporter::ReportStateError(std::string(__FUNCTION__), CREATE, CREATE_TABLE, + RADAR_FAILED, status, FINISHED); return ERR_DB_GETKV_FAIL; } LOG_INFO("create table %{public}s success", key.c_str()); @@ -136,7 +145,7 @@ uint32_t FlatObjectStorageEngine::CreateTable(const std::string &key) deviceIds.push_back(item.deviceId); } SyncAllData(key, deviceIds, onComplete); - RADAR_REPORT(CREATE, CREATE_TABLE, RADAR_SUCCESS); + RadarReporter::ReportStateFinished(std::string(__FUNCTION__), CREATE, CREATE_TABLE, RADAR_SUCCESS, FINISHED); return SUCCESS; } diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp index 7ac84b78..c7b109a3 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp @@ -60,8 +60,8 @@ uint32_t FlatObjectStore::CreateObject(const std::string &sessionId) LOG_ERROR("FlatObjectStore::CreateObject createTable err %{public}d", status); return status; } - ResumeObject(sessionId); SubscribeDataChange(sessionId); + ResumeObject(sessionId); return SUCCESS; } @@ -83,8 +83,8 @@ void FlatObjectStore::ResumeObject(const std::string &sessionId) std::lock_guard lck(mutex_); if (find(retrievedCache_.begin(), retrievedCache_.end(), sessionId) == retrievedCache_.end()) { retrievedCache_.push_back(sessionId); + storageEngine_->NotifyStatus(sessionId, "local", "restored"); } - storageEngine_->NotifyStatus(sessionId, "local", "restored"); } }; cacheManager_->ResumeObject(bundleName_, sessionId, callback); @@ -105,7 +105,11 @@ void FlatObjectStore::SubscribeDataChange(const std::string &sessionId) storageEngine_->NotifyChange(sessionId, filteredData); } if (allReady) { - storageEngine_->NotifyStatus(sessionId, "local", "restored"); + std::lock_guard lck(mutex_); + if (find(retrievedCache_.begin(), retrievedCache_.end(), sessionId) == retrievedCache_.end()) { + retrievedCache_.push_back(sessionId); + storageEngine_->NotifyStatus(sessionId, "local", "restored"); + } } }; cacheManager_->SubscribeDataChange(bundleName_, sessionId, remoteResumeCallback); @@ -182,6 +186,7 @@ uint32_t FlatObjectStore::SetStatusNotifier(std::shared_ptr notif uint32_t FlatObjectStore::Save(const std::string &sessionId, const std::string &deviceId) { + RadarReporter::ReportStateStart(std::string(__FUNCTION__), SAVE, SAVE_TO_SERVICE, IDLE, START, bundleName_); if (cacheManager_ == nullptr) { LOG_ERROR("FlatObjectStore::cacheManager_ is null"); return ERR_NULL_PTR; @@ -190,7 +195,8 @@ uint32_t FlatObjectStore::Save(const std::string &sessionId, const std::string & uint32_t status = storageEngine_->GetItems(sessionId, objectData); if (status != SUCCESS) { LOG_ERROR("FlatObjectStore::GetItems fail"); - RADAR_REPORT(SAVE, SAVE_TO_SERVICE, RADAR_FAILED, ERROR_CODE, status, BIZ_STATE, FINISHED); + RadarReporter::ReportStateError(std::string(__FUNCTION__), SAVE, SAVE_TO_SERVICE, + RADAR_FAILED, status, FINISHED); return status; } return cacheManager_->Save(bundleName_, sessionId, deviceId, objectData); @@ -390,9 +396,6 @@ uint32_t CacheManager::Save(const std::string &bundleName, const std::string &se LOG_INFO("CacheManager::start wait"); auto [timeout, res] = block->GetValue(); LOG_INFO("CacheManager::end wait, timeout: %{public}d, result: %{public}d", timeout, res); - if (timeout) { - RADAR_REPORT(SAVE, SAVE_TO_SERVICE, RADAR_FAILED, ERROR_CODE, TIMEOUT, BIZ_STATE, FINISHED); - } return res; } @@ -421,25 +424,26 @@ int32_t CacheManager::SaveObject(const std::string &bundleName, const std::strin sptr proxy = ClientAdaptor::GetObjectService(); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr."); - RADAR_REPORT(SAVE, SAVE_TO_SERVICE, RADAR_FAILED, ERROR_CODE, SA_DIED, BIZ_STATE, FINISHED); + RadarReporter::ReportStateError(std::string(__FUNCTION__), SAVE, SAVE_TO_SERVICE, + RADAR_FAILED, SA_DIED, FINISHED); return ERR_PROCESSING; } sptr objectSaveCallback = new (std::nothrow) ObjectSaveCallback(callback); if (objectSaveCallback == nullptr) { LOG_ERROR("CacheManager::SaveObject no memory for ObjectSaveCallback malloc!"); - RADAR_REPORT(SAVE, SAVE_TO_SERVICE, RADAR_FAILED, ERROR_CODE, NO_MEMORY, BIZ_STATE, FINISHED); + RadarReporter::ReportStateError(std::string(__FUNCTION__), SAVE, SAVE_TO_SERVICE, + RADAR_FAILED, NO_MEMORY, FINISHED); return ERR_NULL_PTR; } int32_t status = proxy->ObjectStoreSave( bundleName, sessionId, deviceId, objectData, objectSaveCallback->AsObject().GetRefPtr()); if (status != SUCCESS) { LOG_ERROR("object save failed code=%d.", static_cast(status)); - if (status == ERR_IPC) { - RADAR_REPORT(SAVE, SAVE_TO_SERVICE, RADAR_FAILED, ERROR_CODE, IPC_ERROR, BIZ_STATE, FINISHED); - } + RadarReporter::ReportStateError(std::string(__FUNCTION__), SAVE, SAVE_TO_SERVICE, + RADAR_FAILED, IPC_ERROR, FINISHED); + } else { + RadarReporter::ReportStage(std::string(__FUNCTION__), SAVE, SAVE_TO_SERVICE, RADAR_SUCCESS); } - LOG_INFO("object save successful"); - RADAR_REPORT(SAVE, SAVE_TO_SERVICE, RADAR_SUCCESS); return status; } @@ -469,24 +473,20 @@ int32_t CacheManager::RevokeSaveObject( int32_t CacheManager::ResumeObject(const std::string &bundleName, const std::string &sessionId, std::function> &data, bool allReady)> &callback) { - RADAR_REPORT(CREATE, RESTORE, IDLE); sptr proxy = ClientAdaptor::GetObjectService(); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr."); - RADAR_REPORT(CREATE, RESTORE, RADAR_FAILED, ERROR_CODE, SA_DIED, BIZ_STATE, FINISHED); return ERR_NULL_PTR; } sptr objectRetrieveCallback = new (std::nothrow) ObjectRetrieveCallback(callback); if (objectRetrieveCallback == nullptr) { LOG_ERROR("CacheManager::ResumeObject no memory for ObjectRetrieveCallback malloc!"); - RADAR_REPORT(CREATE, RESTORE, RADAR_FAILED, ERROR_CODE, NO_MEMORY, BIZ_STATE, FINISHED); return ERR_NULL_PTR; } int32_t status = proxy->ObjectStoreRetrieve( bundleName, sessionId, objectRetrieveCallback->AsObject().GetRefPtr()); if (status != SUCCESS) { LOG_ERROR("object resume failed code=%d.", static_cast(status)); - RADAR_REPORT(CREATE, RESTORE, RADAR_FAILED, ERROR_CODE, IPC_ERROR, BIZ_STATE, FINISHED); } LOG_INFO("object resume successful"); return status; diff --git a/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp b/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp index 1b2f7aef..92f83396 100644 --- a/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp +++ b/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp @@ -245,20 +245,20 @@ std::vector SoftBusAdapter::GetRemoteNodesBasicInfo() const return dis; } -void SoftBusAdapter::UpdateRelationship(const std::string &networkid, const DeviceChangeType &type) +void SoftBusAdapter::UpdateRelationship(const std::string &networkId, const DeviceChangeType &type) { - auto uuid = DevManager::GetInstance()->GetUuidByNodeId(networkid); + auto uuid = DevManager::GetInstance()->GetUuidByNodeId(networkId); lock_guard lock(networkMutex_); switch (type) { case DeviceChangeType::DEVICE_OFFLINE: { - auto size = this->networkId2Uuid_.erase(networkid); + auto size = this->networkId2Uuid_.erase(networkId); if (size == 0) { - LOG_WARN("not found id:%{public}s.", networkid.c_str()); + LOG_WARN("not found id:%{public}s.", Anonymous::Change(networkId).c_str()); } break; } case DeviceChangeType::DEVICE_ONLINE: { - std::pair value = { networkid, uuid }; + std::pair value = { networkId, uuid }; auto res = this->networkId2Uuid_.insert(std::move(value)); if (!res.second) { LOG_WARN("insert failed."); diff --git a/data_object/frameworks/innerkitsimpl/src/object_radar_reporter.cpp b/data_object/frameworks/innerkitsimpl/src/object_radar_reporter.cpp new file mode 100644 index 00000000..5d6db624 --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/src/object_radar_reporter.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2024 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 "object_radar_reporter.h" + +namespace OHOS::ObjectStore { + using namespace ObjectStore; +void RadarReporter::ReportStateFinished(std::string func, int32_t scene, int32_t stage, int32_t stageRes, int32_t state) +{ + struct HiSysEventParam params[] = { + { .name = { "ORG_PKG" }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(ORG_PKG) }, + .arraySize = 0 }, + { .name = { "FUNC" }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(func.c_str()) }, + .arraySize = 0 }, + { .name = { "BIZ_SCENE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = scene }, + .arraySize = 0 }, + { .name = { "BIZ_STAGE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = stage }, + .arraySize = 0 }, + { .name = { "STAGE_RES" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = stageRes }, + .arraySize = 0 }, + { .name = { "BIZ_STATE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = state }, + .arraySize = 0 } + }; + OH_HiSysEvent_Write( + DOMAIN, + EVENT_NAME, + HISYSEVENT_BEHAVIOR, + params, + sizeof(params) / sizeof(params[0]) + ); +} + +void RadarReporter::ReportStage(std::string func, int32_t scene, int32_t stage, int32_t stageRes) +{ + struct HiSysEventParam params[] = { + { .name = { "ORG_PKG" }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(ORG_PKG) }, + .arraySize = 0 }, + { .name = { "FUNC" }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(func.c_str()) }, + .arraySize = 0 }, + { .name = { "BIZ_SCENE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = scene }, + .arraySize = 0 }, + { .name = { "BIZ_STAGE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = stage }, + .arraySize = 0 }, + { .name = { "STAGE_RES" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = stageRes }, + .arraySize = 0 }, + }; + OH_HiSysEvent_Write( + DOMAIN, + EVENT_NAME, + HISYSEVENT_BEHAVIOR, + params, + sizeof(params) / sizeof(params[0]) + ); +} + +void RadarReporter::ReportStateStart(std::string func, int32_t scene, int32_t stage, int32_t stageRes, + int32_t state, std::string appCaller) +{ + struct HiSysEventParam params[] = { + { .name = { "ORG_PKG" }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(ORG_PKG) }, + .arraySize = 0 }, + { .name = { "FUNC" }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(func.c_str()) }, + .arraySize = 0 }, + { .name = { "BIZ_SCENE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = scene }, + .arraySize = 0 }, + { .name = { "BIZ_STAGE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = stage }, + .arraySize = 0 }, + { .name = { "STAGE_RES" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = stageRes }, + .arraySize = 0 }, + { .name = { "BIZ_STATE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = state }, + .arraySize = 0 }, + { .name = { "APP_CALLER" }, + .t = HISYSEVENT_INT32, + .v = { .s = const_cast(appCaller.c_str()) }, + .arraySize = 0 }, + }; + OH_HiSysEvent_Write( + DOMAIN, + EVENT_NAME, + HISYSEVENT_BEHAVIOR, + params, + sizeof(params) / sizeof(params[0]) + ); +} + +void RadarReporter::ReportStateError(std::string func, int32_t scene, int32_t stage, int32_t stageRes, + int32_t errCode, int32_t state) +{ + struct HiSysEventParam params[] = { + { .name = { "ORG_PKG" }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(ORG_PKG) }, + .arraySize = 0 }, + { .name = { "FUNC" }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(func.c_str()) }, + .arraySize = 0 }, + { .name = { "BIZ_SCENE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = scene }, + .arraySize = 0 }, + { .name = { "BIZ_STAGE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = stage }, + .arraySize = 0 }, + { .name = { "STAGE_RES" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = stageRes }, + .arraySize = 0 }, + { .name = { "ERROR_CODE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = errCode }, + .arraySize = 0 }, + { .name = { "BIZ_STATE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = state }, + .arraySize = 0 }, + }; + OH_HiSysEvent_Write( + DOMAIN, + EVENT_NAME, + HISYSEVENT_BEHAVIOR, + params, + sizeof(params) / sizeof(params[0]) + ); +} + +void RadarReporter::ReportStageError(std::string func, int32_t scene, int32_t stage, + int32_t stageRes, int32_t errCode) +{ + struct HiSysEventParam params[] = { + { .name = { "ORG_PKG" }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(ORG_PKG) }, + .arraySize = 0 }, + { .name = { "FUNC" }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(func.c_str()) }, + .arraySize = 0 }, + { .name = { "BIZ_SCENE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = scene }, + .arraySize = 0 }, + { .name = { "BIZ_STAGE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = stage }, + .arraySize = 0 }, + { .name = { "STAGE_RES" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = stageRes }, + .arraySize = 0 }, + { .name = { "ERROR_CODE" }, + .t = HISYSEVENT_INT32, + .v = { .i32 = errCode }, + .arraySize = 0 }, + }; + OH_HiSysEvent_Write( + DOMAIN, + EVENT_NAME, + HISYSEVENT_BEHAVIOR, + params, + sizeof(params) / sizeof(params[0]) + ); +} +} diff --git a/data_object/frameworks/innerkitsimpl/test/fuzztest/objectstore_fuzzer/BUILD.gn b/data_object/frameworks/innerkitsimpl/test/fuzztest/objectstore_fuzzer/BUILD.gn index 8a8cd1bc..42477193 100644 --- a/data_object/frameworks/innerkitsimpl/test/fuzztest/objectstore_fuzzer/BUILD.gn +++ b/data_object/frameworks/innerkitsimpl/test/fuzztest/objectstore_fuzzer/BUILD.gn @@ -22,7 +22,6 @@ config("module_private_config") { "../../../../../frameworks/innerkitsimpl/include/adaptor", "../../../../../frameworks/innerkitsimpl/include/common", "${data_object_base_path}/frameworks/innerkitsimpl/include", - "${relational_store_path}/interfaces/inner_api/common_type/include", ] } diff --git a/data_object/frameworks/jskitsimpl/include/adaptor/js_object_wrapper.h b/data_object/frameworks/jskitsimpl/include/adaptor/js_object_wrapper.h index ffb68c40..0f8ea760 100644 --- a/data_object/frameworks/jskitsimpl/include/adaptor/js_object_wrapper.h +++ b/data_object/frameworks/jskitsimpl/include/adaptor/js_object_wrapper.h @@ -30,9 +30,9 @@ public: DistributedObject *GetObject(); bool AddWatch(napi_env env, const char *type, napi_value handler); void DeleteWatch(napi_env env, const char *type, napi_value handler = nullptr); - bool isUndefined(char *value); - void AddUndefined(char *value); - void DeleteUndefined(char *value); + bool IsUndefined(const char *value); + void AddUndefined(const char *value); + void DeleteUndefined(const char *value); void DestroyObject(); void SetObjectId(const std::string &objectId); std::string GetObjectId(); diff --git a/data_object/frameworks/jskitsimpl/include/common/uv_queue.h b/data_object/frameworks/jskitsimpl/include/common/uv_queue.h index 3c90ddb5..d7fe19a6 100644 --- a/data_object/frameworks/jskitsimpl/include/common/uv_queue.h +++ b/data_object/frameworks/jskitsimpl/include/common/uv_queue.h @@ -17,8 +17,8 @@ #include #include #include -#include #include +#include #include "napi/native_api.h" #include "napi/native_node_api.h" #include "uv.h" diff --git a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobject.cpp b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobject.cpp index a603ac31..c932c2fc 100644 --- a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobject.cpp +++ b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobject.cpp @@ -58,7 +58,7 @@ napi_value JSDistributedObject::JSGet(napi_env env, napi_callback_info info) status = napi_unwrap(env, thisVar, (void **)&wrapper); NOT_MATCH_RETURN_NULL(status == napi_ok && wrapper != nullptr && wrapper->GetObject() != nullptr); napi_value result = nullptr; - if (wrapper->isUndefined(key)) { + if (wrapper->IsUndefined(key)) { napi_get_undefined(env, &result); return result; } diff --git a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp index 6af72368..f18d2787 100644 --- a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp +++ b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp @@ -20,6 +20,7 @@ #include "ability_context.h" #include "accesstoken_kit.h" +#include "anonymous.h" #include "application_context.h" #include "distributed_objectstore.h" #include "js_ability.h" diff --git a/data_object/frameworks/jskitsimpl/src/adaptor/js_object_wrapper.cpp b/data_object/frameworks/jskitsimpl/src/adaptor/js_object_wrapper.cpp index aa2be5ba..5f3436b6 100644 --- a/data_object/frameworks/jskitsimpl/src/adaptor/js_object_wrapper.cpp +++ b/data_object/frameworks/jskitsimpl/src/adaptor/js_object_wrapper.cpp @@ -65,7 +65,7 @@ void JSObjectWrapper::DeleteWatch(napi_env env, const char *type, napi_value han } } -bool JSObjectWrapper::isUndefined(char *value) +bool JSObjectWrapper::IsUndefined(const char *value) { std::string tmpStr = value; auto it = std::find(undefinedProperties.begin(), undefinedProperties.end(), tmpStr); @@ -75,7 +75,7 @@ bool JSObjectWrapper::isUndefined(char *value) return true; } -void JSObjectWrapper::AddUndefined(char *value) +void JSObjectWrapper::AddUndefined(const char *value) { std::string tmpStr = value; if (std::find(undefinedProperties.begin(), undefinedProperties.end(), tmpStr) == undefinedProperties.end()) { @@ -83,7 +83,7 @@ void JSObjectWrapper::AddUndefined(char *value) } } -void JSObjectWrapper::DeleteUndefined(char *value) +void JSObjectWrapper::DeleteUndefined(const char *value) { std::string tmpStr = value; auto it = std::find(undefinedProperties.begin(), undefinedProperties.end(), tmpStr); diff --git a/data_object/interfaces/innerkits/BUILD.gn b/data_object/interfaces/innerkits/BUILD.gn index f5b8ab1b..5c76f81e 100644 --- a/data_object/interfaces/innerkits/BUILD.gn +++ b/data_object/interfaces/innerkits/BUILD.gn @@ -23,7 +23,6 @@ config("objectstore_config") { "../../frameworks/innerkitsimpl/include/communicator", "../../frameworks/innerkitsimpl/include", "../../interfaces/innerkits", - "${relational_store_path}/interfaces/inner_api/common_type/include", ] ldflags = [ "-Wl,--exclude-libs,ALL" ] @@ -53,11 +52,13 @@ object_source_config = [ "../../frameworks/innerkitsimpl/src/communicator/process_communicator_impl.cpp", "../../frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp", "../../frameworks/innerkitsimpl/src/object_callback_stub.cpp", + "../../frameworks/innerkitsimpl/src/object_radar_reporter.cpp", "../../frameworks/innerkitsimpl/src/object_service_proxy.cpp", "../../frameworks/innerkitsimpl/src/object_types_util.cpp", ] object_deps_config = [] object_external_deps_config = [ + "access_token:libaccesstoken_sdk", "bounds_checking_function:libsec_shared", "c_utils:utils", "device_manager:devicemanagersdk", diff --git a/data_object/interfaces/jskits/BUILD.gn b/data_object/interfaces/jskits/BUILD.gn index 64fdcd18..7b4c7aaf 100644 --- a/data_object/interfaces/jskits/BUILD.gn +++ b/data_object/interfaces/jskits/BUILD.gn @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//arkcompiler/ets_frontend/es2panda/es2abc_config.gni") +import("//build/config/components/ets_frontend/es2abc_config.gni") import("//build/ohos.gni") import("//build/ohos/ace/ace.gni") import("//foundation/distributeddatamgr/data_object/data_object.gni") @@ -42,7 +42,6 @@ config("objectstore_config") { "../../frameworks/innerkitsimpl/include", "../../frameworks/innerkitsimpl/include/communicator", "../../interfaces/innerkits", - "${relational_store_path}/interfaces/inner_api/common_type/include", ] } diff --git a/data_object/interfaces/jskits/distributed_data_object.js b/data_object/interfaces/jskits/distributed_data_object.js index a7656331..28822654 100644 --- a/data_object/interfaces/jskits/distributed_data_object.js +++ b/data_object/interfaces/jskits/distributed_data_object.js @@ -25,6 +25,8 @@ const ASSET_KEY_SEPARATOR = '.'; const JS_ERROR = 1; const SDK_VERSION_8 = 8; const SDK_VERSION_9 = 9; +const SESSION_ID_REGEX = /^\w+$/; +const SESSION_ID_MAX_LENGTH = 128; class Distributed { constructor(obj) { @@ -147,22 +149,18 @@ function getObjectValue(object, key) { } function setObjectValue(object, key, newValue) { - console.info('start set ' + key + ' ' + newValue); + console.info('start set ' + key); if (typeof newValue === 'object') { let value = COMPLEX_TYPE + JSON.stringify(newValue); object.put(key, value); - console.info('set ' + key + ' ' + value); } else if (typeof newValue === 'string') { let value = STRING_TYPE + newValue; object.put(key, value); - console.info('set ' + key + ' ' + value); } else if (newValue == null) { let value = NULL_TYPE; object.put(key, value); - console.info('set ' + key + ' ' + value); } else { object.put(key, newValue); - console.info('set ' + key + ' ' + newValue); } } @@ -179,8 +177,7 @@ function isAsset(obj) { return false; } for (const key of ASSET_KEYS.slice(1)) { - if (!Object.prototype.hasOwnProperty.call(obj, key) || - (typeof obj[key] !== 'string' && typeof obj[key] !== 'undefined')) { + if (!Object.prototype.hasOwnProperty.call(obj, key) || typeof obj[key] !== 'string') { return false; } } @@ -200,7 +197,7 @@ function defineAsset(object, key, data) { }); let asset = object[key]; Object.keys(data).forEach(subKey => { - if (data[subKey] !== undefined) { + if (data[subKey] !== '') { asset[subKey] = data[subKey]; } }); @@ -230,7 +227,7 @@ function setAssetValue(object, key, newValue) { message: 'cannot set ' + key + ' by non Asset type data' }; } - Object.values(newValue).forEach(subKey => { + Object.keys(newValue).forEach(subKey => { setObjectValue(object, key + ASSET_KEY_SEPARATOR + subKey, newValue[subKey]); }); } @@ -375,6 +372,12 @@ class DistributedV9 { } } leaveSession(this.__sdkVersion, this.__proxy); + if (sessionId.length > SESSION_ID_MAX_LENGTH || !SESSION_ID_REGEX.test(sessionId)) { + throw { + code: 401, + message: 'The sessionId allows only letters, digits, and underscores(_), and cannot exceed 128 in length.' + }; + } let object = joinSession(this.__sdkVersion, this.__proxy, this.__objectId, sessionId, this.__context); if (object != null) { this.__proxy = object; diff --git a/data_share/OAT.xml b/data_share/OAT.xml index 0e4aff54..0330ab10 100644 --- a/data_share/OAT.xml +++ b/data_share/OAT.xml @@ -52,15 +52,7 @@ - - - + diff --git a/data_share/frameworks/js/napi/common/include/datashare_predicates_proxy.h b/data_share/frameworks/js/napi/common/include/datashare_predicates_proxy.h index db22b37d..be455506 100644 --- a/data_share/frameworks/js/napi/common/include/datashare_predicates_proxy.h +++ b/data_share/frameworks/js/napi/common/include/datashare_predicates_proxy.h @@ -72,6 +72,7 @@ private: static napi_value NotIn(napi_env env, napi_callback_info info); static napi_value PrefixKey(napi_env env, napi_callback_info info); static napi_value InKeys(napi_env env, napi_callback_info info); + static napi_value CreateConstructor(napi_env env); }; } // namespace DataShare } // namespace OHOS diff --git a/data_share/frameworks/js/napi/common/src/datashare_predicates_proxy.cpp b/data_share/frameworks/js/napi/common/src/datashare_predicates_proxy.cpp index ef9ccf25..1a68e8c5 100644 --- a/data_share/frameworks/js/napi/common/src/datashare_predicates_proxy.cpp +++ b/data_share/frameworks/js/napi/common/src/datashare_predicates_proxy.cpp @@ -15,6 +15,9 @@ #include "datashare_predicates_proxy.h" +#include +#include + #include "datashare_log.h" #include "datashare_js_utils.h" #include "datashare_predicates.h" @@ -30,6 +33,12 @@ napi_value DataSharePredicatesProxy::GetConstructor(napi_env env) NAPI_CALL(env, napi_get_reference_value(env, constructor_, &cons)); return cons; } + return CreateConstructor(env); +} + +napi_value DataSharePredicatesProxy::CreateConstructor(napi_env env) +{ + napi_value cons; napi_property_descriptor descriptors[] = { DECLARE_NAPI_FUNCTION("equalTo", EqualTo), DECLARE_NAPI_FUNCTION("notEqualTo", NotEqualTo), @@ -62,9 +71,17 @@ napi_value DataSharePredicatesProxy::GetConstructor(napi_env env) DECLARE_NAPI_FUNCTION("prefixKey", PrefixKey), DECLARE_NAPI_FUNCTION("inKeys", InKeys), }; + int64_t start = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); NAPI_CALL(env, napi_define_class(env, "DataSharePredicates", NAPI_AUTO_LENGTH, New, nullptr, sizeof(descriptors) / sizeof(napi_property_descriptor), descriptors, &cons)); + int64_t middle = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); NAPI_CALL(env, napi_create_reference(env, cons, 1, &constructor_)); + int64_t finish = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + LOG_INFO("Init predicates create reference, cost time: %{public}" PRIi64 + "ms , cost time:%{public}" PRIi64 "ms", middle - start, finish - middle); return cons; } @@ -74,7 +91,12 @@ void DataSharePredicatesProxy::Init(napi_env env, napi_value exports) // cause use-after-free. constructor_ = nullptr; napi_value cons = GetConstructor(env); + int64_t start = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, exports, "DataSharePredicates", cons)); + int64_t end = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + LOG_INFO("Init predicates set named property, cost time:%{public}" PRIi64 "ms", end - start); } napi_value DataSharePredicatesProxy::New(napi_env env, napi_callback_info info) diff --git a/data_share/frameworks/js/napi/dataShare/src/async_call.cpp b/data_share/frameworks/js/napi/dataShare/src/async_call.cpp index a7e43680..b4e1bf9b 100644 --- a/data_share/frameworks/js/napi/dataShare/src/async_call.cpp +++ b/data_share/frameworks/js/napi/dataShare/src/async_call.cpp @@ -19,8 +19,8 @@ #include "napi_common_data.h" namespace OHOS::DataShare { -AsyncCall::AsyncCall(napi_env env, napi_callback_info info, std::shared_ptr context) - : env_(env) +__attribute__((no_sanitize("undefined"))) AsyncCall::AsyncCall(napi_env env, napi_callback_info info, + std::shared_ptr context) : env_(env) { context_ = new AsyncContext(); size_t argc = ARGS_MAX_COUNT; diff --git a/data_share/frameworks/js/napi/dataShare/src/napi_datashare_helper.cpp b/data_share/frameworks/js/napi/dataShare/src/napi_datashare_helper.cpp index 11cf632c..9e6c5357 100644 --- a/data_share/frameworks/js/napi/dataShare/src/napi_datashare_helper.cpp +++ b/data_share/frameworks/js/napi/dataShare/src/napi_datashare_helper.cpp @@ -16,6 +16,7 @@ #include "napi_datashare_helper.h" #include "data_proxy_observer_stub.h" +#include "datashare_errno.h" #include "datashare_helper.h" #include "datashare_log.h" #include "datashare_predicates_proxy.h" @@ -31,6 +32,7 @@ using namespace OHOS::AppExecFwk; namespace OHOS { namespace DataShare { static constexpr int MAX_ARGC = 6; +static __thread napi_ref constructor_ = nullptr; static bool GetSilentUri(napi_env env, napi_value jsValue, std::string &uri) { napi_valuetype valuetype = napi_undefined; @@ -141,6 +143,10 @@ napi_value NapiDataShareHelper::Napi_CreateDataShareHelper(napi_env env, napi_ca napi_value NapiDataShareHelper::GetConstructor(napi_env env) { napi_value cons = nullptr; + if (constructor_ != nullptr) { + napi_get_reference_value(env, constructor_, &cons); + return cons; + } napi_property_descriptor clzDes[] = { DECLARE_NAPI_FUNCTION("on", Napi_On), DECLARE_NAPI_FUNCTION("off", Napi_Off), @@ -161,6 +167,7 @@ napi_value NapiDataShareHelper::GetConstructor(napi_env env) }; NAPI_CALL(env, napi_define_class(env, "DataShareHelper", NAPI_AUTO_LENGTH, Initialize, nullptr, sizeof(clzDes) / sizeof(napi_property_descriptor), clzDes, &cons)); + napi_create_reference(env, cons, 1, &constructor_); return cons; } diff --git a/data_share/frameworks/js/napi/dataShare/src/native_datashare_predicates_module.cpp b/data_share/frameworks/js/napi/dataShare/src/native_datashare_predicates_module.cpp index 27c39ed8..399ce176 100644 --- a/data_share/frameworks/js/napi/dataShare/src/native_datashare_predicates_module.cpp +++ b/data_share/frameworks/js/napi/dataShare/src/native_datashare_predicates_module.cpp @@ -13,11 +13,10 @@ * limitations under the License. */ -#include "napi/native_api.h" -#include "napi/native_node_api.h" - #include "datashare_log.h" #include "datashare_predicates_proxy.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" namespace OHOS { namespace DataShare { diff --git a/data_share/frameworks/js/napi/datashare_ext_ability/BUILD.gn b/data_share/frameworks/js/napi/datashare_ext_ability/BUILD.gn index e7e8367d..4c45fb80 100644 --- a/data_share/frameworks/js/napi/datashare_ext_ability/BUILD.gn +++ b/data_share/frameworks/js/napi/datashare_ext_ability/BUILD.gn @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//arkcompiler/ets_frontend/es2panda/es2abc_config.gni") +import("//build/config/components/ets_frontend/es2abc_config.gni") import("//build/ohos.gni") es2abc_gen_abc("gen_datashare_ext_ability_abc") { diff --git a/data_share/frameworks/js/napi/datashare_ext_ability/datashare_ext_ability.js b/data_share/frameworks/js/napi/datashare_ext_ability/datashare_ext_ability.js index c58357dc..75f507f0 100644 --- a/data_share/frameworks/js/napi/datashare_ext_ability/datashare_ext_ability.js +++ b/data_share/frameworks/js/napi/datashare_ext_ability/datashare_ext_ability.js @@ -16,6 +16,7 @@ class DataShareExtensionAbility { onCreate(want, callback) { console.log('onCreate, want:' + want.abilityName); + callback(undefined); } getFileTypes(uri, mimeTypeFilter, callback) { diff --git a/data_share/frameworks/js/napi/datashare_ext_ability_context/BUILD.gn b/data_share/frameworks/js/napi/datashare_ext_ability_context/BUILD.gn index cce58b43..31b9ac71 100644 --- a/data_share/frameworks/js/napi/datashare_ext_ability_context/BUILD.gn +++ b/data_share/frameworks/js/napi/datashare_ext_ability_context/BUILD.gn @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//arkcompiler/ets_frontend/es2panda/es2abc_config.gni") +import("//build/config/components/ets_frontend/es2abc_config.gni") import("//build/ohos.gni") es2abc_gen_abc("gen_datashare_ext_ability_context_abc") { diff --git a/data_share/frameworks/native/common/include/call_reporter.h b/data_share/frameworks/native/common/include/call_reporter.h new file mode 100644 index 00000000..52b83e91 --- /dev/null +++ b/data_share/frameworks/native/common/include/call_reporter.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 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 DATASHARE_CALL_REPORTER_H +#define DATASHARE_CALL_REPORTER_H + +#include +#include + +namespace OHOS { +namespace DataShare { +class DataShareCallReporter { +public: + DataShareCallReporter() = default; + struct CallInfo { + int count = 0; + std::chrono::system_clock::time_point firstTime; + }; + void Count(const std::string &funcName, const std::string &uri); +private: + ConcurrentMap callCounts; + static constexpr int RESET_COUNT_THRESHOLD = 100; + static constexpr std::chrono::milliseconds TIME_THRESHOLD = std::chrono::milliseconds(30000); +}; +} // namespace DataShare +} // namespace OHOS +#endif \ No newline at end of file diff --git a/data_share/frameworks/native/common/include/datashare_block_writer_impl.h b/data_share/frameworks/native/common/include/datashare_block_writer_impl.h index dbe2dea9..be0b9bc7 100644 --- a/data_share/frameworks/native/common/include/datashare_block_writer_impl.h +++ b/data_share/frameworks/native/common/include/datashare_block_writer_impl.h @@ -76,7 +76,7 @@ public: /** * Get Block */ - AppDataFwk::SharedBlock *GetBlock() const; + std::shared_ptr GetBlock(); private: /** @@ -93,7 +93,7 @@ private: } private: - AppDataFwk::SharedBlock *shareBlock_; + std::shared_ptr shareBlock_; }; } // namespace DataShare } // namespace OHOS diff --git a/data_share/frameworks/native/common/include/datashare_log.h b/data_share/frameworks/native/common/include/datashare_log.h index 9b33a6e1..24eb67c3 100644 --- a/data_share/frameworks/native/common/include/datashare_log.h +++ b/data_share/frameworks/native/common/include/datashare_log.h @@ -16,6 +16,7 @@ #ifndef DATASHARE_LOG_PRINT_H #define DATASHARE_LOG_PRINT_H +#include #include "hilog/log.h" namespace OHOS::DataShare { @@ -25,15 +26,13 @@ static inline OHOS::HiviewDFX::HiLogLabel LogLabel() } } // namespace OHOS::DataShare -#define FILENAME (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) - #define LOG_DEBUG(fmt, ...) \ do { \ auto lable = LogLabel(); \ if (HiLogIsLoggable(lable.domain, lable.tag, LogLevel::LOG_DEBUG)) { \ ((void)HILOG_IMPL(lable.type, LogLevel::LOG_DEBUG, lable.domain, lable.tag, \ "[%{public}s()-%{public}s:%{public}d]: " fmt, __FUNCTION__, \ - FILENAME, __LINE__, ##__VA_ARGS__)); \ + __FILE_NAME__, __LINE__, ##__VA_ARGS__)); \ } \ } while (0) @@ -43,7 +42,7 @@ static inline OHOS::HiviewDFX::HiLogLabel LogLabel() if (HiLogIsLoggable(lable.domain, lable.tag, LogLevel::LOG_INFO)) { \ ((void)HILOG_IMPL(lable.type, LogLevel::LOG_INFO, lable.domain, lable.tag, \ "[%{public}s()-%{public}s:%{public}d]: " fmt, __FUNCTION__, \ - FILENAME, __LINE__, ##__VA_ARGS__)); \ + __FILE_NAME__, __LINE__, ##__VA_ARGS__)); \ } \ } while (0) @@ -53,7 +52,7 @@ static inline OHOS::HiviewDFX::HiLogLabel LogLabel() if (HiLogIsLoggable(lable.domain, lable.tag, LogLevel::LOG_WARN)) { \ ((void)HILOG_IMPL(lable.type, LogLevel::LOG_WARN, lable.domain, lable.tag, \ "[%{public}s()-%{public}s:%{public}d]: " fmt, __FUNCTION__, \ - FILENAME, __LINE__, ##__VA_ARGS__)); \ + __FILE_NAME__, __LINE__, ##__VA_ARGS__)); \ } \ } while (0) @@ -63,7 +62,7 @@ static inline OHOS::HiviewDFX::HiLogLabel LogLabel() if (HiLogIsLoggable(lable.domain, lable.tag, LogLevel::LOG_ERROR)) { \ ((void)HILOG_IMPL(lable.type, LogLevel::LOG_ERROR, lable.domain, lable.tag, \ "[%{public}s()-%{public}s:%{public}d]: " fmt, __FUNCTION__, \ - FILENAME, __LINE__, ##__VA_ARGS__)); \ + __FILE_NAME__, __LINE__, ##__VA_ARGS__)); \ } \ } while (0) @@ -73,7 +72,7 @@ static inline OHOS::HiviewDFX::HiLogLabel LogLabel() if (HiLogIsLoggable(lable.domain, lable.tag, LogLevel::LOG_FATAL)) { \ ((void)HILOG_IMPL(lable.type, LogLevel::LOG_FATAL, lable.domain, lable.tag, \ "[%{public}s()-%{public}s:%{public}d]: " fmt, __FUNCTION__, \ - FILENAME, __LINE__, ##__VA_ARGS__)); \ + __FILE_NAME__, __LINE__, ##__VA_ARGS__)); \ } \ } while (0) diff --git a/data_share/frameworks/native/common/include/datashare_string_utils.h b/data_share/frameworks/native/common/include/datashare_string_utils.h index be6f7f9e..24b187e9 100644 --- a/data_share/frameworks/native/common/include/datashare_string_utils.h +++ b/data_share/frameworks/native/common/include/datashare_string_utils.h @@ -30,6 +30,8 @@ public: static std::string Change(const std::string &name); + static int32_t GetRandomNumber(const int32_t min, const int32_t max); + private: DataShareStringUtils(); ~DataShareStringUtils(); diff --git a/data_share/frameworks/native/common/include/distributeddata_data_share_ipc_interface_code.h b/data_share/frameworks/native/common/include/distributeddata_data_share_ipc_interface_code.h index b91a91f9..a2189936 100644 --- a/data_share/frameworks/native/common/include/distributeddata_data_share_ipc_interface_code.h +++ b/data_share/frameworks/native/common/include/distributeddata_data_share_ipc_interface_code.h @@ -38,6 +38,9 @@ enum class IDataShareInterfaceCode { CMD_EXECUTE_BATCH, CMD_INSERT_EXT, CMD_BATCH_UPDATE, + CMD_INSERT_EX, + CMD_UPDATE_EX, + CMD_DELETE_EX, }; enum class ISharedResultInterfaceCode { @@ -71,9 +74,6 @@ enum class ISharedResultInterfaceCode { }; enum class DataShareServiceInterfaceCode { - DATA_SHARE_SERVICE_CMD_INSERT, - DATA_SHARE_SERVICE_CMD_DELETE, - DATA_SHARE_SERVICE_CMD_UPDATE, DATA_SHARE_SERVICE_CMD_QUERY, DATA_SHARE_SERVICE_CMD_ADD_TEMPLATE, DATA_SHARE_SERVICE_CMD_DEL_TEMPLATE, @@ -93,6 +93,9 @@ enum class DataShareServiceInterfaceCode { DATA_SHARE_SERVICE_CMD_GET_SILENT_PROXY_STATUS, DATA_SHARE_SERVICE_CMD_REGISTER_OBSERVER, DATA_SHARE_SERVICE_CMD_UNREGISTER_OBSERVER, + DATA_SHARE_SERVICE_CMD_INSERTEX, + DATA_SHARE_SERVICE_CMD_DELETEEX, + DATA_SHARE_SERVICE_CMD_UPDATEEX, DATA_SHARE_SERVICE_CMD_MAX }; diff --git a/data_share/frameworks/native/common/include/idata_share_service.h b/data_share/frameworks/native/common/include/idata_share_service.h index a09d5ac9..538e1c0f 100644 --- a/data_share/frameworks/native/common/include/idata_share_service.h +++ b/data_share/frameworks/native/common/include/idata_share_service.h @@ -19,7 +19,7 @@ #include #include "iremote_broker.h" - +#include "datashare_errno.h" #include "data_proxy_observer.h" #include "datashare_business_error.h" #include "datashare_predicates.h" @@ -34,19 +34,16 @@ class IDataShareService : public IRemoteBroker { public: DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DataShare.IDataShareService"); - enum { - DATA_SHARE_ERROR = -1, - DATA_SHARE_OK = 0, - }; - - virtual int Insert(const Uri &uri, const DataShareValuesBucket &value) = 0; + virtual int Insert(const Uri &uri, const Uri &extUri, const DataShareValuesBucket &value) = 0; - virtual int Update(const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) = 0; + virtual int Update(const Uri &uri, const Uri &extUri, const DataSharePredicates &predicates, + const DataShareValuesBucket &value) = 0; - virtual int Delete(const Uri &uri, const DataSharePredicates &predicates) = 0; + virtual int Delete(const Uri &uri, const Uri &extUri, const DataSharePredicates &predicates) = 0; - virtual std::shared_ptr Query(const Uri &uri, const DataSharePredicates &predicates, - std::vector &columns, DatashareBusinessError &businessError) = 0; + virtual std::shared_ptr Query(const Uri &uri, const Uri &extUri, + const DataSharePredicates &predicates, std::vector &columns, + DatashareBusinessError &businessError) = 0; virtual int AddQueryTemplate(const std::string &uri, int64_t subscriberId, Template &tpl) = 0; @@ -91,6 +88,15 @@ public: virtual int UnRegisterObserver(const Uri &uri, const sptr &dataObserver) = 0; + + virtual std::pair InsertEx(const Uri &uri, const Uri &extUri, + const DataShareValuesBucket &value) = 0; + + virtual std::pair UpdateEx(const Uri &uri, const Uri &extUri, + const DataSharePredicates &predicates, const DataShareValuesBucket &value) = 0; + + virtual std::pair DeleteEx(const Uri &uri, const Uri &extUri, + const DataSharePredicates &predicates) = 0; }; } // namespace OHOS::DataShare #endif diff --git a/data_share/frameworks/native/common/include/idatashare.h b/data_share/frameworks/native/common/include/idatashare.h index eba15128..24ba2bc5 100644 --- a/data_share/frameworks/native/common/include/idatashare.h +++ b/data_share/frameworks/native/common/include/idatashare.h @@ -70,6 +70,13 @@ public: virtual Uri DenormalizeUri(const Uri &uri) = 0; virtual std::vector GetFileTypes(const Uri &uri, const std::string &mimeTypeFilter) = 0; + + virtual std::pair InsertEx(const Uri &uri, const DataShareValuesBucket &value) = 0; + + virtual std::pair UpdateEx( + const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) = 0; + + virtual std::pair DeleteEx(const Uri &uri, const DataSharePredicates &predicates) = 0; }; } // namespace DataShare } // namespace OHOS diff --git a/data_share/frameworks/native/common/include/ikvstore_data_service.h b/data_share/frameworks/native/common/include/ikvstore_data_service.h index b18c292e..9bd0f6b4 100644 --- a/data_share/frameworks/native/common/include/ikvstore_data_service.h +++ b/data_share/frameworks/native/common/include/ikvstore_data_service.h @@ -19,17 +19,13 @@ #include "iremote_broker.h" #include "iremote_proxy.h" +#include "datashare_errno.h" #include "distributeddata_data_share_ipc_interface_code.h" namespace OHOS { namespace DataShare { class IKvStoreDataService : public IRemoteBroker { public: - enum { - DATA_SHARE_ERROR = -1, - DATA_SHARE_OK = 0, - }; - virtual sptr GetFeatureInterface(const std::string &name) = 0; virtual uint32_t RegisterClientDeathObserver(const std::string &appId, sptr observer) = 0; diff --git a/data_share/frameworks/native/common/src/call_reporter.cpp b/data_share/frameworks/native/common/src/call_reporter.cpp new file mode 100644 index 00000000..af25b9e6 --- /dev/null +++ b/data_share/frameworks/native/common/src/call_reporter.cpp @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2024 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 "call_reporter.h" + +#include +#include "datashare_log.h" +#include "datashare_string_utils.h" + +namespace OHOS { +namespace DataShare { +void DataShareCallReporter::Count(const std::string &funcName, const std::string &uri) +{ + int overCount = 0; + int64_t firstCallTime = 0; + callCounts.Compute(funcName, [&overCount, &firstCallTime](auto &key, CallInfo &callInfo) { + auto callCount = callInfo.count; + if (callCount == 0) { + callInfo.firstTime = std::chrono::system_clock::now(); + } + if (++callCount % RESET_COUNT_THRESHOLD == 0) { + int64_t first = std::chrono::duration_cast( + callInfo.firstTime.time_since_epoch()).count(); + int64_t now = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + ++overCount; + firstCallTime = first; + if (now - first <= TIME_THRESHOLD.count()) { + ++overCount; + } + callCount = 0; + } + callInfo.count = callCount; + return true; + }); + int64_t now = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + if (overCount > 0) { + LOG_WARN("Call the threshold, func: %{public}s, first:%{public}" PRIi64 "ms, now:%{public}" PRIi64 + "ms, uri:%{public}s", funcName.c_str(), firstCallTime, now, DataShareStringUtils::Anonymous(uri).c_str()); + } + if (overCount > 1) { + LOG_WARN("Call too frequently, func: %{public}s, first:%{public}" PRIi64 "ms, now:%{public}" PRIi64 + "ms, uri:%{public}s", funcName.c_str(), firstCallTime, now, DataShareStringUtils::Anonymous(uri).c_str()); + } +} +} // namespace DataShare +} // namespace OHOS \ No newline at end of file diff --git a/data_share/frameworks/native/common/src/datashare_block_writer_impl.cpp b/data_share/frameworks/native/common/src/datashare_block_writer_impl.cpp index 0bd75dce..c76c1d3b 100644 --- a/data_share/frameworks/native/common/src/datashare_block_writer_impl.cpp +++ b/data_share/frameworks/native/common/src/datashare_block_writer_impl.cpp @@ -25,7 +25,12 @@ DataShareBlockWriterImpl::DataShareBlockWriterImpl() : shareBlock_(nullptr) DataShareBlockWriterImpl::DataShareBlockWriterImpl(const std::string &name, size_t size) : shareBlock_(nullptr) { - AppDataFwk::SharedBlock::Create(name, size, shareBlock_); + AppDataFwk::SharedBlock *shareBlock = nullptr; + AppDataFwk::SharedBlock::Create(name, size, shareBlock); + if (shareBlock == nullptr) { + return; + } + shareBlock_ = std::shared_ptr(shareBlock); } DataShareBlockWriterImpl::~DataShareBlockWriterImpl() @@ -34,75 +39,102 @@ DataShareBlockWriterImpl::~DataShareBlockWriterImpl() int DataShareBlockWriterImpl::AllocRow() { - if (shareBlock_ == nullptr) { + auto block = GetBlock(); + if (block == nullptr) { LOG_ERROR("shareBlock_ is nullptr"); return E_ERROR; } - return ConvertErrorCode(shareBlock_->AllocRow()); + return ConvertErrorCode(block->AllocRow()); } int DataShareBlockWriterImpl::Write(uint32_t column) { + auto block = GetBlock(); + if (block == nullptr) { + LOG_ERROR("shareBlock_ is nullptr"); + return E_ERROR; + } uint32_t currentRowIndex = 0; if (!GetCurrentRowIndex(currentRowIndex)) { LOG_ERROR("Write null fail"); return E_ERROR; } - return ConvertErrorCode(shareBlock_->PutNull(currentRowIndex, column)); + return ConvertErrorCode(block->PutNull(currentRowIndex, column)); } int DataShareBlockWriterImpl::Write(uint32_t column, int64_t value) { + auto block = GetBlock(); + if (block == nullptr) { + LOG_ERROR("shareBlock_ is nullptr"); + return E_ERROR; + } uint32_t currentRowIndex = 0; if (!GetCurrentRowIndex(currentRowIndex)) { LOG_ERROR("Write long fail"); return E_ERROR; } - return ConvertErrorCode(shareBlock_->PutLong(currentRowIndex, column, value)); + return ConvertErrorCode(block->PutLong(currentRowIndex, column, value)); } int DataShareBlockWriterImpl::Write(uint32_t column, double value) { + auto block = GetBlock(); + if (block == nullptr) { + LOG_ERROR("shareBlock_ is nullptr"); + return E_ERROR; + } uint32_t currentRowIndex = 0; if (!GetCurrentRowIndex(currentRowIndex)) { LOG_ERROR("Write double fail"); return E_ERROR; } - return ConvertErrorCode(shareBlock_->PutDouble(currentRowIndex, column, value)); + return ConvertErrorCode(block->PutDouble(currentRowIndex, column, value)); } int DataShareBlockWriterImpl::Write(uint32_t column, const uint8_t *value, size_t size) { + auto block = GetBlock(); + if (block == nullptr) { + LOG_ERROR("shareBlock_ is nullptr"); + return E_ERROR; + } uint32_t currentRowIndex = 0; if (!GetCurrentRowIndex(currentRowIndex)) { LOG_ERROR("Write blob fail"); return E_ERROR; } - return ConvertErrorCode(shareBlock_->PutBlob(currentRowIndex, column, value, size)); + return ConvertErrorCode(block->PutBlob(currentRowIndex, column, value, size)); } int DataShareBlockWriterImpl::Write(uint32_t column, const char *value, size_t sizeIncludingNull) { + auto block = GetBlock(); + if (block == nullptr) { + LOG_ERROR("shareBlock_ is nullptr"); + return E_ERROR; + } uint32_t currentRowIndex = 0; if (!GetCurrentRowIndex(currentRowIndex)) { LOG_ERROR("Write string fail"); return E_ERROR; } - return ConvertErrorCode(shareBlock_->PutString(currentRowIndex, column, value, sizeIncludingNull)); + return ConvertErrorCode(block->PutString(currentRowIndex, column, value, sizeIncludingNull)); } -AppDataFwk::SharedBlock *DataShareBlockWriterImpl::GetBlock() const +std::shared_ptr DataShareBlockWriterImpl::GetBlock() { return shareBlock_; } bool DataShareBlockWriterImpl::GetCurrentRowIndex(uint32_t &rowIndex) { - if (shareBlock_ == nullptr) { + auto block = GetBlock(); + if (block == nullptr) { LOG_ERROR("shareBlock_ is nullptr"); return false; } - uint32_t rowNum = shareBlock_->GetRowNum(); + uint32_t rowNum = block->GetRowNum(); if (rowNum > 0) { rowIndex = rowNum - 1; return true; diff --git a/data_share/frameworks/native/common/src/datashare_result_set.cpp b/data_share/frameworks/native/common/src/datashare_result_set.cpp index d65ecd83..19674183 100644 --- a/data_share/frameworks/native/common/src/datashare_result_set.cpp +++ b/data_share/frameworks/native/common/src/datashare_result_set.cpp @@ -16,6 +16,8 @@ #include #include +#include +#include #include "adaptor.h" #include "datashare_block_writer_impl.h" @@ -46,9 +48,6 @@ DataShareResultSet::DataShareResultSet(std::shared_ptr &bridge) return; } sharedBlock_ = blockWriter_->GetBlock(); - if (sharedBlock_ == nullptr) { - return; - } } DataShareResultSet::~DataShareResultSet() @@ -58,33 +57,37 @@ DataShareResultSet::~DataShareResultSet() int DataShareResultSet::GetAllColumnNames(std::vector &columnNames) { - if (bridge_ == nullptr) { + auto bridge = GetBridge(); + if (bridge == nullptr) { LOG_ERROR("bridge_ is null!"); return E_ERROR; } - return bridge_->GetAllColumnNames(columnNames); + return bridge->GetAllColumnNames(columnNames); } int DataShareResultSet::GetRowCount(int &count) { - if (bridge_ == nullptr) { + auto bridge = GetBridge(); + if (bridge == nullptr) { LOG_ERROR("bridge_ is null!"); return E_ERROR; } - return bridge_->GetRowCount(count); + return bridge->GetRowCount(count); } bool DataShareResultSet::OnGo(int startRowIndex, int targetRowIndex, int *cachedIndex) { - if (bridge_ == nullptr || blockWriter_ == nullptr || sharedBlock_ == nullptr) { + auto block = GetBlock(); + auto bridge = GetBridge(); + if (bridge == nullptr || blockWriter_ == nullptr || block == nullptr) { LOG_ERROR("bridge_ or blockWriter_ or sharedBlock_ is null!"); return false; } std::vector columnNames; GetAllColumnNames(columnNames); - sharedBlock_->Clear(); - sharedBlock_->SetColumnNum(columnNames.size()); - int result = bridge_->OnGo(startRowIndex, targetRowIndex, *blockWriter_); + block->Clear(); + block->SetColumnNum(columnNames.size()); + int result = bridge->OnGo(startRowIndex, targetRowIndex, *blockWriter_); if (cachedIndex != nullptr) { *cachedIndex = result; } @@ -99,20 +102,35 @@ void DataShareResultSet::FillBlock(int startRowIndex, AppDataFwk::SharedBlock *b return; } +/** + * Get current bridge + */ +std::shared_ptr DataShareResultSet::GetBridge() +{ + std::shared_lock lock(mutex_); + return bridge_; +} + /** * Get current shared block */ -AppDataFwk::SharedBlock *DataShareResultSet::GetBlock() const +std::shared_ptr DataShareResultSet::GetBlock() { + std::shared_lock lock(mutex_); return sharedBlock_; } int DataShareResultSet::GetDataType(int columnIndex, DataType &dataType) { + auto block = GetBlock(); + if (block == nullptr) { + LOG_ERROR("sharedBlock is null!"); + return E_ERROR; + } int rowCount = 0; GetRowCount(rowCount); AppDataFwk::SharedBlock::CellUnit *cellUnit = - sharedBlock_->GetCellUnit(static_cast(rowPos_) - startRowPos_, static_cast(columnIndex)); + block->GetCellUnit(static_cast(rowPos_) - startRowPos_, static_cast(columnIndex)); if (!cellUnit) { return E_ERROR; } @@ -122,8 +140,9 @@ int DataShareResultSet::GetDataType(int columnIndex, DataType &dataType) int DataShareResultSet::GoToRow(int position) { - if (sharedBlock_ == nullptr) { - LOG_ERROR("sharedBlock_ is null!"); + auto block = GetBlock(); + if (block == nullptr) { + LOG_ERROR("sharedBlock is null!"); return E_ERROR; } int rowCnt = 0; @@ -162,12 +181,17 @@ int DataShareResultSet::GoToRow(int position) int DataShareResultSet::GetBlob(int columnIndex, std::vector &value) { + auto block = GetBlock(); + if (block == nullptr) { + LOG_ERROR("sharedBlock is null!"); + return E_ERROR; + } int errorCode = CheckState(columnIndex); if (errorCode != E_OK) { return errorCode; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex); + AppDataFwk::SharedBlock::CellUnit *cellUnit = block->GetCellUnit(rowPos_ - startRowPos_, columnIndex); if (!cellUnit) { return E_ERROR; } @@ -177,7 +201,7 @@ int DataShareResultSet::GetBlob(int columnIndex, std::vector &value) if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB || type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) { size_t size; - const auto *blob = static_cast(sharedBlock_->GetCellUnitValueBlob(cellUnit, &size)); + const auto *blob = static_cast(block->GetCellUnitValueBlob(cellUnit, &size)); if (size == 0 || blob == nullptr) { LOG_WARN("blob data is empty!"); } else { @@ -199,18 +223,19 @@ int DataShareResultSet::GetBlob(int columnIndex, std::vector &value) int DataShareResultSet::GetString(int columnIndex, std::string &value) { - if (sharedBlock_ == nullptr) { + auto block = GetBlock(); + if (block == nullptr) { LOG_ERROR("sharedBlock is null!"); return E_ERROR; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex); + AppDataFwk::SharedBlock::CellUnit *cellUnit = block->GetCellUnit(rowPos_ - startRowPos_, columnIndex); if (!cellUnit) { return E_ERROR; } int type = cellUnit->type; if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) { size_t sizeIncludingNull; - value = std::string(sharedBlock_->GetCellUnitValueString(cellUnit, &sizeIncludingNull)); + value = std::string(block->GetCellUnitValueString(cellUnit, &sizeIncludingNull)); return E_OK; } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) { return E_OK; @@ -235,11 +260,12 @@ int DataShareResultSet::GetString(int columnIndex, std::string &value) int DataShareResultSet::GetInt(int columnIndex, int &value) { - if (sharedBlock_ == nullptr) { + auto block = GetBlock(); + if (block == nullptr) { LOG_ERROR("sharedBlock is null!"); return E_ERROR; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex); + AppDataFwk::SharedBlock::CellUnit *cellUnit = block->GetCellUnit(rowPos_ - startRowPos_, columnIndex); if (!cellUnit) { return E_ERROR; } @@ -249,11 +275,12 @@ int DataShareResultSet::GetInt(int columnIndex, int &value) int DataShareResultSet::GetLong(int columnIndex, int64_t &value) { - if (sharedBlock_ == nullptr) { + auto block = GetBlock(); + if (block == nullptr) { LOG_ERROR("sharedBlock is null!"); return E_ERROR; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex); + AppDataFwk::SharedBlock::CellUnit *cellUnit = block->GetCellUnit(rowPos_ - startRowPos_, columnIndex); if (!cellUnit) { return E_ERROR; } @@ -265,7 +292,7 @@ int DataShareResultSet::GetLong(int columnIndex, int64_t &value) return E_OK; } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) { size_t sizeIncludingNull; - const char *tempValue = sharedBlock_->GetCellUnitValueString(cellUnit, &sizeIncludingNull); + const char *tempValue = block->GetCellUnitValueString(cellUnit, &sizeIncludingNull); value = ((sizeIncludingNull > 1) && (tempValue != nullptr)) ? long(strtoll(tempValue, nullptr, 0)) : 0L; return E_OK; } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) { @@ -285,11 +312,16 @@ int DataShareResultSet::GetLong(int columnIndex, int64_t &value) int DataShareResultSet::GetDouble(int columnIndex, double &value) { + auto block = GetBlock(); + if (block == nullptr) { + LOG_ERROR("sharedBlock is null!"); + return E_ERROR; + } int errorCode = CheckState(columnIndex); if (errorCode != E_OK) { return errorCode; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex); + AppDataFwk::SharedBlock::CellUnit *cellUnit = block->GetCellUnit(rowPos_ - startRowPos_, columnIndex); if (!cellUnit) { return E_ERROR; } @@ -299,7 +331,7 @@ int DataShareResultSet::GetDouble(int columnIndex, double &value) return E_OK; } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) { size_t sizeIncludingNull; - const char *tempValue = sharedBlock_->GetCellUnitValueString(cellUnit, &sizeIncludingNull); + const char *tempValue = block->GetCellUnitValueString(cellUnit, &sizeIncludingNull); value = ((sizeIncludingNull > 1) && (tempValue != nullptr)) ? strtod(tempValue, nullptr) : 0.0; return E_OK; } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) { @@ -320,11 +352,16 @@ int DataShareResultSet::GetDouble(int columnIndex, double &value) int DataShareResultSet::IsColumnNull(int columnIndex, bool &isNull) { + auto block = GetBlock(); + if (block == nullptr) { + LOG_ERROR("sharedBlock is null!"); + return E_ERROR; + } int errorCode = CheckState(columnIndex); if (errorCode != E_OK) { return errorCode; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex); + AppDataFwk::SharedBlock::CellUnit *cellUnit = block->GetCellUnit(rowPos_ - startRowPos_, columnIndex); if (!cellUnit) { return E_ERROR; } @@ -340,8 +377,7 @@ int DataShareResultSet::Close() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); DataShareAbsResultSet::Close(); - ClosedBlock(); - bridge_ = nullptr; + ClosedBlockAndBridge(); return E_OK; } @@ -350,29 +386,34 @@ int DataShareResultSet::Close() */ void DataShareResultSet::SetBlock(AppDataFwk::SharedBlock *block) { - if (sharedBlock_ != block) { - ClosedBlock(); - sharedBlock_ = block; + std::unique_lock lock(mutex_); + if (sharedBlock_ != nullptr) { + if (sharedBlock_.get() != block) { + sharedBlock_ = std::shared_ptr(block); + } + } else { + if (block != nullptr) { + sharedBlock_ = std::shared_ptr(block); + } } } /** * Checks whether an {@code DataShareResultSet} object contains shared blocks */ -bool DataShareResultSet::HasBlock() const +bool DataShareResultSet::HasBlock() { - return sharedBlock_ != nullptr; + return GetBlock() != nullptr; } /** * Closes a shared block that is not empty in this {@code DataShareResultSet} object */ -void DataShareResultSet::ClosedBlock() +void DataShareResultSet::ClosedBlockAndBridge() { - if (sharedBlock_ != nullptr) { - delete sharedBlock_; - sharedBlock_ = nullptr; - } + std::unique_lock lock(mutex_); + sharedBlock_ = nullptr; + bridge_ = nullptr; } void DataShareResultSet::Finalize() @@ -385,10 +426,6 @@ void DataShareResultSet::Finalize() */ int DataShareResultSet::CheckState(int columnIndex) { - if (sharedBlock_ == nullptr) { - LOG_ERROR("sharedBlock is null!"); - return E_ERROR; - } int cnt = 0; GetColumnCount(cnt); if (columnIndex >= cnt || columnIndex < 0) { @@ -402,19 +439,24 @@ int DataShareResultSet::CheckState(int columnIndex) bool DataShareResultSet::Marshalling(MessageParcel &parcel) { - if (sharedBlock_ == nullptr) { + auto block = GetBlock(); + if (block == nullptr) { LOG_ERROR("sharedBlock is null."); return false; } - return sharedBlock_->WriteMessageParcel(parcel); + return block->WriteMessageParcel(parcel); } bool DataShareResultSet::Unmarshalling(MessageParcel &parcel) { - if (sharedBlock_ != nullptr) { + auto block = GetBlock(); + if (block != nullptr) { + LOG_ERROR("sharedBlock is not null."); return false; } - int result = AppDataFwk::SharedBlock::ReadMessageParcel(parcel, sharedBlock_); + AppDataFwk::SharedBlock *sharedBlock = nullptr; + int result = AppDataFwk::SharedBlock::ReadMessageParcel(parcel, sharedBlock); + SetBlock(sharedBlock); if (result < 0) { LOG_ERROR("create from parcel error is %{public}d.", result); } diff --git a/data_share/frameworks/native/common/src/datashare_string_utils.cpp b/data_share/frameworks/native/common/src/datashare_string_utils.cpp index 94d33047..604843ff 100644 --- a/data_share/frameworks/native/common/src/datashare_string_utils.cpp +++ b/data_share/frameworks/native/common/src/datashare_string_utils.cpp @@ -14,6 +14,8 @@ */ #include "datashare_string_utils.h" +#include +#include namespace OHOS { namespace DataShare { @@ -45,6 +47,14 @@ std::string DataShareStringUtils::Change(const std::string &name) } return DEFAULT_ANONYMOUS + name.substr(ANONYMOUS_SIZE); } + +int32_t DataShareStringUtils::GetRandomNumber(const int32_t min, const int32_t max) +{ + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(min, max); + return dis(gen); +} DataShareStringUtils::DataShareStringUtils() {} DataShareStringUtils::~DataShareStringUtils() {} } // namespace DataShare diff --git a/data_share/frameworks/native/consumer/controller/common/general_controller.h b/data_share/frameworks/native/consumer/controller/common/general_controller.h index c8f7ee85..3a1f6fd7 100644 --- a/data_share/frameworks/native/consumer/controller/common/general_controller.h +++ b/data_share/frameworks/native/consumer/controller/common/general_controller.h @@ -20,6 +20,7 @@ #include #include "datashare_business_error.h" +#include "datashare_errno.h" #include "datashare_predicates.h" #include "datashare_result_set.h" #include "datashare_values_bucket.h" @@ -49,6 +50,13 @@ public: virtual void UnregisterObserver(const Uri &uri, const sptr &dataObserver) = 0; virtual void NotifyChange(const Uri &uri) = 0; + + virtual std::pair InsertEx(const Uri &uri, const DataShareValuesBucket &value) = 0; + + virtual std::pair UpdateEx( + const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) = 0; + + virtual std::pair DeleteEx(const Uri &uri, const DataSharePredicates &predicates) = 0; }; } // namespace DataShare } // namespace OHOS diff --git a/data_share/frameworks/native/consumer/controller/provider/include/general_controller_provider_impl.h b/data_share/frameworks/native/consumer/controller/provider/include/general_controller_provider_impl.h index 1f75d74c..e6c5c931 100644 --- a/data_share/frameworks/native/consumer/controller/provider/include/general_controller_provider_impl.h +++ b/data_share/frameworks/native/consumer/controller/provider/include/general_controller_provider_impl.h @@ -46,6 +46,14 @@ public: void UnregisterObserver(const Uri &uri, const sptr &dataObserver) override; void NotifyChange(const Uri &uri) override; + + std::pair InsertEx(const Uri &uri, const DataShareValuesBucket &value) override; + + std::pair UpdateEx( + const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) override; + + std::pair DeleteEx(const Uri &uri, const DataSharePredicates &predicates) override; + private: std::shared_ptr connection_ = nullptr; sptr token_ = {}; diff --git a/data_share/frameworks/native/consumer/controller/provider/src/general_controller_provider_impl.cpp b/data_share/frameworks/native/consumer/controller/provider/src/general_controller_provider_impl.cpp index e7b1c812..6c3420f4 100644 --- a/data_share/frameworks/native/consumer/controller/provider/src/general_controller_provider_impl.cpp +++ b/data_share/frameworks/native/consumer/controller/provider/src/general_controller_provider_impl.cpp @@ -20,18 +20,17 @@ namespace OHOS { namespace DataShare { -constexpr int INVALID_VALUE = -1; int GeneralControllerProviderImpl::Insert(const Uri &uri, const DataShareValuesBucket &value) { auto connection = connection_; if (connection == nullptr) { LOG_ERROR("connection is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } auto proxy = connection->GetDataShareProxy(uri_, token_); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return proxy->Insert(uri, value); } @@ -42,12 +41,12 @@ int GeneralControllerProviderImpl::Update(const Uri &uri, const DataSharePredica auto connection = connection_; if (connection == nullptr) { LOG_ERROR("connection is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } auto proxy = connection->GetDataShareProxy(uri_, token_); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return proxy->Update(uri, predicates, value); } @@ -57,16 +56,64 @@ int GeneralControllerProviderImpl::Delete(const Uri &uri, const DataSharePredica auto connection = connection_; if (connection == nullptr) { LOG_ERROR("connection is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } auto proxy = connection->GetDataShareProxy(uri_, token_); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return proxy->Delete(uri, predicates); } +std::pair GeneralControllerProviderImpl::InsertEx(const Uri &uri, + const DataShareValuesBucket &value) +{ + auto connection = connection_; + if (connection == nullptr) { + LOG_ERROR("connection is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + auto proxy = connection->GetDataShareProxy(uri_, token_); + if (proxy == nullptr) { + LOG_ERROR("proxy is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + return proxy->InsertEx(uri, value); +} + +std::pair GeneralControllerProviderImpl::UpdateEx( + const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) +{ + auto connection = connection_; + if (connection == nullptr) { + LOG_ERROR("connection is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + auto proxy = connection->GetDataShareProxy(uri_, token_); + if (proxy == nullptr) { + LOG_ERROR("proxy is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + return proxy->UpdateEx(uri, predicates, value); +} + +std::pair GeneralControllerProviderImpl::DeleteEx(const Uri &uri, + const DataSharePredicates &predicates) +{ + auto connection = connection_; + if (connection == nullptr) { + LOG_ERROR("connection is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + auto proxy = connection->GetDataShareProxy(uri_, token_); + if (proxy == nullptr) { + LOG_ERROR("proxy is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + return proxy->DeleteEx(uri, predicates); +} + std::shared_ptr GeneralControllerProviderImpl::Query(const Uri &uri, const DataSharePredicates &predicates, std::vector &columns, DatashareBusinessError &businessError) { diff --git a/data_share/frameworks/native/consumer/controller/service/include/general_controller_service_impl.h b/data_share/frameworks/native/consumer/controller/service/include/general_controller_service_impl.h index 6d3ac969..a6d26e32 100644 --- a/data_share/frameworks/native/consumer/controller/service/include/general_controller_service_impl.h +++ b/data_share/frameworks/native/consumer/controller/service/include/general_controller_service_impl.h @@ -31,7 +31,7 @@ class IDataAbilityObserver; namespace DataShare { class GeneralControllerServiceImpl : public GeneralController { public: - GeneralControllerServiceImpl() = default; + GeneralControllerServiceImpl(const std::string &ext); virtual ~GeneralControllerServiceImpl(); @@ -49,12 +49,28 @@ public: void UnregisterObserver(const Uri &uri, const sptr &dataObserver) override; void NotifyChange(const Uri &uri) override; + + std::pair InsertEx(const Uri &uri, const DataShareValuesBucket &value) override; + + std::pair UpdateEx( + const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) override; + + std::pair DeleteEx(const Uri &uri, const DataSharePredicates &predicates) override; + private: void ReRegisterObserver(); void SetRegisterCallback(); ConcurrentMap, std::list> observers_; + + std::string extUri_; + + static constexpr int MAX_RETRY_COUNT = 3; + + static constexpr int RANDOM_MIN = 50; + + static constexpr int RANDOM_MAX = 150; }; } // namespace DataShare } // namespace OHOS diff --git a/data_share/frameworks/native/consumer/controller/service/src/general_controller_service_impl.cpp b/data_share/frameworks/native/consumer/controller/service/src/general_controller_service_impl.cpp index 4605e959..fa26bc1a 100644 --- a/data_share/frameworks/native/consumer/controller/service/src/general_controller_service_impl.cpp +++ b/data_share/frameworks/native/consumer/controller/service/src/general_controller_service_impl.cpp @@ -14,6 +14,7 @@ */ #include "general_controller_service_impl.h" +#include #include "dataobs_mgr_client.h" #include "dataobs_mgr_errors.h" @@ -22,7 +23,11 @@ namespace OHOS { namespace DataShare { -constexpr int INVALID_VALUE = -1; +GeneralControllerServiceImpl::GeneralControllerServiceImpl(const std::string &ext) +{ + extUri_ = ext; +} + GeneralControllerServiceImpl::~GeneralControllerServiceImpl() { auto manager = DataShareManagerImpl::GetInstance(); @@ -31,49 +36,137 @@ GeneralControllerServiceImpl::~GeneralControllerServiceImpl() int GeneralControllerServiceImpl::Insert(const Uri &uri, const DataShareValuesBucket &value) { + auto manager = DataShareManagerImpl::GetInstance(); + if (manager == nullptr) { + LOG_ERROR("Manager is nullptr"); + return DATA_SHARE_ERROR; + } + manager->SetCallCount(__FUNCTION__, uri.ToString()); auto proxy = DataShareManagerImpl::GetServiceProxy(); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } - return proxy->Insert(uri, value); + return proxy->Insert(uri, Uri(extUri_), value); } int GeneralControllerServiceImpl::Update(const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) { + auto manager = DataShareManagerImpl::GetInstance(); + if (manager == nullptr) { + LOG_ERROR("Manager is nullptr"); + return DATA_SHARE_ERROR; + } + manager->SetCallCount(__FUNCTION__, uri.ToString()); auto proxy = DataShareManagerImpl::GetServiceProxy(); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } - return proxy->Update(uri, predicates, value); + return proxy->Update(uri, Uri(extUri_), predicates, value); } int GeneralControllerServiceImpl::Delete(const Uri &uri, const DataSharePredicates &predicates) { + auto manager = DataShareManagerImpl::GetInstance(); + if (manager == nullptr) { + LOG_ERROR("Manager is nullptr"); + return DATA_SHARE_ERROR; + } + manager->SetCallCount(__FUNCTION__, uri.ToString()); + auto proxy = DataShareManagerImpl::GetServiceProxy(); + if (proxy == nullptr) { + LOG_ERROR("proxy is nullptr"); + return DATA_SHARE_ERROR; + } + return proxy->Delete(uri, Uri(extUri_), predicates); +} + +std::pair GeneralControllerServiceImpl::InsertEx(const Uri &uri, const DataShareValuesBucket &value) +{ + auto manager = DataShareManagerImpl::GetInstance(); + if (manager == nullptr) { + LOG_ERROR("Manager is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + manager->SetCallCount(__FUNCTION__, uri.ToString()); auto proxy = DataShareManagerImpl::GetServiceProxy(); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr"); - return INVALID_VALUE; + return std::make_pair(DATA_SHARE_ERROR, 0); } - return proxy->Delete(uri, predicates); + return proxy->InsertEx(uri, Uri(extUri_), value); +} + +std::pair GeneralControllerServiceImpl::UpdateEx( + const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) +{ + auto manager = DataShareManagerImpl::GetInstance(); + if (manager == nullptr) { + LOG_ERROR("Manager is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + manager->SetCallCount(__FUNCTION__, uri.ToString()); + auto proxy = DataShareManagerImpl::GetServiceProxy(); + if (proxy == nullptr) { + LOG_ERROR("proxy is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + return proxy->UpdateEx(uri, Uri(extUri_), predicates, value); +} + +std::pair GeneralControllerServiceImpl::DeleteEx(const Uri &uri, + const DataSharePredicates &predicates) +{ + auto manager = DataShareManagerImpl::GetInstance(); + if (manager == nullptr) { + LOG_ERROR("Manager is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + manager->SetCallCount(__FUNCTION__, uri.ToString()); + auto proxy = DataShareManagerImpl::GetServiceProxy(); + if (proxy == nullptr) { + LOG_ERROR("proxy is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + return proxy->DeleteEx(uri, Uri(extUri_), predicates); } std::shared_ptr GeneralControllerServiceImpl::Query(const Uri &uri, const DataSharePredicates &predicates, std::vector &columns, DatashareBusinessError &businessError) { + auto manager = DataShareManagerImpl::GetInstance(); + if (manager == nullptr) { + LOG_ERROR("Manager is nullptr"); + return nullptr; + } + manager->SetCallCount(__FUNCTION__, uri.ToString()); auto proxy = DataShareManagerImpl::GetServiceProxy(); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr"); return nullptr; } - return proxy->Query(uri, predicates, columns, businessError); + auto resultSet = proxy->Query(uri, Uri(extUri_), predicates, columns, businessError); + int retryCount = 0; + while (resultSet == nullptr && businessError.GetCode() == E_RESULTSET_BUSY && retryCount++ < MAX_RETRY_COUNT) { + LOG_ERROR("resultSet busy retry, uri: %{public}s", DataShareStringUtils::Anonymous(uri.ToString()).c_str()); + std::this_thread::sleep_for(std::chrono::milliseconds( + DataShareStringUtils::GetRandomNumber(RANDOM_MIN, RANDOM_MAX))); + resultSet = proxy->Query(uri, Uri(extUri_), predicates, columns, businessError); + } + return resultSet; } void GeneralControllerServiceImpl::RegisterObserver(const Uri &uri, const sptr &dataObserver) { + auto manager = DataShareManagerImpl::GetInstance(); + if (manager == nullptr) { + LOG_ERROR("Manager is nullptr"); + return; + } + manager->SetCallCount(__FUNCTION__, uri.ToString()); auto obsMgrClient = OHOS::AAFwk::DataObsMgrClient::GetInstance(); if (obsMgrClient == nullptr) { LOG_ERROR("get DataObsMgrClient failed"); diff --git a/data_share/frameworks/native/consumer/include/datashare_connection.h b/data_share/frameworks/native/consumer/include/datashare_connection.h index 7326345c..6e1fa996 100644 --- a/data_share/frameworks/native/consumer/include/datashare_connection.h +++ b/data_share/frameworks/native/consumer/include/datashare_connection.h @@ -23,14 +23,17 @@ #include "ability_connect_callback_stub.h" #include "datashare_proxy.h" #include "event_handler.h" +#include "executor_pool.h" #include "want.h" namespace OHOS { namespace DataShare { using namespace AppExecFwk; -class DataShareConnection : public AAFwk::AbilityConnectionStub { +class DataShareConnection : public AAFwk::AbilityConnectionStub, + public std::enable_shared_from_this { public: - DataShareConnection(const Uri &uri, const sptr &token) : uri_(uri), token_(token) {} + DataShareConnection(const Uri &uri, const sptr &token, int32_t waitTime = 2) : uri_(uri), + token_(token), waitTime_(waitTime) {} virtual ~DataShareConnection(); /** @@ -71,18 +74,34 @@ public: void SetConnectInvalid(); private: + struct DataShareConnectionInfo { + int count = 0; + int64_t firstTime = 0; + int64_t prevTime = 0; + }; struct ConnectCondition { std::condition_variable condition; std::mutex mutex; }; std::shared_ptr ConnectDataShareExtAbility(const Uri &uri, const sptr &token); + std::shared_ptr GetDataShareProxy(); ErrCode Disconnect(); + void ReconnectExtAbility(const std::string &uri); + void DelayConnectExtAbility(const std::string &uri); std::mutex mutex_{}; std::shared_ptr dataShareProxy_; ConnectCondition condition_; Uri uri_; sptr token_ = {}; std::atomic isInvalid_ = false; + static constexpr int MAX_THREADS = 2; + static constexpr int MIN_THREADS = 0; + static constexpr int MAX_RECONNECT = 6; + static constexpr std::chrono::milliseconds RECONNECT_TIME_INTERVAL = std::chrono::milliseconds(10000); + static constexpr std::chrono::milliseconds MAX_RECONNECT_TIME_INTERVAL = std::chrono::milliseconds(70000); + std::shared_ptr pool_; + DataShareConnectionInfo reConnects_; + int32_t waitTime_ = 0; }; } // namespace DataShare } // namespace OHOS diff --git a/data_share/frameworks/native/consumer/include/datashare_helper_impl.h b/data_share/frameworks/native/consumer/include/datashare_helper_impl.h index 6bd3aac2..d71e4c1c 100644 --- a/data_share/frameworks/native/consumer/include/datashare_helper_impl.h +++ b/data_share/frameworks/native/consumer/include/datashare_helper_impl.h @@ -27,7 +27,7 @@ class DataShareHelperImpl : public DataShareHelper { public: DataShareHelperImpl(const Uri &uri, const sptr &token, std::shared_ptr connection); - DataShareHelperImpl(); + DataShareHelperImpl(std::string extUri = ""); ~DataShareHelperImpl() override; @@ -98,6 +98,13 @@ public: std::vector DisablePubSubs(const std::vector &uris, int64_t subscriberId) override; + std::pair InsertEx(Uri &uri, const DataShareValuesBucket &value) override; + + std::pair UpdateEx( + Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) override; + + std::pair DeleteEx(Uri &uri, const DataSharePredicates &predicates) override; + private: std::shared_ptr extSpCtl_ = nullptr; std::shared_ptr generalCtl_ = nullptr; diff --git a/data_share/frameworks/native/consumer/include/datashare_proxy.h b/data_share/frameworks/native/consumer/include/datashare_proxy.h index ee79de3b..7c5fad2a 100644 --- a/data_share/frameworks/native/consumer/include/datashare_proxy.h +++ b/data_share/frameworks/native/consumer/include/datashare_proxy.h @@ -65,6 +65,13 @@ public: virtual Uri DenormalizeUri(const Uri &uri) override; + virtual std::pair InsertEx(const Uri &uri, const DataShareValuesBucket &value) override; + + virtual std::pair UpdateEx(const Uri &uri, const DataSharePredicates &predicates, + const DataShareValuesBucket &value) override; + + virtual std::pair DeleteEx(const Uri &uri, const DataSharePredicates &predicates) override; + private: bool CheckSize(const UpdateOperations &operations); static inline BrokerDelegator delegator_; diff --git a/data_share/frameworks/native/consumer/src/datashare_connection.cpp b/data_share/frameworks/native/consumer/src/datashare_connection.cpp index 55d8efba..84f29533 100644 --- a/data_share/frameworks/native/consumer/src/datashare_connection.cpp +++ b/data_share/frameworks/native/consumer/src/datashare_connection.cpp @@ -25,7 +25,6 @@ namespace OHOS { namespace DataShare { using namespace AppExecFwk; -constexpr int WAIT_TIME = 2; /** * @brief This method is called back to receive the connection result after an ability calls the * ConnectAbility method to connect it to an extension ability. @@ -83,14 +82,78 @@ void DataShareConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName if (uri.empty()) { return; } - AmsMgrProxy* instance = AmsMgrProxy::GetInstance(); - if (instance == nullptr) { - LOG_ERROR("get proxy failed uri:%{public}s", DataShareStringUtils::Change(uri_.ToString()).c_str()); + if (pool_ == nullptr) { + std::lock_guard lock(mutex_); + if (pool_ == nullptr) { + pool_ = std::make_shared(MAX_THREADS, MIN_THREADS); + } + } + ReconnectExtAbility(uri); +} + +void DataShareConnection::ReconnectExtAbility(const std::string &uri) +{ + if (reConnects_.count == 0) { + AmsMgrProxy* instance = AmsMgrProxy::GetInstance(); + if (instance == nullptr) { + LOG_ERROR("get proxy failed uri:%{public}s", DataShareStringUtils::Change(uri_.ToString()).c_str()); + return; + } + ErrCode ret = instance->Connect(uri, this, token_); + LOG_INFO("reconnect ability, uri:%{public}s, ret = %{public}d", + DataShareStringUtils::Change(uri).c_str(), ret); + if (ret == E_OK) { + auto curr = std::chrono::system_clock::now().time_since_epoch(); + reConnects_.count = 1; + reConnects_.firstTime = std::chrono::duration_cast(curr).count(); + reConnects_.prevTime = std::chrono::duration_cast(curr).count(); + } + return; + } + return DelayConnectExtAbility(uri); +} + +void DataShareConnection::DelayConnectExtAbility(const std::string &uri) +{ + int64_t now = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + if (now - reConnects_.prevTime >= MAX_RECONNECT_TIME_INTERVAL.count()) { + reConnects_.count = 0; + reConnects_.firstTime = now; + reConnects_.prevTime = now; + } + if (reConnects_.count >= MAX_RECONNECT) { return; } - ErrCode ret = instance->Connect(uri, this, token_); - LOG_INFO("reconnect ability, uri:%{public}s, ret = %{public}d", - DataShareStringUtils::Change(uri_.ToString()).c_str(), ret); + auto delay = RECONNECT_TIME_INTERVAL; + if (now - reConnects_.prevTime >= RECONNECT_TIME_INTERVAL.count()) { + delay = std::chrono::seconds(0); + } + std::weak_ptr self = weak_from_this(); + auto taskid = pool_->Schedule(delay, [uri, self]() { + auto selfSharedPtr = self.lock(); + if (selfSharedPtr) { + AmsMgrProxy* instance = AmsMgrProxy::GetInstance(); + if (instance == nullptr) { + LOG_ERROR("get proxy failed uri:%{public}s", DataShareStringUtils::Change(uri).c_str()); + return; + } + ErrCode ret = instance->Connect(uri, selfSharedPtr.get(), selfSharedPtr->token_); + LOG_INFO("reconnect ability, uri:%{public}s, ret = %{public}d", + DataShareStringUtils::Change(uri).c_str(), ret); + if (ret == E_OK) { + selfSharedPtr->reConnects_.count++; + selfSharedPtr->reConnects_.prevTime = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + } + } + }); + if (taskid == ExecutorPool::INVALID_TASK_ID) { + LOG_ERROR("create scheduler failed, over the max capacity"); + return; + } + LOG_DEBUG("create scheduler success"); + return; } /** @@ -119,22 +182,22 @@ std::shared_ptr DataShareConnection::ConnectDataShareExtAbility( return nullptr; } std::unique_lock condLock(condition_.mutex); - if (condition_.condition.wait_for(condLock, std::chrono::seconds(WAIT_TIME), + if (condition_.condition.wait_for(condLock, std::chrono::seconds(waitTime_), [this] { return dataShareProxy_ != nullptr; })) { LOG_DEBUG("connect ability ended successfully uri:%{public}s", DataShareStringUtils::Change(reqUri).c_str()); RADAR_REPORT(__FUNCTION__, RadarReporter::CREATE_DATASHARE_HELPER, RadarReporter::CONNECT_EXT, RadarReporter::SUCCESS, RadarReporter::LOCAL_SESS_NAME, Str16ToStr8(token->GetObjectDescriptor()), - RadarReporter::PEER_SESS_NAME, reqUri); + RadarReporter::PEER_SESS_NAME, DataShareStringUtils::Change(reqUri)); } else { LOG_WARN("connect timeout uri:%{public}s", DataShareStringUtils::Change(reqUri).c_str()); RADAR_REPORT(__FUNCTION__, RadarReporter::CREATE_DATASHARE_HELPER, RadarReporter::CONNECT_EXT, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::EXT_CONNECT_TIMEOUT_ERROR, RadarReporter::LOCAL_SESS_NAME, Str16ToStr8(token->GetObjectDescriptor()), - RadarReporter::PEER_SESS_NAME, reqUri); + RadarReporter::PEER_SESS_NAME, DataShareStringUtils::Change(reqUri)); } - return dataShareProxy_; + return GetDataShareProxy(); } /** @@ -158,14 +221,14 @@ void DataShareConnection::DisconnectDataShareExtAbility() RADAR_REPORT(__FUNCTION__, RadarReporter::CREATE_DATASHARE_HELPER, RadarReporter::DIS_CONNECT_EXT, RadarReporter::SUCCESS, RadarReporter::LOCAL_SESS_NAME, Str16ToStr8(token_->GetObjectDescriptor()), - RadarReporter::PEER_SESS_NAME, uri); + RadarReporter::PEER_SESS_NAME, DataShareStringUtils::Change(uri)); return; } RADAR_REPORT(__FUNCTION__, RadarReporter::CREATE_DATASHARE_HELPER, RadarReporter::DIS_CONNECT_EXT, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::EXT_DIS_CONNECT_ERROR, RadarReporter::LOCAL_SESS_NAME, Str16ToStr8(token_->GetObjectDescriptor()), - RadarReporter::PEER_SESS_NAME, uri); + RadarReporter::PEER_SESS_NAME, DataShareStringUtils::Change(uri)); } DataShareConnection::~DataShareConnection() @@ -191,5 +254,11 @@ ErrCode DataShareConnection::Disconnect() } return instance->DisConnect(this); } + +std::shared_ptr DataShareConnection::GetDataShareProxy() +{ + std::lock_guard lock(mutex_); + return dataShareProxy_; +} } // namespace DataShare } // namespace OHOS \ No newline at end of file diff --git a/data_share/frameworks/native/consumer/src/datashare_helper.cpp b/data_share/frameworks/native/consumer/src/datashare_helper.cpp index 1fed4972..7f11998b 100644 --- a/data_share/frameworks/native/consumer/src/datashare_helper.cpp +++ b/data_share/frameworks/native/consumer/src/datashare_helper.cpp @@ -24,7 +24,6 @@ #include "dataobs_mgr_client.h" #include "datashare_errno.h" #include "datashare_log.h" -#include "datashare_radar_reporter.h" #include "datashare_string_utils.h" namespace OHOS { @@ -34,7 +33,6 @@ namespace { static constexpr const char *DATA_SHARE_PREFIX = "datashare:///"; static constexpr const char *FILE_PREFIX = "file://"; } // namespace -constexpr int INVALID_VALUE = -1; class ObserverImpl : public AAFwk::DataAbilityObserverStub { public: explicit ObserverImpl(const std::shared_ptr dataShareObserver) @@ -77,13 +75,10 @@ std::string DataShareHelper::TransferUriPrefix(const std::string &originPrefix, * @return Returns the created DataShareHelper instance. */ std::shared_ptr DataShareHelper::Creator( - const sptr &token, const std::string &strUri, const std::string &extUri) + const sptr &token, const std::string &strUri, const std::string &extUri, const int waitTime) { DISTRIBUTED_DATA_HITRACE(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__)); - RadarReporter::RadarReport report(RadarReporter::CREATE_DATASHARE_HELPER, - RadarReporter::CREATE_HELPER, __FUNCTION__); if (token == nullptr) { - report.SetError(RadarReporter::INVALID_PARAM_ERROR); LOG_ERROR("token == nullptr"); return nullptr; } @@ -92,12 +87,11 @@ std::shared_ptr DataShareHelper::Creator( Uri uri(replacedUriStr); std::shared_ptr helper = nullptr; if (uri.GetQuery().find("Proxy=true") != std::string::npos) { - auto result = CreateServiceHelper(); + auto result = CreateServiceHelper(extUri, ""); if (result != nullptr && GetSilentProxyStatus(strUri) == E_OK) { return result; } if (extUri.empty()) { - report.SetError(RadarReporter::INVALID_PARAM_ERROR); return nullptr; } Uri ext(extUri); @@ -105,55 +99,44 @@ std::shared_ptr DataShareHelper::Creator( } else { helper = CreateExtHelper(uri, token); } - if (helper == nullptr) { - report.SetError(RadarReporter::CREATE_HELPER_ERROR); - } return helper; } std::shared_ptr DataShareHelper::Creator(const string &strUri, const CreateOptions &options, - const std::string &bundleName) + const std::string &bundleName, const int waitTime) { - RadarReporter::RadarReport report(RadarReporter::CREATE_DATASHARE_HELPER, - RadarReporter::CREATE_HELPER, __FUNCTION__); DISTRIBUTED_DATA_HITRACE(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__)); Uri uri(strUri); if (!options.isProxy_ && options.token_ == nullptr) { LOG_ERROR("token is nullptr"); - report.SetError(RadarReporter::INVALID_PARAM_ERROR); return nullptr; } - auto helper = options.isProxy_ ? CreateServiceHelper(bundleName) : CreateExtHelper(uri, options.token_); - if (helper == nullptr) { - report.SetError(RadarReporter::CREATE_HELPER_ERROR); - } - return helper; + return options.isProxy_ ? CreateServiceHelper("", bundleName) : CreateExtHelper(uri, options.token_); } std::pair> DataShareHelper::Create(const sptr &token, - const std::string &strUri, const std::string &extUri) + const std::string &strUri, const std::string &extUri, const int waitTime) { - RadarReporter::RadarReport report(RadarReporter::CREATE_DATASHARE_HELPER, - RadarReporter::CREATE_HELPER, __FUNCTION__); DISTRIBUTED_DATA_HITRACE(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__)); if (token == nullptr) { LOG_ERROR("Create helper failed, err: %{public}d", E_TOKEN_EMPTY); - report.SetError(RadarReporter::INVALID_PARAM_ERROR); return std::make_pair(E_TOKEN_EMPTY, nullptr); } Uri uri(strUri); if (IsProxy(uri)) { - auto [ret, helper] = CreateProxyHelper(strUri); + auto [ret, helper] = CreateProxyHelper(strUri, extUri); if (helper != nullptr) { return std::make_pair(E_OK, helper); } if (ret == E_BMS_NOT_READY) { - report.SetError(RadarReporter::GET_BMS_FAILED); - LOG_ERROR("BMS not ready, err: %{public}d", E_BMS_NOT_READY); + LOG_ERROR("BMS not ready, uri:%{publish}s", DataShareStringUtils::Change(strUri).c_str()); return std::make_pair(E_DATA_SHARE_NOT_READY, nullptr); } + if (ret == E_BUNDLE_NAME_NOT_EXIST) { + LOG_ERROR("BundleName not exist, uri:%{publish}s", DataShareStringUtils::Change(strUri).c_str()); + return std::make_pair(E_BUNDLE_NAME_NOT_EXIST, nullptr); + } if (extUri.empty()) { - report.SetError(RadarReporter::INVALID_PARAM_ERROR); LOG_ERROR("Ext uri empty, err: %{public}d", E_EXT_URI_INVALID); return std::make_pair(E_EXT_URI_INVALID, nullptr); } @@ -163,11 +146,11 @@ std::pair> DataShareHelper::Create(const s if (helper != nullptr) { return std::make_pair(E_OK, helper); } - report.SetError(RadarReporter::CREATE_HELPER_ERROR); return std::make_pair(E_ERROR, nullptr); } -std::shared_ptr DataShareHelper::CreateServiceHelper(const std::string &bundleName) +std::shared_ptr DataShareHelper::CreateServiceHelper(const std::string &extUri, + const std::string &bundleName) { auto manager = DataShareManagerImpl::GetInstance(); if (manager == nullptr) { @@ -179,7 +162,7 @@ std::shared_ptr DataShareHelper::CreateServiceHelper(const std: LOG_ERROR("Service proxy is nullptr."); return nullptr; } - return std::make_shared(); + return std::make_shared(extUri); } int DataShareHelper::GetSilentProxyStatus(const std::string &uri) @@ -192,9 +175,10 @@ int DataShareHelper::GetSilentProxyStatus(const std::string &uri) return proxy->GetSilentProxyStatus(uri); } -std::shared_ptr DataShareHelper::CreateExtHelper(Uri &uri, const sptr &token) +std::shared_ptr DataShareHelper::CreateExtHelper(Uri &uri, const sptr &token, + const int waitTime) { - sptr connection = new (std::nothrow) DataShareConnection(uri, token); + sptr connection = new (std::nothrow) DataShareConnection(uri, token, waitTime); if (connection == nullptr) { LOG_ERROR("Create DataShareConnection failed."); return nullptr; @@ -204,6 +188,12 @@ std::shared_ptr DataShareHelper::CreateExtHelper(Uri &uri, cons holder->SetConnectInvalid(); holder->DisconnectDataShareExtAbility(); }); + auto manager = DataShareManagerImpl::GetInstance(); + if (manager == nullptr) { + LOG_ERROR("Manager is nullptr"); + return nullptr; + } + manager->SetCallCount(__FUNCTION__, uri.ToString()); if (dataShareConnection->GetDataShareProxy(uri, token) == nullptr) { LOG_ERROR("connect failed"); return nullptr; @@ -374,7 +364,7 @@ int DataShareHelper::SetSilentSwitch(Uri &uri, bool enable) auto proxy = DataShareManagerImpl::GetServiceProxy(); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return proxy->SetSilentSwitch(uri, enable); } @@ -384,11 +374,29 @@ bool DataShareHelper::IsProxy(Uri &uri) return (uri.GetQuery().find("Proxy=true") != std::string::npos || uri.GetScheme() == "datashareproxy"); } -std::pair> DataShareHelper::CreateProxyHelper(const std::string &strUri) +std::pair> DataShareHelper::CreateProxyHelper(const std::string &strUri, + const std::string &extUri) { int ret = GetSilentProxyStatus(strUri); - auto helper = ret == E_OK ? CreateServiceHelper() : nullptr; + auto helper = ret == E_OK ? CreateServiceHelper(extUri) : nullptr; return std::make_pair(ret, helper); } + +std::pair DataShareHelper::InsertEx(Uri &uri, const DataShareValuesBucket &value) +{ + return std::make_pair(0, 0); +} + +std::pair DataShareHelper::DeleteEx(Uri &uri, const DataSharePredicates &predicates) +{ + return std::make_pair(0, 0); +} + +std::pair DataShareHelper::UpdateEx(Uri &uri, const DataSharePredicates &predicates, + const DataShareValuesBucket &value) +{ + return std::make_pair(0, 0); +} + } // namespace DataShare } // namespace OHOS \ No newline at end of file diff --git a/data_share/frameworks/native/consumer/src/datashare_helper_impl.cpp b/data_share/frameworks/native/consumer/src/datashare_helper_impl.cpp index f92398d1..bbf76e12 100644 --- a/data_share/frameworks/native/consumer/src/datashare_helper_impl.cpp +++ b/data_share/frameworks/native/consumer/src/datashare_helper_impl.cpp @@ -30,7 +30,6 @@ namespace OHOS { namespace DataShare { using namespace AppExecFwk; -constexpr int INVALID_VALUE = -1; DataShareHelperImpl::DataShareHelperImpl(const Uri &uri, const sptr &token, std::shared_ptr connection) { @@ -39,10 +38,10 @@ DataShareHelperImpl::DataShareHelperImpl(const Uri &uri, const sptr(connection, uri, token); } -DataShareHelperImpl::DataShareHelperImpl() +DataShareHelperImpl::DataShareHelperImpl(std::string extUri) { LOG_DEBUG("starts"); - generalCtl_ = std::make_shared(); + generalCtl_ = std::make_shared(extUri); persistentDataCtl_ = std::make_shared(); publishedDataCtl_ = std::make_shared(); } @@ -77,7 +76,7 @@ int DataShareHelperImpl::OpenFile(Uri &uri, const std::string &mode) auto extSpCtl = extSpCtl_; if (extSpCtl == nullptr) { LOG_ERROR("extSpCtl is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return extSpCtl->OpenFile(uri, mode); } @@ -87,7 +86,7 @@ int DataShareHelperImpl::OpenRawFile(Uri &uri, const std::string &mode) auto extSpCtl = extSpCtl_; if (extSpCtl == nullptr) { LOG_ERROR("extSpCtl is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return extSpCtl->OpenRawFile(uri, mode); } @@ -98,7 +97,7 @@ int DataShareHelperImpl::Insert(Uri &uri, const DataShareValuesBucket &value) auto generalCtl = generalCtl_; if (generalCtl == nullptr) { LOG_ERROR("generalCtl_ is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return generalCtl->Insert(uri, value); } @@ -109,7 +108,7 @@ int DataShareHelperImpl::InsertExt(Uri &uri, const DataShareValuesBucket &value, auto extSpCtl = extSpCtl_; if (extSpCtl == nullptr) { LOG_ERROR("providerSpCtl is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return extSpCtl->InsertExt(uri, value, result); } @@ -120,7 +119,7 @@ int DataShareHelperImpl::Update(Uri &uri, const DataSharePredicates &predicates, auto generalCtl = generalCtl_; if (generalCtl == nullptr) { LOG_ERROR("generalCtl is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return generalCtl->Update(uri, predicates, value); } @@ -130,7 +129,7 @@ int DataShareHelperImpl::BatchUpdate(const UpdateOperations &operations, std::ve auto extSpCtl = extSpCtl_; if (extSpCtl == nullptr) { LOG_ERROR("extSpCtl is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return extSpCtl->BatchUpdate(operations, results); } @@ -141,11 +140,57 @@ int DataShareHelperImpl::Delete(Uri &uri, const DataSharePredicates &predicates) auto generalCtl = generalCtl_; if (generalCtl == nullptr) { LOG_ERROR("generalCtl is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return generalCtl->Delete(uri, predicates); } +std::pair DataShareHelperImpl::InsertEx(Uri &uri, const DataShareValuesBucket &value) +{ + DISTRIBUTED_DATA_HITRACE(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__)); + auto generalCtl = generalCtl_; + if (generalCtl == nullptr) { + LOG_ERROR("generalCtl_ is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + auto [errCode, status] = generalCtl->InsertEx(uri, value); + if (errCode != E_OK) { + LOG_ERROR("generalCtl insert failed, errCode = %{public}d", errCode); + } + return std::make_pair(errCode, status); +} + +std::pair DataShareHelperImpl::UpdateEx( + Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) +{ + DISTRIBUTED_DATA_HITRACE(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__)); + auto generalCtl = generalCtl_; + if (generalCtl == nullptr) { + LOG_ERROR("generalCtl is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + auto [errCode, status] = generalCtl->UpdateEx(uri, predicates, value); + if (errCode != E_OK) { + LOG_ERROR("generalCtl update failed, errCode = %{public}d", errCode); + } + return std::make_pair(errCode, status); +} + +std::pair DataShareHelperImpl::DeleteEx(Uri &uri, const DataSharePredicates &predicates) +{ + DISTRIBUTED_DATA_HITRACE(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__)); + auto generalCtl = generalCtl_; + if (generalCtl == nullptr) { + LOG_ERROR("generalCtl is nullptr"); + return std::make_pair(DATA_SHARE_ERROR, 0); + } + auto [errCode, status] = generalCtl->DeleteEx(uri, predicates); + if (errCode != E_OK) { + LOG_ERROR("generalCtl delete failed, errCode = %{public}d", errCode); + } + return std::make_pair(errCode, status); +} + std::shared_ptr DataShareHelperImpl::Query(Uri &uri, const DataSharePredicates &predicates, std::vector &columns, DatashareBusinessError *businessError) { @@ -179,7 +224,7 @@ int DataShareHelperImpl::BatchInsert(Uri &uri, const std::vectorBatchInsert(uri, values); } @@ -189,7 +234,7 @@ int DataShareHelperImpl::ExecuteBatch(const std::vector &sta auto extSpCtl = extSpCtl_; if (extSpCtl == nullptr) { LOG_ERROR("extSpCtl is nullptr"); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return extSpCtl->ExecuteBatch(statements, result); } @@ -271,7 +316,7 @@ int DataShareHelperImpl::AddQueryTemplate(const std::string &uri, int64_t subscr if (persistentDataCtl == nullptr) { LOG_ERROR("persistentDataCtl is nullptr"); report.SetError(RadarReporter::DATA_SHARE_DIED_ERROR); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return persistentDataCtl->AddQueryTemplate(uri, subscriberId, tpl); } @@ -284,7 +329,7 @@ int DataShareHelperImpl::DelQueryTemplate(const std::string &uri, int64_t subscr if (persistentDataCtl == nullptr) { LOG_ERROR("persistentDataCtl is nullptr"); report.SetError(RadarReporter::DATA_SHARE_DIED_ERROR); - return INVALID_VALUE; + return DATA_SHARE_ERROR; } return persistentDataCtl->DelQueryTemplate(uri, subscriberId); } @@ -326,8 +371,8 @@ std::vector DataShareHelperImpl::SubscribeRdbData(const std::ve return persistentDataCtl->SubscribeRdbData(this, uris, templateId, callback); } -std::vector DataShareHelperImpl::UnsubscribeRdbData(const std::vector &uris, - const TemplateId &templateId) +__attribute__((no_sanitize("cfi"))) std::vector DataShareHelperImpl::UnsubscribeRdbData( + const std::vector &uris, const TemplateId &templateId) { LOG_DEBUG("Start UnsubscribeRdbData"); RadarReporter::RadarReport report(RadarReporter::TEMPLATE_DATA_MANAGER, diff --git a/data_share/frameworks/native/consumer/src/datashare_proxy.cpp b/data_share/frameworks/native/consumer/src/datashare_proxy.cpp index 29bba953..11f9c7a9 100644 --- a/data_share/frameworks/native/consumer/src/datashare_proxy.cpp +++ b/data_share/frameworks/native/consumer/src/datashare_proxy.cpp @@ -56,7 +56,7 @@ std::vector DataShareProxy::GetFileTypes(const Uri &uri, const std: int32_t err = Remote()->SendRequest( static_cast(IDataShareInterfaceCode::CMD_GET_FILE_TYPES), data, reply, option); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("GetFileTypes fail to SendRequest. err: %{public}d", err); } @@ -90,7 +90,7 @@ int DataShareProxy::OpenFile(const Uri &uri, const std::string &mode) MessageOption option; int32_t err = Remote()->SendRequest( static_cast(IDataShareInterfaceCode::CMD_OPEN_FILE), data, reply, option); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("OpenFile fail to SendRequest. err: %{public}d", err); return fd; } @@ -127,7 +127,7 @@ int DataShareProxy::OpenRawFile(const Uri &uri, const std::string &mode) MessageOption option; int32_t err = Remote()->SendRequest( static_cast(IDataShareInterfaceCode::CMD_OPEN_RAW_FILE), data, reply, option); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("OpenRawFile fail to SendRequest. err: %{public}d", err); return fd; } @@ -157,7 +157,7 @@ int DataShareProxy::Insert(const Uri &uri, const DataShareValuesBucket &value) MessageOption option; int32_t err = Remote()->SendRequest( static_cast(IDataShareInterfaceCode::CMD_INSERT), data, reply, option); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("Insert fail to SendRequest. err: %{public}d", err); return err == PERMISSION_ERR ? PERMISSION_ERR_CODE : index; } @@ -186,7 +186,7 @@ int DataShareProxy::InsertExt(const Uri &uri, const DataShareValuesBucket &value MessageOption option; int32_t err = Remote()->SendRequest( static_cast(IDataShareInterfaceCode::CMD_INSERT_EXT), data, reply, option); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("Insert fail to SendRequest. err: %{public}d", err); return index; } @@ -214,7 +214,7 @@ int DataShareProxy::Update(const Uri &uri, const DataSharePredicates &predicates MessageOption option; int32_t err = Remote()->SendRequest( static_cast(IDataShareInterfaceCode::CMD_UPDATE), data, reply, option); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("Update fail to SendRequest. err: %{public}d", err); return err == PERMISSION_ERR ? PERMISSION_ERR_CODE : index; } @@ -245,7 +245,7 @@ int DataShareProxy::BatchUpdate(const UpdateOperations &operations, std::vector< MessageOption option; int32_t err = Remote()->SendRequest( static_cast(IDataShareInterfaceCode::CMD_BATCH_UPDATE), data, reply, option); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("fail to SendRequest. err: %{public}d", err); return err; } @@ -274,7 +274,7 @@ int DataShareProxy::Delete(const Uri &uri, const DataSharePredicates &predicates MessageOption option; int32_t err = Remote()->SendRequest( static_cast(IDataShareInterfaceCode::CMD_DELETE), data, reply, option); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("Delete fail to SendRequest. err: %{public}d", err); return err == PERMISSION_ERR ? PERMISSION_ERR_CODE : index; } @@ -285,6 +285,100 @@ int DataShareProxy::Delete(const Uri &uri, const DataSharePredicates &predicates return index; } +std::pair DataShareProxy::InsertEx(const Uri &uri, const DataShareValuesBucket &value) +{ + MessageParcel data; + data.SetMaxCapacity(MTU_SIZE); + if (!data.WriteInterfaceToken(DataShareProxy::GetDescriptor())) { + LOG_ERROR("WriteInterfaceToken failed"); + return std::make_pair(E_WRITE_TO_PARCE_ERROR, 0); + } + if (!ITypesUtil::Marshal(data, uri, value)) { + LOG_ERROR("fail to Marshal value"); + return std::make_pair(E_MARSHAL_ERROR, 0); + } + + int32_t errCode = -1; + int32_t result = -1; + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest( + static_cast(IDataShareInterfaceCode::CMD_INSERT_EX), data, reply, option); + if (err != E_OK) { + LOG_ERROR("InsertEx fail to SendRequest. err: %{public}d", err); + return std::make_pair((err == PERMISSION_ERR ? PERMISSION_ERR_CODE : errCode), 0); + } + + if (!ITypesUtil::Unmarshal(reply, errCode, result)) { + LOG_ERROR("fail to Unmarshal"); + return std::make_pair(E_UNMARSHAL_ERROR, 0); + } + return std::make_pair(errCode, result); +} + +std::pair DataShareProxy::UpdateEx(const Uri &uri, const DataSharePredicates &predicates, + const DataShareValuesBucket &value) +{ + MessageParcel data; + data.SetMaxCapacity(MTU_SIZE); + if (!data.WriteInterfaceToken(DataShareProxy::GetDescriptor())) { + LOG_ERROR("WriteInterfaceToken failed"); + return std::make_pair(E_WRITE_TO_PARCE_ERROR, 0); + } + if (!ITypesUtil::Marshal(data, uri, predicates, value)) { + LOG_ERROR("fail to Marshal value"); + return std::make_pair(E_MARSHAL_ERROR, 0); + } + + int32_t errCode = -1; + int32_t result = -1; + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest( + static_cast(IDataShareInterfaceCode::CMD_UPDATE_EX), data, reply, option); + if (err != E_OK) { + LOG_ERROR("UpdateEx fail to SendRequest. err: %{public}d", err); + return std::make_pair((err == PERMISSION_ERR ? PERMISSION_ERR_CODE : errCode), 0); + } + + if (!ITypesUtil::Unmarshal(reply, errCode, result)) { + LOG_ERROR("fail to Unmarshal"); + return std::make_pair(E_UNMARSHAL_ERROR, 0); + } + return std::make_pair(errCode, result); +} + +std::pair DataShareProxy::DeleteEx(const Uri &uri, const DataSharePredicates &predicates) +{ + MessageParcel data; + data.SetMaxCapacity(MTU_SIZE); + if (!data.WriteInterfaceToken(DataShareProxy::GetDescriptor())) { + LOG_ERROR("WriteInterfaceToken failed"); + return std::make_pair(E_WRITE_TO_PARCE_ERROR, 0); + } + if (!ITypesUtil::Marshal(data, uri, predicates)) { + LOG_ERROR("fail to Marshalling predicates"); + return std::make_pair(E_MARSHAL_ERROR, 0); + } + + int32_t errCode = -1; + int32_t result = -1; + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest( + static_cast(IDataShareInterfaceCode::CMD_DELETE_EX), data, reply, option); + if (err != E_OK) { + LOG_ERROR("DeleteEx fail to SendRequest. err: %{public}d", err); + return std::make_pair((err == PERMISSION_ERR ? PERMISSION_ERR_CODE : errCode), 0); + } + + if (!ITypesUtil::Unmarshal(reply, errCode, result)) { + LOG_ERROR("fail to Unmarshal"); + return std::make_pair(E_UNMARSHAL_ERROR, 0); + } + return std::make_pair(errCode, result); +} + std::shared_ptr DataShareProxy::Query(const Uri &uri, const DataSharePredicates &predicates, std::vector &columns, DatashareBusinessError &businessError) { @@ -304,7 +398,7 @@ std::shared_ptr DataShareProxy::Query(const Uri &uri, const auto result = ISharedResultSet::ReadFromParcel(reply); businessError.SetCode(reply.ReadInt32()); businessError.SetMessage(reply.ReadString()); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("Query fail to SendRequest. err: %{public}d", err); return nullptr; } @@ -329,7 +423,7 @@ std::string DataShareProxy::GetType(const Uri &uri) MessageOption option; int32_t err = Remote()->SendRequest( static_cast(IDataShareInterfaceCode::CMD_GET_TYPE), data, reply, option); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("GetFileTypes fail to SendRequest. err: %{public}d", err); return type; } @@ -363,7 +457,7 @@ int DataShareProxy::BatchInsert(const Uri &uri, const std::vectorSendRequest( static_cast(IDataShareInterfaceCode::CMD_BATCH_INSERT), data, reply, option); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("fail to SendRequest. err: %{public}d", err); return err == PERMISSION_ERR ? PERMISSION_ERR_CODE : ret; } @@ -391,7 +485,7 @@ int DataShareProxy::ExecuteBatch(const std::vector &statemen MessageOption option; int32_t err = Remote()->SendRequest( static_cast(IDataShareInterfaceCode::CMD_EXECUTE_BATCH), data, reply, option); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("fail to SendRequest. err: %{public}d", err); return -1; } @@ -488,7 +582,7 @@ Uri DataShareProxy::NormalizeUri(const Uri &uri) MessageOption option; int32_t err = Remote()->SendRequest( static_cast(IDataShareInterfaceCode::CMD_NORMALIZE_URI), data, reply, option); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("NormalizeUri fail to SendRequest. err: %{public}d", err); return Uri(""); } @@ -517,7 +611,7 @@ Uri DataShareProxy::DenormalizeUri(const Uri &uri) MessageOption option; int32_t err = Remote()->SendRequest( static_cast(IDataShareInterfaceCode::CMD_DENORMALIZE_URI), data, reply, option); - if (err != DATA_SHARE_NO_ERROR) { + if (err != E_OK) { LOG_ERROR("DenormalizeUri fail to SendRequest. err: %{public}d", err); return Uri(""); } diff --git a/data_share/frameworks/native/provider/include/datashare_stub.h b/data_share/frameworks/native/provider/include/datashare_stub.h index b4d71b43..6bd39753 100644 --- a/data_share/frameworks/native/provider/include/datashare_stub.h +++ b/data_share/frameworks/native/provider/include/datashare_stub.h @@ -20,6 +20,7 @@ #include #include "datashare_business_error.h" +#include "datashare_errno.h" #include "idatashare.h" namespace OHOS { @@ -48,10 +49,17 @@ private: ErrCode CmdExecuteBatch(MessageParcel &data, MessageParcel &reply); ErrCode CmdInsertExt(MessageParcel &data, MessageParcel &reply); ErrCode CmdBatchUpdate(MessageParcel &data, MessageParcel &reply); + ErrCode CmdInsertEx(MessageParcel &data, MessageParcel &reply); + ErrCode CmdUpdateEx(MessageParcel &data, MessageParcel &reply); + ErrCode CmdDeleteEx(MessageParcel &data, MessageParcel &reply); virtual int ExecuteBatch(const std::vector &statements, ExecResultSet &result) override; virtual int InsertExt(const Uri &uri, const DataShareValuesBucket &value, std::string &result) override; virtual int BatchUpdate(const UpdateOperations &operations, std::vector &results) override; + virtual std::pair InsertEx(const Uri &uri, const DataShareValuesBucket &value) override; + virtual std::pair UpdateEx(const Uri &uri, const DataSharePredicates &predicates, + const DataShareValuesBucket &value) override; + virtual std::pair DeleteEx(const Uri &uri, const DataSharePredicates &predicates) override; using RequestFuncType = int (DataShareStub::*)(MessageParcel &data, MessageParcel &reply); std::map stubFuncMap_; diff --git a/data_share/frameworks/native/provider/include/datashare_stub_impl.h b/data_share/frameworks/native/provider/include/datashare_stub_impl.h index f0c3e358..42b4cc32 100644 --- a/data_share/frameworks/native/provider/include/datashare_stub_impl.h +++ b/data_share/frameworks/native/provider/include/datashare_stub_impl.h @@ -67,6 +67,13 @@ public: Uri DenormalizeUri(const Uri &uri) override; + std::pair InsertEx(const Uri &uri, const DataShareValuesBucket &value) override; + + std::pair UpdateEx(const Uri &uri, const DataSharePredicates &predicates, + const DataShareValuesBucket &value) override; + + std::pair DeleteEx(const Uri &uri, const DataSharePredicates &predicates) override; + private: std::shared_ptr GetOwner(); bool CheckCallingPermission(const std::string &permission); diff --git a/data_share/frameworks/native/provider/src/datashare_stub.cpp b/data_share/frameworks/native/provider/src/datashare_stub.cpp index 50c48eaa..0ebf1673 100644 --- a/data_share/frameworks/native/provider/src/datashare_stub.cpp +++ b/data_share/frameworks/native/provider/src/datashare_stub.cpp @@ -55,6 +55,9 @@ DataShareStub::DataShareStub() stubFuncMap_[static_cast(IDataShareInterfaceCode::CMD_EXECUTE_BATCH)] = &DataShareStub::CmdExecuteBatch; stubFuncMap_[static_cast(IDataShareInterfaceCode::CMD_INSERT_EXT)] = &DataShareStub::CmdInsertExt; stubFuncMap_[static_cast(IDataShareInterfaceCode::CMD_BATCH_UPDATE)] = &DataShareStub::CmdBatchUpdate; + stubFuncMap_[static_cast(IDataShareInterfaceCode::CMD_INSERT_EX)] = &DataShareStub::CmdInsertEx; + stubFuncMap_[static_cast(IDataShareInterfaceCode::CMD_UPDATE_EX)] = &DataShareStub::CmdUpdateEx; + stubFuncMap_[static_cast(IDataShareInterfaceCode::CMD_DELETE_EX)] = &DataShareStub::CmdDeleteEx; } DataShareStub::~DataShareStub() @@ -109,7 +112,7 @@ ErrCode DataShareStub::CmdGetFileTypes(MessageParcel &data, MessageParcel &reply LOG_ERROR("Marshal value is nullptr"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdOpenFile(MessageParcel &data, MessageParcel &reply) @@ -134,7 +137,7 @@ ErrCode DataShareStub::CmdOpenFile(MessageParcel &data, MessageParcel &reply) return ERR_INVALID_VALUE; } close(fd); - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdOpenRawFile(MessageParcel &data, MessageParcel &reply) @@ -150,7 +153,7 @@ ErrCode DataShareStub::CmdOpenRawFile(MessageParcel &data, MessageParcel &reply) LOG_ERROR("Marshal value is nullptr"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdInsert(MessageParcel &data, MessageParcel &reply) @@ -173,7 +176,7 @@ ErrCode DataShareStub::CmdInsert(MessageParcel &data, MessageParcel &reply) LOG_ERROR("fail to WriteInt32 index"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdUpdate(MessageParcel &data, MessageParcel &reply) @@ -197,7 +200,7 @@ ErrCode DataShareStub::CmdUpdate(MessageParcel &data, MessageParcel &reply) LOG_ERROR("fail to WriteInt32 index"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdBatchUpdate(OHOS::MessageParcel &data, OHOS::MessageParcel &reply) @@ -217,7 +220,7 @@ ErrCode DataShareStub::CmdBatchUpdate(OHOS::MessageParcel &data, OHOS::MessagePa LOG_ERROR("marshalling updateOperations is failed"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdDelete(MessageParcel &data, MessageParcel &reply) @@ -240,7 +243,81 @@ ErrCode DataShareStub::CmdDelete(MessageParcel &data, MessageParcel &reply) LOG_ERROR("fail to WriteInt32 index"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; +} + +ErrCode DataShareStub::CmdInsertEx(MessageParcel &data, MessageParcel &reply) +{ + Uri uri(""); + DataShareValuesBucket value; + if (!ITypesUtil::Unmarshal(data, uri, value)) { + LOG_ERROR("Unmarshalling value is nullptr"); + return E_UNMARSHAL_ERROR; + } + + auto [errCode, result] = InsertEx(uri, value); + if (errCode == DEFAULT_NUMBER) { + LOG_ERROR("Insert inner error"); + return ERR_INVALID_VALUE; + } else if (errCode == PERMISSION_ERROR_NUMBER) { + LOG_ERROR("Insert permission error"); + return ERR_PERMISSION_DENIED; + } + + if (!ITypesUtil::Marshal(reply, errCode, result)) { + LOG_ERROR("Marshal value is nullptr"); + return E_MARSHAL_ERROR; + } + return E_OK; +} + +ErrCode DataShareStub::CmdUpdateEx(MessageParcel &data, MessageParcel &reply) +{ + Uri uri(""); + DataSharePredicates predicates; + DataShareValuesBucket value; + if (!ITypesUtil::Unmarshal(data, uri, predicates, value)) { + LOG_ERROR("Unmarshalling predicates is nullptr"); + return E_UNMARSHAL_ERROR; + } + + auto [errCode, result] = UpdateEx(uri, predicates, value); + if (errCode == DEFAULT_NUMBER) { + LOG_ERROR("Update inner error"); + return ERR_INVALID_VALUE; + } else if (errCode == PERMISSION_ERROR_NUMBER) { + LOG_ERROR("Update permission error"); + return ERR_PERMISSION_DENIED; + } + + if (!ITypesUtil::Marshal(reply, errCode, result)) { + LOG_ERROR("Marshal value is nullptr"); + return E_MARSHAL_ERROR; + } + return E_OK; +} + +ErrCode DataShareStub::CmdDeleteEx(MessageParcel &data, MessageParcel &reply) +{ + Uri uri(""); + DataSharePredicates predicates; + if (!ITypesUtil::Unmarshal(data, uri, predicates)) { + LOG_ERROR("Unmarshalling predicates is nullptr"); + return E_UNMARSHAL_ERROR; + } + auto [errCode, result] = DeleteEx(uri, predicates); + if (errCode == DEFAULT_NUMBER) { + LOG_ERROR("Delete inner error"); + return ERR_INVALID_VALUE; + } else if (errCode == PERMISSION_ERROR_NUMBER) { + LOG_ERROR("Delete permission error"); + return ERR_PERMISSION_DENIED; + } + if (!ITypesUtil::Marshal(reply, errCode, result)) { + LOG_ERROR("Marshal value is nullptr"); + return E_MARSHAL_ERROR; + } + return E_OK; } ErrCode DataShareStub::CmdQuery(MessageParcel &data, MessageParcel &reply) @@ -261,7 +338,7 @@ ErrCode DataShareStub::CmdQuery(MessageParcel &data, MessageParcel &reply) LOG_ERROR("!resultSet->Marshalling(reply)"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdGetType(MessageParcel &data, MessageParcel &reply) @@ -276,7 +353,7 @@ ErrCode DataShareStub::CmdGetType(MessageParcel &data, MessageParcel &reply) LOG_ERROR("fail to WriteString type"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdBatchInsert(MessageParcel &data, MessageParcel &reply) @@ -300,7 +377,7 @@ ErrCode DataShareStub::CmdBatchInsert(MessageParcel &data, MessageParcel &reply) LOG_ERROR("fail to WriteInt32 ret"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdRegisterObserver(MessageParcel &data, MessageParcel &reply) @@ -322,7 +399,7 @@ ErrCode DataShareStub::CmdRegisterObserver(MessageParcel &data, MessageParcel &r LOG_ERROR("fail to WriteInt32 ret"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdUnregisterObserver(MessageParcel &data, MessageParcel &reply) @@ -344,7 +421,7 @@ ErrCode DataShareStub::CmdUnregisterObserver(MessageParcel &data, MessageParcel LOG_ERROR("fail to WriteInt32 ret"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdNotifyChange(MessageParcel &data, MessageParcel &reply) @@ -360,7 +437,7 @@ ErrCode DataShareStub::CmdNotifyChange(MessageParcel &data, MessageParcel &reply LOG_ERROR("fail to WriteInt32 ret"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdNormalizeUri(MessageParcel &data, MessageParcel &reply) @@ -375,7 +452,7 @@ ErrCode DataShareStub::CmdNormalizeUri(MessageParcel &data, MessageParcel &reply LOG_ERROR("Write to message parcel failed!"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdDenormalizeUri(MessageParcel &data, MessageParcel &reply) @@ -391,7 +468,7 @@ ErrCode DataShareStub::CmdDenormalizeUri(MessageParcel &data, MessageParcel &rep LOG_ERROR("Write to message parcel failed!"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdExecuteBatch(MessageParcel &data, MessageParcel &reply) @@ -411,7 +488,7 @@ ErrCode DataShareStub::CmdExecuteBatch(MessageParcel &data, MessageParcel &reply LOG_ERROR("fail to write result"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } ErrCode DataShareStub::CmdInsertExt(MessageParcel &data, MessageParcel &reply) @@ -432,7 +509,7 @@ ErrCode DataShareStub::CmdInsertExt(MessageParcel &data, MessageParcel &reply) LOG_ERROR("fail to write result"); return ERR_INVALID_VALUE; } - return DATA_SHARE_NO_ERROR; + return E_OK; } int DataShareStub::ExecuteBatch(const std::vector &statements, ExecResultSet &result) @@ -449,5 +526,19 @@ int DataShareStub::BatchUpdate(const UpdateOperations &operations, std::vector DataShareStub::InsertEx(const Uri &uri, const DataShareValuesBucket &value) +{ + return std::make_pair(0, 0); +} +std::pair DataShareStub::UpdateEx(const Uri &uri, const DataSharePredicates &predicates, + const DataShareValuesBucket &value) +{ + return std::make_pair(0, 0); +} +std::pair DataShareStub::DeleteEx(const Uri &uri, const DataSharePredicates &predicates) +{ + return std::make_pair(0, 0); +} + } // namespace DataShare } // namespace OHOS \ No newline at end of file diff --git a/data_share/frameworks/native/provider/src/datashare_stub_impl.cpp b/data_share/frameworks/native/provider/src/datashare_stub_impl.cpp index 1246d099..bee637f5 100644 --- a/data_share/frameworks/native/provider/src/datashare_stub_impl.cpp +++ b/data_share/frameworks/native/provider/src/datashare_stub_impl.cpp @@ -247,6 +247,106 @@ int DataShareStubImpl::Delete(const Uri &uri, const DataSharePredicates &predica return ret; } +std::pair DataShareStubImpl::InsertEx(const Uri &uri, const DataShareValuesBucket &value) +{ + CallingInfo info; + GetCallingInfo(info); + + auto client = sptr(this); + auto extension = client->GetOwner(); + if (extension == nullptr) { + return std::make_pair(DATA_SHARE_ERROR, 0); + } + + if (!CheckCallingPermission(extension->abilityInfo_->writePermission)) { + LOG_ERROR("Check calling permission failed."); + return std::make_pair(PERMISSION_ERROR_NUMBER, 0); + } + + int ret = 0; + std::function syncTaskFunc = [extension, info, uri, value]() { + extension->SetCallingInfo(info); + extension->Insert(uri, value); + }; + std::function getRetFunc = [extension, &ret]() -> bool { + if (extension == nullptr) { + return false; + } + extension->GetResult(ret); + return extension->GetRecvReply(); + }; + std::lock_guard lock(mutex_); + uvQueue_->SyncCall(syncTaskFunc, getRetFunc); + return std::make_pair(E_OK, ret); +} + +std::pair DataShareStubImpl::UpdateEx(const Uri &uri, const DataSharePredicates &predicates, + const DataShareValuesBucket &value) +{ + CallingInfo info; + GetCallingInfo(info); + + auto client = sptr(this); + auto extension = client->GetOwner(); + if (extension == nullptr) { + return std::make_pair(DATA_SHARE_ERROR, 0); + } + + if (!CheckCallingPermission(extension->abilityInfo_->writePermission)) { + LOG_ERROR("Check calling permission failed."); + return std::make_pair(PERMISSION_ERROR_NUMBER, 0); + } + + int ret = 0; + std::function syncTaskFunc = [extension, info, uri, predicates, value]() { + extension->SetCallingInfo(info); + extension->Update(uri, predicates, value); + }; + std::function getRetFunc = [extension, &ret]() -> bool { + if (extension == nullptr) { + return false; + } + extension->GetResult(ret); + return extension->GetRecvReply(); + }; + std::lock_guard lock(mutex_); + uvQueue_->SyncCall(syncTaskFunc, getRetFunc); + return std::make_pair(E_OK, ret); +} + +std::pair DataShareStubImpl::DeleteEx(const Uri &uri, const DataSharePredicates &predicates) +{ + CallingInfo info; + GetCallingInfo(info); + + auto client = sptr(this); + auto extension = client->GetOwner(); + if (extension == nullptr) { + return std::make_pair(DATA_SHARE_ERROR, 0); + } + + if (!CheckCallingPermission(extension->abilityInfo_->writePermission)) { + LOG_ERROR("Check calling permission failed."); + return std::make_pair(PERMISSION_ERROR_NUMBER, 0); + } + + int ret = 0; + std::function syncTaskFunc = [extension, info, uri, predicates]() { + extension->SetCallingInfo(info); + extension->Delete(uri, predicates); + }; + std::function getRetFunc = [extension, &ret]() -> bool { + if (extension == nullptr) { + return false; + } + extension->GetResult(ret); + return extension->GetRecvReply(); + }; + std::lock_guard lock(mutex_); + uvQueue_->SyncCall(syncTaskFunc, getRetFunc); + return std::make_pair(E_OK, ret); +} + std::shared_ptr DataShareStubImpl::Query(const Uri &uri, const DataSharePredicates &predicates, std::vector &columns, DatashareBusinessError &businessError) { @@ -273,9 +373,10 @@ std::shared_ptr DataShareStubImpl::Query(const Uri &uri, if (extension == nullptr) { return false; } + auto isRecvReply = extension->GetRecvReply(); extension->GetResultSet(resultSet); extension->GetBusinessError(businessError); - return extension->GetRecvReply(); + return isRecvReply; }; std::lock_guard lock(mutex_); uvQueue_->SyncCall(syncTaskFunc, getRetFunc); diff --git a/data_share/frameworks/native/proxy/include/ams_mgr_proxy.h b/data_share/frameworks/native/proxy/include/ams_mgr_proxy.h index 3a4fdac8..080f428b 100644 --- a/data_share/frameworks/native/proxy/include/ams_mgr_proxy.h +++ b/data_share/frameworks/native/proxy/include/ams_mgr_proxy.h @@ -24,15 +24,16 @@ namespace OHOS::DataShare { class AmsMgrProxy { public: ~AmsMgrProxy(); - static AmsMgrProxy* GetInstance(); + static AmsMgrProxy *GetInstance(); int Connect(const std::string &uri, const sptr &connect, const sptr &callerToken); int DisConnect(sptr connect); + private: using Proxy = AAFwk::ExtensionManagerProxy; AmsMgrProxy() = default; class ServiceDeathRecipient : public IRemoteObject::DeathRecipient { public: - explicit ServiceDeathRecipient(AmsMgrProxy* owner) : owner_(owner) + explicit ServiceDeathRecipient(AmsMgrProxy *owner) : owner_(owner) { } void OnRemoteDied(const wptr &object) override @@ -43,7 +44,7 @@ private: } private: - AmsMgrProxy* owner_; + AmsMgrProxy *owner_; }; void OnProxyDied(); bool ConnectSA(); diff --git a/data_share/frameworks/native/proxy/include/data_share_manager_impl.h b/data_share/frameworks/native/proxy/include/data_share_manager_impl.h index dcb38fe9..8ff96ca2 100644 --- a/data_share/frameworks/native/proxy/include/data_share_manager_impl.h +++ b/data_share/frameworks/native/proxy/include/data_share_manager_impl.h @@ -16,13 +16,17 @@ #ifndef DATASHARESERVICE_DATA_SHARE_MANAGER_IMPL_H #define DATASHARESERVICE_DATA_SHARE_MANAGER_IMPL_H +#include #include #include #include +#include +#include +#include "call_reporter.h" #include "concurrent_map.h" #include "data_share_service_proxy.h" -#include "data_share_errno.h" +#include "datashare_errno.h" #include "idata_share_client_death_observer.h" #include "iremote_object.h" #include "refbase.h" @@ -85,6 +89,8 @@ public: void RemoveRegisterCallback(GeneralControllerServiceImpl* ptr); void OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId); + + void SetCallCount(const std::string &funcName, const std::string &uri); private: DataShareManagerImpl(); @@ -108,13 +114,10 @@ private: sptr dataMgrService_; std::shared_ptr dataShareService_; std::string bundleName_; - static constexpr int WAIT_TIME = 2; - static constexpr int MAX_THREADS = 2; - static constexpr int MIN_THREADS = 0; - std::shared_ptr pool_; std::function)> deathCallback_ = {}; sptr clientDeathObserverPtr_; ConcurrentMap> observers_; + DataShareCallReporter dataShareCallReporter_; }; } } // namespace OHOS::DataShare diff --git a/data_share/frameworks/native/proxy/include/data_share_service_proxy.h b/data_share/frameworks/native/proxy/include/data_share_service_proxy.h index 5b7658ca..ab1028ee 100644 --- a/data_share/frameworks/native/proxy/include/data_share_service_proxy.h +++ b/data_share/frameworks/native/proxy/include/data_share_service_proxy.h @@ -26,14 +26,14 @@ namespace OHOS::DataShare { class DataShareServiceProxy final : public IRemoteProxy { public: explicit DataShareServiceProxy(const sptr &object); - int Insert(const Uri &uri, const DataShareValuesBucket &valuesBucket) override; + int Insert(const Uri &uri, const Uri &extUri, const DataShareValuesBucket &valuesBucket) override; - int Update(const Uri &uri, const DataSharePredicates &predicate, + int Update(const Uri &uri, const Uri &extUri, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) override; - int Delete(const Uri &uri, const DataSharePredicates &predicate) override; + int Delete(const Uri &uri, const Uri &extUri, const DataSharePredicates &predicate) override; - std::shared_ptr Query(const Uri &uri, const DataSharePredicates &predicates, + std::shared_ptr Query(const Uri &uri, const Uri &extUri, const DataSharePredicates &predicates, std::vector &columns, DatashareBusinessError &businessError) override; int AddQueryTemplate(const std::string &uri, int64_t subscriberId, Template &tpl) override; @@ -79,6 +79,15 @@ public: int UnRegisterObserver(const Uri &uri, const sptr &dataObserver) override; + std::pair InsertEx(const Uri &uri, const Uri &extUri, + const DataShareValuesBucket &valuesBucket) override; + + std::pair UpdateEx(const Uri &uri, const Uri &extUri, const DataSharePredicates &predicate, + const DataShareValuesBucket &valuesBucket) override; + + std::pair DeleteEx(const Uri &uri, const Uri &extUri, + const DataSharePredicates &predicate) override; + private: static inline BrokerDelegator delegator_; }; diff --git a/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp b/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp index 73bdba45..0ae950da 100644 --- a/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp +++ b/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp @@ -45,11 +45,8 @@ AmsMgrProxy::~AmsMgrProxy() AmsMgrProxy* AmsMgrProxy::GetInstance() { - static AmsMgrProxy* proxy = nullptr; - if (proxy != nullptr) { - return proxy; - } std::lock_guard lock(pmutex_); + static AmsMgrProxy* proxy = nullptr; if (proxy != nullptr) { return proxy; } diff --git a/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp b/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp index 8395eb12..df392164 100644 --- a/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp +++ b/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp @@ -23,7 +23,6 @@ #include "ipc_skeleton.h" #include "iservice_registry.h" #include "system_ability_definition.h" -#include "executor_pool.h" #include "rdb_subscriber_manager.h" #include "published_data_subscriber_manager.h" @@ -35,9 +34,6 @@ DataShareManagerImpl* DataShareManagerImpl::manager_ = nullptr; DataShareManagerImpl* DataShareManagerImpl::GetInstance() { - if (manager_ != nullptr) { - return manager_; - } std::lock_guard lock(pmutex_); if (manager_ != nullptr) { return manager_; @@ -133,7 +129,6 @@ void DataShareManagerImpl::RegisterClientDeathObserver() DataShareManagerImpl::DataShareManagerImpl() { - pool_ = std::make_shared(MAX_THREADS, MIN_THREADS); SetDeathCallback([](std::shared_ptr proxy) { LOG_INFO("RecoverObs start"); RdbSubscriberManager::GetInstance().RecoverObservers(proxy); @@ -147,10 +142,6 @@ DataShareManagerImpl::~DataShareManagerImpl() std::shared_ptr DataShareManagerImpl::GetProxy() { - if (dataShareService_ != nullptr) { - return dataShareService_; - } - std::lock_guard lock(mutex_); if (dataShareService_ != nullptr) { return dataShareService_; @@ -199,16 +190,6 @@ void DataShareManagerImpl::OnRemoteDied() { LOG_INFO("#######datashare service has dead"); ResetServiceHandle(); - auto taskid = pool_->Schedule(std::chrono::seconds(WAIT_TIME), [this]() { - if (GetServiceProxy() != nullptr) { - deathCallback_(dataShareService_); - } - }); - if (taskid == ExecutorPool::INVALID_TASK_ID) { - LOG_ERROR("create scheduler failed, over the max capacity"); - return; - } - LOG_DEBUG("create scheduler success"); } void DataShareManagerImpl::SetRegisterCallback(GeneralControllerServiceImpl* ptr, @@ -235,6 +216,15 @@ void DataShareManagerImpl::OnAddSystemAbility(int32_t systemAbilityId, const std callback(); return false; }); + auto serviceProxy = GetServiceProxy(); + if (serviceProxy != nullptr) { + deathCallback_(serviceProxy); + } +} + +void DataShareManagerImpl::SetCallCount(const std::string &funcName, const std::string &uri) +{ + dataShareCallReporter_.Count(funcName, uri); } } } diff --git a/data_share/frameworks/native/proxy/src/data_share_service_proxy.cpp b/data_share/frameworks/native/proxy/src/data_share_service_proxy.cpp index bc14154c..66ae66a0 100644 --- a/data_share/frameworks/native/proxy/src/data_share_service_proxy.cpp +++ b/data_share/frameworks/native/proxy/src/data_share_service_proxy.cpp @@ -25,90 +25,146 @@ namespace OHOS { namespace DataShare { using InterfaceCode = OHOS::DistributedShare::DataShare::DataShareServiceInterfaceCode; - DataShareServiceProxy::DataShareServiceProxy(const sptr &object) : IRemoteProxy(object) { } -int32_t DataShareServiceProxy::Insert(const Uri &uri, const DataShareValuesBucket &value) +int32_t DataShareServiceProxy::Insert(const Uri &uri, const Uri &extUri, const DataShareValuesBucket &value) +{ + auto [errCode, status] = InsertEx(uri, extUri, value); + if (errCode == NO_ERROR) { + return status; + } else if (errCode < NO_ERROR) { + return errCode; + } + LOG_ERROR("DataShareServiceProxy insert failed, errCode = %{public}d", errCode); + return DATA_SHARE_ERROR; +} + +int32_t DataShareServiceProxy::Update(const Uri &uri, const Uri &extUri, + const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) +{ + auto [errCode, status] = UpdateEx(uri, extUri, predicate, valuesBucket); + if (errCode == NO_ERROR) { + return status; + } else if (errCode < NO_ERROR) { + return errCode; + } + LOG_ERROR("DataShareServiceProxy update failed, errCode = %{public}d", errCode); + return DATA_SHARE_ERROR; +} + +int32_t DataShareServiceProxy::Delete(const Uri &uri, const Uri &extUri, const DataSharePredicates &predicate) +{ + auto [errCode, status] = DeleteEx(uri, extUri, predicate); + if (errCode == NO_ERROR) { + return status; + } else if (errCode < NO_ERROR) { + return errCode; + } + LOG_ERROR("DataShareServiceProxy delete failed, errCode = %{public}d", errCode); + return DATA_SHARE_ERROR; +} + +std::pair DataShareServiceProxy::InsertEx(const Uri &uri, const Uri &extUri, + const DataShareValuesBucket &value) { const std::string &uriStr = uri.ToString(); MessageParcel data; if (!data.WriteInterfaceToken(IDataShareService::GetDescriptor())) { LOG_ERROR("Write descriptor failed!"); - return DATA_SHARE_ERROR; + return std::make_pair(E_WRITE_TO_PARCE_ERROR, 0); } - if (!ITypesUtil::Marshal(data, uriStr, value)) { + if (!ITypesUtil::Marshal(data, uriStr, extUri.ToString(), value)) { LOG_ERROR("Write to message parcel failed!"); - return DATA_SHARE_ERROR; + return std::make_pair(E_MARSHAL_ERROR, 0); } + int32_t result = -1; + int32_t errCode = -1; MessageParcel reply; MessageOption option; int32_t err = Remote()->SendRequest( - static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_INSERT), data, reply, option); + static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_INSERTEX), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("Insert fail to sendRequest. uri: %{public}s, err: %{public}d", + LOG_ERROR("InsertEx fail to sendRequest. uri: %{public}s, err: %{public}d", DataShareStringUtils::Anonymous(uriStr).c_str(), err); - return DATA_SHARE_ERROR; + return std::make_pair(DATA_SHARE_ERROR, 0); } - return reply.ReadInt32(); + if (!ITypesUtil::Unmarshal(reply, errCode, result)) { + LOG_ERROR("fail to Unmarshal"); + return std::make_pair(E_UNMARSHAL_ERROR, 0); + } + return std::make_pair(errCode, result); } -int32_t DataShareServiceProxy::Update(const Uri &uri, +std::pair DataShareServiceProxy::UpdateEx(const Uri &uri, const Uri &extUri, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) { const std::string &uriStr = uri.ToString(); MessageParcel data; if (!data.WriteInterfaceToken(IDataShareService::GetDescriptor())) { LOG_ERROR("Write descriptor failed!"); - return DATA_SHARE_ERROR; + return std::make_pair(E_WRITE_TO_PARCE_ERROR, 0); } - if (!ITypesUtil::Marshal(data, uriStr, predicate, valuesBucket)) { + if (!ITypesUtil::Marshal(data, uriStr, extUri.ToString(), predicate, valuesBucket)) { LOG_ERROR("Write to message parcel failed!"); - return DATA_SHARE_ERROR; + return std::make_pair(E_MARSHAL_ERROR, 0); } + int32_t result = -1; + int32_t errCode = -1; MessageParcel reply; MessageOption option; int32_t err = Remote()->SendRequest( - static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_UPDATE), data, reply, option); + static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_UPDATEEX), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("Update fail to sendRequest. uri: %{public}s, err: %{public}d", + LOG_ERROR("UpdateEx fail to sendRequest. uri: %{public}s, err: %{public}d", DataShareStringUtils::Anonymous(uriStr).c_str(), err); - return DATA_SHARE_ERROR; + return std::make_pair(DATA_SHARE_ERROR, 0); } - return reply.ReadInt32(); + if (!ITypesUtil::Unmarshal(reply, errCode, result)) { + LOG_ERROR("fail to Unmarshal"); + return std::make_pair(E_UNMARSHAL_ERROR, 0); + } + return std::make_pair(errCode, result); } -int32_t DataShareServiceProxy::Delete(const Uri &uri, const DataSharePredicates &predicate) +std::pair DataShareServiceProxy::DeleteEx(const Uri &uri, const Uri &extUri, + const DataSharePredicates &predicate) { const std::string &uriStr = uri.ToString(); MessageParcel data; if (!data.WriteInterfaceToken(IDataShareService::GetDescriptor())) { LOG_ERROR("Write descriptor failed!"); - return DATA_SHARE_ERROR; + return std::make_pair(E_WRITE_TO_PARCE_ERROR, 0); } - if (!ITypesUtil::Marshal(data, uriStr, predicate)) { + if (!ITypesUtil::Marshal(data, uriStr, extUri.ToString(), predicate)) { LOG_ERROR("Write to message parcel failed!"); - return DATA_SHARE_ERROR; + return std::make_pair(E_MARSHAL_ERROR, 0); } + int32_t result = -1; + int32_t errCode = -1; MessageParcel reply; MessageOption option; int32_t err = Remote()->SendRequest( - static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_DELETE), data, reply, option); + static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_DELETEEX), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("Delete fail to sendRequest. uri: %{public}s, err: %{public}d", + LOG_ERROR("DeleteEx fail to sendRequest. uri: %{public}s, err: %{public}d", DataShareStringUtils::Anonymous(uriStr).c_str(), err); - return DATA_SHARE_ERROR; + return std::make_pair(DATA_SHARE_ERROR, 0); } - return reply.ReadInt32(); + if (!ITypesUtil::Unmarshal(reply, errCode, result)) { + LOG_ERROR("fail to Unmarshal"); + return std::make_pair(E_UNMARSHAL_ERROR, 0); + } + return std::make_pair(errCode, result); } -std::shared_ptr DataShareServiceProxy::Query(const Uri &uri, const DataSharePredicates &predicates, - std::vector &columns, DatashareBusinessError &businessError) +std::shared_ptr DataShareServiceProxy::Query(const Uri &uri, const Uri &extUri, + const DataSharePredicates &predicates, std::vector &columns, DatashareBusinessError &businessError) { const std::string &uriStr = uri.ToString(); MessageParcel data; @@ -117,7 +173,7 @@ std::shared_ptr DataShareServiceProxy::Query(const Uri &uri, return nullptr; } - if (!ITypesUtil::Marshal(data, uriStr, predicates, columns)) { + if (!ITypesUtil::Marshal(data, uriStr, extUri.ToString(), predicates, columns)) { LOG_ERROR("Write to message parcel failed!"); return nullptr; } diff --git a/data_share/interfaces/inner_api/BUILD.gn b/data_share/interfaces/inner_api/BUILD.gn index fabe3a7c..bb9b3dce 100644 --- a/data_share/interfaces/inner_api/BUILD.gn +++ b/data_share/interfaces/inner_api/BUILD.gn @@ -48,6 +48,7 @@ config("datashare_public_config") { } datashare_consumer_sources = [ + "${datashare_common_native_path}/src/call_reporter.cpp", "${datashare_common_native_path}/src/datashare_string_utils.cpp", "${datashare_native_consumer_path}/controller/provider/src/ext_special_controller.cpp", "${datashare_native_consumer_path}/controller/provider/src/general_controller_provider_impl.cpp", diff --git a/data_share/interfaces/inner_api/common/include/datashare_errno.h b/data_share/interfaces/inner_api/common/include/datashare_errno.h index 3bdf68dc..0c58659e 100644 --- a/data_share/interfaces/inner_api/common/include/datashare_errno.h +++ b/data_share/interfaces/inner_api/common/include/datashare_errno.h @@ -18,6 +18,10 @@ namespace OHOS { namespace DataShare { +/** +* @brief The error code in the data share error case. +*/ +constexpr int DATA_SHARE_ERROR = -1; /** * @brief The error code in the correct case. @@ -99,22 +103,56 @@ constexpr int E_BMS_NOT_READY = (E_BASE + 50); * @brief metaData not exists */ constexpr int E_METADATA_NOT_EXISTS = (E_BASE + 51); + /** * @brief silent proxy is disable */ constexpr int E_SILENT_PROXY_DISABLE = (E_BASE + 52); + /** * @brief token is empty */ constexpr int E_TOKEN_EMPTY = (E_BASE + 53); + /** * @brief ext uri is empty */ constexpr int E_EXT_URI_INVALID = (E_BASE + 54); + /** * @brief DataShare not ready */ constexpr int E_DATA_SHARE_NOT_READY = (E_BASE + 55); + +/** +* @brief The error code for db error. +*/ +constexpr int E_DB_ERROR = (E_BASE + 56); + +/** +* @brief The error code for data supplier error +*/ +constexpr int E_DATA_SUPPLIER_ERROR = (E_BASE + 57); + +/** +* @brief The error code for marshal error. +*/ +constexpr int E_MARSHAL_ERROR = (E_BASE + 58); + +/** +* @brief The error code for unmarshal error. +*/ +constexpr int E_UNMARSHAL_ERROR = (E_BASE + 59); + +/** +* @brief The error code for write interface token to data error. +*/ +constexpr int E_WRITE_TO_PARCE_ERROR = (E_BASE + 60); + +/** +* @brief The error code for resultSet busy error. +*/ +constexpr int E_RESULTSET_BUSY = (E_BASE + 61); } // namespace DataShare } // namespace OHOS diff --git a/data_share/interfaces/inner_api/consumer/include/datashare_helper.h b/data_share/interfaces/inner_api/consumer/include/datashare_helper.h index 7e7efc9a..c2450aa2 100644 --- a/data_share/interfaces/inner_api/consumer/include/datashare_helper.h +++ b/data_share/interfaces/inner_api/consumer/include/datashare_helper.h @@ -24,6 +24,7 @@ #include "data_ability_observer_interface.h" #include "datashare_business_error.h" +#include "datashare_errno.h" #include "datashare_observer.h" #include "datashare_operation_statement.h" #include "datashare_predicates.h" @@ -56,22 +57,28 @@ public: * * @param token Indicates the System token. * @param strUri Indicates the database table or disk file to operate. + * @param waitTime connect extension waiting time. * * @return Returns the created DataShareHelper instance. */ - static std::shared_ptr Creator( - const sptr &token, const std::string &strUri, const std::string &extUri = ""); + [[deprecated( + "Use Create(const sptr &, const std::string &, const std::string &, const int &) instead.")]] + static std::shared_ptr Creator(const sptr &token, + const std::string &strUri, const std::string &extUri = "", const int waitTime = 2); /** * @brief Creates a DataShareHelper instance with the Uri and {@link #CreateOptions} . * * @param strUri Indicates the database table or disk file to operate. * @param options Indicates the optional config. + * @param waitTime connect extension waiting time. * * @return Returns the created DataShareHelper instance with a specified Uri. */ + [[deprecated( + "Use Create(const sptr &, const std::string &,const std::string &, const int &) instead.")]] static std::shared_ptr Creator(const std::string &strUri, const CreateOptions &options, - const std::string &bundleName = ""); + const std::string &bundleName = "", const int waitTime = 2); /** * @brief Creates a DataShareHelper instance, priority silent access, use non-silent access when silent is not @@ -80,11 +87,12 @@ public: * @param token Indicates the System token. * @param strUri Indicates the database table or disk file to operate for silent access. * @param extUri Indicates the database table or disk file to operate for non silent access. + * @param waitTime connect extension waiting time. * * @return Returns the created DataShareHelper instance with a specified Uri. */ static std::pair> Create(const sptr &token, - const std::string &strUri, const std::string &extUri); + const std::string &strUri, const std::string &extUri, const int waitTime = 2); /** * @brief Releases the client resource of the Data share. @@ -139,6 +147,7 @@ public: * * @return Returns the index of the inserted data record. */ + [[deprecated("Use InsertEx(Uri &, const DataShareValuesBucket &) instead.")]] virtual int Insert(Uri &uri, const DataShareValuesBucket &value) = 0; /** @@ -161,6 +170,7 @@ public: * * @return Returns the number of data records updated. */ + [[deprecated("Use UpdateEx(Uri &, const DataSharePredicates &, const DataShareValuesBucket &) instead.")]] virtual int Update(Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) = 0; /** @@ -181,6 +191,7 @@ public: * * @return Returns the number of data records deleted. */ + [[deprecated("Use DeleteEx(Uri &, const DataSharePredicates &) instead.")]] virtual int Delete(Uri &uri, const DataSharePredicates &predicates) = 0; /** @@ -413,19 +424,54 @@ public: */ static int SetSilentSwitch(Uri &uri, bool enable); + /** + * @brief Inserts a single data record into the database. + * + * @param uri Indicates the path of the data to operate. + * @param value Indicates the data record to insert. If this parameter is null, a blank row will be inserted. + * + * @return Returns pair, the errCode and the index of the inserted data record. + */ + virtual std::pair InsertEx(Uri &uri, const DataShareValuesBucket &value); + + /** + * @brief Updates data records in the database. + * + * @param uri Indicates the path of data to update. + * @param predicates Indicates filter criteria. You should define the processing logic when this parameter is null. + * @param value Indicates the data to update. This parameter can be null. + * + * @return Returns pair, the errCode and the index of data records updated. + */ + virtual std::pair UpdateEx( + Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value); + + /** + * @brief Deletes one or more data records from the database. + * + * @param uri Indicates the path of the data to operate. + * @param predicates Indicates filter criteria. You should define the processing logic when this parameter is null. + * + * @return Returns pair, the errCode and the index of data records deleted. + */ + virtual std::pair DeleteEx(Uri &uri, const DataSharePredicates &predicates); + private: - static std::shared_ptr CreateServiceHelper(const std::string &bundleName = ""); + static std::shared_ptr CreateServiceHelper(const std::string &extUri = "", + const std::string &bundleName = ""); static int GetSilentProxyStatus(const std::string &uri); - static std::shared_ptr CreateExtHelper(Uri &uri, const sptr &token); + static std::shared_ptr CreateExtHelper(Uri &uri, const sptr &token, + const int waitTime = 2); static std::string TransferUriPrefix(const std::string &originPrefix, const std::string &replacedPrefix, const std::string &originUriStr); static bool IsProxy(Uri &uri); - static std::pair> CreateProxyHelper(const std::string &strUri); + static std::pair> CreateProxyHelper(const std::string &strUri, + const std::string &extUri); }; } // namespace DataShare } // namespace OHOS diff --git a/data_share/interfaces/inner_api/consumer/include/datashare_result_set.h b/data_share/interfaces/inner_api/consumer/include/datashare_result_set.h index 29983c73..9a2a94d4 100644 --- a/data_share/interfaces/inner_api/consumer/include/datashare_result_set.h +++ b/data_share/interfaces/inner_api/consumer/include/datashare_result_set.h @@ -17,6 +17,7 @@ #define DATASHARE_RESULT_SET_H #include +#include #include #include #include @@ -134,7 +135,7 @@ public: /** * Obtains a block from the SharedResultSet. */ - AppDataFwk::SharedBlock *GetBlock() const override; + std::shared_ptr GetBlock() override; /** * Called when the position of the result set changes. @@ -159,11 +160,12 @@ public: /** * Checks whether an DataShareResultSet object contains shared blocks. */ - bool HasBlock() const; + bool HasBlock(); + std::shared_ptr GetBridge(); protected: int CheckState(int columnIndex); - void ClosedBlock(); + void ClosedBlockAndBridge(); virtual void Finalize(); friend class ISharedResultSetStub; @@ -178,7 +180,8 @@ private: // The actual position of the last row of data in the shareblock int endRowPos_ = -1; // The SharedBlock owned by this DataShareResultSet - AppDataFwk::SharedBlock *sharedBlock_ = nullptr; + std::shared_mutex mutex_; + std::shared_ptr sharedBlock_ = nullptr; std::shared_ptr blockWriter_ = nullptr; std::shared_ptr bridge_ = nullptr; }; diff --git a/data_share/interfaces/inner_api/consumer/include/datashare_shared_result_set.h b/data_share/interfaces/inner_api/consumer/include/datashare_shared_result_set.h index 2b5aaafd..8335aca7 100644 --- a/data_share/interfaces/inner_api/consumer/include/datashare_shared_result_set.h +++ b/data_share/interfaces/inner_api/consumer/include/datashare_shared_result_set.h @@ -30,7 +30,7 @@ public: /** * Obtains a block from the {@link SharedResultSet} */ - virtual AppDataFwk::SharedBlock *GetBlock() const = 0; + virtual std::shared_ptr GetBlock() = 0; /** * Adds the data of a {@code SharedResultSet} to a {@link SharedBlock} */ diff --git a/data_share/test/native/BUILD.gn b/data_share/test/native/BUILD.gn index f2ac1cff..1fc9557d 100644 --- a/data_share/test/native/BUILD.gn +++ b/data_share/test/native/BUILD.gn @@ -404,6 +404,7 @@ ohos_unittest("ValueProxyTest") { deps = [ "${datashare_innerapi_path}/common:datashare_common_static" ] external_deps = [ + "ability_base:zuri", "c_utils:utils", "hilog:libhilog", "ipc:ipc_single", diff --git a/data_share/test/native/resource/datashare_ext_bundle/entry/src/main/ets/DataShareExtAbility/DataShareExtAbility.ts b/data_share/test/native/resource/datashare_ext_bundle/entry/src/main/ets/DataShareExtAbility/DataShareExtAbility.ts index 82bf0301..ea35214f 100644 --- a/data_share/test/native/resource/datashare_ext_bundle/entry/src/main/ets/DataShareExtAbility/DataShareExtAbility.ts +++ b/data_share/test/native/resource/datashare_ext_bundle/entry/src/main/ets/DataShareExtAbility/DataShareExtAbility.ts @@ -13,7 +13,8 @@ * limitations under the License. */ -import Extension from '@ohos.application.DataShareExtensionAbility' +import Extension from '@ohos.application.DataShareExtensionAbility'; +import { UpdateOperation } from '@ohos.application.DataShareExtensionAbility'; import rdb from '@ohos.data.relationalStore'; import rpc from '@ohos.rpc'; @@ -68,6 +69,25 @@ extends Extension { console.info('[ttt] [DataShareTest] [insert] leave'); } + async batchUpdate(operations, callback) { + let recordOps : Record> = operations; + let results : Record> = {}; + for (const [key, values] of Object.entries(recordOps)) { + let result : number[] = []; + for (const value of values) { + await rdbStore.update(TBL_NAME, value.values, value.predicates).then(async (rows) => { + console.info('[ttt] [DataShareTest] [batchUpdate] row count is ' + rows); + result.push(rows); + }).catch((err) => { + console.info("[ttt] [DataShareTest] [batchUpdate] failed, err is " + err); + result.push(-1) + }) + } + results[key] = result; + } + callback(null, results); + } + async update(uri, predicates, value, callback) { console.info('[ttt] [DataShareTest] [update] enter'); if (predicates == null || predicates == undefined) { diff --git a/data_share/test/native/unittest/datashareproxy_test/proxydatas_with_permission_test.cpp b/data_share/test/native/unittest/datashareproxy_test/proxydatas_with_permission_test.cpp index adabe3e6..4ef42d23 100644 --- a/data_share/test/native/unittest/datashareproxy_test/proxydatas_with_permission_test.cpp +++ b/data_share/test/native/unittest/datashareproxy_test/proxydatas_with_permission_test.cpp @@ -141,11 +141,9 @@ HWTEST_F(ProxyDatasTest, ProxyDatasTest_ResultSet_Test_001, TestSize.Level0) resultSet->GetRowCount(result); EXPECT_EQ(result, 1); - AppDataFwk::SharedBlock *block = nullptr; bool hasBlock = resultSet->HasBlock(); EXPECT_EQ(hasBlock, true); - block = resultSet->GetBlock(); - EXPECT_NE(block, nullptr); + EXPECT_NE(resultSet->GetBlock(), nullptr); std::vector blob; int err = resultSet->GetBlob(-1, blob); diff --git a/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp b/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp index 2b466b0a..2eb0d012 100644 --- a/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp +++ b/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp @@ -899,13 +899,12 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ResultSet_Test_003, TestSize.Lev bool hasBlock = resultSet->HasBlock(); EXPECT_EQ(hasBlock, true); - block = resultSet->GetBlock(); - EXPECT_NE(block, nullptr); - + EXPECT_NE(resultSet->GetBlock(), nullptr); + block = (resultSet->GetBlock()).get(); resultSet->SetBlock(block); - EXPECT_EQ(block, resultSet->GetBlock()); + EXPECT_EQ(block, (resultSet->GetBlock()).get()); resultSet->FillBlock(0, block); - EXPECT_EQ(block, resultSet->GetBlock()); + EXPECT_EQ(block, (resultSet->GetBlock()).get()); LOG_INFO("MediaDataShare_ResultSet_Test_003, End"); } @@ -1073,7 +1072,44 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_CRUD_Test_001, TestSize.Level0) LOG_INFO("MediaDataShare_CRUD_Test_001, End"); } -HWTEST_F(MediaDataShareUnitTest, MediaDataShare_NotImplPredicates_Test_zyp, TestSize.Level0) +HWTEST_F(MediaDataShareUnitTest, MediaDataShare_CRUDEX_Test_001, TestSize.Level0) +{ + LOG_INFO("MediaDataShare_CRUDEX_Test_001::Start"); + std::shared_ptr helper = g_dataShareHelper; + ASSERT_TRUE(helper != nullptr); + Uri uri(MEDIALIBRARY_DATA_URI); + DataShare::DataShareValuesBucket valuesBucket; + valuesBucket.Put("name", "Datashare_CRUDEX_Test001"); + auto [errCode, retVal] = helper->InsertEx(uri, valuesBucket); + EXPECT_EQ((errCode == 0), true); + EXPECT_EQ((retVal >= 0), true); + DataShare::DataSharePredicates predicates; + predicates.EqualTo("name", "Datashare_CRUDEX_Test001"); + + valuesBucket.Clear(); + valuesBucket.Put("name", "Datashare_CRUDEX_Test002"); + auto [errCode1, retVal1] = helper->UpdateEx(uri, predicates, valuesBucket); + EXPECT_EQ((errCode1 == 0), true); + EXPECT_EQ((retVal1 >= 0), true); + DataShare::DataSharePredicates queryPredicates; + queryPredicates.EqualTo("name", "Datashare_CRUDEX_Test002"); + vector columns; + auto resultSet = helper->Query(uri, queryPredicates, columns); + int result = 0; + if (resultSet != nullptr) { + resultSet->GetRowCount(result); + } + EXPECT_EQ(result, 1); + + DataShare::DataSharePredicates deletePredicates; + deletePredicates.EqualTo("name", "Datashare_CRUDEX_Test002'"); + auto [errCode2, retVal2] = helper->DeleteEx(uri, deletePredicates); + EXPECT_EQ((errCode2 == 0), true); + EXPECT_EQ((retVal2 >= 0), true); + LOG_INFO("MediaDataShare_CRUDEX_Test_001, End"); +} + +HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ImplPredicates_Test_001, TestSize.Level0) { LOG_INFO("MediaDataShare_ImplPredicates_Test_001::Start"); DataShare::DataSharePredicates predicates; @@ -1574,5 +1610,68 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_UnregisterObserverExt_002, TestS dataObserver->Clear(); LOG_INFO("MediaDataShare_UnregisterObserverExt_002 end"); } + +HWTEST_F(MediaDataShareUnitTest, MediaDataShare_BatchUpdate_Test_001, TestSize.Level0) +{ + LOG_INFO("MediaDataShare_BatchUpdate_Test_001::Start"); + std::shared_ptr helper = g_dataShareHelper; + ASSERT_TRUE(helper != nullptr); + Uri uri(MEDIALIBRARY_DATA_URI); + DataShare::DataShareValuesBucket valuesBucket; + valuesBucket.Put("name", "batchUpdateTest"); + int ret = helper->Insert(uri, valuesBucket); + EXPECT_GT(ret, 0); + + DataShare::UpdateOperations operations; + std::vector updateOperations1; + DataShare::UpdateOperation updateOperation1; + updateOperation1.valuesBucket.Put("name", "batchUpdateTested"); + updateOperation1.predicates.EqualTo("name", "batchUpdateTest"); + updateOperations1.push_back(updateOperation1); + + std::vector updateOperations2; + DataShare::UpdateOperation updateOperation2; + updateOperation2.valuesBucket.Put("name", "undefined1"); + updateOperation2.predicates.EqualTo("name", "undefined"); + updateOperations1.push_back(updateOperation2); + updateOperations2.push_back(updateOperation2); + + operations.emplace("uri1", updateOperations1); + operations.emplace("uri2", updateOperations2); + std::vector results; + ret = helper->BatchUpdate(operations, results); + EXPECT_EQ(results.size(), 2); + EXPECT_EQ(results[0].codes[0], 1); + EXPECT_EQ(results[0].codes[1], 0); + EXPECT_EQ(results[1].codes[0], 0); + DataShare::DataSharePredicates predicates3; + predicates3.EqualTo("name", "batchUpdateTested"); + ret = helper->Delete(uri, predicates3); + EXPECT_GT(ret, 0); + LOG_INFO("MediaDataShare_BatchUpdate_Test_001 End"); +} + +HWTEST_F(MediaDataShareUnitTest, MediaDataShare_BatchUpdateThanLimit_Test_001, TestSize.Level0) +{ + LOG_INFO("MediaDataShare_BatchUpdateThanLimit_Test_001::Start"); + std::shared_ptr helper = g_dataShareHelper; + ASSERT_TRUE(helper != nullptr); + Uri uri(MEDIALIBRARY_DATA_URI); + + DataShare::UpdateOperations operations; + std::vector updateOperations1; + DataShare::UpdateOperation updateOperation1; + updateOperation1.valuesBucket.Put("name", "batchUpdateTested"); + updateOperation1.predicates.EqualTo("name", "batchUpdateTest"); + for (int i = 0; i < 4001; i++) { + updateOperations1.push_back(updateOperation1); + } + operations.emplace("uri1", updateOperations1); + std::vector results; + int ret = helper->BatchUpdate(operations, results); + EXPECT_EQ(ret, -1); + EXPECT_EQ(results.size(), 0); + LOG_INFO("MediaDataShare_BatchUpdateThanLimit_Test_001 End"); +} } // namespace DataShare } // namespace OHOS \ No newline at end of file diff --git a/data_share/test/native/unittest/mediadatashare_test/src/slientaccess_test.cpp b/data_share/test/native/unittest/mediadatashare_test/src/slientaccess_test.cpp index a5ab5b7a..bc6a74f6 100644 --- a/data_share/test/native/unittest/mediadatashare_test/src/slientaccess_test.cpp +++ b/data_share/test/native/unittest/mediadatashare_test/src/slientaccess_test.cpp @@ -83,6 +83,7 @@ protected: std::string TBL_STU_NAME = "name"; std::string TBL_STU_AGE = "age"; std::string SLIENT_ACCESS_PERMISSION1_URI = "datashare:///com.acts.datasharetest/entry/DB00/permission1?Proxy=true"; + std::string SLIENT_ERROR_URI = "datashare:///com.acts.datashare/entry/DB00/TBL00?Proxy=true"; std::string SLIENT_PROXY_PERMISSION1_URI = "datashareproxy://com.acts.datasharetest/entry/DB00/permission1"; std::string SLIENT_ACCESS_PERMISSION2_URI = "datashare:///com.acts.datasharetest/entry/DB00/permission2?Proxy=true"; std::string SLIENT_PROXY_PERMISSION2_URI = "datashareproxy://com.acts.datasharetest/entry/DB00/permission2"; @@ -218,6 +219,126 @@ void SlientAccessTest::TearDownTestCase(void) void SlientAccessTest::SetUp(void) {} void SlientAccessTest::TearDown(void) {} +HWTEST_F(SlientAccessTest, SlientAccess_Creator_Errorcode_Test_001, TestSize.Level0) +{ + LOG_INFO("SlientAccess_Creator_Errorcode_Test_001::Start"); + std::string uriStr1(SLIENT_ACCESS_URI); + std::string uriStr2 (DATA_SHARE_URI); + auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (saManager == nullptr) { + LOG_ERROR("GetSystemAbilityManager get samgr failed."); + } + auto remoteObj = saManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID); + if (remoteObj == nullptr) { + LOG_ERROR("GetSystemAbility service failed."); + } + auto [ret, helper] = DataShare::DataShareHelper::Create(remoteObj, uriStr1, uriStr2); + EXPECT_EQ(ret, DataShare::E_OK); + EXPECT_NE(helper, nullptr); + helper = nullptr; + LOG_INFO("SlientAccess_Creator_Errorcode_Test_001::End"); +} + +HWTEST_F(SlientAccessTest, SlientAccess_Creator_Errorcode_Test_002, TestSize.Level0) +{ + LOG_INFO("SlientAccess_Creator_Errorcode_Test_002::Start"); + std::string uriStr1(SLIENT_ACCESS_URI); + std::string uriStr2 (DATA_SHARE_URI); + auto [ret, helper] = DataShare::DataShareHelper::Create(nullptr, uriStr1, uriStr2); + EXPECT_EQ(ret, DataShare::E_TOKEN_EMPTY); + EXPECT_EQ(helper, nullptr); + LOG_INFO("SlientAccess_Creator_Errorcode_Test_002::End"); +} + +HWTEST_F(SlientAccessTest, SlientAccess_Creator_Errorcode_Test_003, TestSize.Level0) +{ + LOG_INFO("SlientAccess_Creator_Errorcode_Test_003::Start"); + std::string uriStr1(SLIENT_ERROR_URI); + std::string uriStr2 (DATA_SHARE_URI); + auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (saManager == nullptr) { + LOG_ERROR("GetSystemAbilityManager get samgr failed."); + } + auto remoteObj = saManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID); + if (remoteObj == nullptr) { + LOG_ERROR("GetSystemAbility service failed."); + } + auto [ret, helper] = DataShare::DataShareHelper::Create(remoteObj, uriStr1, uriStr2); + EXPECT_EQ(ret, DataShare::E_BUNDLE_NAME_NOT_EXIST); + EXPECT_EQ(helper, nullptr); + helper = nullptr; + LOG_INFO("SlientAccess_Creator_Errorcode_Test_003::End"); +} + +HWTEST_F(SlientAccessTest, SlientAccess_Creator_Errorcode_Test_004, TestSize.Level0) +{ + LOG_INFO("SlientAccess_Creator_Errorcode_Test_004::Start"); + std::string uriStr1(DATA_SHARE_URI); + std::string uriStr2 (DATA_SHARE_URI); + auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (saManager == nullptr) { + LOG_ERROR("GetSystemAbilityManager get samgr failed."); + } + auto remoteObj = saManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID); + if (remoteObj == nullptr) { + LOG_ERROR("GetSystemAbility service failed."); + } + auto [ret, helper] = DataShare::DataShareHelper::Create(remoteObj, uriStr1, uriStr2); + EXPECT_EQ(ret, DataShare::E_OK); + EXPECT_NE(helper, nullptr); + helper = nullptr; + LOG_INFO("SlientAccess_Creator_Errorcode_Test_004::End"); +} + +HWTEST_F(SlientAccessTest, SlientAccess_InsertEx_Test_001, TestSize.Level0) +{ + LOG_INFO("SlientAccess_InsertEx_Test_001::Start"); + auto helper = g_slientAccessHelper; + Uri uri(SLIENT_ACCESS_URI); + DataShare::DataShareValuesBucket valuesBucket; + std::string value = "lisi"; + valuesBucket.Put(TBL_STU_NAME, value); + int age = 25; + valuesBucket.Put(TBL_STU_AGE, age); + + auto [errCode, retVal] = helper->InsertEx(uri, valuesBucket); + EXPECT_EQ((errCode == 0), true); + EXPECT_EQ((retVal > 0), true); + LOG_INFO("SlientAccess_InsertEx_Test_001::End"); +} + +HWTEST_F(SlientAccessTest, SlientAccess_UpdateEx_Test_001, TestSize.Level0) +{ + LOG_INFO("SlientAccess_UpdateEx_Test_001::Start"); + auto helper = g_slientAccessHelper; + Uri uri(SLIENT_ACCESS_URI); + DataShare::DataShareValuesBucket valuesBucket; + int value = 50; + valuesBucket.Put(TBL_STU_AGE, value); + DataShare::DataSharePredicates predicates; + std::string selections = TBL_STU_NAME + " = 'lisi'"; + predicates.SetWhereClause(selections); + auto [errCode, retVal] = helper->UpdateEx(uri, predicates, valuesBucket); + EXPECT_EQ((errCode == 0), true); + EXPECT_EQ((retVal > 0), true); + LOG_INFO("SlientAccess_UpdateEx_Test_001::End"); +} + +HWTEST_F(SlientAccessTest, SlientAccess_DeleteEx_Test_001, TestSize.Level0) +{ + LOG_INFO("SlientAccess_DeleteEx_Test_001::Start"); + auto helper = g_slientAccessHelper; + Uri uri(SLIENT_ACCESS_URI); + + DataShare::DataSharePredicates deletePredicates; + std::string selections = TBL_STU_NAME + " = 'lisi'"; + deletePredicates.SetWhereClause(selections); + auto [errCode, retVal] = helper->DeleteEx(uri, deletePredicates); + EXPECT_EQ((errCode == 0), true); + EXPECT_EQ((retVal > 0), true); + LOG_INFO("SlientAccess_DeleteEx_Test_001::End"); +} + HWTEST_F(SlientAccessTest, SlientAccess_Insert_Test_001, TestSize.Level0) { LOG_INFO("SlientAccess_Insert_Test_001::Start"); diff --git a/datamgr_service/bundle.json b/datamgr_service/bundle.json index c4a0ef43..3d202f77 100644 --- a/datamgr_service/bundle.json +++ b/datamgr_service/bundle.json @@ -80,6 +80,7 @@ "resource_management", "safwk", "samgr", + "screenlock_mgr", "time_service", "udmf", "app_file_service", @@ -107,6 +108,7 @@ "name": "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:distributeddatasvcfwk", "header": { "header_files": [ + "account/account_delegate.h", "backuprule/backup_rule_manager.h", "checker/checker_manager.h", "cloud/asset_loader.h", @@ -135,6 +137,7 @@ "metadata/store_meta_data_local.h", "metadata/strategy_meta_data.h", "metadata/user_meta_data.h", + "screen/screen_manager.h", "serializable/serializable.h", "snapshot/bind_event.h", "snapshot/machine_status.h", diff --git a/datamgr_service/services/distributeddataservice/adapter/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/BUILD.gn index ae76a3ce..15f7c5f8 100644 --- a/datamgr_service/services/distributeddataservice/adapter/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/BUILD.gn @@ -54,13 +54,18 @@ ohos_shared_library("distributeddata_adapter") { configs = [ ":distributeddata_adapter_private_config" ] deps = [ + "${data_service_path}/adapter/account:distributeddata_account_static", + "${data_service_path}/adapter/communicator:distributeddata_communicator_static", + "${data_service_path}/adapter/dfx:distributeddata_dfx_static", + "${data_service_path}/adapter/permission:distributeddata_permission_static", "${data_service_path}/framework:distributeddatasvcfwk", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/account:distributeddata_account_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/communicator:distributeddata_communicator_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/dfx:distributeddata_dfx_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/permission:distributeddata_permission_static", ] + if (defined(global_parts_info) && + defined(global_parts_info.theme_screenlock_mgr)) { + deps += [ "${data_service_path}/adapter/screenlock:distributeddata_screenlock_static" ] + } + external_deps = [ "c_utils:utils", "hilog:libhilog", diff --git a/datamgr_service/services/distributeddataservice/adapter/CMakeLists.txt b/datamgr_service/services/distributeddataservice/adapter/CMakeLists.txt index 3f76667f..3b7c83fd 100644 --- a/datamgr_service/services/distributeddataservice/adapter/CMakeLists.txt +++ b/datamgr_service/services/distributeddataservice/adapter/CMakeLists.txt @@ -19,6 +19,7 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/dfx/src/fault adapterSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/dfx/src/statistic adapterSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/dfx/src adapterSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/permission/src adapterSrc) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/screenlock/src adapterSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/utils/src adapterSrc) list(REMOVE_ITEM adapterSrc "${CMAKE_CURRENT_SOURCE_DIR}/account/src/account_delegate_default_impl.cpp") @@ -50,4 +51,5 @@ target_include_directories(adapter PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/br target_include_directories(adapter PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/communicator) target_include_directories(adapter PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/dfx) target_include_directories(adapter PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/permission) +target_include_directories(adapter PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/screenlock) target_include_directories(adapter PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/utils) diff --git a/datamgr_service/services/distributeddataservice/adapter/account/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/account/BUILD.gn index 95465797..2bc40d6e 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/account/BUILD.gn @@ -22,13 +22,10 @@ ohos_static_library("distributeddata_account_static") { boundary_sanitize = true ubsan = true } - sources = [ - "src/account_delegate.cpp", - "src/account_delegate_impl.cpp", - ] + sources = [ "src/account_delegate_impl.cpp" ] include_dirs = [ - "../include/account", + "../../framework/include/account", "../include/autils", "../include/log", "../include/permission", diff --git a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp index 7cf33587..444d7b29 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp @@ -22,13 +22,7 @@ namespace DistributedKv { namespace { constexpr const char *DEFAULT_OHOS_ACCOUNT_UID = ""; // default UID } - -AccountDelegate::BaseInstance AccountDelegate::getInstance_ = AccountDelegateDefaultImpl::GetBaseInstance; -AccountDelegate *AccountDelegateDefaultImpl::GetBaseInstance() -{ - static AccountDelegateDefaultImpl accountDelegate; - return &accountDelegate; -} +__attribute__((used)) static bool g_isInit = AccountDelegateDefaultImpl::Init(); std::string AccountDelegateDefaultImpl::GetCurrentAccountId() const { @@ -87,5 +81,13 @@ void AccountDelegateDefaultImpl::BindExecutor(std::shared_ptr exec { ZLOGD("no account part"); } -} // namespace DistributedKv + +bool AccountDelegateDefaultImpl::Init() +{ + static AccountDelegateDefaultImpl defaultAccountDelegate; + static std::once_flag onceFlag; + std::call_once(onceFlag, [&]() { AccountDelegate::RegisterAccountInstance(&defaultAccountDelegate); }); + return true; +} +} // namespace DistributedKv } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h index 74298cb5..04ebda1d 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h +++ b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h @@ -21,7 +21,6 @@ namespace OHOS { namespace DistributedKv { class AccountDelegateDefaultImpl final : public AccountDelegateImpl { public: - static AccountDelegate *GetBaseInstance(); std::string GetCurrentAccountId() const override; int32_t GetUserByToken(uint32_t tokenId) const override; bool QueryUsers(std::vector &users) override; @@ -31,6 +30,7 @@ public: void SubscribeAccountEvent() override; void UnsubscribeAccountEvent() override; void BindExecutor(std::shared_ptr executors) override; + static bool Init(); private: ~AccountDelegateDefaultImpl(); diff --git a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp index edc5a7a9..e59d08a2 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp @@ -17,7 +17,6 @@ #include "account_delegate_normal_impl.h" #include #include -#include #include #include #include @@ -32,12 +31,7 @@ using namespace OHOS::EventFwk; using namespace OHOS::AAFwk; using namespace OHOS::DistributedData; using namespace Security::AccessToken; -AccountDelegate::BaseInstance AccountDelegate::getInstance_ = AccountDelegateNormalImpl::GetBaseInstance; -AccountDelegate *AccountDelegateNormalImpl::GetBaseInstance() -{ - static AccountDelegateNormalImpl accountDelegate; - return &accountDelegate; -} +__attribute__((used)) static bool g_isInit = AccountDelegateNormalImpl::Init(); std::string AccountDelegateNormalImpl::GetCurrentAccountId() const { @@ -216,7 +210,20 @@ std::string AccountDelegateNormalImpl::GetUnencryptedAccountId(int32_t userId) c bool AccountDelegateNormalImpl::QueryForegroundUserId(int &foregroundUserId) { - return AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(foregroundUserId); + int32_t status = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(foregroundUserId); + if (status != ERR_OK) { + ZLOGE("GetForegroundOsAccountLocalId failed, status: %{public}d", status); + return false; + } + return true; +} + +bool AccountDelegateNormalImpl::Init() +{ + static AccountDelegateNormalImpl normalAccountDelegate; + static std::once_flag onceFlag; + std::call_once(onceFlag, [&]() { AccountDelegate::RegisterAccountInstance(&normalAccountDelegate); }); + return true; } -} // namespace DistributedKv +} // namespace DistributedKv } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h index 758e25d4..63c86d66 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h +++ b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h @@ -26,7 +26,6 @@ namespace OHOS { namespace DistributedKv { class AccountDelegateNormalImpl final : public AccountDelegateImpl { public: - static AccountDelegate *GetBaseInstance(); std::string GetCurrentAccountId() const override; int32_t GetUserByToken(uint32_t tokenId) const override; bool QueryUsers(std::vector &users) override; @@ -38,6 +37,7 @@ public: void BindExecutor(std::shared_ptr executors) override; std::string GetUnencryptedAccountId(int32_t userId = 0) const override; bool QueryForegroundUserId(int &foregroundUserId) override; + static bool Init(); private: ~AccountDelegateNormalImpl(); diff --git a/datamgr_service/services/distributeddataservice/adapter/account/test/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/account/test/BUILD.gn index 1fb62f2e..3b3df7fe 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/account/test/BUILD.gn @@ -18,10 +18,13 @@ module_output_path = "datamgr_service/distributeddatafwk" ohos_unittest("AccountDelegateTest") { module_out_path = module_output_path - sources = [ "account_delegate_test.cpp" ] + sources = [ + "${data_service_path}/framework/account/account_delegate.cpp", + "account_delegate_test.cpp", + ] include_dirs = [ "//commonlibrary/c_utils/base/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include/account", + "${data_service_path}/framework/include/account", "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include/autils", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include/utils", @@ -51,6 +54,13 @@ ohos_unittest("AccountDelegateTest") { "os_account:libaccountkits", "os_account:os_account_innerkits", ] + if (os_account_part_is_enabled) { + sources += [ "${data_service_path}/adapter/account/src/account_delegate_normal_impl.cpp" ] + cflags_cc = [ "-DOS_ACCOUNT_PART_IS_ENABLED" ] + external_deps += [ "access_token:libaccesstoken_sdk" ] + } else { + sources += [ "${data_service_path}/adapter/account/src/account_delegate_default_impl.cpp" ] + } defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp index 1f9db263..cd9f85c7 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp @@ -747,4 +747,14 @@ std::string DeviceManagerAdapter::GetEncryptedUuidByNetworkId(const std::string } return encryptedUuid; } + +bool DeviceManagerAdapter::IsSameAccount(const std::string &id) +{ + if (id.empty()) { + ZLOGE("params id is empty"); + return false; + } + auto networkId = DeviceManagerAdapter::GetInstance().ToNetworkID(id); + return DeviceManager::GetInstance().IsSameAccount(networkId); +} } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h index 3d163898..c1d5ffea 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h @@ -91,6 +91,10 @@ private: std::string DelConnect(int32_t socket); void StartCloseSessionTask(const std::string &deviceId); Task GetCloseSessionTask(); + bool CloseSession(const std::string &networkId); + void Reuse(const PipeInfo &pipeInfo, const DeviceId &deviceId, + uint32_t qosType, std::shared_ptr &conn); + void GetExpireTime(std::shared_ptr &conn); static constexpr const char *PKG_NAME = "distributeddata-default"; static constexpr Time INVALID_NEXT = std::chrono::steady_clock::time_point::max(); static constexpr uint32_t QOS_COUNT = 3; diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp index e5237c4a..0827053d 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter_standard.cpp @@ -17,6 +17,7 @@ #include #include "communicator_context.h" +#include "communication/connect_manager.h" #include "data_level.h" #include "device_manager_adapter.h" #include "dfx_types.h" @@ -108,6 +109,15 @@ SoftBusAdapter::SoftBusAdapter() Context::GetInstance().SetSessionListener([this](const std::string &deviceId) { StartCloseSessionTask(deviceId); }); + + ConnectManager::GetInstance()->RegisterCloseSessionTask([this](const std::string &networkId) { + return CloseSession(networkId); + }); + ConnectManager::GetInstance()->RegisterSessionCloseListener("context", [](const std::string &networkId) { + auto uuid = DmAdapter::GetInstance().GetUuidByNetworkId(networkId); + Context::GetInstance().NotifySessionClose(uuid); + }); + ConnectManager::GetInstance()->OnStart(); } SoftBusAdapter::~SoftBusAdapter() @@ -117,6 +127,7 @@ SoftBusAdapter::~SoftBusAdapter() UnregDataLevelChangeCb(PKG_NAME); } connects_.Clear(); + ConnectManager::GetInstance()->OnDestory(); } std::shared_ptr SoftBusAdapter::GetInstance() @@ -155,38 +166,77 @@ Status SoftBusAdapter::StopWatchDataChange(__attribute__((unused)) const AppData return Status::ERROR; } +void SoftBusAdapter::Reuse(const PipeInfo &pipeInfo, const DeviceId &deviceId, + uint32_t qosType, std::shared_ptr &conn) +{ + std::vector> connects; + auto connect = std::make_shared(pipeInfo, deviceId, qosType); + connect->isReuse = true; + connects.emplace_back(connect); + conn = connect; + connects_.Insert(deviceId.deviceId, connects); + ZLOGI("reuse connect:%{public}s", KvStoreUtils::ToBeAnonymous(deviceId.deviceId).c_str()); +} + +void SoftBusAdapter::GetExpireTime(std::shared_ptr &conn) +{ + Time now = std::chrono::steady_clock::now(); + auto expireTime = conn->GetExpireTime() > now ? conn->GetExpireTime() : now; + lock_guard lock(taskMutex_); + if (taskId_ != ExecutorPool::INVALID_TASK_ID && expireTime < next_) { + taskId_ = Context::GetInstance().GetThreadPool()->Reset(taskId_, expireTime - now); + next_ = expireTime; + } +} + Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, uint32_t length, const MessageInfo &info) { std::shared_ptr conn; - bool isReady = DmAdapter::GetInstance().IsDeviceReady(deviceId.deviceId); - uint32_t qosType = isReady ? SoftBusClient::QOS_HML : SoftBusClient::QOS_BR; + bool isOHOSType = DmAdapter::GetInstance().IsOHOSType(deviceId.deviceId); + uint32_t qosType = isOHOSType ? SoftBusClient::QOS_HML : SoftBusClient::QOS_BR; + bool isReuse = false; connects_.Compute(deviceId.deviceId, - [&pipeInfo, &deviceId, &conn, qosType](const auto &key, + [&pipeInfo, &deviceId, &conn, qosType, isOHOSType, &isReuse](const auto &key, std::vector> &connects) -> bool { for (auto &connect : connects) { - if (connect->GetQoSType() == qosType) { - conn = connect; - return true; + if (connect->GetQoSType() != qosType) { + continue; + } + if (!isOHOSType && connect->needRemove) { + isReuse = true; + return false; } + conn = connect; + return true; } auto connect = std::make_shared(pipeInfo, deviceId, qosType); connects.emplace_back(connect); conn = connect; return true; }); + if (!isOHOSType && isReuse) { + Reuse(pipeInfo, deviceId, qosType, conn); + } if (conn == nullptr) { return Status::ERROR; } - auto status = conn->SendData(dataInfo, &clientListener_); + auto status = conn->CheckStatus(); + if (status == Status::RATE_LIMIT) { + return Status::RATE_LIMIT; + } + if (status != Status::SUCCESS) { + auto task = [this, conn]() { + conn->OpenConnect(&clientListener_); + }; + auto networkId = DmAdapter::GetInstance().GetDeviceInfo(deviceId.deviceId).networkId; + ConnectManager::GetInstance()->ApplyConnect(networkId, task); + return Status::RATE_LIMIT; + } + + status = conn->SendData(dataInfo, &clientListener_); if ((status != Status::NETWORK_ERROR) && (status != Status::RATE_LIMIT)) { - Time now = std::chrono::steady_clock::now(); - auto expireTime = conn->GetExpireTime() > now ? conn->GetExpireTime() : now; - lock_guard lock(taskMutex_); - if (taskId_ != ExecutorPool::INVALID_TASK_ID && expireTime < next_) { - taskId_ = Context::GetInstance().GetThreadPool()->Reset(taskId_, expireTime - now); - next_ = expireTime; - } + GetExpireTime(conn); } return status; } @@ -194,8 +244,8 @@ Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &device void SoftBusAdapter::StartCloseSessionTask(const std::string &deviceId) { std::shared_ptr conn; - bool isReady = DmAdapter::GetInstance().IsDeviceReady(deviceId); - uint32_t qosType = isReady ? SoftBusClient::QOS_HML : SoftBusClient::QOS_BR; + bool isOHOSType = DmAdapter::GetInstance().IsOHOSType(deviceId); + uint32_t qosType = isOHOSType ? SoftBusClient::QOS_HML : SoftBusClient::QOS_BR; auto connects = connects_.Find(deviceId); if (!connects.first) { return; @@ -243,7 +293,7 @@ SoftBusAdapter::Task SoftBusAdapter::GetCloseSessionTask() }); connects_.EraseIf([](const auto &key, const auto &conn) -> bool { if (conn.empty()) { - Context::GetInstance().NotifySessionClose(key); + ConnectManager::GetInstance()->OnSessionClose(DmAdapter::GetInstance().GetDeviceInfo(key).networkId); } return conn.empty(); }); @@ -316,7 +366,8 @@ uint32_t SoftBusAdapter::GetTimeout(const DeviceId &deviceId) std::string SoftBusAdapter::DelConnect(int32_t socket) { std::string name; - connects_.ForEach([socket, &name](const auto &deviceId, auto &connects) -> bool { + std::set closedConnect; + connects_.EraseIf([socket, &name, &closedConnect](const auto &deviceId, auto &connects) -> bool { for (auto iter = connects.begin(); iter != connects.end();) { if (*iter != nullptr && **iter == socket) { name += deviceId; @@ -326,8 +377,16 @@ std::string SoftBusAdapter::DelConnect(int32_t socket) iter++; } } + if (connects.empty()) { + closedConnect.insert(deviceId); + return true; + } return false; }); + for (const auto &deviceId : closedConnect) { + auto networkId = DmAdapter::GetInstance().GetDeviceInfo(deviceId).networkId; + ConnectManager::GetInstance()->OnSessionClose(networkId); + } return name; } @@ -506,6 +565,18 @@ void SoftBusAdapter::OnBind(int32_t socket, PeerSocketInfo info) socketInfo.networkId = info.networkId; socketInfo.pkgName = info.pkgName; peerSocketInfos_.Insert(socket, socketInfo); + if (!DmAdapter::GetInstance().IsOHOSType(info.networkId)) { + auto uuid = DmAdapter::GetInstance().ToUUID(info.networkId); + auto connects = connects_.Find(uuid); + if (!connects.first) { + return; + } + for (auto &conn : connects.second) { + if (!conn->isReuse) { + conn->needRemove = true; + } + } + } } void SoftBusAdapter::OnServerShutdown(int32_t socket) @@ -518,5 +589,15 @@ void SoftBusAdapter::OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, { return; } + +bool SoftBusAdapter::CloseSession(const std::string &networkId) +{ + auto uuid = DmAdapter::GetInstance().GetUuidByNetworkId(networkId); + auto ret = connects_.Erase(uuid); + if (ret != 0) { + ConnectManager::GetInstance()->OnSessionClose(networkId); + } + return ret != 0; +} } // namespace AppDistributedKv } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp index f46d4e0d..304b8cd2 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp @@ -17,6 +17,7 @@ #include "softbus_client.h" #include "communicator_context.h" +#include "communication/connect_manager.h" #include "device_manager_adapter.h" #include "inner_socket.h" #include "kvstore_utils.h" @@ -64,7 +65,7 @@ uint32_t SoftBusClient::GetTimeout() const Status SoftBusClient::SendData(const DataInfo &dataInfo, const ISocketListener *listener) { std::lock_guard lock(mutex_); - auto result = OpenConnect(listener); + auto result = CheckStatus(); if (result != Status::SUCCESS) { return result; } @@ -81,15 +82,14 @@ Status SoftBusClient::SendData(const DataInfo &dataInfo, const ISocketListener * Status SoftBusClient::OpenConnect(const ISocketListener *listener) { - if (bindState_ == 0) { - return Status ::SUCCESS; + std::lock_guard lock(mutex_); + auto status = CheckStatus(); + if (status == Status::SUCCESS || status == Status::RATE_LIMIT) { + return status; } if (isOpening_.exchange(true)) { return Status::RATE_LIMIT; } - if (bindState_ == 0) { - return Status ::SUCCESS; - } SocketInfo socketInfo; std::string peerName = pipe_.pipeId; socketInfo.peerName = const_cast(peerName.c_str()); @@ -122,6 +122,20 @@ Status SoftBusClient::OpenConnect(const ISocketListener *listener) return Status::RATE_LIMIT; } +Status SoftBusClient::CheckStatus() +{ + if (bindState_ == 0) { + return Status::SUCCESS; + } + if (isOpening_.load()) { + return Status::RATE_LIMIT; + } + if (bindState_ == 0) { + return Status::SUCCESS; + } + return Status::ERROR; +} + Status SoftBusClient::Open(int32_t socket, const QosTV qos[], const ISocketListener *listener) { int32_t status = ::Bind(socket, qos, QOS_COUNT, listener); @@ -149,6 +163,7 @@ Status SoftBusClient::Open(int32_t socket, const QosTV qos[], const ISocketListe } ZLOGI("open %{public}s, session:%{public}s success, socket:%{public}d", KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), socket_); + ConnectManager::GetInstance()->OnSessionOpen(DmAdapter::GetInstance().GetDeviceInfo(device_.deviceId).networkId); return Status::SUCCESS; } diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h index b20cf012..898a7ada 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h @@ -37,6 +37,8 @@ public: using Time = std::chrono::steady_clock::time_point; using Duration = std::chrono::steady_clock::duration; + Status CheckStatus(); + Status OpenConnect(const ISocketListener *listener); Status SendData(const DataInfo &dataInfo, const ISocketListener *listener); bool operator==(int32_t socket) const; bool operator==(const std::string &deviceId) const; @@ -46,9 +48,10 @@ public: int32_t GetSocket() const; uint32_t GetQoSType() const; void UpdateExpireTime(); + bool needRemove = false; + bool isReuse = false; private: - Status OpenConnect(const ISocketListener *listener); Status Open(int32_t socket, const QosTV qos[], const ISocketListener *listener); std::pair GetMtu(int32_t socket); Time CalcExpireTime() const; diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/BUILD.gn index a7c54aff..3ee6efe2 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/test/fuzztest/softbusadapter_fuzzer/BUILD.gn @@ -26,6 +26,7 @@ ohos_fuzztest("SoftBusAdapterFuzzTest") { "${data_service_path}/adapter/include/autils", "${data_service_path}/adapter/include/utils", "${data_service_path}/adapter/communicator/src", + "${data_service_path}/framework/include", "${dsoftbus_core_path}", "${kv_store_common_path}", "${kv_store_distributeddb_path}/interfaces/include", diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/softbus_adapter_standard_test.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/softbus_adapter_standard_test.cpp index d0c91821..9804ce14 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/softbus_adapter_standard_test.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/softbus_adapter_standard_test.cpp @@ -19,7 +19,6 @@ #include "gtest/gtest.h" #include #include "log_print.h" -#define private public #include "softbus_adapter.h" #include "types.h" #include diff --git a/datamgr_service/services/distributeddataservice/adapter/dfx/src/radar_reporter.cpp b/datamgr_service/services/distributeddataservice/adapter/dfx/src/radar_reporter.cpp index 56048427..0a22c8f6 100644 --- a/datamgr_service/services/distributeddataservice/adapter/dfx/src/radar_reporter.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/dfx/src/radar_reporter.cpp @@ -49,14 +49,14 @@ void RadarReporter::Report(const RadarParam ¶m, const char *funcName, int32_ BIZ_SCENE_LABEL, param.scene_, BIZ_STAGE_LABEL, param.stage_, BIZ_STATE_LABEL, state, STAGE_RES_LABEL, res, ERROR_CODE_LABEL, param.errCode_, HOST_PKG, param.bundleName_, LOCAL_UUID_LABEL, AnonymousUuid(DmAdapter::GetInstance().GetLocalDevice().uuid), CONCURRENT_ID, - std::to_string(param.syncId_)); + std::to_string(param.syncId_), TRIGGER_MODE, param.triggerMode_, WATER_VERSION, param.changeCount); } else { HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::DISTRIBUTED_DATAMGR, eventName, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, ORG_PKG_LABEL, ORG_PKG, FUNC_LABEL, funcName, BIZ_SCENE_LABEL, param.scene_, BIZ_STAGE_LABEL, param.stage_, STAGE_RES_LABEL, res, ERROR_CODE_LABEL, param.errCode_, HOST_PKG, param.bundleName_, LOCAL_UUID_LABEL, AnonymousUuid(DmAdapter::GetInstance().GetLocalDevice().uuid), CONCURRENT_ID, - std::to_string(param.syncId_)); + std::to_string(param.syncId_), TRIGGER_MODE, param.triggerMode_, WATER_VERSION, param.changeCount); } return; } diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h index f02d2891..7c99f1fb 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h @@ -77,6 +77,7 @@ public: bool IsNetworkAvailable(); NetworkType GetNetworkType(bool retrieve = false); int32_t GetAuthType(const std::string& id); + bool IsSameAccount(const std::string &id); friend class DataMgrDmStateCall; friend class NetConnCallbackObserver; diff --git a/datamgr_service/services/distributeddataservice/adapter/include/dfx/radar_reporter.h b/datamgr_service/services/distributeddataservice/adapter/include/dfx/radar_reporter.h index 72a6752b..7a60cc06 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/dfx/radar_reporter.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/dfx/radar_reporter.h @@ -70,6 +70,8 @@ struct RadarParam { int32_t scene_ = CLOUD_SYNC; int32_t stage_ = GENERAL_STAGE; uint64_t syncId_ = 0; + int32_t triggerMode_ = 0; + uint64_t changeCount = 0; int32_t errCode_ = 0; int32_t res_ = RES_SUCCESS; }; @@ -102,6 +104,8 @@ private: static constexpr const char *REPLACE_CHAIN = "**"; static constexpr const char *DEFAULT_ANONYMOUS = "************"; static constexpr const char *CONCURRENT_ID = "CONCURRENT_ID"; + static constexpr const char *TRIGGER_MODE = "TRIGGER_MODE"; + static constexpr const char *WATER_VERSION = "WATER_VERSION"; static constexpr const int32_t NO_ERROR = 0; static constexpr const int32_t HEAD_SIZE = 5; static constexpr const int32_t END_SIZE = 5; diff --git a/datamgr_service/services/distributeddataservice/adapter/include/screenlock/screen_lock.h b/datamgr_service/services/distributeddataservice/adapter/include/screenlock/screen_lock.h new file mode 100644 index 00000000..db40555e --- /dev/null +++ b/datamgr_service/services/distributeddataservice/adapter/include/screenlock/screen_lock.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 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 DISTRIBUTEDDATAMGR_ADAPTER_SCREEN_LOCK_H +#define DISTRIBUTEDDATAMGR_ADAPTER_SCREEN_LOCK_H + +#include "visibility.h" +#include "screen/screen_manager.h" + +namespace OHOS { +namespace DistributedData { +class ScreenLock : public ScreenManager { +public: + API_EXPORT bool IsLocked(); +}; +} // namespace DistributedData +} // namespace OHOS +#endif //DISTRIBUTEDDATAMGR_ADAPTER_SCREEN_LOCK_H diff --git a/datamgr_service/services/distributeddataservice/adapter/include/utils/visibility.h b/datamgr_service/services/distributeddataservice/adapter/include/utils/visibility.h new file mode 100644 index 00000000..a5aec548 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/adapter/include/utils/visibility.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 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_DATA_FRAMEWORKS_COMMON_VISIBILITY_H +#define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_VISIBILITY_H + +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility ("default"))) +#endif +#ifndef API_LOCAL +#define API_LOCAL __attribute__((visibility ("hidden"))) +#endif +#ifndef KVSTORE_API +#define KVSTORE_API API_EXPORT +#endif + +#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_VISIBILITY_H diff --git a/datamgr_service/services/distributeddataservice/adapter/screenlock/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/screenlock/BUILD.gn new file mode 100644 index 00000000..cb30d1da --- /dev/null +++ b/datamgr_service/services/distributeddataservice/adapter/screenlock/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2024 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("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +ohos_static_library("distributeddata_screenlock_static") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + boundary_sanitize = true + ubsan = true + } + sources = [ "src/screen_lock.cpp" ] + + cflags_cc = [ "-fvisibility=hidden" ] + + include_dirs = [ + "../include/screenlock", + "../include/utils", + "${data_service_path}/framework/include", + ] + + external_deps = [ + "c_utils:utils", + "screenlock_mgr:screenlock_client", + ] + subsystem_name = "distributeddatamgr" + part_name = "datamgr_service" + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] +} diff --git a/datamgr_service/services/distributeddataservice/adapter/screenlock/src/screen_lock.cpp b/datamgr_service/services/distributeddataservice/adapter/screenlock/src/screen_lock.cpp new file mode 100644 index 00000000..92e9118e --- /dev/null +++ b/datamgr_service/services/distributeddataservice/adapter/screenlock/src/screen_lock.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 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 "screen_lock.h" +#include "screenlock_manager.h" + +namespace OHOS::DistributedData { +using namespace OHOS::ScreenLock; +__attribute__((used)) static bool g_init = + ScreenManager::RegisterInstance(std::static_pointer_cast(std::make_shared())); +bool ScreenLock::IsLocked() +{ + auto manager = ScreenLockManager::GetInstance(); + if (manager == nullptr) { + return false; + } + return manager->IsScreenLocked(); +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/app/BUILD.gn b/datamgr_service/services/distributeddataservice/app/BUILD.gn index cc59341f..fd6efcbc 100644 --- a/datamgr_service/services/distributeddataservice/app/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/BUILD.gn @@ -58,6 +58,7 @@ config("module_private_config") { "${data_service_path}/service/permission/include", "${data_service_path}/service/matrix/include", "${data_service_path}/service/backup/include", + "${data_service_path}/service/app_id_mapping/include", "${data_service_path}/service/kvdb", "${data_service_path}/service/waterversion", "${data_service_path}/service/dumper/include", diff --git a/datamgr_service/services/distributeddataservice/app/distributed_data.cfg b/datamgr_service/services/distributeddataservice/app/distributed_data.cfg index a9e48f7b..b4b210b2 100644 --- a/datamgr_service/services/distributeddataservice/app/distributed_data.cfg +++ b/datamgr_service/services/distributeddataservice/app/distributed_data.cfg @@ -17,7 +17,7 @@ "name" : "distributeddata", "path" : ["/system/bin/sa_main","/system/profile/distributeddata.json"], "uid" : "ddms", - "gid" : ["system","shell","readproc","ddms","dfs_share","netsys_socket"], + "gid" : ["system","shell","readproc","ddms","dfs_share","netsys_socket","data_reserve"], "writepid":[ "/dev/cpuset/foreground/tasks", "/dev/stune/foreground/tasks", @@ -38,7 +38,6 @@ "ohos.permission.PUBLISH_SYSTEM_COMMON_EVENT", "ohos.permission.GET_BUNDLE_INFO", "ohos.permission.GET_NETWORK_INFO", - "ohos.permission.INTERNET", "ohos.permission.DISTRIBUTED_SOFTBUS_CENTER", "ohos.permission.MONITOR_DEVICE_NETWORK_STATE", "ohos.permission.USE_CLOUD_DRIVE_SERVICE", diff --git a/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.cpp b/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.cpp index 0ec512f6..62832996 100644 --- a/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.cpp @@ -60,10 +60,6 @@ void InstallEventSubscriber::OnReceiveEvent(const CommonEventData &event) int32_t appIndex = want.GetIntParam(SANDBOX_APP_INDEX, 0); ZLOGI("bundleName:%{public}s, user:%{public}d, appIndex:%{public}d", bundleName.c_str(), userId, appIndex); (this->*(it->second))(bundleName, userId, appIndex); - } else if (action == CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED) { - int32_t userId = want.GetIntParam(USER_ID, -1); - ZLOGI("user:%{public}d ScreenUnlocked", userId); - OnScreenUnlocked(userId); } } @@ -119,11 +115,6 @@ void InstallEventSubscriber::OnInstall(const std::string &bundleName, int32_t us kvStoreDataService_->OnInstall(bundleName, userId, appIndex); } -void InstallEventSubscriber::OnScreenUnlocked(int32_t userId) -{ - kvStoreDataService_->OnScreenUnlocked(userId); -} - InstallerImpl::~InstallerImpl() { ZLOGD("destruct"); @@ -153,7 +144,6 @@ Status InstallerImpl::Init(KvStoreDataService *kvStoreDataService, std::shared_p matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED); matchingSkills.AddEvent(OHOS::AppExecFwk::COMMON_EVENT_SANDBOX_PACKAGE_ADDED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED); CommonEventSubscribeInfo info(matchingSkills); auto subscriber = std::make_shared(info, kvStoreDataService); diff --git a/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.h b/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.h index aabcd933..683ae729 100644 --- a/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.h +++ b/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.h @@ -36,7 +36,6 @@ private: void OnUninstall(const std::string &bundleName, int32_t userId, int32_t appIndex); void OnUpdate(const std::string &bundleName, int32_t userId, int32_t appIndex); void OnInstall(const std::string &bundleName, int32_t userId, int32_t appIndex); - void OnScreenUnlocked(int32_t userId); std::map callbacks_; KvStoreDataService *kvStoreDataService_; }; diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp index 94d55d6c..ecc50daa 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -23,7 +23,6 @@ #include "accesstoken_kit.h" #include "auth_delegate.h" #include "auto_launch_export.h" -#include "auto_sync_matrix.h" #include "bootstrap.h" #include "checker/checker_manager.h" #include "communication_provider.h" @@ -63,6 +62,7 @@ #include "utils/block_integer.h" #include "utils/crypto.h" #include "water_version_manager.h" +#include "app_id_mapping/app_id_mapping_config_manager.h" namespace OHOS::DistributedKv { using namespace std::chrono; @@ -76,6 +76,8 @@ using DBConfig = DistributedDB::RuntimeConfig; REGISTER_SYSTEM_ABILITY_BY_ID(KvStoreDataService, DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID, true); +constexpr char FOUNDATION_PROCESS_NAME[] = "foundation"; + KvStoreDataService::KvStoreDataService(bool runOnCreate) : SystemAbility(runOnCreate), clients_() { @@ -200,26 +202,14 @@ Status KvStoreDataService::RegisterClientDeathObserver(const AppId &appId, sptr< ZLOGW("check bundleName:%{public}s uid:%{public}d failed.", appId.appId.c_str(), info.uid); return Status::PERMISSION_DENIED; } - KvStoreClientDeathObserverImpl kvStoreClientDeathObserver(*this); - auto inserted = clients_.Emplace( - [&info, &appId, &kvStoreClientDeathObserver](decltype(clients_)::map_type &entries) { - auto it = entries.find(info.tokenId); - if (it == entries.end()) { - return true; - } - if (IPCSkeleton::GetCallingPid() == it->second.GetPid()) { - ZLOGW("bundleName:%{public}s, uid:%{public}d, pid:%{public}d has already registered.", - appId.appId.c_str(), info.uid, IPCSkeleton::GetCallingPid()); - return false; - } - kvStoreClientDeathObserver = std::move(it->second); - entries.erase(it); - return true; - }, - std::piecewise_construct, std::forward_as_tuple(info.tokenId), - std::forward_as_tuple(appId, *this, std::move(observer))); - ZLOGI("bundleName:%{public}s, uid:%{public}d, pid:%{public}d, inserted:%{public}s.", appId.appId.c_str(), info.uid, - IPCSkeleton::GetCallingPid(), inserted ? "success" : "failed"); + auto pid = IPCSkeleton::GetCallingPid(); + clients_.Compute( + info.tokenId, [&appId, &info, pid, this, obs = std::move(observer)](const auto tokenId, auto &clients) { + auto res = clients.try_emplace(pid, appId, *this, std::move(obs)); + ZLOGI("bundleName:%{public}s, uid:%{public}d, pid:%{public}d, inserted:%{public}s.", appId.appId.c_str(), + info.uid, pid, res.second ? "success" : "failed"); + return !clients.empty(); + }); return Status::SUCCESS; } @@ -230,9 +220,14 @@ Status KvStoreDataService::AppExit(pid_t uid, pid_t pid, uint32_t token, const A // clientDeathObserverMap_ erase, so we have to take a copy if we want to use this parameter after erase operation. AppId appIdTmp = appId; KvStoreClientDeathObserverImpl impl(*this); - clients_.ComputeIfPresent(token, [&impl](auto &, auto &value) { - impl = std::move(value); - return false; + clients_.ComputeIfPresent(token, [&impl, pid](auto &, auto &value) { + auto it = value.find(pid); + if (it == value.end()) { + return !value.empty(); + } + impl = std::move(it->second); + value.erase(it); + return !value.empty(); }); return Status::SUCCESS; } @@ -281,12 +276,7 @@ void KvStoreDataService::OnStart() ZLOGW("GetLocalDeviceId failed, retry count:%{public}d", static_cast(retry)); } ZLOGI("Bootstrap configs and plugins."); - Bootstrap::GetInstance().LoadComponents(); - Bootstrap::GetInstance().LoadDirectory(); - Bootstrap::GetInstance().LoadCheckers(); - Bootstrap::GetInstance().LoadNetworks(); - Bootstrap::GetInstance().LoadBackup(executors_); - Bootstrap::GetInstance().LoadCloud(); + LoadConfigs(); Initialize(); auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (samgr != nullptr) { @@ -315,6 +305,17 @@ void KvStoreDataService::OnStart() StartService(); } +void KvStoreDataService::LoadConfigs() +{ + Bootstrap::GetInstance().LoadComponents(); + Bootstrap::GetInstance().LoadDirectory(); + Bootstrap::GetInstance().LoadCheckers(); + Bootstrap::GetInstance().LoadNetworks(); + Bootstrap::GetInstance().LoadBackup(executors_); + Bootstrap::GetInstance().LoadCloud(); + Bootstrap::GetInstance().LoadAppIdMappings(); +} + void KvStoreDataService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) { ZLOGI("add system abilityid:%{public}d", systemAbilityId); @@ -346,7 +347,6 @@ void KvStoreDataService::StartService() ZLOGI("begin."); KvStoreMetaManager::GetInstance().InitMetaListener(); DeviceMatrix::GetInstance().Initialize(IPCSkeleton::GetCallingTokenID(), Bootstrap::GetInstance().GetMetaDBName()); - AutoSyncMatrix::GetInstance().Initialize(); WaterVersionManager::GetInstance().Init(); LoadFeatures(); bool ret = SystemAbility::Publish(this); @@ -396,6 +396,25 @@ void KvStoreDataService::OnStoreMetaChanged( ZLOGI("dirty kv store. storeId:%{public}s", Anonymous::Change(metaData.storeId).c_str()); } +bool KvStoreDataService::CompareTripleIdentifier(const std::string &accountId, const std::string &identifier, + const StoreMetaData &storeMeta) +{ + std::vector accountIds { accountId, "ohosAnonymousUid", "default" }; + for (auto &id : accountIds) { + auto convertedIds = + AppIdMappingConfigManager::GetInstance().Convert(storeMeta.appId, storeMeta.user); + const std::string &tempTripleIdentifier = + DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(id, convertedIds.first, + storeMeta.storeId, false); + if (tempTripleIdentifier == identifier) { + ZLOGI("find triple identifier,storeId:%{public}s,id:%{public}s", + Anonymous::Change(storeMeta.storeId).c_str(), Anonymous::Change(id).c_str()); + return true; + } + } + return false; +} + bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier( const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) { @@ -414,15 +433,13 @@ bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier( // judge local userid and local meta continue; } - const std::string &itemTripleIdentifier = - DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(accountId, storeMeta.appId, - storeMeta.storeId, false); + bool isTripleIdentifierEqual = CompareTripleIdentifier(accountId, identifier, storeMeta); const std::string &itemDualIdentifier = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true); - if (identifier == itemTripleIdentifier && storeMeta.bundleName != Bootstrap::GetInstance().GetProcessLabel()) { + if (isTripleIdentifierEqual && storeMeta.bundleName != Bootstrap::GetInstance().GetProcessLabel()) { ResolveAutoLaunchCompatible(storeMeta, identifier, accountId); } - if (identifier == itemDualIdentifier || identifier == itemTripleIdentifier) { + if (identifier == itemDualIdentifier || isTripleIdentifierEqual) { ZLOGI("identifier find"); DistributedDB::AutoLaunchOption option; option.createIfNecessary = false; @@ -709,7 +726,8 @@ void KvStoreDataService::InitSecurityAdapter(std::shared_ptr execu ZLOGE("security is nullptr."); return; } - + + security_->InitLocalSecurity(); auto dbStatus = DistributedDB::RuntimeConfig::SetProcessSystemAPIAdapter(security_); ZLOGD("set distributed db system api adapter: %d.", static_cast(dbStatus)); @@ -809,10 +827,10 @@ int32_t KvStoreDataService::OnScreenUnlocked(int32_t user) int32_t KvStoreDataService::ClearAppStorage(const std::string &bundleName, int32_t userId, int32_t appIndex, int32_t tokenId) { - HapTokenInfo hapTokenInfo; - if (AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo) != RET_SUCCESS || - hapTokenInfo.bundleName != bundleName || hapTokenInfo.userID != userId || - hapTokenInfo.instIndex != appIndex) { + auto callerToken = IPCSkeleton::GetCallingTokenID(); + NativeTokenInfo nativeTokenInfo; + if (AccessTokenKit::GetNativeTokenInfo(callerToken, nativeTokenInfo) != RET_SUCCESS || + nativeTokenInfo.processName != FOUNDATION_PROCESS_NAME) { ZLOGE("passed wrong, tokenId: %{public}u, bundleName:%{public}s, user:%{public}d, appIndex:%{public}d", tokenId, bundleName.c_str(), userId, appIndex); return ERROR; diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h index ae5b3b1c..53a02afe 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h @@ -169,13 +169,18 @@ private: bool ResolveAutoLaunchParamByIdentifier(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); void ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier, const std::string &accountId); + + void LoadConfigs(); + + bool CompareTripleIdentifier(const std::string &accountId, const std::string &identifier, + const StoreMetaData &storeMeta); static DistributedDB::SecurityOption ConvertSecurity(int securityLevel); static Status InitNbDbOption(const Options &options, const std::vector &cipherKey, DistributedDB::KvStoreNbDelegate::Option &dbOption); static constexpr int TEN_SEC = 10; - ConcurrentMap clients_; + ConcurrentMap> clients_; std::shared_ptr accountEventObserver_; std::shared_ptr security_; diff --git a/datamgr_service/services/distributeddataservice/app/src/security/security.cpp b/datamgr_service/services/distributeddataservice/app/src/security/security.cpp index b3cceb71..ca7c9720 100644 --- a/datamgr_service/services/distributeddataservice/app/src/security/security.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/security/security.cpp @@ -165,6 +165,12 @@ bool Security::IsExits(const std::string &file) const return access(file.c_str(), F_OK) == 0; } +void Security::InitLocalSecurity() +{ + auto devInfo = DistributedData::DeviceManagerAdapter::GetInstance().GetLocalDevice(); + GetSensitiveByUuid(devInfo.uuid); +} + Sensitive Security::GetSensitiveByUuid(const std::string &uuid) const { auto it = devicesUdid_.Find(uuid); diff --git a/datamgr_service/services/distributeddataservice/app/src/security/security.h b/datamgr_service/services/distributeddataservice/app/src/security/security.h index 702f2af2..bfa2a541 100644 --- a/datamgr_service/services/distributeddataservice/app/src/security/security.h +++ b/datamgr_service/services/distributeddataservice/app/src/security/security.h @@ -58,6 +58,8 @@ public: AppDistributedKv::ChangeLevelType GetChangeLevelType() const override; + void InitLocalSecurity(); + private: enum { NO_PWD = -1, diff --git a/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp b/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp index 5d5dc15e..318891be 100644 --- a/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp @@ -34,6 +34,7 @@ using namespace OHOS::DistributedKv; using namespace std::chrono; using DmAdapter = DistributedData::DeviceManagerAdapter; constexpr const int ALIGN_WIDTH = 8; +constexpr const char *DEFAULT_USERID = "0"; std::shared_ptr RouteHeadHandlerImpl::Create(const ExtendInfo &info) { auto handler = std::make_shared(info); @@ -58,6 +59,9 @@ void RouteHeadHandlerImpl::Init() if (deviceId_.empty()) { return; } + if (!DmAdapter::GetInstance().IsOHOSType(deviceId_) && userId_ != DEFAULT_USERID) { + userId_ = DEFAULT_USERID; + } SessionPoint localPoint { DmAdapter::GetInstance().GetLocalDevice().uuid, static_cast(atoi(userId_.c_str())), appId_, storeId_ }; session_ = SessionManager::GetInstance().GetSession(localPoint, deviceId_); diff --git a/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.cpp b/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.cpp index 271c1d8c..d46217a4 100644 --- a/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.cpp @@ -27,7 +27,7 @@ #include "user_delegate.h" #include "utils/anonymous.h" #include "utils/converter.h" - +#include "types.h" namespace OHOS::DistributedData { using namespace OHOS::DistributedKv; SessionManager &SessionManager::GetInstance() @@ -57,9 +57,17 @@ Session SessionManager::GetSession(const SessionPoint &from, const std::string & session.targetUserIds.push_back(UserDelegate::SYSTEM_USER); } } + + std::string bundleName = ""; + int32_t authType = static_cast(AuthType::DEFAULT); + if (!GetAuthParams(from, bundleName, authType)) { + ZLOGE("GetAuthParams failed"); + return session; + } for (const auto &user : users) { - bool isPermitted = AuthDelegate::GetInstance()->CheckAccess(from.userId, user.id, targetDeviceId, from.appId); + bool isPermitted = AuthDelegate::GetInstance()->CheckAccess(from.userId, user.id, + targetDeviceId, authType); ZLOGD("access to peer user %{public}d is %{public}d", user.id, isPermitted); if (isPermitted) { auto it = std::find(session.targetUserIds.begin(), session.targetUserIds.end(), user.id); @@ -72,9 +80,36 @@ Session SessionManager::GetSession(const SessionPoint &from, const std::string & return session; } +bool SessionManager::GetAuthParams(const SessionPoint &from, std::string &bundleName, int32_t &auth) const +{ + std::vector metaData; + if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ from.deviceId }), metaData)) { + ZLOGW("load meta failed, deviceId:%{public}s", Anonymous::Change(from.deviceId).c_str()); + return false; + } + for (const auto &storeMeta : metaData) { + if (storeMeta.appId == from.appId) { + bundleName = storeMeta.bundleName; + auth = storeMeta.authType; + break; + } + } + if (bundleName.empty()) { + ZLOGE("not find bundleName"); + return false; + } + return true; +} + bool SessionManager::CheckSession(const SessionPoint &from, const SessionPoint &to) const { - return AuthDelegate::GetInstance()->CheckAccess(from.userId, to.userId, to.deviceId, from.appId); + std::string bundleName = ""; + int32_t authType = static_cast(AuthType::DEFAULT); + if (!GetAuthParams(from, bundleName, authType)) { + ZLOGE("GetAuthParams failed"); + return false; + } + return AuthDelegate::GetInstance()->CheckAccess(from.userId, to.userId, to.deviceId, authType, false); } bool Session::Marshal(json &node) const diff --git a/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.h b/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.h index bad2b8e2..43c6312f 100644 --- a/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.h +++ b/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.h @@ -49,6 +49,8 @@ public: static SessionManager &GetInstance(); Session GetSession(const SessionPoint &from, const std::string &targetDeviceId) const; bool CheckSession(const SessionPoint &from, const SessionPoint &to) const; +private: + bool GetAuthParams(const SessionPoint &from, std::string &bundleName, int32_t &auth) const; }; } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp b/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp index 0627708f..65360d84 100644 --- a/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp @@ -23,6 +23,7 @@ #include "metadata/meta_data_manager.h" #include "utils/anonymous.h" #include "utils/constant.h" +#include "app_id_mapping/app_id_mapping_config_manager.h" namespace OHOS::DistributedData { using namespace OHOS::DistributedKv; @@ -119,20 +120,24 @@ void UpgradeManager::SetCompatibleIdentifyByType(DistributedDB::KvStoreNbDelegat GetIdentifierParams(sameAccountDevs, uuids, IDENTICAL_ACCOUNT); GetIdentifierParams(defaultAccountDevs, uuids, NO_ACCOUNT); if (!sameAccountDevs.empty()) { - auto syncIdentifier = - DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(tuple.userId, tuple.appId, tuple.storeId); - ZLOGI("same account set compatible identifier store:%{public}s, user:%{public}s, device:%{public}.10s", - Anonymous::Change(tuple.storeId).c_str(), Anonymous::Change(tuple.userId).c_str(), - DistributedData::Serializable::Marshall(sameAccountDevs).c_str()); - storeDelegate->SetEqualIdentifier(syncIdentifier, sameAccountDevs); + auto convertedIds = AppIdMappingConfigManager::GetInstance().Convert(tuple.appId, tuple.userId); + auto identifier = + DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(convertedIds.second, + convertedIds.first, tuple.storeId); + ZLOGI("same account store:%{public}s, user:%{public}s, device:%{public}.10s, appId:%{public}s", + Anonymous::Change(tuple.storeId).c_str(), Anonymous::Change(convertedIds.second).c_str(), + DistributedData::Serializable::Marshall(sameAccountDevs).c_str(), convertedIds.first.c_str()); + storeDelegate->SetEqualIdentifier(identifier, sameAccountDevs); } if (!defaultAccountDevs.empty()) { - auto syncIdentifier = - DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(defaultAccountId, tuple.appId, tuple.storeId); - ZLOGI("no account set compatible identifier, store:%{public}s, device:%{public}.10s", + auto convertedIds = AppIdMappingConfigManager::GetInstance().Convert(tuple.appId, defaultAccountId); + auto identifier = + DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(convertedIds.second, + convertedIds.first, tuple.storeId); + ZLOGI("no account identifier, store:%{public}s, device:%{public}.10s, appId:%{public}s", Anonymous::Change(tuple.storeId).c_str(), - DistributedData::Serializable::Marshall(defaultAccountDevs).c_str()); - storeDelegate->SetEqualIdentifier(syncIdentifier, defaultAccountDevs); + DistributedData::Serializable::Marshall(defaultAccountDevs).c_str(), convertedIds.first.c_str()); + storeDelegate->SetEqualIdentifier(identifier, defaultAccountDevs); } } } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.h b/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.h index 9fc71a2f..9348fc02 100644 --- a/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.h +++ b/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.h @@ -47,7 +47,7 @@ private: static constexpr int32_t NO_ACCOUNT = 0; static constexpr int32_t IDENTICAL_ACCOUNT = 1; - static constexpr const char *defaultAccountId = "default"; + static constexpr const char *defaultAccountId = "ohosAnonymousUid"; }; } // namespace OHOS::DistributedData #endif // DISTRIBUTEDDATAMGR_UPGRADE_MANAGER_H diff --git a/datamgr_service/services/distributeddataservice/app/test/unittest/kvstore_data_service_clear_test.cpp b/datamgr_service/services/distributeddataservice/app/test/unittest/kvstore_data_service_clear_test.cpp index 506d689b..26881120 100644 --- a/datamgr_service/services/distributeddataservice/app/test/unittest/kvstore_data_service_clear_test.cpp +++ b/datamgr_service/services/distributeddataservice/app/test/unittest/kvstore_data_service_clear_test.cpp @@ -45,11 +45,8 @@ class KvStoreDataServiceClearTest : public testing::Test { public: static void SetUpTestCase(void); static void TearDownTestCase(void); - void SetUp(); void TearDown(); - - NativeTokenInfoParams infoInstance {0}; protected: static constexpr const char *TEST_USER = "100"; static constexpr const char *TEST_BUNDLE = "ohos.test.demo"; @@ -57,16 +54,10 @@ protected: static constexpr int32_t TEST_UID = 2000000; static constexpr int32_t TEST_USERID = 100; static constexpr const char *BUNDLE_NAME = "ohos.test.demo"; - static constexpr const char *BUNDLENAME_NO = "com.sample.helloworld"; static constexpr int32_t USER_ID = 100; - static constexpr int32_t USERID_NO = 10; static constexpr int32_t APP_INDEX = 0; - static constexpr int32_t APPINDEX_NO = 2; - static constexpr int32_t INVALID_TOKEN = 222; - DistributedData::StoreMetaData metaData_; DistributedData::StoreMetaDataLocal localMeta_; - void InitMetaData(); }; @@ -80,55 +71,12 @@ void KvStoreDataServiceClearTest::TearDownTestCase(void) void KvStoreDataServiceClearTest::SetUp(void) { - DistributedData::Bootstrap::GetInstance().LoadComponents(); DistributedData::Bootstrap::GetInstance().LoadDirectory(); DistributedData::Bootstrap::GetInstance().LoadCheckers(); - - infoInstance.dcapsNum = 0; - infoInstance.permsNum = 0; - infoInstance.aclsNum = 0; - infoInstance.dcaps = nullptr; - infoInstance.perms = nullptr; - infoInstance.acls = nullptr; - infoInstance.processName = "KvStoreDataServiceClearTest"; - infoInstance.aplStr = "system_core"; - - HapInfoParams info = { - .userID = TEST_USERID, - .bundleName = TEST_BUNDLE, - .instIndex = 0, - .appIDDesc = TEST_BUNDLE - }; - PermissionDef infoManagerTestPermDef = { - .permissionName = "ohos.permission.test", - .bundleName = TEST_BUNDLE, - .grantMode = 1, - .availableLevel = APL_NORMAL, - .label = "label", - .labelId = 1, - .description = "open the door", - .descriptionId = 1 - }; - PermissionStateFull infoManagerTestState = { - .permissionName = "ohos.permission.test", - .isGeneral = true, - .resDeviceID = {"local"}, - .grantStatus = {PermissionState::PERMISSION_GRANTED}, - .grantFlags = {1} - }; - HapPolicyParams policy = { - .apl = APL_NORMAL, - .domain = "test.domain", - .permList = {infoManagerTestPermDef}, - .permStateList = {infoManagerTestState} - }; - AccessTokenKit::AllocHapToken(info, policy); } void KvStoreDataServiceClearTest::TearDown(void) { - auto tokenId = AccessTokenKit::GetHapTokenID(TEST_USERID, TEST_BUNDLE, 0); - AccessTokenKit::DeleteToken(tokenId); } void KvStoreDataServiceClearTest::InitMetaData() @@ -155,7 +103,7 @@ void KvStoreDataServiceClearTest::InitMetaData() /** * @tc.name: ClearAppStorage001 - * @tc.desc: Test that the parameters are entered correctly + * @tc.desc: The parameters are valid but have no metaData * @tc.type: FUNC * @tc.require: * @tc.author: suoqilong @@ -163,49 +111,23 @@ void KvStoreDataServiceClearTest::InitMetaData() HWTEST_F(KvStoreDataServiceClearTest, ClearAppStorage001, TestSize.Level1) { auto kvDataService = OHOS::DistributedKv::KvStoreDataService(); - auto tokenIdOk = AccessTokenKit::GetHapTokenID(TEST_USERID, TEST_BUNDLE, 0); - auto ret = - kvDataService.ClearAppStorage(BUNDLE_NAME, USER_ID, APP_INDEX, INVALID_TOKEN); - EXPECT_EQ(ret, Status::ERROR); - - ret = kvDataService.ClearAppStorage(BUNDLENAME_NO, USER_ID, APP_INDEX, tokenIdOk); - EXPECT_EQ(ret, Status::ERROR); - - ret = kvDataService.ClearAppStorage(BUNDLE_NAME, USERID_NO, APP_INDEX, tokenIdOk); - EXPECT_EQ(ret, Status::ERROR); - - ret = kvDataService.ClearAppStorage(BUNDLE_NAME, USER_ID, APPINDEX_NO, tokenIdOk); + auto tokenIdOk = AccessTokenKit::GetNativeTokenId("foundation"); + SetSelfTokenID(tokenIdOk); + auto ret = kvDataService.ClearAppStorage(BUNDLE_NAME, USER_ID, APP_INDEX, tokenIdOk); EXPECT_EQ(ret, Status::ERROR); } /** * @tc.name: ClearAppStorage002 - * @tc.desc: The parameters are valid but have no metaData - * @tc.type: FUNC - * @tc.require: - * @tc.author: suoqilong - */ -HWTEST_F(KvStoreDataServiceClearTest, ClearAppStorage002, TestSize.Level1) -{ - auto kvDataService = OHOS::DistributedKv::KvStoreDataService(); - auto tokenIdOk = AccessTokenKit::GetHapTokenID(TEST_USERID, TEST_BUNDLE, 0); - - auto ret = - kvDataService.ClearAppStorage(BUNDLE_NAME, USER_ID, APP_INDEX, tokenIdOk); - EXPECT_EQ(ret, Status::ERROR); -} - -/** - * @tc.name: ClearAppStorage003 * @tc.desc: Test that the cleanup is implemented * @tc.type: FUNC * @tc.require: * @tc.author: suoqilong */ -HWTEST_F(KvStoreDataServiceClearTest, ClearAppStorage003, TestSize.Level1) +HWTEST_F(KvStoreDataServiceClearTest, ClearAppStorage002, TestSize.Level1) { - auto executors = std::make_shared(12, 5); - // Create an object of the ExecutorPool class and pass 12 and 5 as arguments to the constructor of the class + auto executors = std::make_shared(2, 1); + // Create an object of the ExecutorPool class and pass 2 and 1 as arguments to the constructor of the class KvStoreMetaManager::GetInstance().BindExecutor(executors); KvStoreMetaManager::GetInstance().InitMetaParameter(); DmAdapter::GetInstance().Init(executors); @@ -226,10 +148,10 @@ HWTEST_F(KvStoreDataServiceClearTest, ClearAppStorage003, TestSize.Level1) EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(metaData_.appId, metaData_, true)); EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(metaData_.GetKeyLocal(), localMeta_, true)); - auto tokenIdOk = AccessTokenKit::GetHapTokenID(TEST_USERID, TEST_BUNDLE, 0); + auto tokenIdOk = AccessTokenKit::GetNativeTokenId("foundation"); + SetSelfTokenID(tokenIdOk); auto kvDataService = OHOS::DistributedKv::KvStoreDataService(); - auto ret = - kvDataService.ClearAppStorage(BUNDLE_NAME, USER_ID, APP_INDEX, tokenIdOk); + auto ret = kvDataService.ClearAppStorage(BUNDLE_NAME, USER_ID, APP_INDEX, tokenIdOk); EXPECT_EQ(ret, Status::SUCCESS); EXPECT_FALSE(MetaDataManager::GetInstance().LoadMeta(metaData_.GetKey(), metaData_)); diff --git a/datamgr_service/services/distributeddataservice/app/test/unittest/session_manager_test.cpp b/datamgr_service/services/distributeddataservice/app/test/unittest/session_manager_test.cpp index 554891ba..96fa8ca7 100644 --- a/datamgr_service/services/distributeddataservice/app/test/unittest/session_manager_test.cpp +++ b/datamgr_service/services/distributeddataservice/app/test/unittest/session_manager_test.cpp @@ -93,6 +93,7 @@ public: StoreMetaData metaData; metaData.bundleName = "ohos.test.demo"; + metaData.appId = "ohos.test.demo"; metaData.storeId = "test_store"; metaData.user = "100"; metaData.deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; @@ -110,6 +111,7 @@ public: MetaDataManager::GetInstance().DelMeta(std::string(peerCapMetaKey.begin(), peerCapMetaKey.end())); StoreMetaData metaData; metaData.bundleName = "ohos.test.demo"; + metaData.appId = "ohos.test.demo"; metaData.storeId = "test_store"; metaData.user = "100"; metaData.deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; @@ -142,7 +144,7 @@ HWTEST_F(SessionManagerTest, PackAndUnPack01, TestSize.Level2) ASSERT_NE(sendHandler, nullptr); uint32_t routeHeadSize = 0; sendHandler->GetHeadDataSize(routeHeadSize); - ASSERT_GT(routeHeadSize, 0); + ASSERT_EQ(routeHeadSize, 0); std::unique_ptr data = std::make_unique(routeHeadSize); sendHandler->FillHeadData(data.get(), routeHeadSize, routeHeadSize); @@ -152,7 +154,6 @@ HWTEST_F(SessionManagerTest, PackAndUnPack01, TestSize.Level2) uint32_t parseSize = 1; recvHandler->ParseHeadData(data.get(), routeHeadSize, parseSize, users); EXPECT_EQ(routeHeadSize, parseSize); - ASSERT_EQ(users.size(), 1); - EXPECT_EQ(users[0], "100"); + ASSERT_EQ(users.size(), 0); } } // namespace \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/BUILD.gn b/datamgr_service/services/distributeddataservice/framework/BUILD.gn index f069d43e..ca78af92 100644 --- a/datamgr_service/services/distributeddataservice/framework/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/framework/BUILD.gn @@ -33,6 +33,7 @@ config("module_public_config") { visibility = [ ":*" ] include_dirs = [ "include", + "${data_service_path}/framework/include/account", "${kv_store_common_path}", ] } @@ -47,6 +48,8 @@ ohos_shared_library("distributeddatasvcfwk") { debug = false } sources = [ + "account/account_delegate.cpp", + "app_id_mapping/app_id_mapping_config_manager.cpp", "backuprule/backup_rule_manager.cpp", "changeevent/remote_change_event.cpp", "checker/checker_manager.cpp", @@ -56,6 +59,7 @@ ohos_shared_library("distributeddatasvcfwk") { "cloud/cloud_event.cpp", "cloud/cloud_extra_data.cpp", "cloud/cloud_info.cpp", + "cloud/cloud_lock_event.cpp", "cloud/cloud_server.cpp", "cloud/cloud_share_event.cpp", "cloud/cloud_sync_finished_event.cpp", @@ -65,6 +69,7 @@ ohos_shared_library("distributeddatasvcfwk") { "cloud/subscription.cpp", "cloud/sync_event.cpp", "cloud/sync_strategy.cpp", + "communication/connect_manager.cpp", "directory/directory_manager.cpp", "dump/dump_manager.cpp", "eventcenter/event.cpp", @@ -86,6 +91,7 @@ ohos_shared_library("distributeddatasvcfwk") { "metadata/switches_meta_data.cpp", "metadata/user_meta_data.cpp", "metadata/version_meta_data.cpp", + "screen/screen_manager.cpp", "serializable/serializable.cpp", "snapshot/bind_event.cpp", "snapshot/snapshot.cpp", diff --git a/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt b/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt index d72ea16e..9166243b 100644 --- a/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt +++ b/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt @@ -10,18 +10,22 @@ 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") set(KV_STORE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../kv_store") +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/account svcFwkSrc) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/app_id_mapping svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/backuprule svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/changeevent svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/checker svcFwkSrc) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/cloud svcFwkSrc) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/communication svcFwkSrc) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/directory svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/dump svcFwkSrc) -aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/metadata svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/eventcenter svcFwkSrc) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/feature svcFwkSrc) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/metadata svcFwkSrc) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/screen svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/serializable svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/snapshot svcFwkSrc) -aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/feature svcFwkSrc) -aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/directory svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/store svcFwkSrc) -aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/cloud svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/utils svcFwkSrc) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../adapter/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../utils_native/base/include) @@ -35,3 +39,4 @@ set(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/../../../../") add_library(svcFwk SHARED ${svcFwkSrc}) target_link_libraries(svcFwk ${links}) target_include_directories(svcFwk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_include_directories(svcFwk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/account) diff --git a/datamgr_service/services/distributeddataservice/framework/account/account_delegate.cpp b/datamgr_service/services/distributeddataservice/framework/account/account_delegate.cpp new file mode 100644 index 00000000..1734d654 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/account/account_delegate.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 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 "account_delegate.h" + +namespace OHOS { +namespace DistributedKv { +AccountDelegate *AccountDelegate::instance_ = nullptr; + +bool AccountDelegate::RegisterAccountInstance(AccountDelegate *instance) +{ + if (instance_ != nullptr) { + return false; + } + instance_ = instance; + return true; +} + +AccountDelegate *AccountDelegate::GetInstance() +{ + return instance_; +} +} // namespace DistributedKv +} // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/app_id_mapping/app_id_mapping_config_manager.cpp b/datamgr_service/services/distributeddataservice/framework/app_id_mapping/app_id_mapping_config_manager.cpp new file mode 100644 index 00000000..3d03d524 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/app_id_mapping/app_id_mapping_config_manager.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 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 "AppIdMappingConfigManager" +#include "app_id_mapping/app_id_mapping_config_manager.h" + +namespace OHOS::DistributedData { +AppIdMappingConfigManager &AppIdMappingConfigManager::GetInstance() +{ + static AppIdMappingConfigManager instance; + return instance; +} + +void AppIdMappingConfigManager::Initialize(const std::vector &mapper) +{ + for (const auto &info : mapper) { + toDstMapper_.insert_or_assign(info.srcAppId, info.dstAppId); + } +} + +std::pair AppIdMappingConfigManager::Convert(const std::string &appId, + const std::string &accountId) +{ + auto it = toDstMapper_.find(appId); + if (it == toDstMapper_.end()) { + return std::make_pair(appId, accountId); + } + return std::make_pair(it->second, "default"); +} + +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_db.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_db.cpp index 612c5a08..0e3c2a4c 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_db.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_db.cpp @@ -35,7 +35,7 @@ int32_t CloudDB::BatchUpdate(const std::string &table, VBuckets &&values, const return E_NOT_SUPPORT; } -int32_t CloudDB::BatchDelete(const std::string &table, const VBuckets &extends) +int32_t CloudDB::BatchDelete(const std::string &table, VBuckets &extends) { return E_NOT_SUPPORT; } diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_event.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_event.cpp index bfaf3c9e..701bce29 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_event.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_event.cpp @@ -17,7 +17,7 @@ namespace OHOS::DistributedData { CloudEvent::CloudEvent(int32_t evtId, StoreInfo storeInfo) - : Event(evtId), storeInfo_(std::move(storeInfo)) + : Event(evtId), eventId_(evtId), storeInfo_(std::move(storeInfo)) { } @@ -25,4 +25,9 @@ const StoreInfo& CloudEvent::GetStoreInfo() const { return storeInfo_; } + +int32_t CloudEvent::GetEventId() const +{ + return eventId_; +} } \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_info.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_info.cpp index d723adfe..191c6f88 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_info.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_info.cpp @@ -14,6 +14,7 @@ */ #include "cloud/cloud_info.h" + #include "utils/constant.h" namespace OHOS::DistributedData { @@ -76,8 +77,7 @@ std::map CloudInfo::GetSchemaKey() const { std::map keys; for (const auto &[bundle, app] : apps) { - const auto key = GetKey( - SCHEMA_PREFIX, { std::to_string(user), bundle, std::to_string(app.instanceId) }); + const auto key = GetKey(SCHEMA_PREFIX, { std::to_string(user), bundle, std::to_string(app.instanceId) }); keys.insert_or_assign(app.bundleName, key); } return keys; @@ -98,12 +98,12 @@ std::string CloudInfo::GetSchemaPrefix(const std::string &bundleName) const if (bundleName.empty()) { return GetKey(SCHEMA_PREFIX, { std::to_string(user) }); } - return GetKey(SCHEMA_PREFIX, { std::to_string(user), bundleName}); + return GetKey(SCHEMA_PREFIX, { std::to_string(user), bundleName }); } std::string CloudInfo::GetSchemaKey(const StoreMetaData &meta) { - return GetKey(SCHEMA_PREFIX, { meta.user, meta.bundleName, std::to_string(meta.instanceId) }); + return GetKey(SCHEMA_PREFIX, { meta.user, meta.bundleName, std::to_string(meta.instanceId) }); } bool CloudInfo::IsValid() const diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_lock_event.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_lock_event.cpp new file mode 100644 index 00000000..c0bf9a1a --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_lock_event.cpp @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2024 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 "cloud/cloud_lock_event.h" + +namespace OHOS::DistributedData { +CloudLockEvent::CloudLockEvent(int32_t evtId, StoreInfo storeInfo, Callback callback) + :CloudEvent(evtId, storeInfo), callback_(std::move(callback)) +{ +} +CloudLockEvent::Callback CloudLockEvent::GetCallback() const +{ + return callback_; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/schema_meta.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/schema_meta.cpp index f22c28ae..e0df1177 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/schema_meta.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/schema_meta.cpp @@ -39,7 +39,7 @@ std::vector Database::GetTableNames() const { std::vector tableNames; tableNames.reserve(tables.size()); - for (auto& table : tables) { + for (auto &table : tables) { tableNames.push_back(table.name); if (!table.sharedTableName.empty()) { tableNames.push_back(table.sharedTableName); diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/sharing_center.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/sharing_center.cpp index 09866496..cb171858 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/sharing_center.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/sharing_center.cpp @@ -15,50 +15,50 @@ #include "cloud/sharing_center.h" namespace OHOS::DistributedData { -SharingCenter::Results SharingCenter::Share(int32_t userId, const std::string &bundleName, - const std::string &sharingRes, const Participants &participants) +SharingCenter::Results SharingCenter::Share( + int32_t userId, const std::string &bundleName, const std::string &sharingRes, const Participants &participants) { return {}; } -SharingCenter::Results SharingCenter::Unshare(int32_t userId, const std::string &bundleName, - const std::string &sharingRes, const Participants &participants) +SharingCenter::Results SharingCenter::Unshare( + int32_t userId, const std::string &bundleName, const std::string &sharingRes, const Participants &participants) { return {}; } -std::pair SharingCenter::Exit(int32_t userId, const std::string &bundleName, - const std::string &sharingRes) +std::pair SharingCenter::Exit( + int32_t userId, const std::string &bundleName, const std::string &sharingRes) { return {}; } -SharingCenter::Results SharingCenter::ChangePrivilege(int32_t userId, const std::string &bundleName, - const std::string &sharingRes, const Participants &participants) +SharingCenter::Results SharingCenter::ChangePrivilege( + int32_t userId, const std::string &bundleName, const std::string &sharingRes, const Participants &participants) { return {}; } -SharingCenter::QueryResults SharingCenter::Query(int32_t userId, const std::string &bundleName, - const std::string &sharingRes) +SharingCenter::QueryResults SharingCenter::Query( + int32_t userId, const std::string &bundleName, const std::string &sharingRes) { return {}; } -SharingCenter::QueryResults SharingCenter::QueryByInvitation(int32_t userId, const std::string &bundleName, - const std::string &invitation) +SharingCenter::QueryResults SharingCenter::QueryByInvitation( + int32_t userId, const std::string &bundleName, const std::string &invitation) { return {}; } -std::tuple SharingCenter::ConfirmInvitation(int32_t userId, - const std::string &bundleName, const std::string &invitation, int32_t confirmation) +std::tuple SharingCenter::ConfirmInvitation( + int32_t userId, const std::string &bundleName, const std::string &invitation, int32_t confirmation) { return {}; } -std::pair SharingCenter::ChangeConfirmation(int32_t userId, - const std::string &bundleName, const std::string &sharingRes, int32_t confirmation) +std::pair SharingCenter::ChangeConfirmation( + int32_t userId, const std::string &bundleName, const std::string &sharingRes, int32_t confirmation) { return {}; } diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/subscription.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/subscription.cpp index 28030d88..1f570f3c 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/subscription.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/subscription.cpp @@ -14,6 +14,7 @@ */ #include "cloud/subscription.h" + #include "utils/constant.h" namespace OHOS::DistributedData { bool Subscription::Relation::Marshal(json &node) const diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/sync_event.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/sync_event.cpp index badf9ffe..f2c78e6c 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/sync_event.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/sync_event.cpp @@ -22,7 +22,7 @@ SyncEvent::EventInfo::EventInfo(int32_t mode, int32_t wait, bool retry, std::sha } SyncEvent::EventInfo::EventInfo(const SyncParam &syncParam, bool retry, std::shared_ptr query, GenAsync async) : retry_(retry), mode_(syncParam.mode), wait_(syncParam.wait), query_(std::move(query)), - asyncDetail_(std::move(async)), isCompensation_(syncParam.isCompensation) + asyncDetail_(std::move(async)), isCompensation_(syncParam.isCompensation), triggerMode_(syncParam.triggerMode) { } @@ -42,6 +42,7 @@ SyncEvent::EventInfo &SyncEvent::EventInfo::operator=(SyncEvent::EventInfo &&inf query_ = std::move(info.query_); asyncDetail_ = std::move(info.asyncDetail_); isCompensation_ = info.isCompensation_; + triggerMode_ = info.triggerMode_; return *this; } @@ -84,4 +85,9 @@ bool SyncEvent::IsCompensation() const { return info_.isCompensation_; } + +int32_t SyncEvent::GetTriggerMode() const +{ + return info_.triggerMode_; +} } // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/communication/connect_manager.cpp b/datamgr_service/services/distributeddataservice/framework/communication/connect_manager.cpp new file mode 100644 index 00000000..74f8f70a --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/communication/connect_manager.cpp @@ -0,0 +1,137 @@ +/* +* Copyright (c) 2024 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 "ConnectManager" +#include "communication/connect_manager.h" + +#include "log_print.h" + +namespace OHOS::AppDistributedKv { +std::mutex ConnectManager::mtx_; +std::shared_ptr ConnectManager::instance_ = nullptr; +ConnectManager::CloseSessionTask ConnectManager::closeSessionTask_ = nullptr; +ConcurrentMap ConnectManager::sessionCloseListener_; +ConcurrentMap ConnectManager::sessionOpenListener_; + +std::shared_ptr ConnectManager::GetInstance() +{ + static std::once_flag onceFlag; + std::call_once(onceFlag, [&]() { + std::lock_guard lock(mtx_); + if (instance_ == nullptr) { + instance_ = std::make_shared(); + } + }); + return instance_; +} + +bool ConnectManager::RegisterInstance(std::shared_ptr instance) +{ + std::lock_guard lock(mtx_); + if (instance_ != nullptr) { + ZLOGW("ConnectManager instance has been replaced!"); + } + instance_ = instance; + return true; +} + +bool ConnectManager::CloseSession(const std::string &networkId) +{ + if (closeSessionTask_ != nullptr) { + return closeSessionTask_(networkId); + } + return false; +} + +bool ConnectManager::RegisterCloseSessionTask(CloseSessionTask task) +{ + if (closeSessionTask_ != nullptr) { + ZLOGE("Register close session task error, task already exists."); + return false; + } + closeSessionTask_ = std::move(task); + return true; +} + +bool ConnectManager::RegisterSessionCloseListener(const std::string &name, SessionCloseListener listener) +{ + bool success = false; + sessionCloseListener_.Compute(name, [&success, &listener](const auto &key, auto &value) { + if (value != nullptr) { + ZLOGE("Register session close listener error, type:%{public}s already exists.", key.c_str()); + return true; + } + value = std::move(listener); + success = true; + return true; + }); + return success; +} + +void ConnectManager::UnRegisterSessionCloseListener(const std::string &name) +{ + sessionCloseListener_.Erase(name); +} + +void ConnectManager::OnSessionClose(const std::string &networkId) +{ + sessionCloseListener_.ForEach([&networkId](const auto &key, auto &listener) { + listener(networkId); + return false; + }); +} + +bool ConnectManager::RegisterSessionOpenListener(const std::string &name, SessionOpenListener listener) +{ + bool success = false; + sessionOpenListener_.Compute(name, [&success, &listener](const auto &key, auto &value) { + if (value != nullptr) { + ZLOGE("Register session open listener error, type:%{public}s already exists.", key.c_str()); + return true; + } + value = std::move(listener); + success = true; + return true; + }); + return success; +} + +void ConnectManager::UnRegisterSessionOpenListener(const std::string &name) +{ + sessionOpenListener_.Erase(name); +} + +void ConnectManager::OnSessionOpen(const std::string &networkId) +{ + sessionOpenListener_.ForEach([&networkId](const auto &key, auto &listener) { + listener(networkId); + return false; + }); +} + +void ConnectManager::OnStart() +{ +} + +void ConnectManager::OnDestory() +{ +} + +int32_t ConnectManager::ApplyConnect(__attribute__((unused)) const std::string &networkId, ConnectTask task) +{ + task(); + return 0; +} +} // OHOS::AppDistributedKv \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/directory/directory_manager.cpp b/datamgr_service/services/distributeddataservice/framework/directory/directory_manager.cpp index 16b34ce0..bb954fd1 100644 --- a/datamgr_service/services/distributeddataservice/framework/directory/directory_manager.cpp +++ b/datamgr_service/services/distributeddataservice/framework/directory/directory_manager.cpp @@ -117,18 +117,18 @@ std::string DirectoryManager::GetType(const StoreMetaData &metaData) const std::string DirectoryManager::GetStore(const StoreMetaData &metaData) const { - if (metaData.storeType >= StoreMetaData::StoreType::STORE_KV_BEGIN - && metaData.storeType <= StoreMetaData::StoreType::STORE_KV_END) { + if (metaData.storeType >= StoreMetaData::StoreType::STORE_KV_BEGIN && + metaData.storeType <= StoreMetaData::StoreType::STORE_KV_END) { return "kvdb"; } // rdb use empty session - if (metaData.storeType >= StoreMetaData::StoreType::STORE_RELATIONAL_BEGIN - && metaData.storeType <= StoreMetaData::StoreType::STORE_RELATIONAL_END) { + if (metaData.storeType >= StoreMetaData::StoreType::STORE_RELATIONAL_BEGIN && + metaData.storeType <= StoreMetaData::StoreType::STORE_RELATIONAL_END) { return "rdb"; } // object use meta - if (metaData.storeType >= StoreMetaData::StoreType::STORE_OBJECT_BEGIN - && metaData.storeType <= StoreMetaData::StoreType::STORE_OBJECT_END) { + if (metaData.storeType >= StoreMetaData::StoreType::STORE_OBJECT_BEGIN && + metaData.storeType <= StoreMetaData::StoreType::STORE_OBJECT_END) { return "kvdb"; } return "other"; @@ -142,7 +142,8 @@ std::string DirectoryManager::GetSecurity(const StoreMetaData &metaData) const break; } [[fallthrough]]; - case SecurityLevel::S0: [[fallthrough]]; + case SecurityLevel::S0: + [[fallthrough]]; case SecurityLevel::S1: return "misc_de"; } @@ -271,4 +272,41 @@ bool DirectoryManager::CreateDirectory(const std::string &path) const return access(path.c_str(), F_OK) == 0; } + +bool DirectoryManager::DeleteDirectory(const char* path) +{ + if (path == nullptr) { + return false; + } + DIR* dir; + struct dirent* dirEntry; + struct stat buf; + char* curWorkDir = getcwd(nullptr, 0); + if ((dir = opendir(path)) == nullptr) { + return true; + } + if (chdir(path) == -1) { + return false; + } + while ((dirEntry = readdir(dir))) { + if ((strcmp(dirEntry->d_name, ".") == 0) || (strcmp(dirEntry->d_name, "..") == 0)) { + continue; + } + if (stat(dirEntry->d_name, &buf) == -1) { + return false; + } + if (S_ISDIR(buf.st_mode)) { + DeleteDirectory(dirEntry->d_name); + continue; + } + if (remove(dirEntry->d_name) == -1) { + return false; + } + } + closedir(dir); + if (chdir(curWorkDir) == -1 || rmdir(path) == -1) { + return false; + } + return true; +} } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/adapter/include/account/account_delegate.h b/datamgr_service/services/distributeddataservice/framework/include/account/account_delegate.h similarity index 80% rename from datamgr_service/services/distributeddataservice/adapter/include/account/account_delegate.h rename to datamgr_service/services/distributeddataservice/framework/include/account/account_delegate.h index 4c645815..29a8c7e4 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/account/account_delegate.h +++ b/datamgr_service/services/distributeddataservice/framework/include/account/account_delegate.h @@ -16,8 +16,9 @@ #ifndef DISTRIBUTEDDATAMGR_ACCOUNT_DELEGATE_H #define DISTRIBUTEDDATAMGR_ACCOUNT_DELEGATE_H -#include #include +#include + #include "executor_pool.h" #include "types.h" #include "visibility.h" @@ -26,11 +27,11 @@ namespace OHOS { namespace DistributedKv { enum class AccountStatus { HARMONY_ACCOUNT_LOGIN = 0, // the openHarmony account is logged in - HARMONY_ACCOUNT_LOGOUT, // the openHarmony account is logged out - HARMONY_ACCOUNT_DELETE, // the openHarmony account is deleted - DEVICE_ACCOUNT_DELETE, // the device account is deleted - DEVICE_ACCOUNT_SWITCHED, // the device account is switched - DEVICE_ACCOUNT_UNLOCKED, // the device account is unlocked + HARMONY_ACCOUNT_LOGOUT, // the openHarmony account is logged out + HARMONY_ACCOUNT_DELETE, // the openHarmony account is deleted + DEVICE_ACCOUNT_DELETE, // the device account is deleted + DEVICE_ACCOUNT_SWITCHED, // the device account is switched + DEVICE_ACCOUNT_UNLOCKED, // the device account is unlocked }; struct AccountEventInfo { @@ -54,7 +55,7 @@ public: API_EXPORT virtual std::string Name() = 0; API_EXPORT virtual LevelType GetLevel() = 0; }; - using HashFunc = std::string(*)(const void *data, size_t size, bool isUpper); + using HashFunc = std::string (*)(const void *data, size_t size, bool isUpper); API_EXPORT virtual ~AccountDelegate() = default; API_EXPORT virtual Status Subscribe(std::shared_ptr observer) = 0; API_EXPORT virtual Status Unsubscribe(std::shared_ptr observer) = 0; @@ -71,11 +72,11 @@ public: API_EXPORT virtual void BindExecutor(std::shared_ptr executors) = 0; API_EXPORT virtual std::string GetUnencryptedAccountId(int32_t userId = 0) const = 0; API_EXPORT static AccountDelegate *GetInstance(); + API_EXPORT static bool RegisterAccountInstance(AccountDelegate *instance); private: - using BaseInstance = AccountDelegate *(*)(); - static BaseInstance getInstance_; + static AccountDelegate *instance_; }; -} // namespace DistributedKv -} // namespace OHOS +} // namespace DistributedKv +} // namespace OHOS #endif // DISTRIBUTEDDATAMGR_ACCOUNT_DELEGATE_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/app_id_mapping/app_id_mapping_config_manager.h b/datamgr_service/services/distributeddataservice/framework/include/app_id_mapping/app_id_mapping_config_manager.h new file mode 100644 index 00000000..9799f9af --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/include/app_id_mapping/app_id_mapping_config_manager.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 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_DATA_SERVICES_FRAMEWORK_APP_ID_MAPPING_CONFIG_MANAGER_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_APP_ID_MAPPING_CONFIG_MANAGER_H +#include +#include +#include +#include "visibility.h" +namespace OHOS { +namespace DistributedData { +class AppIdMappingConfigManager { +public: + struct AppMappingInfo { + std::string srcAppId; + std::string dstAppId; + }; + API_EXPORT static AppIdMappingConfigManager &GetInstance(); + API_EXPORT void Initialize(const std::vector &mapper); + API_EXPORT std::pair Convert(const std::string &appId, + const std::string &accountId); + +private: + std::map toDstMapper_; +}; + +} // namespace DistributedData +} // namespace OHOS +#endif //OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_APP_ID_MAPPING_CONFIG_MANAGER_H diff --git a/datamgr_service/services/distributeddataservice/framework/include/changeevent/remote_change_event.h b/datamgr_service/services/distributeddataservice/framework/include/changeevent/remote_change_event.h index 8236df1b..bf58f432 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/changeevent/remote_change_event.h +++ b/datamgr_service/services/distributeddataservice/framework/include/changeevent/remote_change_event.h @@ -33,6 +33,7 @@ public: std::string storeId; std::string deviceId; std::string bundleName; + int changeType = 0; // 0 means CLOUD_DATA_CHANGE std::vector tables; }; diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_db.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_db.h index f0517d10..6927a277 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_db.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_db.h @@ -38,7 +38,7 @@ public: virtual int32_t BatchUpdate(const std::string &table, VBuckets &&values, const VBuckets &extends); - virtual int32_t BatchDelete(const std::string &table, const VBuckets &extends); + virtual int32_t BatchDelete(const std::string &table, VBuckets &extends); virtual std::shared_ptr Query(const std::string &table, const VBucket &extend); diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_event.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_event.h index 0ac070ad..8cd2d2d4 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_event.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_event.h @@ -27,20 +27,26 @@ public: FEATURE_INIT = EVT_CLOUD, GET_SCHEMA, LOCAL_CHANGE, + CLEAN_DATA, CLOUD_SYNC, DATA_CHANGE, + SET_SEARCHABLE, CLOUD_SHARE, MAKE_QUERY, CLOUD_SYNC_FINISHED, DATA_SYNC, + LOCK_CLOUD_CONTAINER, + UNLOCK_CLOUD_CONTAINER, CLOUD_BUTT }; CloudEvent(int32_t evtId, StoreInfo storeInfo); ~CloudEvent() = default; const StoreInfo& GetStoreInfo() const; + int32_t GetEventId() const; private: + int32_t eventId_; StoreInfo storeInfo_; }; } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_lock_event.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_lock_event.h new file mode 100644 index 00000000..cbced1b0 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_lock_event.h @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2024 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_DATA_SERVICES_FRAMEWORK_CLOUD_LOCK_EVENT_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_LOCK_EVENT_H +#include "cloud/cloud_event.h" +#include "store/general_value.h" +#include "store/general_store.h" +#include "visibility.h" + +namespace OHOS::DistributedData { +class API_EXPORT CloudLockEvent : public CloudEvent { +public: + using Callback = std::function; + CloudLockEvent(int32_t evtId, StoreInfo storeInfo, Callback callback); + ~CloudLockEvent() override = default; + Callback GetCallback() const; +private: + Callback callback_; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_LOCK_EVENT_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/sync_event.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/sync_event.h index 9887d9a7..22a06c07 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/sync_event.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/sync_event.h @@ -37,6 +37,7 @@ public: std::shared_ptr query_; GenAsync asyncDetail_; bool isCompensation_ = false; + int32_t triggerMode_ = MODE_DEFAULT; }; SyncEvent(StoreInfo storeInfo, EventInfo info); ~SyncEvent() override = default; @@ -46,7 +47,7 @@ public: std::shared_ptr GetQuery() const; GenAsync GetAsyncDetail() const; bool IsCompensation() const; - + int32_t GetTriggerMode() const; protected: SyncEvent(int32_t evtId, StoreInfo storeInfo, EventInfo info); diff --git a/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_change_event.h b/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_change_event.h index be3970cd..d6648288 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_change_event.h +++ b/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_change_event.h @@ -27,6 +27,7 @@ public: using TableProperties = std::map; struct EventInfo { TableProperties tableProperties; + bool isFull; }; DataChangeEvent(StoreInfo storeInfo, EventInfo evtInfo) @@ -40,6 +41,11 @@ public: { return info_.tableProperties; } + + bool IsFull() const + { + return info_.isFull; + } private: EventInfo info_; }; diff --git a/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_sync_event.h b/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_sync_event.h index 51e83a7d..5ff60b65 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_sync_event.h +++ b/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_sync_event.h @@ -26,8 +26,9 @@ public: FINISH, }; - DataSyncEvent(StoreInfo storeInfo, uint32_t syncMode, int32_t status) - : CloudEvent(DATA_SYNC, std::move(storeInfo)), syncMode_(syncMode), status_(std::move(status)) + DataSyncEvent(StoreInfo storeInfo, uint32_t syncMode, int32_t status, uint32_t traceId, uint32_t count = 0) + : CloudEvent(DATA_SYNC, std::move(storeInfo)), syncMode_(syncMode), status_(std::move(status)), + traceId_(traceId), count_(count) { } @@ -38,14 +39,26 @@ public: return syncMode_; } - uint32_t GetSyncStatus() const + int32_t GetSyncStatus() const { return status_; } + uint32_t GetTraceId() const + { + return traceId_; + } + + uint32_t GetCount() const + { + return count_; + } + private: uint32_t syncMode_; int32_t status_; + uint32_t traceId_; + uint32_t count_; }; } // OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_DATA_SYNC_EVENT_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/commonevent/set_searchable_event.h b/datamgr_service/services/distributeddataservice/framework/include/commonevent/set_searchable_event.h new file mode 100644 index 00000000..833ddd82 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/include/commonevent/set_searchable_event.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 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_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_SET_SEARCHABLE_EVENT_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_SET_SEARCHABLE_EVENT_H + +#include "cloud/cloud_event.h" +#include "visibility.h" +namespace OHOS::DistributedData { +class API_EXPORT SetSearchableEvent : public CloudEvent { +public: + struct EventInfo { + bool isSearchable; + }; + + SetSearchableEvent(StoreInfo storeInfo, EventInfo evtInfo) + : CloudEvent(SET_SEARCHABLE, std::move(storeInfo)), info_(std::move(evtInfo)) + { + } + + ~SetSearchableEvent() override = default; + + bool GetIsSearchabl() const + { + return info_.isSearchable; + } +private: + EventInfo info_; +}; +} // OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_SET_SEARCHABLE_EVENT_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/communication/connect_manager.h b/datamgr_service/services/distributeddataservice/framework/include/communication/connect_manager.h new file mode 100644 index 00000000..5e9093c7 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/include/communication/connect_manager.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2024 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_DATA_SERVICES_FRAMEWORK_COMMUNICATION_CONNECT_MANAGER_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMUNICATION_CONNECT_MANAGER_H + +#include +#include +#include +#include + +#include "concurrent_map.h" +#include "visibility.h" +namespace OHOS { +namespace AppDistributedKv { +class API_EXPORT ConnectManager { +public: + using ConnectTask = std::function; + using CloseSessionTask = std::function; + using SessionCloseListener = std::function; + using SessionOpenListener = std::function; + + API_EXPORT static std::shared_ptr GetInstance(); + API_EXPORT static bool RegisterInstance(std::shared_ptr instance); + + API_EXPORT static bool CloseSession(const std::string &networkId); + API_EXPORT static bool RegisterCloseSessionTask(CloseSessionTask task); + + API_EXPORT static bool RegisterSessionCloseListener(const std::string &name, SessionCloseListener listener); + API_EXPORT static void UnRegisterSessionCloseListener(const std::string &name); + API_EXPORT static void OnSessionClose(const std::string &networkId); + + API_EXPORT static bool RegisterSessionOpenListener(const std::string &name, SessionOpenListener listener); + API_EXPORT static void UnRegisterSessionOpenListener(const std::string &name); + API_EXPORT static void OnSessionOpen(const std::string &networkId); + + ConnectManager() = default; + virtual ~ConnectManager() = default; + + virtual void OnStart(); + virtual void OnDestory(); + virtual int32_t ApplyConnect(const std::string &networkId, ConnectTask task); + +private: + static std::mutex mtx_; + static std::shared_ptr instance_; + static CloseSessionTask closeSessionTask_; + static ConcurrentMap sessionCloseListener_; + static ConcurrentMap sessionOpenListener_; +}; +} // namespace AppDistributedKv +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMUNICATION_CONNECT_MANAGER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/directory/directory_manager.h b/datamgr_service/services/distributeddataservice/framework/include/directory/directory_manager.h index 737b7f5f..e2642ec8 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/directory/directory_manager.h +++ b/datamgr_service/services/distributeddataservice/framework/include/directory/directory_manager.h @@ -40,6 +40,7 @@ public: API_EXPORT std::vector GetVersions(); API_EXPORT void Initialize(const std::vector &strategies); API_EXPORT bool CreateDirectory(const std::string &path) const; + API_EXPORT bool DeleteDirectory(const char* path); private: using Action = std::string (DirectoryManager::*)(const StoreMetaData &) const; diff --git a/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h b/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h index 25c3cdf8..f798cecf 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h +++ b/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h @@ -39,6 +39,19 @@ enum GeneralError : int32_t { E_RECORD_EXIST_CONFLICT, E_WITH_INVENTORY_DATA, E_SYNC_TASK_MERGED, + E_RECORD_NOT_FOUND, + E_RECORD_ALREADY_EXISTED, + E_DB_ERROR, + E_INVALID_VALUE_FIELDS, + E_INVALID_FIELD_TYPE, + E_CONSTRAIN_VIOLATION, + E_INVALID_FORMAT, + E_INVALID_QUERY_FORMAT, + E_INVALID_QUERY_FIELD, + E_TIME_OUT, + E_OVER_MAX_LIMITS, + E_SECURITY_LEVEL_ERROR, + E_FILE_NOT_EXIST, E_BUTT, }; } diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/auto_launch_meta_data.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/auto_launch_meta_data.h index de1da05c..293e3c2a 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/metadata/auto_launch_meta_data.h +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/auto_launch_meta_data.h @@ -21,6 +21,7 @@ namespace OHOS::DistributedData { struct API_EXPORT AutoLaunchMetaData final : public Serializable { std::map> datas; + bool launchForCleanData = false; API_EXPORT AutoLaunchMetaData(); API_EXPORT ~AutoLaunchMetaData() = default; diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/matrix_meta_data.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/matrix_meta_data.h index ac6ee82a..909be37d 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/metadata/matrix_meta_data.h +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/matrix_meta_data.h @@ -48,4 +48,4 @@ private: static constexpr const char *RMOTE_CONSISTENT = "Consistent"; }; } // namespace OHOS::DistributedData -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_MATRIX_META_DATA_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_MATRIX_META_DATA_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h index 61bf6fd0..ff5e203a 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h @@ -45,6 +45,7 @@ struct API_EXPORT StoreMetaData final : public Serializable { int32_t area = 0; int32_t uid = -1; int32_t instanceId = 0; + int32_t haMode = 0; uint32_t tokenId = 0; std::string appId = ""; std::string appType = ""; @@ -57,6 +58,7 @@ struct API_EXPORT StoreMetaData final : public Serializable { std::string storeId = ""; std::string user = ""; std::string account = ""; + int32_t authType = 0; enum StoreType { STORE_KV_BEGIN = 0, diff --git a/datamgr_service/services/distributeddataservice/framework/include/screen/screen_manager.h b/datamgr_service/services/distributeddataservice/framework/include/screen/screen_manager.h new file mode 100644 index 00000000..cbf7c866 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/include/screen/screen_manager.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 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 DISTRIBUTEDDATAMGR_FRAMEWORK_SCREEN_LOCK_H +#define DISTRIBUTEDDATAMGR_FRAMEWORK_SCREEN_LOCK_H + +#include +#include +#include "visibility.h" + +namespace OHOS { +namespace DistributedData { +class ScreenManager { +public: + API_EXPORT static std::shared_ptr GetInstance(); + API_EXPORT static bool RegisterInstance(std::shared_ptr instance); + ScreenManager() = default; + virtual ~ScreenManager() = default; + virtual bool IsLocked(); + +private: + static std::mutex mutex_; + static std::shared_ptr instance_; +}; +} // namespace DistributedData +} // namespace OHOS +#endif //DISTRIBUTEDDATAMGR_FRAMEWORK_SCREEN_LOCK_H diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h b/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h index 9fcf14a4..0ee41a97 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h @@ -50,9 +50,7 @@ public: API_EXPORT Stores GetStoresIfPresent(uint32_t tokenId, const std::string &storeName = ""); - API_EXPORT void CloseStore(uint32_t tokenId, const std::string &storeId); - - API_EXPORT void CloseStore(uint32_t tokenId); + API_EXPORT void CloseStore(uint32_t tokenId, const std::string &storeId = ""); API_EXPORT void CloseExcept(const std::set &users); @@ -69,11 +67,14 @@ private: void StartTimer(); struct Delegate : public GeneralWatcher { Delegate(GeneralStore *delegate, const Watchers &watchers, int32_t user, const StoreMetaData &meta); + Delegate(const Delegate& delegate); ~Delegate(); operator Store(); bool operator<(const Time &time) const; bool Close(); int32_t GetUser() const; + int32_t GetArea() const; + const std::string& GetDataDir() const; void SetObservers(const Watchers &watchers); int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) override; int32_t OnChange(const Origin &origin, const Fields &fields, ChangeData &&datas) override; @@ -84,7 +85,7 @@ private: GeneralStore *store_ = nullptr; Watchers watchers_; int32_t user_; - StoreMetaData meta_; + const StoreMetaData meta_; std::shared_mutex mutex_; }; @@ -96,6 +97,7 @@ private: ConcurrentMap> stores_; ConcurrentMap> disables_; Creator creators_[MAX_CREATOR_NUM]; + std::set disableStores_; }; } // namespace OHOS::DistributedData -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_STORE_AUTO_CACHE_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_STORE_AUTO_CACHE_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h b/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h index 17f9db29..efc2db66 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h @@ -20,10 +20,12 @@ #include #include +#include "executor_pool.h" #include "snapshot/snapshot.h" #include "store/cursor.h" #include "store/general_value.h" #include "store/general_watcher.h" + namespace OHOS::DistributedData { class CloudDB; class AssetLoader; @@ -33,6 +35,7 @@ public: using Watcher = GeneralWatcher; using DetailAsync = GenAsync; using Devices = std::vector; + using Executor = ExecutorPool; enum SyncMode { NEARBY_BEGIN, NEARBY_PUSH = NEARBY_BEGIN, @@ -60,6 +63,15 @@ public: CLEAN_MODE_BUTT }; + enum Area : int32_t { + EL0, + EL1, + EL2, + EL3, + EL4, + EL5 + }; + static inline uint32_t MixMode(uint32_t syncMode, uint32_t highMode) { return syncMode | highMode; @@ -107,6 +119,8 @@ public: virtual ~GeneralStore() = default; + virtual void SetExecutor(std::shared_ptr executor) = 0; + virtual int32_t Bind(Database &database, const std::map &bindInfos, const CloudConfig &config) = 0; @@ -129,13 +143,14 @@ public: virtual int32_t Delete(const std::string &table, const std::string &sql, Values &&args) = 0; - virtual std::shared_ptr Query(const std::string &table, const std::string &sql, Values &&args) = 0; + virtual std::pair> Query(const std::string &table, const std::string &sql, + Values &&args) = 0; - virtual std::shared_ptr Query(const std::string &table, GenQuery &query) = 0; + virtual std::pair> Query(const std::string &table, GenQuery &query) = 0; virtual int32_t Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) = 0; - virtual std::shared_ptr PreSharing(GenQuery &query) = 0; + virtual std::pair> PreSharing(GenQuery &query) = 0; virtual int32_t Clean(const std::vector &devices, int32_t mode, const std::string &tableName) = 0; @@ -147,7 +162,7 @@ public: virtual int32_t UnregisterDetailProgressObserver() = 0; - virtual int32_t Close() = 0; + virtual int32_t Close(bool isForce = false) = 0; virtual int32_t AddRef() = 0; @@ -162,6 +177,10 @@ public: virtual void SetEqualIdentifier(const std::string &appId, const std::string &storeId) {}; virtual void SetConfig(const StoreConfig &storeConfig) {}; + + virtual std::pair LockCloudDB() = 0; + + virtual int32_t UnLockCloudDB() = 0; }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_STORE_H diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h b/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h index aed711a1..f0bc9b25 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h @@ -31,6 +31,15 @@ enum GenProgress { SYNC_FINISH, }; +enum SyncTriggerMode { + MODE_DEFAULT = 0, + MODE_PUSH, + MODE_ONLINE, + MODE_UNLOCK, + MODE_BROADCASTER, + MODE_CONSISTENCY, +}; + struct GenStatistic { uint32_t total; uint32_t success; @@ -47,6 +56,7 @@ struct GenProgressDetail { int32_t progress; int32_t code; int32_t dbCode; + uint64_t changeCount = 0; std::map details; }; @@ -86,6 +96,7 @@ struct SyncParam { int32_t mode; int32_t wait; bool isCompensation = false; + int32_t triggerMode = MODE_DEFAULT; }; using Assets = std::vector; diff --git a/datamgr_service/services/distributeddataservice/framework/include/utils/constant.h b/datamgr_service/services/distributeddataservice/framework/include/utils/constant.h index ff0dffda..bfeaee6b 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/utils/constant.h +++ b/datamgr_service/services/distributeddataservice/framework/include/utils/constant.h @@ -42,6 +42,8 @@ public: API_EXPORT static bool NotEqual(bool first, bool second); + API_EXPORT static std::vector Split(const std::string &str, const std::string &delim); + template inline static constexpr bool is_pod = (std::is_standard_layout_v && std::is_trivial_v); diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/auto_launch_meta_data.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/auto_launch_meta_data.cpp index 3224368c..8ecf15ed 100644 --- a/datamgr_service/services/distributeddataservice/framework/metadata/auto_launch_meta_data.cpp +++ b/datamgr_service/services/distributeddataservice/framework/metadata/auto_launch_meta_data.cpp @@ -25,12 +25,14 @@ AutoLaunchMetaData::AutoLaunchMetaData() bool AutoLaunchMetaData::Marshal(json& node) const { SetValue(node[GET_NAME(datas)], datas); + SetValue(node[GET_NAME(launchForCleanData)], launchForCleanData); return true; } bool AutoLaunchMetaData::Unmarshal(const json& node) { GetValue(node, GET_NAME(datas), datas); + GetValue(node, GET_NAME(launchForCleanData), launchForCleanData); return true; } diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp index 1f77a82b..777a8d93 100644 --- a/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp +++ b/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp @@ -29,8 +29,8 @@ public: using DBOrigin = DistributedDB::Origin; using DBChangeData = DistributedDB::ChangedData; using Type = DistributedDB::Type; - MetaObserver(std::shared_ptr metaStore, - std::shared_ptr filter, Observer observer, bool isLocal = false); + MetaObserver(std::shared_ptr metaStore, std::shared_ptr filter, Observer observer, + bool isLocal = false); virtual ~MetaObserver(); // Database change callback @@ -38,14 +38,15 @@ public: void OnChange(DBOrigin origin, const std::string &originalId, DBChangeData &&data) override; void HandleChanges(int32_t flag, std::vector> &priData); + private: std::shared_ptr metaStore_; std::shared_ptr filter_; Observer observer_; }; -MetaObserver::MetaObserver(std::shared_ptr metaStore, - std::shared_ptr filter, Observer observer, bool isLocal) +MetaObserver::MetaObserver( + std::shared_ptr metaStore, std::shared_ptr filter, Observer observer, bool isLocal) : metaStore_(std::move(metaStore)), filter_(std::move(filter)), observer_(std::move(observer)) { if (metaStore_ != nullptr) { @@ -78,8 +79,7 @@ std::vector MetaDataManager::Filter::GetKey() const return std::vector(); } -MetaDataManager::Filter::Filter(const std::string &pattern) - : pattern_(pattern) +MetaDataManager::Filter::Filter(const std::string &pattern) : pattern_(pattern) { } @@ -191,8 +191,8 @@ bool MetaDataManager::SaveMeta(const std::string &key, const Serializable &value cloudSyncer_(); } if (status != DistributedDB::DBStatus::OK) { - ZLOGE("failed! status:%{public}d isLocal:%{public}d, key:%{public}s", - status, isLocal, Anonymous::Change(key).c_str()); + ZLOGE("failed! status:%{public}d isLocal:%{public}d, key:%{public}s", status, isLocal, + Anonymous::Change(key).c_str()); } return status == DistributedDB::DBStatus::OK; } @@ -256,8 +256,7 @@ bool MetaDataManager::Sync(const std::vector &devices, OnComplete c if (!inited_ || devices.empty()) { return false; } - auto status = metaStore_->Sync( - devices, DistributedDB::SyncMode::SYNC_MODE_PUSH_PULL, [complete](auto &dbResults) { + auto status = metaStore_->Sync(devices, DistributedDB::SyncMode::SYNC_MODE_PUSH_PULL, [complete](auto &dbResults) { std::map results; for (auto &[uuid, status] : dbResults) { results.insert_or_assign(uuid, static_cast(status)); @@ -276,10 +275,9 @@ bool MetaDataManager::Subscribe(std::shared_ptr filter, Observer observe return false; } - return metaObservers_.ComputeIfAbsent( - "", [ this, &observer, &filter ](const std::string &key) -> auto { - return std::make_shared(metaStore_, filter, observer); - }); + return metaObservers_.ComputeIfAbsent("", [this, &observer, &filter](const std::string &key) -> auto { + return std::make_shared(metaStore_, filter, observer); + }); } bool MetaDataManager::Subscribe(std::string prefix, Observer observer, bool isLocal) @@ -288,10 +286,9 @@ bool MetaDataManager::Subscribe(std::string prefix, Observer observer, bool isLo return false; } - return metaObservers_.ComputeIfAbsent( - prefix, [ this, isLocal, &observer, &prefix ](const std::string &key) -> auto { - return std::make_shared(metaStore_, std::make_shared(prefix), observer, isLocal); - }); + return metaObservers_.ComputeIfAbsent(prefix, [this, isLocal, &observer, &prefix](const std::string &key) -> auto { + return std::make_shared(metaStore_, std::make_shared(prefix), observer, isLocal); + }); } bool MetaDataManager::Unsubscribe(std::string filter) diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp index 219780e5..2a31c380 100644 --- a/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp +++ b/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp @@ -55,14 +55,14 @@ bool StoreMetaData::Marshal(json &node) const SetValue(node[GET_NAME(dataType)], dataType); SetValue(node[GET_NAME(enableCloud)], enableCloud); SetValue(node[GET_NAME(cloudAutoSync)], cloudAutoSync); - // compatible with the versions which lower than VERSION_TAG_0000 SetValue(node[GET_NAME(kvStoreType)], storeType); SetValue(node[GET_NAME(deviceAccountID)], user); SetValue(node[GET_NAME(userId)], account); SetValue(node[GET_NAME(UID)], uid); SetValue(node[GET_NAME(customDir)], customDir); - + SetValue(node[GET_NAME(authType)], authType); + SetValue(node[GET_NAME(haMode)], haMode); return true; } @@ -95,7 +95,6 @@ bool StoreMetaData::Unmarshal(const json &node) GetValue(node, GET_NAME(dataType), dataType); GetValue(node, GET_NAME(enableCloud), enableCloud); GetValue(node, GET_NAME(cloudAutoSync), cloudAutoSync); - // compatible with the older versions if (version < FIELD_CHANGED_TAG) { GetValue(node, GET_NAME(kvStoreType), storeType); @@ -104,6 +103,8 @@ bool StoreMetaData::Unmarshal(const json &node) GetValue(node, GET_NAME(userId), account); } GetValue(node, GET_NAME(customDir), customDir); + GetValue(node, GET_NAME(authType), authType); + GetValue(node, GET_NAME(haMode), haMode); return true; } @@ -120,7 +121,7 @@ StoreMetaData::StoreMetaData(const std::string &userId, const std::string &appId { } -StoreMetaData::StoreMetaData(const StoreInfo& storeInfo) +StoreMetaData::StoreMetaData(const StoreInfo &storeInfo) : instanceId(storeInfo.instanceId), bundleName(storeInfo.bundleName), storeId(storeInfo.storeName), user(std::to_string(storeInfo.user)) { @@ -141,7 +142,7 @@ bool StoreMetaData::operator==(const StoreMetaData &metaData) const tokenId == metaData.tokenId && instanceId == metaData.instanceId && appId == metaData.appId && appType == metaData.appType && bundleName == metaData.bundleName && dataDir == metaData.dataDir && storeId == metaData.storeId && user == metaData.user && deviceId == metaData.deviceId && - account == metaData.account); + account == metaData.account && authType == metaData.authType && haMode == metaData.haMode); } bool StoreMetaData::operator!=(const StoreMetaData &metaData) const diff --git a/datamgr_service/services/distributeddataservice/framework/screen/screen_manager.cpp b/datamgr_service/services/distributeddataservice/framework/screen/screen_manager.cpp new file mode 100644 index 00000000..9f7698f5 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/screen/screen_manager.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 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 "ScreenManager" +#include "screen/screen_manager.h" +#include "log_print.h" + +namespace OHOS::DistributedData { +std::mutex ScreenManager::mutex_; +std::shared_ptr ScreenManager::instance_ = nullptr; +std::shared_ptr ScreenManager::GetInstance() +{ + std::lock_guard lock(mutex_); + if (instance_ != nullptr) { + return instance_; + } + instance_ = std::make_shared(); + ZLOGW("no register, new instance!"); + return instance_; +} + +bool ScreenManager::RegisterInstance(std::shared_ptr instance) +{ + std::lock_guard lock(mutex_); + instance_ = std::move(instance); + return true; +} + +bool ScreenManager::IsLocked() +{ + return false; +} + +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp b/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp index 0e5420b2..fa94983b 100644 --- a/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp +++ b/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp @@ -13,13 +13,15 @@ * limitations under the License. */ #define LOG_TAG "AutoCache" +#include "store/auto_cache.h" + #include + #include "changeevent/remote_change_event.h" #include "eventcenter/event_center.h" -#include "utils/anonymous.h" -#include "store/auto_cache.h" - #include "log_print.h" +#include "screenlock/screen_lock.h" +#include "utils/anonymous.h" namespace OHOS::DistributedData { AutoCache &AutoCache::GetInstance() { @@ -41,10 +43,12 @@ void AutoCache::Bind(std::shared_ptr executor) if (executor == nullptr || taskId_ != Executor::INVALID_TASK_ID) { return; } - executor_ = executor; + executor_ = std::move(executor); } -AutoCache::AutoCache() {} +AutoCache::AutoCache() +{ +} AutoCache::~AutoCache() { @@ -57,15 +61,22 @@ AutoCache::~AutoCache() AutoCache::Store AutoCache::GetStore(const StoreMetaData &meta, const Watchers &watchers) { Store store; - if (meta.storeType >= MAX_CREATOR_NUM || meta.storeType < 0 || !creators_[meta.storeType] || - disables_.ContainIf(meta.tokenId, [&meta](const std::set& stores) -> bool { + if ((meta.area >= GeneralStore::EL4 && ScreenManager::GetInstance()->IsLocked()) || + meta.storeType >= MAX_CREATOR_NUM || meta.storeType < 0 || !creators_[meta.storeType] || + disables_.ContainIf(meta.tokenId, [&meta](const std::set &stores) -> bool { return stores.count(meta.storeId) != 0; })) { return store; } - stores_.Compute(meta.tokenId, - [this, &meta, &watchers, &store](auto &, std::map &stores) -> bool { + stores_.Compute( + meta.tokenId, [this, &meta, &watchers, &store](auto &, std::map &stores) -> bool { + if (disableStores_.count(meta.dataDir) != 0) { + ZLOGW("store is closing, tokenId:0x%{public}x user:%{public}s" + "bundleName:%{public}s storeName:%{public}s", + meta.tokenId, meta.user.c_str(), meta.bundleName.c_str(), meta.GetStoreAlias().c_str()); + return !stores.empty(); + } auto it = stores.find(meta.storeId); if (it != stores.end()) { if (!watchers.empty()) { @@ -79,6 +90,7 @@ AutoCache::Store AutoCache::GetStore(const StoreMetaData &meta, const Watchers & ZLOGE("creator failed. storeName:%{public}s", meta.GetStoreAlias().c_str()); return !stores.empty(); } + dbStore->SetExecutor(executor_); auto result = stores.emplace(std::piecewise_construct, std::forward_as_tuple(meta.storeId), std::forward_as_tuple(dbStore, watchers, atoi(meta.user.c_str()), meta)); store = result.first->second; @@ -88,22 +100,23 @@ AutoCache::Store AutoCache::GetStore(const StoreMetaData &meta, const Watchers & return store; } -AutoCache::Stores AutoCache::GetStoresIfPresent(uint32_t tokenId, const std::string& storeName) +AutoCache::Stores AutoCache::GetStoresIfPresent(uint32_t tokenId, const std::string &storeName) { Stores stores; - stores_.ComputeIfPresent(tokenId, [&stores, &storeName](auto&, std::map& delegates) -> bool { - if (storeName.empty()) { - for (auto& [_, delegate] : delegates) { - stores.push_back(delegate); - } - } else { - auto it = delegates.find(storeName); - if (it != delegates.end()) { - stores.push_back(it->second); + stores_.ComputeIfPresent( + tokenId, [&stores, &storeName](auto &, std::map &delegates) -> bool { + if (storeName.empty()) { + for (auto &[_, delegate] : delegates) { + stores.push_back(delegate); + } + } else { + auto it = delegates.find(storeName); + if (it != delegates.end()) { + stores.push_back(it->second); + } } - } - return !stores.empty(); - }); + return !stores.empty(); + }); return stores; } @@ -131,31 +144,51 @@ void AutoCache::StartTimer() void AutoCache::CloseStore(uint32_t tokenId, const std::string &storeId) { - stores_.ComputeIfPresent(tokenId, [&storeId](auto &key, std::map &delegates) { - auto it = delegates.find(storeId); - if (it != delegates.end()) { - it->second.Close(); - delegates.erase(it); + ZLOGD("close store start, store:%{public}s, token:%{public}u", Anonymous::Change(storeId).c_str(), tokenId); + std::set storeIds; + std::list closeStores; + bool isScreenLocked = ScreenManager::GetInstance()->IsLocked(); + stores_.ComputeIfPresent(tokenId, + [this, &storeId, isScreenLocked, &storeIds, &closeStores](auto &key, auto &delegates) { + auto it = delegates.begin(); + while (it != delegates.end()) { + if ((storeId == it->first || storeId.empty()) && + (!isScreenLocked || it->second.GetArea() < GeneralStore::EL4) && + disableStores_.count(it->second.GetDataDir()) == 0) { + disableStores_.insert(it->second.GetDataDir()); + storeIds.insert(it->first); + closeStores.emplace(closeStores.end(), it->second); + } else { + ++it; + } + } + return !delegates.empty(); + }); + closeStores.clear(); + stores_.ComputeIfPresent(tokenId, [this, &storeIds](auto &key, auto &delegates) { + for (auto it = delegates.begin(); it != delegates.end();) { + if (storeIds.count(it->first) != 0) { + disableStores_.erase(it->second.GetDataDir()); + it = delegates.erase(it); + } else { + ++it; + } } return !delegates.empty(); }); } -void AutoCache::CloseStore(uint32_t tokenId) -{ - stores_.Erase(tokenId); -} - void AutoCache::CloseExcept(const std::set &users) { - stores_.EraseIf([&users](const auto &tokenId, std::map &delegates) { + bool isScreenLocked = ScreenManager::GetInstance()->IsLocked(); + stores_.EraseIf([&users, isScreenLocked](const auto &tokenId, std::map &delegates) { if (delegates.empty() || users.count(delegates.begin()->second.GetUser()) != 0) { return delegates.empty(); } for (auto it = delegates.begin(); it != delegates.end();) { // if the kv store is BUSY we wait more INTERVAL minutes again - if (!it->second.Close()) { + if ((isScreenLocked && it->second.GetArea() >= GeneralStore::EL4) || !it->second.Close()) { ++it; } else { it = delegates.erase(it); @@ -168,8 +201,8 @@ void AutoCache::CloseExcept(const std::set &users) void AutoCache::SetObserver(uint32_t tokenId, const std::string &storeId, const AutoCache::Watchers &watchers) { stores_.ComputeIfPresent(tokenId, [&storeId, &watchers](auto &key, auto &stores) { - ZLOGD("tokenId:0x%{public}x storeId:%{public}s observers:%{public}zu", key, Anonymous::Change(storeId).c_str(), - watchers.size()); + ZLOGD("tokenId:0x%{public}x storeId:%{public}s observers:%{public}zu", key, + Anonymous::Change(storeId).c_str(), watchers.size()); auto it = stores.find(storeId); if (it != stores.end()) { it->second.SetObservers(watchers); @@ -181,10 +214,12 @@ void AutoCache::SetObserver(uint32_t tokenId, const std::string &storeId, const void AutoCache::GarbageCollect(bool isForce) { auto current = std::chrono::steady_clock::now(); - stores_.EraseIf([¤t, isForce](auto &key, std::map &delegates) { + bool isScreenLocked = ScreenManager::GetInstance()->IsLocked(); + stores_.EraseIf([¤t, isForce, isScreenLocked](auto &key, std::map &delegates) { for (auto it = delegates.begin(); it != delegates.end();) { // if the store is BUSY we wait more INTERVAL minutes again - if ((isForce || it->second < current) && it->second.Close()) { + if ((!isScreenLocked || it->second.GetArea() < GeneralStore::EL4) && (isForce || it->second < current) && + it->second.Close()) { it = delegates.erase(it); } else { ++it; @@ -194,25 +229,24 @@ void AutoCache::GarbageCollect(bool isForce) }); } -void AutoCache::Enable(uint32_t tokenId, const std::string& storeId) +void AutoCache::Enable(uint32_t tokenId, const std::string &storeId) { - disables_.ComputeIfPresent(tokenId, [&storeId](auto key, std::set& stores) { + disables_.ComputeIfPresent(tokenId, [&storeId](auto key, std::set &stores) { stores.erase(storeId); return !(stores.empty() || storeId.empty()); }); } -void AutoCache::Disable(uint32_t tokenId, const std::string& storeId) +void AutoCache::Disable(uint32_t tokenId, const std::string &storeId) { - disables_.Compute(tokenId, [&storeId](auto key, std::set& stores) { + disables_.Compute(tokenId, [&storeId](auto key, std::set &stores) { stores.insert(storeId); return !stores.empty(); }); CloseStore(tokenId, storeId); } -AutoCache::Delegate::Delegate(GeneralStore *delegate, const Watchers &watchers, int32_t user, - const StoreMetaData &meta) +AutoCache::Delegate::Delegate(GeneralStore *delegate, const Watchers &watchers, int32_t user, const StoreMetaData &meta) : store_(delegate), watchers_(watchers), user_(user), meta_(meta) { time_ = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL); @@ -221,11 +255,19 @@ AutoCache::Delegate::Delegate(GeneralStore *delegate, const Watchers &watchers, } } +AutoCache::Delegate::Delegate(const Delegate& delegate) +{ + store_ = delegate.store_; + if (store_ != nullptr) { + store_->AddRef(); + } +} + AutoCache::Delegate::~Delegate() { if (store_ != nullptr) { + store_->Close(true); store_->Unwatch(Origin::ORIGIN_ALL, *this); - store_->Close(); store_->Release(); store_ = nullptr; } @@ -248,7 +290,6 @@ bool AutoCache::Delegate::operator<(const AutoCache::Time &time) const bool AutoCache::Delegate::Close() { - std::unique_lock lock(mutex_); if (store_ != nullptr) { auto status = store_->Close(); if (status == Error::E_BUSY) { @@ -270,6 +311,16 @@ int32_t AutoCache::Delegate::GetUser() const return user_; } +int32_t AutoCache::Delegate::GetArea() const +{ + return meta_.area; +} + +const std::string& AutoCache::Delegate::GetDataDir() const +{ + return meta_.dataDir; +} + int32_t AutoCache::Delegate::OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) { std::vector tables; @@ -327,4 +378,4 @@ void AutoCache::Delegate::PostDataChange(const StoreMetaData &meta, const std::v auto evt = std::make_unique(RemoteChangeEvent::DATA_CHANGE, std::move(info)); EventCenter::GetInstance().PostEvent(std::move(evt)); } -} // namespace OHOS::DistributedData +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/BUILD.gn b/datamgr_service/services/distributeddataservice/framework/test/BUILD.gn index 026e7a90..2476ad7d 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/framework/test/BUILD.gn @@ -127,6 +127,11 @@ ohos_unittest("ServiceUtilsTest") { configs = [ ":module_private_config" ] + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] + external_deps = [ "access_token:libaccesstoken_sdk", "access_token:libnativetoken", diff --git a/datamgr_service/services/distributeddataservice/framework/test/checker_manager_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/checker_manager_test.cpp index 8dfc80b4..d95a7df7 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/checker_manager_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/checker_manager_test.cpp @@ -170,4 +170,36 @@ HWTEST_F(CheckerManagerTest, BundleChecker, TestSize.Level0) AccessTokenKit::GetHapTokenInfo(storeInfo.tokenId, tokenInfo); ASSERT_EQ(Crypto::Sha256(tokenInfo.appID), CheckerManager::GetInstance().GetAppId(storeInfo)); ASSERT_TRUE(CheckerManager::GetInstance().IsValid(storeInfo)); +} + +/** +* @tc.name: IsDynamic +* @tc.desc: checker data type. +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(CheckerManagerTest, IsDynamic, TestSize.Level0) +{ + CheckerManager::StoreInfo storeInfo; + storeInfo.uid = 2000000; + storeInfo.tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.test.demo", 0); + storeInfo.bundleName = "ohos.test.demo"; + ASSERT_FALSE(CheckerManager::GetInstance().IsDynamic(storeInfo)); +} + +/** +* @tc.name: IsStatic +* @tc.desc: checker data type. +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(CheckerManagerTest, IsStatic, TestSize.Level0) +{ + CheckerManager::StoreInfo storeInfo; + storeInfo.uid = 2000000; + storeInfo.tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.test.demo", 0); + storeInfo.bundleName = "ohos.test.demo"; + ASSERT_FALSE(CheckerManager::GetInstance().IsStatic(storeInfo)); } \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp index 15a83e10..90232b18 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp @@ -18,11 +18,13 @@ #include "serializable/serializable.h" #include "cloud/cloud_db.h" +#include "cloud/cloud_event.h" #include "cloud/cloud_info.h" #include "cloud/cloud_server.h" #include "cloud/schema_meta.h" #include "nlohmann/json.hpp" #include "utils/crypto.h" +#include "screen/screen_manager.h" #include "store/general_store.h" #include "store/general_value.h" #include "store/general_watcher.h" @@ -54,6 +56,22 @@ public: void TearDown(){}; }; +class CloudEventTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + +class ScreenManagerTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + class MockGeneralWatcher : public DistributedData::GeneralWatcher { public: int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, @@ -207,13 +225,13 @@ HWTEST_F(CloudInfoTest, GetPrefix, TestSize.Level0) } /** -* @tc.name: CloudInfoTest +* @tc.name: CloudInfoTest001 * @tc.desc: Marshal and Unmarshal of CloudInfo. * @tc.type: FUNC * @tc.require: * @tc.author: Anvette */ -HWTEST_F(CloudInfoTest, CloudInfoTest, TestSize.Level0) +HWTEST_F(CloudInfoTest, CloudInfoTest001, TestSize.Level0) { CloudInfo cloudInfo1; cloudInfo1.user = 111; @@ -231,6 +249,33 @@ HWTEST_F(CloudInfoTest, CloudInfoTest, TestSize.Level0) EXPECT_EQ(Serializable::Marshall(cloudInfo1), Serializable::Marshall(cloudInfo1)); } +/** +* @tc.name: CloudInfoTest002 +* @tc.desc: Marshal and Unmarshal of CloudInfo. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(CloudInfoTest, CloudInfoTest002, TestSize.Level0) +{ + CloudInfo cloudInfo1; + cloudInfo1.user = 111; + cloudInfo1.id = "test1_id"; + cloudInfo1.totalSpace = 0; + cloudInfo1.remainSpace = 0; + cloudInfo1.enableCloud = false; + cloudInfo1.maxNumber = CloudInfo::DEFAULT_BATCH_NUMBER; + cloudInfo1.maxSize = CloudInfo::DEFAULT_BATCH_SIZE; + + Serializable::json node1; + cloudInfo1.Marshal(node1); + EXPECT_EQ(Serializable::Marshall(cloudInfo1), to_string(node1)); + + CloudInfo cloudInfo2; + cloudInfo2.Unmarshal(node1); + EXPECT_EQ(Serializable::Marshall(cloudInfo1), Serializable::Marshall(cloudInfo1)); +} + /** * @tc.name: AppInfoTest * @tc.desc: Marshal and Unmarshal of AppInfo. @@ -506,4 +551,32 @@ HWTEST_F(CloudInfoTest, SchemaMeta, TestSize.Level0) auto result2 = schemaMeta.GetHighVersion(); EXPECT_EQ(result2, metaVersion); } + +/** +* @tc.name: GetEventId +* @tc.desc: test GetEventId function +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(CloudEventTest, GetEventId, TestSize.Level0) +{ + int32_t evtId = 1; + StoreInfo info; + CloudEvent event(evtId, info); + auto ret = event.GetEventId(); + EXPECT_EQ(ret, evtId); +} + +/** +* @tc.name: IsLocked +* @tc.desc: test IsLocked function +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(ScreenManagerTest, IsLocked, TestSize.Level0) +{ + ASSERT_FALSE(ScreenManager::GetInstance()->IsLocked()); +} } // namespace OHOS::Test diff --git a/datamgr_service/services/distributeddataservice/framework/test/constant_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/constant_test.cpp index a5147d35..79e748d8 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/constant_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/constant_test.cpp @@ -31,14 +31,10 @@ class ConstantTest : public testing::Test { */ HWTEST_F(ConstantTest, EqualTest, TestSize.Level1) { - bool result = Constant::Equal(true, true); - ASSERT_TRUE(result); - - result = Constant::Equal(true, false); - ASSERT_FALSE(result); - - result = OHOS::DistributedData::Constant::Equal(false, false); - ASSERT_TRUE(result); + ASSERT_TRUE(Constant::Equal(true, true)); + ASSERT_TRUE(Constant::Equal(false, false)); + ASSERT_FALSE(Constant::Equal(true, false)); + ASSERT_FALSE(Constant::Equal(false, true)); } /** @@ -50,12 +46,127 @@ HWTEST_F(ConstantTest, EqualTest, TestSize.Level1) */ HWTEST_F(ConstantTest, NotEqualTest, TestSize.Level1) { - bool result = Constant::NotEqual(true, true); - ASSERT_FALSE(result); + ASSERT_TRUE(Constant::NotEqual(true, false)); + ASSERT_TRUE(Constant::NotEqual(false, true)); + ASSERT_FALSE(Constant::NotEqual(true, true)); + ASSERT_FALSE(Constant::NotEqual(false, false)); +} + +/** +* @tc.name: SplitTest +* @tc.desc: SplitEmptyStringTest. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ConstantTest, SplitEmptyStringTest, TestSize.Level1) +{ + auto tokens = Constant::Split("", ","); + ASSERT_EQ(tokens.size(), 1); + EXPECT_EQ(tokens[0], ""); +} + +/** +* @tc.name: SplitTest +* @tc.desc: SplitStringOneDelimTest. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ConstantTest, SplitStringOneDelimTest, TestSize.Level1) +{ + auto tokens = Constant::Split("abc_123", "_"); + ASSERT_EQ(tokens.size(), 2); + EXPECT_EQ(tokens[0], "abc"); + EXPECT_EQ(tokens[1], "123"); +} + +/** +* @tc.name: SplitTest +* @tc.desc: SplitStringOneDelimAtBeginTest. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ConstantTest, SplitStringOneDelimAtBeginTest, TestSize.Level1) +{ + auto tokens = Constant::Split("#abc123", "#"); + ASSERT_EQ(tokens.size(), 2); + EXPECT_EQ(tokens[0], ""); + EXPECT_EQ(tokens[1], "abc123"); +} + +/** +* @tc.name: SplitTest +* @tc.desc: SplitStringOneDelimAtEndTest. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ConstantTest, SplitStringOneDelimAtEndTest, TestSize.Level1) +{ + auto tokens = Constant::Split("abc123!", "!"); + ASSERT_EQ(tokens.size(), 1); + EXPECT_EQ(tokens[0], "abc123"); +} + +/** +* @tc.name: SplitTest +* @tc.desc: SplitStringMutipleDelimTest. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ConstantTest, SplitStringMutipleDelimTest, TestSize.Level1) +{ + auto tokens = Constant::Split("abc!123!", "!"); + ASSERT_EQ(tokens.size(), 2); + EXPECT_EQ(tokens[0], "abc"); + EXPECT_EQ(tokens[1], "123"); +} + +/** +* @tc.name: SplitTest +* @tc.desc: SplitStringNoDelimTest. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ConstantTest, SplitStringNoDelimTest, TestSize.Level1) +{ + auto tokens = Constant::Split("abc123", "^"); + ASSERT_EQ(tokens.size(), 1); + EXPECT_EQ(tokens[0], "abc123"); +} - result = Constant::NotEqual(true, false); - ASSERT_TRUE(result); +/** +* @tc.name: SplitTest +* @tc.desc: SplitStringContinuousDelimTest. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ConstantTest, SplitStringContinuousDelimTest, TestSize.Level1) +{ + auto tokens = Constant::Split("abc$$$123", "$"); + ASSERT_EQ(tokens.size(), 4); + EXPECT_EQ(tokens[0], "abc"); + EXPECT_EQ(tokens[1], ""); + EXPECT_EQ(tokens[2], ""); + EXPECT_EQ(tokens[3], "123"); +} - result = Constant::NotEqual(false, false); - ASSERT_FALSE(result); +/** +* @tc.name: SplitTest +* @tc.desc: SplitStringLongDelimTest. +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(ConstantTest, SplitStringLongDelimTest, TestSize.Level1) +{ + auto tokens = Constant::Split("abc&&&123", "&&"); + ASSERT_EQ(tokens.size(), 2); + EXPECT_EQ(tokens[0], "abc"); + EXPECT_EQ(tokens[1], "&123"); } diff --git a/datamgr_service/services/distributeddataservice/framework/test/feature_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/feature_test.cpp index 5490d043..befe45f8 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/feature_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/feature_test.cpp @@ -257,4 +257,19 @@ HWTEST_F(FeatureSystemTest, FeatureTest002, TestSize.Level1) ret = mockFeature.OnSessionReady(device); EXPECT_EQ(ret, E_OK); } + +/** +* @tc.name: OnScreenUnlockedTest +* @tc.desc: test OnScreenUnlocked +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(FeatureSystemTest, OnScreenUnlockedTest, TestSize.Level1) +{ + MockFeature mockFeature; + int32_t user = 0; + int32_t ret = mockFeature.OnScreenUnlocked(user); + EXPECT_EQ(ret, E_OK); +} } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/meta_data_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/meta_data_test.cpp index 992b78a6..1e99a721 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/meta_data_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/meta_data_test.cpp @@ -45,7 +45,6 @@ public: static void SetUpTestCase() { std::shared_ptr executors = std::make_shared(NUM_MAX, NUM_MIN); - Bootstrap::GetInstance().LoadComponents(); Bootstrap::GetInstance().LoadDirectory(); Bootstrap::GetInstance().LoadCheckers(); KvStoreMetaManager::GetInstance().BindExecutor(executors); @@ -462,6 +461,16 @@ HWTEST_F(ServiceMetaDataTest, StoreMetaData006, TestSize.Level1) EXPECT_FALSE(storemetaData1 == storemetaData2); storemetaData2.isNeedCompress = true; EXPECT_TRUE(storemetaData1 == storemetaData2); + + storemetaData1.enableCloud = true; + EXPECT_FALSE(storemetaData1 == storemetaData2); + storemetaData2.enableCloud = true; + EXPECT_TRUE(storemetaData1 == storemetaData2); + + storemetaData1.cloudAutoSync = true; + EXPECT_FALSE(storemetaData1 == storemetaData2); + storemetaData2.cloudAutoSync = true; + EXPECT_TRUE(storemetaData1 == storemetaData2); } /** @@ -508,6 +517,16 @@ HWTEST_F(ServiceMetaDataTest, StoreMetaData007, TestSize.Level1) EXPECT_TRUE(storemetaData1 != storemetaData2); storemetaData2.isNeedCompress = true; EXPECT_FALSE(storemetaData1 != storemetaData2); + + storemetaData1.enableCloud = true; + EXPECT_TRUE(storemetaData1 != storemetaData2); + storemetaData2.enableCloud = true; + EXPECT_FALSE(storemetaData1 != storemetaData2); + + storemetaData1.cloudAutoSync = true; + EXPECT_TRUE(storemetaData1 != storemetaData2); + storemetaData2.cloudAutoSync = true; + EXPECT_FALSE(storemetaData1 != storemetaData2); } /** @@ -771,5 +790,8 @@ HWTEST_F(ServiceMetaDataTest, MatrixMetaData, TestSize.Level1) matrixMetaData3.deviceId = "DEVICE_ID"; EXPECT_TRUE(matrixMetaData1 != matrixMetaData3); EXPECT_FALSE(matrixMetaData1 != matrixMetaData2); + + std::string key = matrixMetaData3.GetConsistentKey(); + EXPECT_EQ(key, "MatrixMeta###DEVICE_ID###Consistent"); } } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp index fa78ec5d..5527998e 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp @@ -37,22 +37,45 @@ public: HWTEST_F(StoreMetaDataLocalTest, EqualityOperatorTest, TestSize.Level1) { StoreMetaDataLocal metaData1; - metaData1.isAutoSync = true; - metaData1.isBackup = true; StoreMetaDataLocal metaData2; - metaData2.isAutoSync = true; - metaData2.isBackup = false; StoreMetaDataLocal metaData3; + + ASSERT_TRUE(metaData1 == metaData2); metaData3.isAutoSync = true; + ASSERT_FALSE(metaData1 == metaData3); metaData3.isBackup = true; + ASSERT_FALSE(metaData1 == metaData3); + ASSERT_TRUE(metaData1 != metaData3); + ASSERT_FALSE(metaData1 != metaData2); + metaData3.isDirty = true; + ASSERT_FALSE(metaData1 == metaData3); + metaData3.isEncrypt = true; + ASSERT_FALSE(metaData1 == metaData3); + metaData3.isPublic = true; + ASSERT_FALSE(metaData1 == metaData3); - ASSERT_FALSE(metaData1 == metaData2); - ASSERT_TRUE(metaData1 == metaData3); + metaData2.isAutoSync = true; + ASSERT_FALSE(metaData2 == metaData3); + metaData2.isBackup = true; + ASSERT_FALSE(metaData2 == metaData3); + metaData2.isDirty = true; + ASSERT_FALSE(metaData2 == metaData3); + metaData2.isEncrypt = true; ASSERT_FALSE(metaData2 == metaData3); + metaData2.isPublic = true; + ASSERT_TRUE(metaData2 == metaData3); - ASSERT_TRUE(metaData1 != metaData2); - ASSERT_FALSE(metaData1 != metaData3); - ASSERT_TRUE(metaData2 != metaData3); + metaData2.isBackup = false; + ASSERT_FALSE(metaData2 == metaData3); + metaData2.isBackup = true; + metaData2.isDirty = false; + ASSERT_FALSE(metaData2 == metaData3); + metaData2.isBackup = true; + metaData2.isEncrypt = false; + ASSERT_FALSE(metaData2 == metaData3); + metaData2.isBackup = true; + metaData2.isPublic = false; + ASSERT_FALSE(metaData2 == metaData3); } /** @@ -95,5 +118,8 @@ HWTEST_F(StoreMetaDataLocalTest, GetPolicy, TestSize.Level1) policy.index = 1; EXPECT_FALSE(metaData.HasPolicy(type)); EXPECT_TRUE(policy.IsValueEffect()); + type = UINT32_MAX; + policy = metaData.GetPolicy(type); + EXPECT_EQ(policy.type, type); } } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/store_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/store_test.cpp index 322b494a..18db822c 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/store_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/store_test.cpp @@ -21,7 +21,6 @@ #include "metadata/store_meta_data.h" #include "rdb_query.h" #include "rdb_types.h" -#define private public #include "store/auto_cache.h" #include "store/general_store.h" #include "store/general_value.h" diff --git a/datamgr_service/services/distributeddataservice/framework/test/utils_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/utils_test.cpp index e81c8602..7f5da600 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/utils_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/utils_test.cpp @@ -21,6 +21,7 @@ #include "ipc_skeleton.h" #include "log_print.h" #include "utils/block_integer.h" +#include "utils/constant.h" #include "utils/converter.h" #include "utils/ref_count.h" #include "utils/endian_converter.h" @@ -130,6 +131,10 @@ HWTEST_F(RefCountTest, Constructortest, TestSize.Level2) std::function action = []() { }; RefCount refCountWithAction(action); EXPECT_TRUE(refCountWithAction); + + std::function actions; + RefCount refCountWithActions(actions); + EXPECT_TRUE(refCountWithActions); int num = 0; { RefCount refCount([&num]() { @@ -158,6 +163,8 @@ HWTEST_F(RefCountTest, Constructortest, TestSize.Level2) RefCount refCount6 = std::move(refCount2); refCount6 = std::move(refCount4); ASSERT_TRUE(refCount6); + + EXPECT_TRUE(refCount5 = refCount5); } ASSERT_EQ(num, 10); } @@ -189,4 +196,34 @@ HWTEST_F(ServiceUtilsTest, HostToNet, TestSize.Level1) uint64_t hostValue64 = NetToHost(NET_VALUE64); EXPECT_EQ(hostValue64, le64toh(NET_VALUE64)); } + +/** +* @tc.name: DCopy +* @tc.desc: test Constant::DCopy function. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceUtilsTest, DCopy, TestSize.Level1) +{ + Constant constant; + uint8_t *tag = nullptr; + size_t tagLen = 1; + uint8_t *src = nullptr; + size_t srcLen = 0; + + uint8_t tags[10]; + size_t tagsLen = 10; + uint8_t srcs[10]; + size_t srcsLen = 10; + + EXPECT_FALSE(constant.DCopy(tag, tagLen, src, srcLen)); + EXPECT_FALSE(constant.DCopy(tag, tagsLen, src, srcsLen)); + EXPECT_FALSE(constant.DCopy(tags, tagLen, src, srcLen)); + EXPECT_FALSE(constant.DCopy(tag, tagLen, srcs, srcLen)); + EXPECT_FALSE(constant.DCopy(tags, tagsLen, src, srcsLen)); + EXPECT_FALSE(constant.DCopy(tag, tagsLen, srcs, srcsLen)); + EXPECT_FALSE(constant.DCopy(tags, tagLen, srcs, srcLen)); + EXPECT_TRUE(constant.DCopy(tags, tagsLen, srcs, srcsLen)); +} } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/utils/constant.cpp b/datamgr_service/services/distributeddataservice/framework/utils/constant.cpp index 2b834643..6fedf3f6 100644 --- a/datamgr_service/services/distributeddataservice/framework/utils/constant.cpp +++ b/datamgr_service/services/distributeddataservice/framework/utils/constant.cpp @@ -51,6 +51,25 @@ std::string Constant::Join(const std::string &prefix, const std::string &separat return result; } +std::vector Constant::Split(const std::string &str, const std::string &delim) +{ + if (str.empty()) { + return { str }; + } + std::vector res; + size_t pos = 0; + while (pos < str.size()) { + size_t found = str.find(delim, pos); + if (found == std::string::npos) { + res.push_back(str.substr(pos)); + break; + } + res.push_back(str.substr(pos, found - pos)); + pos = found + delim.size(); + } + return res; +} + bool Constant::Equal(bool first, bool second) { return (first && second) || (!first && !second); diff --git a/datamgr_service/services/distributeddataservice/rust/extension/BUILD.gn b/datamgr_service/services/distributeddataservice/rust/extension/BUILD.gn index 302f89d6..cffbfca9 100644 --- a/datamgr_service/services/distributeddataservice/rust/extension/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/rust/extension/BUILD.gn @@ -56,6 +56,7 @@ ohos_shared_library("opencloudextension") { external_deps = [ "access_token:libaccesstoken_sdk", "hilog:libhilog", + "json:nlohmann_json_static", "kv_store:distributeddata_inner", ] subsystem_name = "distributeddatamgr" diff --git a/datamgr_service/services/distributeddataservice/rust/extension/cloud_cursor_impl.cpp b/datamgr_service/services/distributeddataservice/rust/extension/cloud_cursor_impl.cpp index fc420497..9d62cc7e 100644 --- a/datamgr_service/services/distributeddataservice/rust/extension/cloud_cursor_impl.cpp +++ b/datamgr_service/services/distributeddataservice/rust/extension/cloud_cursor_impl.cpp @@ -271,6 +271,7 @@ int32_t CloudCursorImpl::Get(const std::string &col, DBValue &value) auto it = std::find(names_.begin(), names_.end(), col); if (it == names_.end()) { value = GetExtend(vBucket, EXTEND_TO_KEYS[col]); + OhCloudExtValueBucketFree(vBucket); return DBErr::E_OK; } auto pair = GetData(vBucket); diff --git a/datamgr_service/services/distributeddataservice/rust/extension/cloud_db_impl.cpp b/datamgr_service/services/distributeddataservice/rust/extension/cloud_db_impl.cpp index 8cac03c4..da137619 100644 --- a/datamgr_service/services/distributeddataservice/rust/extension/cloud_db_impl.cpp +++ b/datamgr_service/services/distributeddataservice/rust/extension/cloud_db_impl.cpp @@ -57,6 +57,8 @@ int32_t CloudDbImpl::BatchInsert(const std::string &table, DBVBuckets &&values, auto valIn = ExtensionUtil::Convert(std::move(inValues)); auto exdIn = ExtensionUtil::Convert(std::move(extends)); if (valIn.first == nullptr || exdIn.first == nullptr) { + OhCloudExtVectorFree(valIn.first); + OhCloudExtVectorFree(exdIn.first); return DBErr::E_ERROR; } auto status = OhCloudExtCloudDbBatchInsert(database_, reinterpret_cast(table.c_str()), @@ -74,6 +76,8 @@ int32_t CloudDbImpl::BatchUpdate(const std::string &table, DBVBuckets &&values, auto exdIn = ExtensionUtil::Convert(std::move(extends)); auto valIn = ExtensionUtil::Convert(std::move(values)); if (valIn.first == nullptr || exdIn.first == nullptr) { + OhCloudExtVectorFree(valIn.first); + OhCloudExtVectorFree(exdIn.first); return DBErr::E_ERROR; } auto status = OhCloudExtCloudDbBatchUpdate(database_, reinterpret_cast(table.c_str()), @@ -91,6 +95,8 @@ int32_t CloudDbImpl::BatchUpdate(const std::string &table, DBVBuckets &&values, auto exdIn = ExtensionUtil::Convert(std::move(const_cast(extends))); auto valIn = ExtensionUtil::Convert(std::move(values)); if (valIn.first == nullptr || exdIn.first == nullptr) { + OhCloudExtVectorFree(valIn.first); + OhCloudExtVectorFree(exdIn.first); return DBErr::E_ERROR; } auto status = OhCloudExtCloudDbBatchUpdate(database_, reinterpret_cast(table.c_str()), @@ -100,14 +106,15 @@ int32_t CloudDbImpl::BatchUpdate(const std::string &table, DBVBuckets &&values, return ExtensionUtil::ConvertStatus(status); } -int32_t CloudDbImpl::BatchDelete(const std::string &table, const DBVBuckets &extends) +int32_t CloudDbImpl::BatchDelete(const std::string &table, DBVBuckets &extends) { - auto data = ExtensionUtil::Convert(std::move(const_cast(extends))); + auto data = ExtensionUtil::Convert(std::move(extends)); if (data.first == nullptr) { return DBErr::E_ERROR; } auto status = OhCloudExtCloudDbBatchDelete(database_, reinterpret_cast(table.c_str()), table.size(), data.first); + extends = ExtensionUtil::ConvertBuckets(data.first); OhCloudExtVectorFree(data.first); return ExtensionUtil::ConvertStatus(status); } diff --git a/datamgr_service/services/distributeddataservice/rust/extension/cloud_db_impl.h b/datamgr_service/services/distributeddataservice/rust/extension/cloud_db_impl.h index dee05c43..099bfaad 100644 --- a/datamgr_service/services/distributeddataservice/rust/extension/cloud_db_impl.h +++ b/datamgr_service/services/distributeddataservice/rust/extension/cloud_db_impl.h @@ -35,7 +35,7 @@ public: int32_t BatchInsert(const std::string &table, DBVBuckets &&values, DBVBuckets &extends) override; int32_t BatchUpdate(const std::string &table, DBVBuckets &&values, DBVBuckets &extends) override; int32_t BatchUpdate(const std::string &table, DBVBuckets &&values, const DBVBuckets &extends) override; - int32_t BatchDelete(const std::string &table, const DBVBuckets &extends) override; + int32_t BatchDelete(const std::string &table, DBVBuckets &extends) override; std::shared_ptr Query(const std::string &table, const DBVBucket &extend) override; int32_t Lock() override; int32_t Heartbeat() override; diff --git a/datamgr_service/services/distributeddataservice/rust/ylong_cloud_extension/BUILD.gn b/datamgr_service/services/distributeddataservice/rust/ylong_cloud_extension/BUILD.gn index dd7526a6..4ac4309e 100644 --- a/datamgr_service/services/distributeddataservice/rust/ylong_cloud_extension/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/rust/ylong_cloud_extension/BUILD.gn @@ -22,7 +22,6 @@ ohos_rust_shared_ffi("ylong_cloud_extension") { subsystem_name = "distributeddatamgr" part_name = "datamgr_service" - branch_protector_ret = "pac_ret" sanitize = { cfi = true cfi_cross_dso = true @@ -39,18 +38,23 @@ ohos_rust_shared_ffi("ylong_cloud_extension") { ] } -ohos_rust_unittest("rust_ylong_cloud_ext_unit_test") { - module_out_path = - "distributeddatamgr/datamgr_service/services/rust/ylong_cloud_extension" - sources = [ "src/lib.rs" ] - - external_deps = [ - "hilog:hilog_rust", - "ipc:ipc_rust", - ] - deps = [ - ":ylong_cloud_extension", - "../connect_adapter:conn_adapter", - ] - rustflags = [ "--cfg=feature=\"test_server_ready\"" ] +if (use_clang_coverage) { + group("rust_ylong_cloud_ext_unit_test") { + } +} else { + ohos_rust_unittest("rust_ylong_cloud_ext_unit_test") { + module_out_path = + "distributeddatamgr/datamgr_service/services/rust/ylong_cloud_extension" + sources = [ "src/lib.rs" ] + + external_deps = [ + "hilog:hilog_rust", + "ipc:ipc_rust", + ] + deps = [ + ":ylong_cloud_extension", + "../connect_adapter:conn_adapter", + ] + rustflags = [ "--cfg=feature=\"test_server_ready\"" ] + } } diff --git a/datamgr_service/services/distributeddataservice/rust/ylong_cloud_extension/src/ipc_conn/function.rs b/datamgr_service/services/distributeddataservice/rust/ylong_cloud_extension/src/ipc_conn/function.rs index f68387e7..522b80e1 100644 --- a/datamgr_service/services/distributeddataservice/rust/ylong_cloud_extension/src/ipc_conn/function.rs +++ b/datamgr_service/services/distributeddataservice/rust/ylong_cloud_extension/src/ipc_conn/function.rs @@ -31,7 +31,7 @@ pub(crate) enum AssetLoaderFunc { } pub(crate) enum CloudServiceFunc { - ConnectAssetLoader = 1, + ConnectAssetLoader, ConnectDatabase, GetAppBriefInfo, GetServiceInfo, diff --git a/datamgr_service/services/distributeddataservice/service/BUILD.gn b/datamgr_service/services/distributeddataservice/service/BUILD.gn index f2b756ec..df0103f7 100644 --- a/datamgr_service/services/distributeddataservice/service/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/BUILD.gn @@ -68,6 +68,7 @@ ohos_shared_library("distributeddatasvc") { "${kv_store_distributeddb_path}", ] sources = [ + "${dataobject_path}/frameworks/innerkitsimpl/src/object_radar_reporter.cpp", "backup/src/backup_manager.cpp", "bootstrap/src/bootstrap.cpp", "cloud/cloud_service_impl.cpp", @@ -80,6 +81,7 @@ ohos_shared_library("distributeddatasvc") { "common/value_proxy.cpp", "common/xcollie.cpp", "config/src/config_factory.cpp", + "config/src/model/app_id_mapping_config.cpp", "config/src/model/backup_config.cpp", "config/src/model/checker_config.cpp", "config/src/model/cloud_config.cpp", @@ -101,7 +103,6 @@ ohos_shared_library("distributeddatasvc") { "kvdb/query_helper.cpp", "kvdb/upgrade.cpp", "kvdb/user_delegate.cpp", - "matrix/src/auto_sync_matrix.cpp", "matrix/src/device_matrix.cpp", "matrix/src/matrix_event.cpp", "object/object_asset_loader.cpp", diff --git a/datamgr_service/services/distributeddataservice/service/CMakeLists.txt b/datamgr_service/services/distributeddataservice/service/CMakeLists.txt index 0781c718..31fe3b6a 100644 --- a/datamgr_service/services/distributeddataservice/service/CMakeLists.txt +++ b/datamgr_service/services/distributeddataservice/service/CMakeLists.txt @@ -5,7 +5,7 @@ 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} -Wa,-mbig-obj") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -Wenum-compare") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat=0 -fpermissive -Wattributes") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=deprecated-declarations -Wno-deprecated-declarations") diff --git a/datamgr_service/services/distributeddataservice/service/backup/src/backup_manager.cpp b/datamgr_service/services/distributeddataservice/service/backup/src/backup_manager.cpp index 1de16acc..be05b0be 100644 --- a/datamgr_service/services/distributeddataservice/service/backup/src/backup_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/backup/src/backup_manager.cpp @@ -15,9 +15,10 @@ #define LOG_TAG "BackupManager" #include "backup_manager.h" +#include + #include #include -#include #include "backuprule/backup_rule_manager.h" #include "crypto_manager.h" @@ -53,13 +54,12 @@ void BackupManager::Init() { std::vector metas; MetaDataManager::GetInstance().LoadMeta( - StoreMetaData::GetPrefix({DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid}), metas, true); + StoreMetaData::GetPrefix({ DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid }), metas, true); for (auto &meta : metas) { if (!meta.isBackup || meta.isDirty) { - continue; + continue; } - auto backupPath = - DirectoryManager::GetInstance().GetStoreBackupPath(meta) + "/" + AUTO_BACKUP_NAME; + auto backupPath = DirectoryManager::GetInstance().GetStoreBackupPath(meta) + "/" + AUTO_BACKUP_NAME; switch (GetClearType(meta)) { case ROLLBACK: RollBackData(backupPath); @@ -171,8 +171,7 @@ void BackupManager::KeepData(const std::string &path) CopyFile(path, backupPath, true); } -void BackupManager::SaveData( - const std::string &path, const std::string &key, const SecretKeyMetaData &secretKey) +void BackupManager::SaveData(const std::string &path, const std::string &key, const SecretKeyMetaData &secretKey) { auto tmpPath = path + BACKUP_TMP_POSTFIX; auto backupPath = path + BACKUP_BK_POSTFIX; @@ -249,8 +248,7 @@ void BackupManager::CleanData(const std::string &path) * */ BackupManager::ClearType BackupManager::GetClearType(const StoreMetaData &meta) { - auto backupFile = - DirectoryManager::GetInstance().GetStoreBackupPath(meta) + "/" + AUTO_BACKUP_NAME; + auto backupFile = DirectoryManager::GetInstance().GetStoreBackupPath(meta) + "/" + AUTO_BACKUP_NAME; auto dbKey = meta.GetSecretKey(); auto backupKey = meta.GetBackupSecretKey(); auto bkFile = backupFile + BACKUP_BK_POSTFIX; @@ -289,7 +287,7 @@ void BackupManager::CopyFile(const std::string &oldPath, const std::string &newP } else { fout.open(newPath, std::ios_base::out | std::ios_base::trunc); } - char buf[COPY_SIZE] = {0}; + char buf[COPY_SIZE] = { 0 }; while (fin.good()) { fin.read(buf, COPY_SIZE); fout.write(buf, fin.gcount()); diff --git a/datamgr_service/services/distributeddataservice/service/bootstrap/include/bootstrap.h b/datamgr_service/services/distributeddataservice/service/bootstrap/include/bootstrap.h index 967ad097..50b86fd8 100644 --- a/datamgr_service/services/distributeddataservice/service/bootstrap/include/bootstrap.h +++ b/datamgr_service/services/distributeddataservice/service/bootstrap/include/bootstrap.h @@ -31,6 +31,7 @@ public: API_EXPORT void LoadDirectory(); API_EXPORT void LoadCloud(); API_EXPORT void LoadBackup(std::shared_ptr executors); + API_EXPORT void LoadAppIdMappings(); private: static constexpr const char *DEFAULT_LABEL = "distributeddata"; static constexpr const char *DEFAULT_META = "service_meta"; diff --git a/datamgr_service/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp b/datamgr_service/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp index 8ef60d48..3dda8f45 100644 --- a/datamgr_service/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp +++ b/datamgr_service/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp @@ -24,6 +24,7 @@ #include "config_factory.h" #include "directory/directory_manager.h" #include "log_print.h" +#include "app_id_mapping/app_id_mapping_config_manager.h" namespace OHOS { namespace DistributedData { Bootstrap &Bootstrap::GetInstance() @@ -167,5 +168,18 @@ void Bootstrap::LoadCloud() } CloudConfigManager::GetInstance().Initialize(infos); } + +void Bootstrap::LoadAppIdMappings() +{ + auto *appIdMapping = ConfigFactory::GetInstance().GetAppIdMappingConfig(); + if (appIdMapping == nullptr) { + return; + } + std::vector infos; + for (auto &info : *appIdMapping) { + infos.push_back({ info.srcAppId, info.dstAppId }); + } + AppIdMappingConfigManager::GetInstance().Initialize(infos); +} } // namespace DistributedData } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp index 76237bc9..f48a1f65 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp @@ -19,6 +19,7 @@ #include #include + #include "accesstoken_kit.h" #include "account/account_delegate.h" #include "checker/checker_manager.h" @@ -28,6 +29,7 @@ #include "cloud/sharing_center.h" #include "cloud_value_util.h" #include "communicator/device_manager_adapter.h" +#include "device_matrix.h" #include "dfx/radar_reporter.h" #include "eventcenter/event_center.h" #include "hap_token_info.h" @@ -112,11 +114,13 @@ int32_t CloudServiceImpl::EnableCloud(const std::string &id, const std::map(CloudEvent::CLEAN_DATA, storeInfo)); auto status = store->Clean({}, action, ""); if (status != E_OK) { ZLOGW("remove device data status:%{public}d, user:%{public}d, bundleName:%{public}s, " "storeId:%{public}s", status, static_cast(user), meta.bundleName.c_str(), meta.GetStoreAlias().c_str()); + } else { + ZLOGD("clean success, user:%{public}d, bundleName:%{public}s, storeId:%{public}s", + static_cast(user), meta.bundleName.c_str(), meta.GetStoreAlias().c_str()); } } } @@ -262,6 +281,7 @@ int32_t CloudServiceImpl::CheckNotifyConditions(const std::string &id, const std return INVALID_ARGUMENT; } if (!cloudInfo.enableCloud) { + ZLOGD("cloud is disabled, id:%{public}s, app:%{public}s ", Anonymous::Change(id).c_str(), bundleName.c_str()); return CLOUD_DISABLE; } if (!cloudInfo.Exist(bundleName)) { @@ -269,6 +289,8 @@ int32_t CloudServiceImpl::CheckNotifyConditions(const std::string &id, const std return INVALID_ARGUMENT; } if (!cloudInfo.apps[bundleName].cloudSwitch) { + ZLOGD("cloud switch is disabled, id:%{public}s, app:%{public}s ", Anonymous::Change(id).c_str(), + bundleName.c_str()); return CLOUD_DISABLE_SWITCH; } return SUCCESS; @@ -317,18 +339,14 @@ std::map> CloudServiceImpl::GetDbInfoFromE return dbInfos; } -bool CloudServiceImpl::DoKvCloudSync(int32_t userId, const std::string &bundleName) +bool CloudServiceImpl::DoKvCloudSync(int32_t userId, const std::string &bundleName, int32_t triggerMode) { auto stores = CheckerManager::GetInstance().GetDynamicStores(); auto staticStores = CheckerManager::GetInstance().GetStaticStores(); stores.insert(stores.end(), staticStores.begin(), staticStores.end()); - bool found = false; - for (auto &store : stores) { - if (store.bundleName == bundleName || bundleName.empty()) { - found = true; - break; - } - } + bool found = std::any_of(stores.begin(), stores.end(), [&bundleName](const CheckerManager::StoreInfo &storeInfo) { + return bundleName.empty() || storeInfo.bundleName == bundleName; + }); if (!found) { return found; } @@ -339,8 +357,10 @@ bool CloudServiceImpl::DoKvCloudSync(int32_t userId, const std::string &bundleNa Account::GetInstance()->QueryForegroundUsers(users); } for (auto user : users) { - for (auto &store : stores) { - syncManager_.DoCloudSync(SyncManager::SyncInfo(user, store.bundleName, store.storeId)); + for (const auto &store : stores) { + int32_t mode = (store.bundleName != bundleName && triggerMode == MODE_PUSH) ? MODE_CONSISTENCY + : triggerMode; + syncManager_.DoCloudSync(SyncManager::SyncInfo(user, store.bundleName, store.storeId, {}, mode)); } } return found; @@ -381,9 +401,6 @@ int32_t CloudServiceImpl::NotifyDataChange(const std::string &eventId, const std ZLOGD("invalid user:%{public}d", user); return INVALID_ARGUMENT; } - if (DoKvCloudSync(cloudInfo.user, exData.info.bundleName)) { - continue; - } auto schemaKey = CloudInfo::GetSchemaKey(user, exData.info.bundleName); SchemaMeta schemaMeta; if (!MetaDataManager::GetInstance().LoadMeta(schemaKey, schemaMeta, true)) { @@ -395,9 +412,9 @@ int32_t CloudServiceImpl::NotifyDataChange(const std::string &eventId, const std ZLOGE("GetDbInfoFromExtraData failed, empty database info."); return INVALID_ARGUMENT; } - for (auto &dbInfo : dbInfos) { + for (const auto &dbInfo : dbInfos) { syncManager_.DoCloudSync( - SyncManager::SyncInfo(cloudInfo.user, exData.info.bundleName, dbInfo.first, dbInfo.second)); + SyncManager::SyncInfo(cloudInfo.user, exData.info.bundleName, dbInfo.first, dbInfo.second, MODE_PUSH)); } } return SUCCESS; @@ -407,7 +424,7 @@ std::map CloudServiceImpl::ExecuteStatistics(const const CloudInfo &cloudInfo, const SchemaMeta &schemaMeta) { std::map result; - for (auto& database : schemaMeta.databases) { + for (auto &database : schemaMeta.databases) { if (storeId.empty() || database.alias == storeId) { StoreMetaData meta; meta.bundleName = schemaMeta.bundleName; @@ -438,7 +455,7 @@ StatisticInfos CloudServiceImpl::QueryStatistics(const StoreMetaData &storeMetaD return infos; } infos.reserve(database.tables.size()); - for (auto& table : database.tables) { + for (const auto &table : database.tables) { auto [success, info] = QueryTableStatistic(table.name, store); if (success) { info.table = table.alias; @@ -453,8 +470,8 @@ std::pair CloudServiceImpl::QueryTableStatistic(const std:: { StatisticInfo info; auto sql = BuildStatisticSql(tableName); - auto cursor = store->Query(tableName, sql, {}); - if (cursor == nullptr || cursor->GetCount() != 1 || cursor->MoveToFirst() != E_OK) { + auto [errCode, cursor] = store->Query(tableName, sql, {}); + if (errCode != E_OK || cursor == nullptr || cursor->GetCount() != 1 || cursor->MoveToFirst() != E_OK) { ZLOGE("query failed, cursor is nullptr or move to first failed,tableName:%{public}s", Anonymous::Change(tableName).c_str()); return { false, info }; @@ -519,7 +536,7 @@ std::pair> CloudServiceImpl::Quer int32_t CloudServiceImpl::SetGlobalCloudStrategy(Strategy strategy, const std::vector &values) { - if (strategy < 0 || strategy >= Strategy::STRATEGY_BUTT) { + if (strategy >= Strategy::STRATEGY_BUTT) { ZLOGE("invalid strategy:%{public}d, size:%{public}zu", strategy, values.size()); return INVALID_ARGUMENT; } @@ -644,13 +661,7 @@ int32_t CloudServiceImpl::OnUserChange(uint32_t code, const std::string &user, c return E_OK; } -int32_t CloudServiceImpl::OnScreenUnlocked(int32_t user) -{ - DoKvCloudSync(user); - return E_OK; -} - -int32_t CloudServiceImpl::OnReady(const std::string& device) +int32_t CloudServiceImpl::OnReady(const std::string &device) { if (device != DeviceManagerAdapter::CLOUD_DEVICE_UUID) { return SUCCESS; @@ -661,7 +672,7 @@ int32_t CloudServiceImpl::OnReady(const std::string& device) return SUCCESS; } for (auto user : users) { - DoKvCloudSync(user); + DoKvCloudSync(user, "", MODE_ONLINE); Execute(GenTask(0, user, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_DO_CLOUD_SYNC, WORK_SUB })); } return SUCCESS; @@ -700,15 +711,17 @@ std::pair CloudServiceImpl::GetCloudInfoFromServer(int32_t u CloudInfo cloudInfo; cloudInfo.user = userId; if (!DmAdapter::GetInstance().IsNetworkAvailable()) { + ZLOGD("network is not available"); return { NETWORK_ERROR, cloudInfo }; } auto instance = CloudServer::GetInstance(); if (instance == nullptr) { + ZLOGD("cloud server is nullptr, user:%{public}d", userId); return { SERVER_UNAVAILABLE, cloudInfo }; } cloudInfo = instance->GetServerInfo(cloudInfo.user); if (!cloudInfo.IsValid()) { - ZLOGE("cloud is empty, user%{public}d", cloudInfo.user); + ZLOGE("cloud is empty, user:%{public}d", cloudInfo.user); return { CLOUD_INFO_INVALID, cloudInfo }; } return { SUCCESS, cloudInfo }; @@ -731,7 +744,7 @@ bool CloudServiceImpl::UpdateCloudInfo(int32_t user) ZLOGE("user:%{public}d, status:%{public}d", user, status); return false; } - ZLOGI("[server] id:%{public}s, enableCloud:%{pubic}d, user:%{public}d, app size:%{public}zu", + ZLOGI("[server] id:%{public}s, enableCloud:%{public}d, user:%{public}d, app size:%{public}zu", Anonymous::Change(cloudInfo.id).c_str(), cloudInfo.enableCloud, cloudInfo.user, cloudInfo.apps.size()); CloudInfo oldInfo; if (!MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetKey(), oldInfo, true)) { @@ -758,7 +771,6 @@ bool CloudServiceImpl::UpdateSchema(int32_t user) { auto [status, cloudInfo] = GetCloudInfo(user); if (status != SUCCESS) { - ZLOGE("user:%{public}d, status:%{public}d", user, status); return false; } auto keys = cloudInfo.GetSchemaKey(); @@ -786,6 +798,7 @@ std::pair CloudServiceImpl::GetAppSchemaFromServer(int32_t { SchemaMeta schemaMeta; if (!DmAdapter::GetInstance().IsNetworkAvailable()) { + ZLOGD("network is not available"); return { NETWORK_ERROR, schemaMeta }; } auto instance = CloudServer::GetInstance(); @@ -823,13 +836,14 @@ ExecutorPool::Task CloudServiceImpl::GenTask(int32_t retry, int32_t user, Handle return; } if (!DmAdapter::GetInstance().IsNetworkAvailable()) { + ZLOGD("network is not available"); return; } bool finished = true; std::vector users; if (user == 0) { auto account = Account::GetInstance(); - finished = !(account == nullptr) && account->QueryUsers(users); + finished = (account != nullptr) && account->QueryUsers(users); } else { users.push_back(user); } @@ -968,7 +982,7 @@ void CloudServiceImpl::CloudShare(const Event &event) } std::pair> CloudServiceImpl::PreShare( - const StoreInfo& storeInfo, GenQuery& query) + const StoreInfo &storeInfo, GenQuery &query) { StoreMetaData meta(storeInfo); meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; @@ -982,7 +996,7 @@ std::pair> CloudServiceImpl::P ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); return { GeneralError::E_ERROR, nullptr }; } - return { GeneralError::E_OK, store->PreSharing(query) }; + return store->PreSharing(query); } bool CloudServiceImpl::ReleaseUserInfo(int32_t user) @@ -997,7 +1011,8 @@ bool CloudServiceImpl::ReleaseUserInfo(int32_t user) bool CloudServiceImpl::DoCloudSync(int32_t user) { - syncManager_.DoCloudSync(user); + SyncManager::SyncInfo info(user); + syncManager_.DoCloudSync(info); return true; } @@ -1101,8 +1116,8 @@ std::map CloudServiceImpl::ConvertAction(const std::map> CloudServiceImpl::AllocResourceAndShare( - const std::string& storeId, const DistributedRdb::PredicatesMemo& predicates, - const std::vector& columns, const Participants& participants) + const std::string &storeId, const DistributedRdb::PredicatesMemo &predicates, + const std::vector &columns, const Participants &participants) { auto tokenId = IPCSkeleton::GetCallingTokenID(); auto hapInfo = GetHapInfo(tokenId); @@ -1390,7 +1405,7 @@ void CloudServiceImpl::InitSubTask(const Subscription &sub, uint64_t minInterval if (executor == nullptr) { return; } - ZLOGI("Subscription Info, subTask:%{public}" PRIu64", user:%{public}d", subTask_, sub.userId); + ZLOGI("Subscription Info, subTask:%{public}" PRIu64 ", user:%{public}d", subTask_, sub.userId); expire = expire - TIME_BEFORE_SUB; // before 12 hours auto now = static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); Duration delay = milliseconds(std::max(expire > now ? expire - now : 0, minInterval)); @@ -1408,7 +1423,7 @@ void CloudServiceImpl::InitSubTask(const Subscription &sub, uint64_t minInterval int32_t CloudServiceImpl::SetCloudStrategy(Strategy strategy, const std::vector &values) { - if (strategy < 0 || strategy >= Strategy::STRATEGY_BUTT) { + if (strategy >= Strategy::STRATEGY_BUTT) { ZLOGE("invalid strategy:%{public}d, size:%{public}zu", strategy, values.size()); return INVALID_ARGUMENT; } diff --git a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h index 76476c25..212b7780 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h @@ -18,12 +18,13 @@ #include #include + #include "cloud/cloud_event.h" #include "cloud/cloud_extra_data.h" #include "cloud/cloud_info.h" #include "cloud/schema_meta.h" -#include "cloud/subscription.h" #include "cloud/sharing_center.h" +#include "cloud/subscription.h" #include "cloud_service_stub.h" #include "feature/static_acts.h" #include "sync_manager.h" @@ -67,7 +68,6 @@ public: int32_t OnInitialize() override; int32_t OnBind(const BindInfo &info) override; int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; - int32_t OnScreenUnlocked(int32_t user) override; int32_t OnReady(const std::string &device) override; int32_t Offline(const std::string &device) override; @@ -158,7 +158,7 @@ private: const DistributedData::ExtraData &extraData, const SchemaMeta &schemaMeta); std::shared_ptr GetSharingHandle(const HapInfo& hapInfo); bool GetStoreMetaData(StoreMetaData &meta); - bool DoKvCloudSync(int32_t userId, const std::string &bundleName = ""); + bool DoKvCloudSync(int32_t userId, const std::string &bundleName = "", int32_t triggerMode = 0); using SaveStrategy = int32_t (*)(const std::vector &values, const HapInfo &hapInfo); static const SaveStrategy STRATEGY_SAVERS[Strategy::STRATEGY_BUTT]; diff --git a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_stub.cpp index 3fc50188..ef5c357e 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_stub.cpp @@ -15,14 +15,14 @@ #define LOG_TAG "CloudServiceStub" #include "cloud_service_stub.h" -#include "ipc_skeleton.h" -#include "cloud_types_util.h" #include "cloud/cloud_config_manager.h" +#include "cloud_types_util.h" +#include "ipc_skeleton.h" #include "log_print.h" #include "permission/permission_validator.h" #include "rdb_types.h" -#include "utils/anonymous.h" #include "tokenid_kit.h" +#include "utils/anonymous.h" namespace OHOS::CloudData { using namespace DistributedData; using namespace OHOS::Security::AccessToken; @@ -89,7 +89,7 @@ int32_t CloudServiceStub::OnEnableCloud(MessageParcel &data, MessageParcel &repl return IPC_STUB_INVALID_DATA_ERR; } std::map localSwitches; - for (auto &[bundle, status] : switches) { + for (const auto &[bundle, status] : switches) { localSwitches.insert_or_assign(CloudConfigManager::GetInstance().ToLocal(bundle), status); } auto result = EnableCloud(id, localSwitches); @@ -129,7 +129,7 @@ int32_t CloudServiceStub::OnClean(MessageParcel &data, MessageParcel &reply) return IPC_STUB_INVALID_DATA_ERR; } std::map localActions; - for (auto &[bundle, action] : actions) { + for (const auto &[bundle, action] : actions) { localActions.insert_or_assign(CloudConfigManager::GetInstance().ToLocal(bundle), action); } auto result = Clean(id, localActions); diff --git a/datamgr_service/services/distributeddataservice/service/cloud/cloud_types_util.h b/datamgr_service/services/distributeddataservice/service/cloud/cloud_types_util.h index 4e151fa9..afb74b6c 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_types_util.h +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_types_util.h @@ -17,7 +17,6 @@ #define OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_TYPES_UTIL_H #include "cloud_types.h" #include "itypes_util.h" -#include "cloud_types.h" #include "values_bucket.h" namespace OHOS::ITypesUtil { @@ -69,4 +68,4 @@ bool Marshalling(const CloudSyncInfo &input, MessageParcel &data); template<> bool Unmarshalling(CloudSyncInfo &output, MessageParcel &data); } // namespace OHOS::ITypesUtil -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_TYPES_UTIL_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_TYPES_UTIL_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/cloud/cloud_value_util.h b/datamgr_service/services/distributeddataservice/service/cloud/cloud_value_util.h index 4b3e9cdc..b9d66441 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_value_util.h +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_value_util.h @@ -16,9 +16,9 @@ #ifndef OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_VALUE_UTIL_H #define OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_VALUE_UTIL_H +#include "cloud/sharing_center.h" #include "cloud_service.h" #include "cloud_types.h" -#include "cloud/sharing_center.h" #include "error/general_error.h" namespace OHOS::CloudData { @@ -53,4 +53,4 @@ Status Convert(CenterCode code); Status Convert(GenErr code); } // namespace SharingUtil } // namespace OHOS::CloudData -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_VALUE_UTIL_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_VALUE_UTIL_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp index c52040fa..40f41784 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp @@ -18,10 +18,13 @@ #include #include "account/account_delegate.h" +#include "bootstrap.h" +#include "checker/checker_manager.h" #include "cloud/cloud_server.h" #include "cloud/schema_meta.h" #include "cloud/sync_event.h" #include "cloud_value_util.h" +#include "cloud/cloud_lock_event.h" #include "device_manager_adapter.h" #include "dfx/radar_reporter.h" #include "eventcenter/event_center.h" @@ -40,8 +43,9 @@ using Account = OHOS::DistributedKv::AccountDelegate; using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; using Defer = EventCenter::Defer; std::atomic SyncManager::genId_ = 0; -SyncManager::SyncInfo::SyncInfo(int32_t user, const std::string &bundleName, const Store &store, const Tables &tables) - : user_(user), bundleName_(bundleName) +SyncManager::SyncInfo::SyncInfo( + int32_t user, const std::string &bundleName, const Store &store, const Tables &tables, int32_t triggerMode) + : user_(user), bundleName_(bundleName), triggerMode_(triggerMode) { if (!store.empty()) { tables_[store] = tables; @@ -90,6 +94,11 @@ void SyncManager::SyncInfo::SetCompensation(bool isCompensation) isCompensation_ = isCompensation; } +void SyncManager::SyncInfo::SetTriggerMode(int32_t triggerMode) +{ + triggerMode_ = triggerMode; +} + void SyncManager::SyncInfo::SetError(int32_t code) const { if (async_) { @@ -132,10 +141,56 @@ bool SyncManager::SyncInfo::Contains(const std::string &storeName) return tables_.empty() || tables_.find(storeName) != tables_.end(); } +std::function SyncManager::GetLockChangeHandler() +{ + return [](const Event &event) { + auto &evt = static_cast(event); + auto storeInfo = evt.GetStoreInfo(); + auto callback = evt.GetCallback(); + if (callback == nullptr) { + ZLOGE("callback is nullptr. bundleName: %{public}s, storeName: %{public}s, user: %{public}d.", + storeInfo.bundleName.c_str(), Anonymous::Change(storeInfo.storeName).c_str(), storeInfo.user); + return; + } + StoreMetaData meta(storeInfo); + meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { + ZLOGE("not found meta. bundleName: %{public}s, storeName: %{public}s, user: %{public}d.", + storeInfo.bundleName.c_str(), Anonymous::Change(storeInfo.storeName).c_str(), storeInfo.user); + return; + } + auto store = GetStore(meta, storeInfo.user); + if (store == nullptr) { + ZLOGE("failed to get store. bundleName: %{public}s, storeName: %{public}s, user: %{public}d.", + storeInfo.bundleName.c_str(), Anonymous::Change(storeInfo.storeName).c_str(), storeInfo.user); + return; + } + if (evt.GetEventId() == CloudEvent::LOCK_CLOUD_CONTAINER) { + auto [result, expiredTime] = store->LockCloudDB(); + callback(result, expiredTime); + } else { + auto result = store->UnLockCloudDB(); + callback(result, 0); + } + }; +} + SyncManager::SyncManager() { + EventCenter::GetInstance().Subscribe(CloudEvent::LOCK_CLOUD_CONTAINER, GetLockChangeHandler()); + EventCenter::GetInstance().Subscribe(CloudEvent::UNLOCK_CLOUD_CONTAINER, GetLockChangeHandler()); EventCenter::GetInstance().Subscribe(CloudEvent::LOCAL_CHANGE, GetClientChangeHandler()); syncStrategy_ = std::make_shared(); + auto metaName = Bootstrap::GetInstance().GetProcessLabel(); + kvApps_.insert(std::move(metaName)); + auto stores = CheckerManager::GetInstance().GetStaticStores(); + for (auto &store : stores) { + kvApps_.insert(std::move(store.bundleName)); + } + stores = CheckerManager::GetInstance().GetDynamicStores(); + for (auto &store : stores) { + kvApps_.insert(std::move(store.bundleName)); + } } SyncManager::~SyncManager() @@ -210,10 +265,11 @@ GeneralError SyncManager::IsValid(SyncInfo &info, CloudInfo &cloud) return E_OK; } -std::function SyncManager::GetPostEventTask(const std::vector &schemas, CloudInfo &cloud, +std::function SyncManager::GetPostEventTask(const std::vector &schemas, CloudInfo &cloud, SyncInfo &info, bool retry) { return [this, &cloud, &info, &schemas, retry]() { + bool isPostEvent = false; for (auto &schema : schemas) { if (!cloud.IsOn(schema.bundleName)) { continue; @@ -234,12 +290,18 @@ std::function SyncManager::GetPostEventTask(const std::vector(std::move(storeInfo), SyncEvent::EventInfo{ syncParam, retry, std::move(query), info.async_ }); EventCenter::GetInstance().PostEvent(std::move(evt)); + isPostEvent = true; } } + if (!isPostEvent) { + ZLOGE("schema is invalid, user: %{public}d", cloud.user); + info.SetError(E_ERROR); + } + return isPostEvent; }; } @@ -261,9 +323,7 @@ ExecutorPool::Task SyncManager::GetSyncTask(int32_t times, bool retry, RefCount UpdateStartSyncInfo(cloudSyncInfos); auto code = IsValid(info, cloud); if (code != E_OK) { - for (const auto &[queryKey, syncId] : cloudSyncInfos) { - UpdateFinishSyncInfo(queryKey, syncId, code); - } + BatchUpdateFinishState(cloudSyncInfos, code); return; } @@ -273,7 +333,8 @@ ExecutorPool::Task SyncManager::GetSyncTask(int32_t times, bool retry, RefCount UpdateSchema(info); schemas = GetSchemaMeta(cloud, info.bundleName_); if (schemas.empty()) { - retryer(RETRY_INTERVAL, E_RETRY_TIMEOUT, Status::SCHEMA_INVALID); + retryer(RETRY_INTERVAL, E_RETRY_TIMEOUT, E_CLOUD_DISABLED); + BatchUpdateFinishState(cloudSyncInfos, E_CLOUD_DISABLED); return; } } @@ -282,9 +343,10 @@ ExecutorPool::Task SyncManager::GetSyncTask(int32_t times, bool retry, RefCount info.user_ = 0; } auto task = GetPostEventTask(schemas, cloud, info, retry); - if (task != nullptr) { - task(); + if (task != nullptr && task()) { + return; } + BatchUpdateFinishState(cloudSyncInfos, E_ERROR); }; } @@ -312,25 +374,30 @@ std::function SyncManager::GetSyncHandler(Retryer retryer) auto store = GetStore(meta, storeInfo.user); if (store == nullptr) { ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); - DoExceptionalCallback(async, details, storeInfo); - return; + return DoExceptionalCallback(async, details, storeInfo); } ZLOGD("database:<%{public}d:%{public}s:%{public}s> sync start", storeInfo.user, storeInfo.bundleName.c_str(), meta.GetStoreAlias().c_str()); RadarReporter::Report( - { storeInfo.bundleName.c_str(), CLOUD_SYNC, TRIGGER_SYNC, storeInfo.syncId }, "GetSyncHandler", BEGIN); + { storeInfo.bundleName.c_str(), CLOUD_SYNC, TRIGGER_SYNC, storeInfo.syncId, evt.GetTriggerMode() }, + "GetSyncHandler", BEGIN); SyncParam syncParam = { evt.GetMode(), evt.GetWait(), evt.IsCompensation() }; auto status = store->Sync({ SyncInfo::DEFAULT_ID }, *(evt.GetQuery()), - evt.AutoRetry() ? RetryCallback(storeInfo, retryer) : GetCallback(evt.GetAsyncDetail(), storeInfo), + evt.AutoRetry() ? RetryCallback(storeInfo, retryer, evt.GetTriggerMode()) + : GetCallback(evt.GetAsyncDetail(), storeInfo, evt.GetTriggerMode()), syncParam); if (status != E_OK) { - int32_t errCode = status + GenStore::DB_ERR_OFFSET; - RadarReporter::Report({ storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId, errCode }, - "GetSyncHandler", END); if (async) { detail.code = status; async(std::move(details)); } + UpdateFinishSyncInfo({ GetAccountId(storeInfo.user), storeInfo.bundleName, "" }, storeInfo.syncId, E_ERROR); + if (status == GeneralError::E_NOT_SUPPORT) { + return; + } + int32_t errCode = status + GenStore::DB_ERR_OFFSET; + RadarReporter::Report({ storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId, + evt.GetTriggerMode(), false, errCode }, "GetSyncHandler", END); } }; } @@ -346,6 +413,7 @@ std::function SyncManager::GetClientChangeHandler() syncInfo.SetAsyncDetail(evt.GetAsyncDetail()); syncInfo.SetQuery(evt.GetQuery()); syncInfo.SetCompensation(evt.IsCompensation()); + syncInfo.SetTriggerMode(evt.GetTriggerMode()); auto times = evt.AutoRetry() ? RETRY_TIMES - CLIENT_RETRY_TIMES : RETRY_TIMES; executor_->Execute(GetSyncTask(times, evt.AutoRetry(), RefCount(), std::move(syncInfo))); }; @@ -360,7 +428,8 @@ SyncManager::Retryer SyncManager::GetRetryer(int32_t times, const SyncInfo &sync } info.SetError(code); RadarReporter::Report( - { info.bundleName_.c_str(), CLOUD_SYNC, FINISH_SYNC, info.syncId_, dbCode }, "GetRetryer", END); + { info.bundleName_.c_str(), CLOUD_SYNC, FINISH_SYNC, info.syncId_, info.triggerMode_, false, dbCode }, + "GetRetryer", END); return true; }; } @@ -371,7 +440,8 @@ SyncManager::Retryer SyncManager::GetRetryer(int32_t times, const SyncInfo &sync if (code == E_NO_SPACE_FOR_ASSET || code == E_RECODE_LIMIT_EXCEEDED) { info.SetError(code); RadarReporter::Report( - { info.bundleName_.c_str(), CLOUD_SYNC, FINISH_SYNC, info.syncId_, dbCode }, "GetRetryer", END); + { info.bundleName_.c_str(), CLOUD_SYNC, FINISH_SYNC, info.syncId_, info.triggerMode_, false, dbCode }, + "GetRetryer", END); return true; } @@ -479,7 +549,7 @@ AutoCache::Store SyncManager::GetStore(const StoreMetaData &meta, int32_t user, } SchemaMeta schemaMeta; std::string schemaKey = info.GetSchemaKey(meta.bundleName, meta.instanceId); - if (!MetaDataManager::GetInstance().LoadMeta(std::move(schemaKey), schemaMeta, true)) { + if (!MetaDataManager::GetInstance().LoadMeta(schemaKey, schemaMeta, true)) { ZLOGE("failed, no schema bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(), meta.GetStoreAlias().c_str()); return nullptr; @@ -523,7 +593,6 @@ std::vector> SyncManager::GetCloudSyncInfo(const ZLOGW("save cloud info fail, user: %{public}d", cloud.user); } } - if (info.bundleName_.empty()) { for (const auto &it : cloud.apps) { QueryKey queryKey{ .accountId = cloud.id, .bundleName = it.first, .storeId = "" }; @@ -546,9 +615,20 @@ void SyncManager::GetLastResults( } } +bool SyncManager::NeedSaveSyncInfo(const QueryKey &queryKey) +{ + if (queryKey.accountId.empty()) { + return false; + } + if (std::find(kvApps_.begin(), kvApps_.end(), queryKey.bundleName) != kvApps_.end()) { + return false; + } + return true; +} + int32_t SyncManager::QueryLastSyncInfo(const std::vector &queryKeys, QueryLastResults &results) { - for (auto &queryKey : queryKeys) { + for (const auto &queryKey : queryKeys) { std::string storeId = queryKey.storeId; QueryKey key{ .accountId = queryKey.accountId, .bundleName = queryKey.bundleName, .storeId = "" }; lastSyncInfos_.ComputeIfPresent( @@ -564,6 +644,9 @@ void SyncManager::UpdateStartSyncInfo(const std::vector(system_clock::now().time_since_epoch()).count(); for (const auto &[queryKey, syncId] : cloudSyncInfos) { + if (!NeedSaveSyncInfo(queryKey)) { + continue; + } lastSyncInfos_.Compute(queryKey, [id = syncId, startTime](auto &, std::map &val) { val[id] = { .startTime = startTime }; return !val.empty(); @@ -573,14 +656,21 @@ void SyncManager::UpdateStartSyncInfo(const std::vector &val) { + auto now = duration_cast(system_clock::now().time_since_epoch()).count(); for (auto iter = val.begin(); iter != val.end();) { - if (iter->first != syncId && iter->second.code != -1) { + bool isExpired = ((now - iter->second.startTime) >= EXPIRATION_TIME) && iter->second.code == -1; + if ((iter->first != syncId && ((iter->second.code != -1) || isExpired))) { iter = val.erase(iter); - } else { + } else if (iter->first == syncId) { iter->second.finishTime = duration_cast(system_clock::now().time_since_epoch()).count(); iter->second.code = code; iter++; + } else { + iter++; } } return true; @@ -588,9 +678,9 @@ void SyncManager::UpdateFinishSyncInfo(const QueryKey &queryKey, uint64_t syncId } std::function SyncManager::GetCallback(const GenAsync &async, - const StoreInfo &storeInfo) + const StoreInfo &storeInfo, int32_t triggerMode) { - return [this, async, storeInfo](const GenDetails &result) { + return [this, async, storeInfo, triggerMode](const GenDetails &result) { if (async != nullptr) { async(result); } @@ -606,6 +696,7 @@ std::function SyncManager::GetCallback(const Gen auto id = GetAccountId(storeInfo.user); if (id.empty()) { + ZLOGD("account id is empty"); return; } QueryKey queryKey{ @@ -617,8 +708,9 @@ std::function SyncManager::GetCallback(const Gen int32_t code = result.begin()->second.code; int32_t dbCode = (result.begin()->second.dbCode == GenStore::DB_ERR_OFFSET) ? 0 : result.begin()->second.dbCode; UpdateFinishSyncInfo(queryKey, storeInfo.syncId, code); - RadarReporter::Report( - { storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId, dbCode }, "GetCallback", END); + RadarReporter::Report({ storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId, triggerMode, + result.begin()->second.changeCount, dbCode }, + "GetCallback", END); }; } @@ -677,9 +769,9 @@ bool SyncManager::InitDefaultUser(int32_t &user) } std::function SyncManager::RetryCallback( - const StoreInfo &storeInfo, Retryer retryer) + const StoreInfo &storeInfo, Retryer retryer, int32_t triggerMode) { - return [this, retryer, storeInfo](const GenDetails &details) { + return [this, retryer, storeInfo, triggerMode](const GenDetails &details) { if (details.empty()) { ZLOGE("retry, details empty"); return; @@ -690,11 +782,21 @@ std::function SyncManager::Retr QueryKey queryKey{ GetAccountId(storeInfo.user), storeInfo.bundleName, "" }; UpdateFinishSyncInfo(queryKey, storeInfo.syncId, code); if (code == E_OK) { - RadarReporter::Report( - { storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId }, "RetryCallback", END); + RadarReporter::Report({ storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId, + triggerMode, details.begin()->second.changeCount }, + "RetryCallback", END); } } retryer(GetInterval(code), code, dbCode); }; } + +void SyncManager::BatchUpdateFinishState(const std::vector> &cloudSyncInfos, + int32_t code) +{ + for (const auto &[queryKey, syncId] : cloudSyncInfos) { + UpdateFinishSyncInfo(queryKey, syncId, code); + } +} + } // namespace OHOS::CloudData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.h b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.h index e4d7b0e4..2aed28de 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.h +++ b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.h @@ -46,7 +46,8 @@ public: using Stores = std::vector; using Tables = std::vector; using MutliStoreTables = std::map; - SyncInfo(int32_t user, const std::string &bundleName = "", const Store &store = "", const Tables &tables = {}); + explicit SyncInfo(int32_t user, const std::string &bundleName = "", const Store &store = "", + const Tables &tables = {}, int32_t triggerMode = 0); SyncInfo(int32_t user, const std::string &bundleName, const Stores &stores); SyncInfo(int32_t user, const std::string &bundleName, const MutliStoreTables &tables); void SetMode(int32_t mode); @@ -55,6 +56,7 @@ public: void SetQuery(std::shared_ptr query); void SetError(int32_t code) const; void SetCompensation(bool isCompensation); + void SetTriggerMode(int32_t triggerMode); std::shared_ptr GenerateQuery(const std::string &store, const Tables &tables); bool Contains(const std::string &storeName); inline static constexpr const char *DEFAULT_ID = "default"; @@ -71,6 +73,7 @@ public: GenAsync async_; std::shared_ptr query_; bool isCompensation_ = false; + int32_t triggerMode_ = 0; }; SyncManager(); ~SyncManager(); @@ -93,13 +96,14 @@ private: using GenProgress = DistributedData::GenProgress; using GenDetails = DistributedData::GenDetails; - static constexpr ExecutorPool::Duration RETRY_INTERVAL = std::chrono::seconds(10); // second + static constexpr ExecutorPool::Duration RETRY_INTERVAL = std::chrono::seconds(10); // second static constexpr ExecutorPool::Duration LOCKED_INTERVAL = std::chrono::seconds(30); // second - static constexpr ExecutorPool::Duration BUSY_INTERVAL = std::chrono::seconds(180); // second - static constexpr int32_t RETRY_TIMES = 6; // normal retry - static constexpr int32_t CLIENT_RETRY_TIMES = 3; // normal retry - static constexpr uint64_t USER_MARK = 0xFFFFFFFF00000000; // high 32 bit + static constexpr ExecutorPool::Duration BUSY_INTERVAL = std::chrono::seconds(180); // second + static constexpr int32_t RETRY_TIMES = 6; // normal retry + static constexpr int32_t CLIENT_RETRY_TIMES = 3; // normal retry + static constexpr uint64_t USER_MARK = 0xFFFFFFFF00000000; // high 32 bit static constexpr int32_t MV_BIT = 32; + static constexpr int32_t EXPIRATION_TIME = 6 * 60 * 60 * 1000; // 6 hours static uint64_t GenerateId(int32_t user); static ExecutorPool::Duration GetInterval(int32_t code); @@ -120,15 +124,18 @@ private: void UpdateStartSyncInfo(const std::vector> &cloudSyncInfos); void UpdateFinishSyncInfo(const QueryKey &queryKey, uint64_t syncId, int32_t code); std::function GetCallback(const GenAsync &async, - const StoreInfo &storeInfo); - std::function GetPostEventTask(const std::vector &schemas, CloudInfo &cloud, SyncInfo &info, + const StoreInfo &storeInfo, int32_t triggerMode); + std::function GetPostEventTask(const std::vector &schemas, CloudInfo &cloud, SyncInfo &info, bool retry); void DoExceptionalCallback(const GenAsync &async, GenDetails &details, const StoreInfo &storeInfo); bool InitDefaultUser(int32_t &user); std::function RetryCallback( - const StoreInfo &storeInfo, Retryer retryer); + const StoreInfo &storeInfo, Retryer retryer, int32_t triggerMode); static void GetLastResults( const std::string &storeId, std::map &infos, QueryLastResults &results); + void BatchUpdateFinishState(const std::vector> &cloudSyncInfos, int32_t code); + bool NeedSaveSyncInfo(const QueryKey &queryKey); + std::function GetLockChangeHandler(); static std::atomic genId_; std::shared_ptr executor_; @@ -136,6 +143,7 @@ private: ConcurrentMap activeInfos_; std::shared_ptr syncStrategy_; ConcurrentMap> lastSyncInfos_; + std::set kvApps_; }; } // namespace OHOS::CloudData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_SYNC_MANAGER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/cloud/sync_strategies/network_sync_strategy.cpp b/datamgr_service/services/distributeddataservice/service/cloud/sync_strategies/network_sync_strategy.cpp index 043cb5e7..827bf628 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/sync_strategies/network_sync_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/sync_strategies/network_sync_strategy.cpp @@ -16,17 +16,19 @@ #define LOG_TAG "NetworkSyncStrategy" #include "network_sync_strategy.h" -#include "metadata/meta_data_manager.h" + #include "device_manager_adapter.h" #include "error/general_error.h" -#include "utils/constant.h" #include "log_print.h" +#include "metadata/meta_data_manager.h" +#include "utils/constant.h" namespace OHOS::CloudData { using namespace OHOS::DistributedData; NetworkSyncStrategy::NetworkSyncStrategy() { MetaDataManager::GetInstance().Subscribe( - StrategyInfo::PREFIX, [this](const std::string &key, const std::string &value, int32_t flag) -> auto { + StrategyInfo::PREFIX, + [this](const std::string &key, const std::string &value, int32_t flag) -> auto { StrategyInfo info; StrategyInfo::Unmarshall(value, info); ZLOGI("flag:%{public}d, value:%{public}s", flag, value.c_str()); @@ -41,14 +43,20 @@ NetworkSyncStrategy::NetworkSyncStrategy() ZLOGE("ignored operation"); } return true; - }, true); + }, + true); } + NetworkSyncStrategy::~NetworkSyncStrategy() { MetaDataManager::GetInstance().Unsubscribe(StrategyInfo::PREFIX); } + int32_t NetworkSyncStrategy::CheckSyncAction(const StoreInfo &storeInfo) { + if (storeInfo.user == StrategyInfo::ROOT_USER) { + return E_OK; + } if (!DeviceManagerAdapter::GetInstance().IsNetworkAvailable()) { return E_NETWORK_ERROR; } @@ -125,4 +133,4 @@ NetworkSyncStrategy::StrategyInfo NetworkSyncStrategy::GetStrategy(int32_t user, strategies_.Insert(info.bundleName, info); return info; } -} +} // namespace OHOS::CloudData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/cloud/sync_strategies/network_sync_strategy.h b/datamgr_service/services/distributeddataservice/service/cloud/sync_strategies/network_sync_strategy.h index 2d19ece4..af2680a1 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/sync_strategies/network_sync_strategy.h +++ b/datamgr_service/services/distributeddataservice/service/cloud/sync_strategies/network_sync_strategy.h @@ -36,16 +36,18 @@ public: bool Unmarshal(const json &node) override; std::string GetKey(); static constexpr int32_t INVALID_USER = -1; + static constexpr int32_t ROOT_USER = 0; static constexpr const char *PREFIX = "NETWORK_SYNC_STRATEGY"; }; NetworkSyncStrategy(); ~NetworkSyncStrategy(); - int32_t CheckSyncAction(const StoreInfo& storeInfo) override; + int32_t CheckSyncAction(const StoreInfo &storeInfo) override; static std::string GetKey(int32_t user); - static std::string GetKey(int32_t user, const std::string& bundleName); + static std::string GetKey(int32_t user, const std::string &bundleName); + private: - StrategyInfo GetStrategy(int32_t user, const std::string& bundleName); + StrategyInfo GetStrategy(int32_t user, const std::string &bundleName); static bool Check(uint32_t strategy); static constexpr uint32_t DEFAULT_STRATEGY = WIFI | CELLULAR; @@ -53,5 +55,5 @@ private: int32_t user_ = -1; ConcurrentMap strategies_; }; -} -#endif //OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_NETWORK_SYNC_STRATEGY_H +} // namespace OHOS::CloudData +#endif //OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_NETWORK_SYNC_STRATEGY_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/config/include/config_factory.h b/datamgr_service/services/distributeddataservice/service/config/include/config_factory.h index e6e4025c..6ebb1e0d 100644 --- a/datamgr_service/services/distributeddataservice/service/config/include/config_factory.h +++ b/datamgr_service/services/distributeddataservice/service/config/include/config_factory.h @@ -31,6 +31,7 @@ public: API_EXPORT DirectoryConfig *GetDirectoryConfig(); API_EXPORT BackupConfig *GetBackupConfig(); API_EXPORT CloudConfig *GetCloudConfig(); + API_EXPORT std::vector *GetAppIdMappingConfig(); private: static constexpr const char *CONF_PATH = "/system/etc/distributeddata/conf"; ConfigFactory(); diff --git a/datamgr_service/services/distributeddataservice/service/config/include/model/app_id_mapping_config.h b/datamgr_service/services/distributeddataservice/service/config/include/model/app_id_mapping_config.h new file mode 100644 index 00000000..a0ff96a3 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/config/include/model/app_id_mapping_config.h @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2024 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_DATA_SERVICES_CONFIG_MODEL_APP_ID_MAPPING_CONFIG_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_CONFIG_MODEL_APP_ID_MAPPING_CONFIG_H + +#include "serializable/serializable.h" +namespace OHOS { +namespace DistributedData { +class AppIdMappingConfig final : public Serializable { +public: + std::string srcAppId = ""; + std::string dstAppId = ""; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; +}; +} // namespace DistributedData +} // namespace OHOS +#endif //OHOS_DISTRIBUTED_DATA_SERVICES_CONFIG_MODEL_APP_ID_MAPPING_CONFIG_H diff --git a/datamgr_service/services/distributeddataservice/service/config/include/model/global_config.h b/datamgr_service/services/distributeddataservice/service/config/include/model/global_config.h index c96926e4..0d974d5b 100644 --- a/datamgr_service/services/distributeddataservice/service/config/include/model/global_config.h +++ b/datamgr_service/services/distributeddataservice/service/config/include/model/global_config.h @@ -22,6 +22,7 @@ #include "model/network_config.h" #include "model/directory_config.h" #include "model/backup_config.h" +#include "model/app_id_mapping_config.h" namespace OHOS { namespace DistributedData { class GlobalConfig final : public Serializable { @@ -36,6 +37,7 @@ public: DirectoryConfig *directory = nullptr; BackupConfig *backup = nullptr; CloudConfig *cloud = nullptr; + std::vector *appIdMapping = nullptr; ~GlobalConfig(); bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; diff --git a/datamgr_service/services/distributeddataservice/service/config/src/config_factory.cpp b/datamgr_service/services/distributeddataservice/service/config/src/config_factory.cpp index 733ab0ea..996f6e58 100644 --- a/datamgr_service/services/distributeddataservice/service/config/src/config_factory.cpp +++ b/datamgr_service/services/distributeddataservice/service/config/src/config_factory.cpp @@ -82,5 +82,10 @@ CloudConfig *ConfigFactory::GetCloudConfig() { return config_.cloud; } + +std::vector *ConfigFactory::GetAppIdMappingConfig() +{ + return config_.appIdMapping; +} } // namespace DistributedData } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/config/src/model/app_id_mapping_config.cpp b/datamgr_service/services/distributeddataservice/service/config/src/model/app_id_mapping_config.cpp new file mode 100644 index 00000000..001336e6 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/config/src/model/app_id_mapping_config.cpp @@ -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. + */ + +#include "model/app_id_mapping_config.h" +namespace OHOS { +namespace DistributedData { +bool AppIdMappingConfig::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(srcAppId)], srcAppId); + SetValue(node[GET_NAME(dstAppId)], dstAppId); + return true; +} +bool AppIdMappingConfig::Unmarshal(const Serializable::json &node) +{ + GetValue(node, GET_NAME(srcAppId), srcAppId); + GetValue(node, GET_NAME(dstAppId), dstAppId); + return true; +} +} // namespace DistributedData +} // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/config/src/model/global_config.cpp b/datamgr_service/services/distributeddataservice/service/config/src/model/global_config.cpp index b3078891..d4ee7971 100644 --- a/datamgr_service/services/distributeddataservice/service/config/src/model/global_config.cpp +++ b/datamgr_service/services/distributeddataservice/service/config/src/model/global_config.cpp @@ -28,6 +28,7 @@ bool GlobalConfig::Marshal(json &node) const SetValue(node[GET_NAME(directory)], directory); SetValue(node[GET_NAME(backup)], backup); SetValue(node[GET_NAME(cloud)], cloud); + SetValue(node[GET_NAME(appIdMapping)], appIdMapping); return true; } @@ -43,6 +44,7 @@ bool GlobalConfig::Unmarshal(const json &node) GetValue(node, GET_NAME(directory), directory); GetValue(node, GET_NAME(backup), backup); GetValue(node, GET_NAME(cloud), cloud); + GetValue(node, GET_NAME(appIdMapping), appIdMapping); return true; } @@ -54,6 +56,7 @@ GlobalConfig::~GlobalConfig() delete directory; delete backup; delete cloud; + delete appIdMapping; } } // namespace DistributedData } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp index a54df936..dec8551c 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp @@ -16,11 +16,13 @@ #include "bundle_mgr_proxy.h" #include "account/account_delegate.h" +#include "datashare_errno.h" #include "datashare_radar_reporter.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" #include "log_print.h" #include "system_ability_definition.h" +#include "uri_utils.h" namespace OHOS::DataShare { sptr BundleMgrProxy::GetBundleMgrProxy() @@ -59,32 +61,39 @@ sptr BundleMgrProxy::CheckBMS() return systemAbilityManager->CheckSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); } -bool BundleMgrProxy::GetBundleInfoFromBMS( - const std::string &bundleName, int32_t userId, AppExecFwk::BundleInfo &bundleInfo) +int BundleMgrProxy::GetBundleInfoFromBMS( + const std::string &bundleName, int32_t userId, BundleConfig &bundleConfig) { auto bundleKey = bundleName + std::to_string(userId); auto it = bundleCache_.Find(bundleKey); if (it.first) { - bundleInfo = it.second; - return true; + bundleConfig = it.second; + return E_OK; } auto bmsClient = GetBundleMgrProxy(); if (bmsClient == nullptr) { RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::GET_BMS, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::GET_BMS_FAILED); ZLOGE("GetBundleMgrProxy is nullptr!"); - return false; + return E_BMS_NOT_READY; } + AppExecFwk::BundleInfo bundleInfo; bool ret = bmsClient->GetBundleInfo( bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId); if (!ret) { RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::GET_BMS, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::GET_BUNDLE_INFP_FAILED); ZLOGE("GetBundleInfo failed!bundleName is %{public}s, userId is %{public}d", bundleName.c_str(), userId); - return false; + return E_BUNDLE_NAME_NOT_EXIST; } - bundleCache_.Insert(bundleKey, bundleInfo); - return true; + auto [errCode, bundle] = ConvertToDataShareBundle(bundleInfo); + if (errCode != E_OK) { + ZLOGE("Profile Unmarshall failed! bundleName:%{public}s", URIUtils::Anonymous(bundle.name).c_str()); + return errCode; + } + bundleConfig = bundle; + bundleCache_.Insert(bundleKey, bundle); + return E_OK; } void BundleMgrProxy::OnProxyDied() @@ -117,4 +126,92 @@ std::shared_ptr BundleMgrProxy::GetInstance() static std::shared_ptr proxy(new BundleMgrProxy()); return proxy; } + +std::pair BundleMgrProxy::ConvertToDataShareBundle(AppExecFwk::BundleInfo &bundleInfo) +{ + BundleConfig bundleConfig; + bundleConfig.name = std::move(bundleInfo.name); + bundleConfig.singleton = std::move(bundleInfo.singleton); + auto [errCode, hapModuleInfos] = ConvertHapModuleInfo(bundleInfo); + if (errCode != E_OK) { + return std::make_pair(errCode, bundleConfig); + } + bundleConfig.hapModuleInfos = hapModuleInfos; + + auto [err, extensionInfos] = ConvertExtensionAbility(bundleInfo); + if (err != E_OK) { + return std::make_pair(err, bundleConfig); + } + bundleConfig.extensionInfos = extensionInfos; + return std::make_pair(E_OK, bundleConfig); +} + +std::pair> BundleMgrProxy::ConvertExtensionAbility( + AppExecFwk::BundleInfo &bundleInfo) +{ + std::vector extensionInfos; + for (auto &item : bundleInfo.extensionInfos) { + if (item.type != AppExecFwk::ExtensionAbilityType::DATASHARE) { + continue; + } + ExtensionAbilityInfo extensionInfo; + extensionInfo.type = std::move(item.type); + extensionInfo.readPermission = std::move(item.readPermission); + extensionInfo.writePermission = std::move(item.writePermission); + extensionInfo.uri = std::move(item.uri); + extensionInfo.resourcePath = std::move(item.resourcePath); + extensionInfo.hapPath = std::move(item.hapPath); + ProfileConfig profileConfig; + auto [ret, profileInfo] = DataShareProfileConfig::GetDataProperties( + item.metadata, extensionInfo.resourcePath, extensionInfo.hapPath, DATA_SHARE_EXTENSION_META); + if (ret == NOT_FOUND) { + profileConfig.resultCode = NOT_FOUND; + } + if (ret == ERROR) { + profileConfig.resultCode = ERROR; + ZLOGE("Profile unmarshall error.uri: %{public}s", URIUtils::Anonymous(extensionInfo.uri).c_str()); + return std::make_pair(E_ERROR, extensionInfos); + } + profileConfig.profile = profileInfo; + extensionInfo.profileInfo = profileConfig; + extensionInfos.emplace_back(extensionInfo); + } + return std::make_pair(E_OK, extensionInfos); +} + +std::pair> BundleMgrProxy::ConvertHapModuleInfo(AppExecFwk::BundleInfo &bundleInfo) +{ + std::vector hapModuleInfos; + for (auto &item : bundleInfo.hapModuleInfos) { + HapModuleInfo hapModuleInfo; + hapModuleInfo.resourcePath = std::move(item.resourcePath); + hapModuleInfo.hapPath = std::move(item.hapPath); + hapModuleInfo.moduleName = std::move(item.moduleName); + std::vector proxyDatas; + for (auto &proxyData : item.proxyDatas) { + ProxyData data; + data.uri = std::move(proxyData.uri); + data.requiredReadPermission = std::move(proxyData.requiredReadPermission); + data.requiredWritePermission = std::move(proxyData.requiredWritePermission); + ProfileConfig profileConfig; + auto [ret, profileInfo] = DataShareProfileConfig::GetDataProperties( + std::vector{proxyData.metadata}, hapModuleInfo.resourcePath, + hapModuleInfo.hapPath, DATA_SHARE_PROPERTIES_META); + if (ret == NOT_FOUND) { + profileConfig.resultCode = NOT_FOUND; + } + if (ret == ERROR) { + profileConfig.resultCode = ERROR; + ZLOGE("Profile unmarshall error.uri: %{public}s", URIUtils::Anonymous(data.uri).c_str()); + return std::make_pair(E_ERROR, hapModuleInfos); + } + profileConfig.profile = profileInfo; + data.profileInfo = profileConfig; + proxyDatas.emplace_back(data); + } + hapModuleInfo.proxyDatas = proxyDatas; + hapModuleInfos.emplace_back(hapModuleInfo); + } + return std::make_pair(E_OK, hapModuleInfos); +} } // namespace OHOS::DataShare \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h b/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h index a4137405..9b4b325c 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h @@ -22,12 +22,50 @@ #include "bundle_info.h" #include "bundlemgr/bundle_mgr_proxy.h" #include "concurrent_map.h" +#include "data_share_profile_config.h" + namespace OHOS::DataShare { +struct ProfileConfig { + ProfileInfo profile; + int resultCode = 0; +}; + +struct ProxyData { + std::string uri; + std::string requiredReadPermission; + std::string requiredWritePermission; + ProfileConfig profileInfo; +}; + +struct HapModuleInfo { + std::string resourcePath; + std::string hapPath; + std::string moduleName; + std::vector proxyDatas; +}; + +struct ExtensionAbilityInfo { + AppExecFwk::ExtensionAbilityType type = AppExecFwk::ExtensionAbilityType::UNSPECIFIED; + std::string readPermission; + std::string writePermission; + std::string uri; + std::string resourcePath; + std::string hapPath; + ProfileConfig profileInfo; +}; + +struct BundleConfig { + std::string name; + bool singleton = false; + std::vector hapModuleInfos; + std::vector extensionInfos; +}; + class BundleMgrProxy final : public std::enable_shared_from_this { public: ~BundleMgrProxy(); static std::shared_ptr GetInstance(); - bool GetBundleInfoFromBMS(const std::string &bundleName, int32_t userId, AppExecFwk::BundleInfo &bundleInfo); + int GetBundleInfoFromBMS(const std::string &bundleName, int32_t userId, BundleConfig &bundleConfig); void Delete(const std::string &bundleName, int32_t userId); sptr CheckBMS(); @@ -49,10 +87,15 @@ private: }; sptr GetBundleMgrProxy(); void OnProxyDied(); + std::pair ConvertToDataShareBundle(AppExecFwk::BundleInfo &bundleInfo); + std::pair> ConvertExtensionAbility(AppExecFwk::BundleInfo &bundleInfo); + std::pair> ConvertHapModuleInfo(AppExecFwk::BundleInfo &bundleInfo); std::mutex mutex_; sptr proxy_; sptr deathRecipient_; - ConcurrentMap bundleCache_; + ConcurrentMap bundleCache_; + static constexpr const char *DATA_SHARE_EXTENSION_META = "ohos.extension.dataShare"; + static constexpr const char *DATA_SHARE_PROPERTIES_META = "dataProperties"; }; } // namespace OHOS::DataShare #endif // DATASHARESERVICE_BUNDLEMGR_PROXY_H diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/context.h b/datamgr_service/services/distributeddataservice/service/data_share/common/context.h index e347eb03..25995eaa 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/context.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/context.h @@ -21,7 +21,7 @@ #include #include -#include "bundle_info.h" +#include "bundle_mgr_proxy.h" namespace OHOS::DataShare { enum AccessSystemMode : uint8_t { @@ -53,7 +53,7 @@ public: bool needAutoLoadCallerBundleName = false; bool isEncryptDb = false; AccessSystemMode accessSystemMode = AccessSystemMode::UNDEFINED; - OHOS::AppExecFwk::BundleInfo bundleInfo; + BundleConfig bundleInfo; std::string type = "rdb"; }; } // namespace OHOS::DataShare diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.cpp index 84b9b544..f9ba94f0 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.cpp @@ -20,9 +20,89 @@ #include "log_print.h" #include "rdb_delegate.h" namespace OHOS::DataShare { -std::shared_ptr DBDelegate::Create(DistributedData::StoreMetaData &metaData) +ExecutorPool::TaskId DBDelegate::taskId_ = ExecutorPool::INVALID_TASK_ID; +ConcurrentMap>> DBDelegate::stores_ = {}; +std::shared_ptr DBDelegate::executor_ = nullptr; +std::shared_ptr DBDelegate::Create(DistributedData::StoreMetaData &metaData, + const std::string &extUri, const std::string &backup) { - return std::make_shared(metaData, NO_CHANGE_VERSION, true); + if (metaData.tokenId == 0) { + return std::make_shared(metaData, NO_CHANGE_VERSION, true, extUri, backup); + } + std::shared_ptr store; + stores_.Compute(metaData.tokenId, + [&metaData, &store, extUri, &backup](auto &, std::map> &stores) -> bool { + auto it = stores.find(metaData.storeId); + if (it != stores.end()) { + store = it->second->store_; + it->second->time_ = std::chrono::steady_clock::now() + std::chrono::seconds(INTERVAL); + return !stores.empty(); + } + store = std::make_shared(metaData, NO_CHANGE_VERSION, true, extUri, backup); + if (store->IsInvalid()) { + store = nullptr; + ZLOGE("creator failed, storeName: %{public}s", metaData.GetStoreAlias().c_str()); + return false; + } + auto entity = std::make_shared(store); + stores.emplace(metaData.storeId, entity); + StartTimer(); + return !stores.empty(); + }); + return store; +} + +void DBDelegate::SetExecutorPool(std::shared_ptr executor) +{ + executor_ = std::move(executor); +} + +void DBDelegate::GarbageCollect() +{ + stores_.EraseIf([](auto &, std::map> &stores) { + auto current = std::chrono::steady_clock::now(); + for (auto it = stores.begin(); it != stores.end();) { + // if the store is BUSY we wait more INTERVAL minutes again + if (it->second->time_ < current) { + it = stores.erase(it); + } else { + ++it; + } + } + return stores.empty(); + }); +} + +void DBDelegate::StartTimer() +{ + if (executor_ == nullptr || taskId_ != Executor::INVALID_TASK_ID) { + return; + } + taskId_ = executor_->Schedule( + []() { + GarbageCollect(); + stores_.DoActionIfEmpty([]() { + if (executor_ == nullptr || taskId_ == Executor::INVALID_TASK_ID) { + return; + } + executor_->Remove(taskId_); + ZLOGD("remove timer, taskId: %{public}" PRIu64, taskId_); + taskId_ = Executor::INVALID_TASK_ID; + }); + }, + std::chrono::seconds(INTERVAL), std::chrono::seconds(INTERVAL)); + ZLOGD("start timer, taskId: %{public}" PRIu64, taskId_); +} + +DBDelegate::Entity::Entity(std::shared_ptr store) +{ + store_ = std::move(store); + time_ = std::chrono::steady_clock::now() + std::chrono::seconds(INTERVAL); +} + +void DBDelegate::EraseStoreCache(const int32_t tokenId) +{ + stores_.Erase(tokenId); } std::shared_ptr KvDBDelegate::GetInstance( diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.h b/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.h index 99f13253..18e40523 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.h @@ -31,19 +31,37 @@ namespace OHOS::DataShare { class DBDelegate { public: - static std::shared_ptr Create(DistributedData::StoreMetaData &metaData); - virtual int64_t Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) = 0; - virtual int64_t Update(const std::string &tableName, const DataSharePredicates &predicate, - const DataShareValuesBucket &valuesBucket) = 0; - virtual int64_t Delete(const std::string &tableName, const DataSharePredicates &predicate) = 0; + using Time = std::chrono::steady_clock::time_point; + static std::shared_ptr Create(DistributedData::StoreMetaData &metaData, + const std::string &extUri = "", const std::string &backup = ""); virtual std::pair> Query(const std::string &tableName, const DataSharePredicates &predicates, const std::vector &columns, const int32_t callingPid) = 0; virtual std::string Query( const std::string &sql, const std::vector &selectionArgs = std::vector()) = 0; virtual std::shared_ptr QuerySql(const std::string &sql) = 0; + virtual bool IsInvalid() = 0; + static void SetExecutorPool(std::shared_ptr executor); + static void EraseStoreCache(const int32_t tokenId); + virtual std::pair InsertEx(const std::string &tableName, + const DataShareValuesBucket &valuesBucket) = 0; + virtual std::pair UpdateEx(const std::string &tableName, + const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) = 0; + virtual std::pair DeleteEx(const std::string &tableName, + const DataSharePredicates &predicate) = 0; private: + static void GarbageCollect(); + static void StartTimer(); + struct Entity { + explicit Entity(std::shared_ptr store); + std::shared_ptr store_; + Time time_; + }; static constexpr int NO_CHANGE_VERSION = -1; + static constexpr int64_t INTERVAL = 20; //seconds + static ConcurrentMap>> stores_; + static std::shared_ptr executor_; + static ExecutorPool::TaskId taskId_; }; class Id : public DistributedData::Serializable { @@ -107,6 +125,7 @@ public: std::string &result) = 0; virtual int32_t GetBatch(const std::string &collectionName, const std::string &filter, const std::string &projection, std::vector &result) = 0; + virtual void NotifyBackup() = 0; }; } // namespace OHOS::DataShare #endif // DATASHARESERVICE_DB_DELEGATE_H diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_ability_manager.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_ability_manager.cpp index 8a7c7f38..2328285d 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_ability_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_ability_manager.cpp @@ -34,7 +34,7 @@ void ExtensionAbilityManager::SetExecutorPool(std::shared_ptr exec } int32_t ExtensionAbilityManager::ConnectExtension(const std::string &uri, const std::string &bundleName, - const sptr &callback) + const sptr &callback, AAFwk::WantParams &wantParams) { auto absent = connectCallbackCache_.ComputeIfAbsent(bundleName, [callback](const std::string &) { return std::move(callback); @@ -44,32 +44,38 @@ int32_t ExtensionAbilityManager::ConnectExtension(const std::string &uri, const bundleName.c_str(), URIUtils::Anonymous(uri).c_str()); return E_ERROR; } - ErrCode ret = ExtensionMgrProxy::GetInstance()->Connect(uri, callback, nullptr); + ErrCode ret = ExtensionMgrProxy::GetInstance()->Connect(uri, callback, nullptr, wantParams); if (ret != E_OK) { ZLOGE("Connect ability failed, ret:%{public}d, uri:%{public}s, bundleName:%{public}s", ret, URIUtils::Anonymous(uri).c_str(), bundleName.c_str()); connectCallbackCache_.Erase(bundleName); return E_ERROR; } + Disconnect(bundleName, MAX_WAIT_DISCONNECT_TIME); return E_OK; } void ExtensionAbilityManager::DelayDisconnect(const std::string &bundleName) { - executor_->Schedule(std::chrono::seconds(WAIT_DISCONNECT_TIME), [bundleName, this]() { + Disconnect(bundleName, WAIT_DISCONNECT_TIME); +} + +void ExtensionAbilityManager::Disconnect(const std::string &bundleName, int time) +{ + executor_->Schedule(std::chrono::seconds(time), [bundleName, this]() { ZLOGI("Delay disconnect %{public}s", bundleName.c_str()); - connectCallbackCache_.ComputeIfPresent(bundleName, [bundleName](const std::string &, - sptr &disconnect) { - if (disconnect == nullptr) { - ZLOGI("Delay disconnect nullptr %{public}s", bundleName.c_str()); + connectCallbackCache_.ComputeIfPresent(bundleName, + [bundleName](const std::string &, sptr &disconnect) { + if (disconnect == nullptr) { + ZLOGI("Delay disconnect nullptr %{public}s", bundleName.c_str()); + return false; + } + auto ret = ExtensionMgrProxy::GetInstance()->DisConnect(disconnect); + if (ret != E_OK) { + ZLOGE("Delay disConnect failed bundleName: %{public}s, ret: %{public}d", bundleName.c_str(), ret); + } return false; - } - auto ret = ExtensionMgrProxy::GetInstance()->DisConnect(disconnect); - if (ret != E_OK) { - ZLOGE("Delay disConnect failed bundleName: %{public}s, ret: %{public}d", bundleName.c_str(), ret); - } - return false; - }); + }); }); } } // namespace OHOS::DataShare diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_ability_manager.h b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_ability_manager.h index 0640fa6e..a78e4e20 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_ability_manager.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_ability_manager.h @@ -19,6 +19,7 @@ #include "concurrent_map.h" #include "executor_pool.h" #include "iremote_object.h" +#include "want.h" namespace OHOS::DataShare { class ExtensionAbilityManager { @@ -26,13 +27,15 @@ public: static ExtensionAbilityManager &GetInstance(); void SetExecutorPool(std::shared_ptr executor); int32_t ConnectExtension(const std::string &uri, const std::string &bundleName, - const sptr &callback); + const sptr &callback, AAFwk::WantParams &wantParams); void DelayDisconnect(const std::string &bundleName); private: + void Disconnect(const std::string &bundleName, int time); std::shared_ptr executor_ = nullptr; ConcurrentMap> connectCallbackCache_; static constexpr int WAIT_DISCONNECT_TIME = 5; + static constexpr int MAX_WAIT_DISCONNECT_TIME = 30; }; } // namespace OHOS::DataShare #endif // DATASHARESERVICE_EXTENSION_ABILITY_MANAGER_H diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp index 9256abd3..6a48232a 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.cpp @@ -32,13 +32,15 @@ ExtensionConnectAdaptor::ExtensionConnectAdaptor() : data_(std::make_sharedClear(); if (callback_ == nullptr) { return false; } - ErrCode ret = ExtensionAbilityManager::GetInstance().ConnectExtension(uri, bundleName, callback_->AsObject()); + ErrCode ret = ExtensionAbilityManager::GetInstance().ConnectExtension(uri, bundleName, + callback_->AsObject(), wantParams); if (ret != ERR_OK) { ZLOGE("connect ability failed, ret = %{public}d, uri: %{public}s", ret, URIUtils::Anonymous(uri).c_str()); @@ -51,13 +53,13 @@ bool ExtensionConnectAdaptor::DoConnect(const std::string &uri, const std::strin } bool ExtensionConnectAdaptor::TryAndWait(const std::string &uri, const std::string &bundleName, - int maxWaitTime) + AAFwk::WantParams &wantParams, int maxWaitTime) { ExtensionConnectAdaptor strategy; return AppConnectManager::Wait( bundleName, maxWaitTime, - [&uri, &bundleName, &strategy]() { - return strategy.DoConnect(uri, bundleName); + [&uri, &bundleName, &strategy, &wantParams]() { + return strategy.DoConnect(uri, bundleName, wantParams); }, [&strategy]() { strategy.Disconnect(); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h index e36d61ed..ad585d10 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_connect_adaptor.h @@ -19,15 +19,16 @@ #include "ability_connect_callback_interface.h" #include "block_data.h" #include "context.h" +#include "want.h" namespace OHOS::DataShare { class ExtensionConnectAdaptor { public: - static bool TryAndWait(const std::string &uri, const std::string &bundleName, + static bool TryAndWait(const std::string &uri, const std::string &bundleName, AAFwk::WantParams &wantParams, int maxWaitTime = 2); ExtensionConnectAdaptor(); private: void Disconnect(); - bool DoConnect(const std::string &uri, const std::string &bundleName); + bool DoConnect(const std::string &uri, const std::string &bundleName, AAFwk::WantParams &wantParams); std::shared_ptr> data_; sptr callback_ = nullptr; }; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.cpp index 3303346e..1d7f44d1 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.cpp @@ -49,10 +49,12 @@ std::shared_ptr ExtensionMgrProxy::GetInstance() } int ExtensionMgrProxy::Connect( - const std::string &uri, const sptr &connect, const sptr &callerToken) + const std::string &uri, const sptr &connect, const sptr &callerToken, + AAFwk::WantParams &wantParams) { AAFwk::Want want; want.SetUri(uri); + want.SetParams(wantParams); std::lock_guard lock(mutex_); if (ConnectSA()) { int ret = proxy_->ConnectAbilityCommon(want, connect, callerToken, AppExecFwk::ExtensionAbilityType::DATASHARE); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.h b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.h index a93a4c90..21bda2dd 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.h @@ -20,6 +20,7 @@ #include #include "extension_manager_proxy.h" +#include "want.h" namespace OHOS::DataShare { class ExtensionMgrProxy final : public std::enable_shared_from_this { public: @@ -27,7 +28,8 @@ public: ExtensionMgrProxy() = default; ~ExtensionMgrProxy(); static std::shared_ptr GetInstance(); - int Connect(const std::string &uri, const sptr &connect, const sptr &callerToken); + int Connect(const std::string &uri, const sptr &connect, + const sptr &callerToken, AAFwk::WantParams &wantParams); int DisConnect(sptr connect); private: using Proxy = AAFwk::ExtensionManagerProxy; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.cpp index 9e36164a..23aa6a61 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 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 @@ -13,6 +13,12 @@ * limitations under the License. */ #define LOG_TAG "KvAdaptor" + +#include +#include +#include +#include + #include "kv_delegate.h" #include "datashare_errno.h" @@ -24,6 +30,103 @@ namespace OHOS::DataShare { constexpr int WAIT_TIME = 30; + +// If using multi-process access, back up dataShare.db.map as well. Check config file to see whether +// using multi-process maccess +const char* g_backupFiles[] = { + "dataShare.db", + "dataShare.db.redo", + "dataShare.db.safe", + "dataShare.db.undo", +}; +const char* BACKUP_SUFFIX = ".backup"; + +// If isBackUp is true, remove db backup files. Otherwise remove source db files. +void KvDelegate::RemoveDbFile(bool isBackUp) +{ + for (auto &fileName: g_backupFiles) { + std::string dbPath = path_ + "/" + fileName; + if (isBackUp) { + dbPath += BACKUP_SUFFIX; + } + if (std::filesystem::exists(dbPath)) { + std::error_code ec; + bool success = std::filesystem::remove(dbPath, ec); + if (!success) { + ZLOGE("failed to remove file %{public}s, err: %{public}s", fileName, ec.message().c_str()); + } + } + } +} + +bool KvDelegate::CopyFile(bool isBackup) +{ + std::filesystem::copy_options options = std::filesystem::copy_options::overwrite_existing; + std::error_code code; + bool ret = true; + for (auto &fileName : g_backupFiles) { + std::string src = path_ + "/" + fileName; + std::string dst = src; + isBackup ? dst.append(BACKUP_SUFFIX) : src.append(BACKUP_SUFFIX); + // If src doesn't exist, error will be returned through `std::error_code` + bool copyRet = std::filesystem::copy_file(src, dst, options, code); + if (!copyRet) { + ZLOGE("failed to copy file %{public}s, isBackup %{public}d, err: %{public}s", + fileName, isBackup, code.message().c_str()); + ret = false; + RemoveDbFile(isBackup); + break; + } + } + return ret; +} + +// Restore database data when it is broken somehow. Some failure of insertion / deletion / updates will be considered +// as database files damage, and therefore trigger the process of restoration. +void KvDelegate::Restore() +{ + // No need to lock because this inner method will only be called when upper methods lock up + CopyFile(false); + ZLOGD("finish restoring kv"); +} + +// Backup database data by copying its key files. This mechanism might be costly, but acceptable when updating +// contents of KV database happens not so frequently now. +void KvDelegate::Backup() +{ + // No need to lock because this inner method will only be called when upper methods lock up + ZLOGD("backup kv"); + if (hasChange_) { + CopyFile(true); + hasChange_ = false; + } + ZLOGD("finish backing up kv"); +} + +// Set hasChange_ to true. Caller can use this to control when to back up db. +void OHOS::DataShare::KvDelegate::NotifyBackup() +{ + std::lock_guard lock(mutex_); + hasChange_ = true; +} + +// The return val indicates whether the database has been restored +bool KvDelegate::RestoreIfNeed(int32_t dbStatus) +{ + // No need to lock because this inner method will only be called when upper methods lock up + if (dbStatus == GRD_INVALID_FILE_FORMAT || dbStatus == GRD_REBUILD_DATABASE) { + if (db_ != NULL) { + GRD_DBClose(db_, GRD_DB_CLOSE); + db_ = nullptr; + isInitDone_ = false; + } + // If db is NULL, it has been closed. + Restore(); + return true; + } + return false; +} + int64_t KvDelegate::Upsert(const std::string &collectionName, const std::string &filter, const std::string &value) { std::lock_guard lock(mutex_); @@ -33,7 +136,8 @@ int64_t KvDelegate::Upsert(const std::string &collectionName, const std::string } int count = GRD_UpsertDoc(db_, collectionName.c_str(), filter.c_str(), value.c_str(), 0); if (count <= 0) { - ZLOGE("GRD_UpSertDoc failed,status %{public}d", count); + ZLOGE("GRD_UpSertDoc failed,status %{public}d", count); + RestoreIfNeed(count); return count; } Flush(); @@ -52,12 +156,16 @@ int32_t KvDelegate::Delete(const std::string &collectionName, const std::string int32_t status = GetBatch(collectionName, filter, "{\"id_\": true}", queryResults); if (status != E_OK) { ZLOGE("db GetBatch failed, %{public}s %{public}d", filter.c_str(), status); + // `GetBatch` should decide whether to restore before errors are returned, so skip restoration here. return status; } for (auto &result : queryResults) { auto count = GRD_DeleteDoc(db_, collectionName.c_str(), result.c_str(), 0); if (count < 0) { - ZLOGE("GRD_UpSertDoc failed,status %{public}d %{public}s", count, result.c_str()); + ZLOGE("GRD_DeleteDoc failed,status %{public}d %{public}s", count, result.c_str()); + if (RestoreIfNeed(count)) { + return count; + } continue; } } @@ -79,7 +187,8 @@ bool KvDelegate::Init() int status = GRD_DBOpen( (path_ + "/dataShare.db").c_str(), nullptr, GRD_DB_OPEN_CREATE | GRD_DB_OPEN_CHECK_FOR_ABNORMAL, &db_); if (status != GRD_OK || db_ == nullptr) { - ZLOGE("GRD_DBOpen failed,status %{public}d", status); + ZLOGE("GRD_DBOpen failed,status %{public}d", status); + RestoreIfNeed(status); return false; } if (executors_ != nullptr) { @@ -89,17 +198,22 @@ bool KvDelegate::Init() db_ = nullptr; isInitDone_ = false; taskId_ = ExecutorPool::INVALID_TASK_ID; + Backup(); }); } status = GRD_CreateCollection(db_, TEMPLATE_TABLE, nullptr, 0); if (status != GRD_OK) { - ZLOGE("GRD_CreateCollection template table failed,status %{public}d", status); + // If opeaning db succeeds, it is rare to fail to create tables + ZLOGE("GRD_CreateCollection template table failed,status %{public}d", status); + RestoreIfNeed(status); return false; } status = GRD_CreateCollection(db_, DATA_TABLE, nullptr, 0); if (status != GRD_OK) { - ZLOGE("GRD_CreateCollection data table failed,status %{public}d", status); + // If opeaning db succeeds, it is rare to fail to create tables + ZLOGE("GRD_CreateCollection data table failed,status %{public}d", status); + RestoreIfNeed(status); return false; } isInitDone_ = true; @@ -112,7 +226,7 @@ KvDelegate::~KvDelegate() if (isInitDone_) { int status = GRD_DBClose(db_, 0); if (status != GRD_OK) { - ZLOGE("GRD_DBClose failed,status %{public}d", status); + ZLOGE("GRD_DBClose failed,status %{public}d", status); } } } @@ -124,7 +238,7 @@ int32_t KvDelegate::Upsert(const std::string &collectionName, const KvData &valu int version = -1; if (GetVersion(collectionName, id, version)) { if (value.GetVersion() <= version) { - ZLOGE("GetVersion failed,%{public}s id %{private}s %{public}d %{public}d", collectionName.c_str(), + ZLOGE("GetVersion failed,%{public}s id %{private}s %{public}d %{public}d", collectionName.c_str(), id.c_str(), value.GetVersion(), version); return E_VERSION_NOT_NEWER; } @@ -152,7 +266,7 @@ bool KvDelegate::GetVersion(const std::string &collectionName, const std::string } VersionData data(-1); if (!DistributedData::Serializable::Unmarshall(value, data)) { - ZLOGE("Unmarshall failed,data %{public}s", value.c_str()); + ZLOGE("Unmarshall failed,data %{public}s", value.c_str()); return false; } version = data.GetVersion(); @@ -173,20 +287,23 @@ int32_t KvDelegate::Get( GRD_ResultSet *resultSet = nullptr; int status = GRD_FindDoc(db_, collectionName.c_str(), query, 0, &resultSet); if (status != GRD_OK || resultSet == nullptr) { - ZLOGE("GRD_FindDoc failed,status %{public}d", status); + ZLOGE("GRD_FindDoc failed,status %{public}d", status); + RestoreIfNeed(status); return status; } status = GRD_Next(resultSet); if (status != GRD_OK) { GRD_FreeResultSet(resultSet); - ZLOGE("GRD_Next failed,status %{public}d", status); + ZLOGE("GRD_Next failed,status %{public}d", status); + RestoreIfNeed(status); return status; } char *value = nullptr; status = GRD_GetValue(resultSet, &value); if (status != GRD_OK || value == nullptr) { GRD_FreeResultSet(resultSet); - ZLOGE("GRD_GetValue failed,status %{public}d", status); + ZLOGE("GRD_GetValue failed,status %{public}d", status); + RestoreIfNeed(status); return status; } result = value; @@ -199,7 +316,8 @@ void KvDelegate::Flush() { int status = GRD_Flush(db_, GRD_DB_FLUSH_ASYNC); if (status != GRD_OK) { - ZLOGE("GRD_Flush failed,status %{public}d", status); + ZLOGE("GRD_Flush failed,status %{public}d", status); + RestoreIfNeed(status); } } @@ -217,7 +335,8 @@ int32_t KvDelegate::GetBatch(const std::string &collectionName, const std::strin GRD_ResultSet *resultSet; int status = GRD_FindDoc(db_, collectionName.c_str(), query, GRD_DOC_ID_DISPLAY, &resultSet); if (status != GRD_OK || resultSet == nullptr) { - ZLOGE("GRD_UpSertDoc failed,status %{public}d", status); + ZLOGE("GRD_FindDoc failed,status %{public}d", status); + RestoreIfNeed(status); return status; } char *value = nullptr; @@ -225,7 +344,8 @@ int32_t KvDelegate::GetBatch(const std::string &collectionName, const std::strin status = GRD_GetValue(resultSet, &value); if (status != GRD_OK || value == nullptr) { GRD_FreeResultSet(resultSet); - ZLOGE("GRD_GetValue failed,status %{public}d", status); + ZLOGE("GRD_GetValue failed,status %{public}d", status); + RestoreIfNeed(status); return status; } result.emplace_back(value); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.h b/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.h index e3d19e08..13499f70 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 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 @@ -36,18 +36,25 @@ public: std::string &result) override; int32_t GetBatch(const std::string &collectionName, const std::string &filter, const std::string &projection, std::vector &result) override; + void NotifyBackup() override; private: bool Init(); bool GetVersion(const std::string &collectionName, const std::string &filter, int &version); int64_t Upsert(const std::string &collectionName, const std::string &filter, const std::string &value); void Flush(); + bool RestoreIfNeed(int32_t dbStatus); + void Backup(); + void Restore(); + void RemoveDbFile(bool isBackUp); + bool CopyFile(bool isBackup); std::recursive_mutex mutex_; std::string path_; GRD_DB *db_ = nullptr; bool isInitDone_ = false; std::shared_ptr executors_ = nullptr; ExecutorPool::TaskId taskId_ = ExecutorPool::INVALID_TASK_ID; + bool hasChange_ = false; }; } // namespace OHOS::DataShare #endif // DATASHARESERVICE_KV_DELEGATE_H diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp index 603c9fcf..013ce8b0 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp @@ -16,21 +16,28 @@ #include "rdb_delegate.h" #include "crypto_manager.h" +#include "datashare_errno.h" #include "datashare_radar_reporter.h" #include "device_manager_adapter.h" +#include "extension_connect_adaptor.h" +#include "int_wrapper.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" #include "metadata/secret_key_meta_data.h" #include "resultset_json_formatter.h" #include "log_print.h" +#include "rdb_errno.h" #include "rdb_utils.h" #include "scheduler_manager.h" +#include "string_wrapper.h" #include "utils/anonymous.h" +#include "want_params.h" namespace OHOS::DataShare { -constexpr static int32_t MAX_RESULTSET_COUNT = 16; +constexpr static int32_t MAX_RESULTSET_COUNT = 32; constexpr static int64_t TIMEOUT_TIME = 500; std::atomic RdbDelegate::resultSetCount = 0; +ConcurrentMap RdbDelegate::resultSetCallingPids; enum REMIND_TIMER_ARGS : int32_t { ARG_DB_PATH = 0, ARG_VERSION, @@ -61,6 +68,7 @@ RdbStoreConfig RdbDelegate::GetConfig(const DistributedData::StoreMetaData &meta { RdbStoreConfig config(meta.dataDir); config.SetCreateNecessary(false); + config.SetHaMode(meta.haMode); config.SetBundleName(meta.bundleName); if (meta.isEncrypt) { DistributedData::SecretKeyMetaData secretKeyMeta; @@ -76,22 +84,46 @@ RdbStoreConfig RdbDelegate::GetConfig(const DistributedData::StoreMetaData &meta return config; } -RdbDelegate::RdbDelegate(const DistributedData::StoreMetaData &meta, int version, bool registerFunction) +RdbDelegate::RdbDelegate(const DistributedData::StoreMetaData &meta, int version, + bool registerFunction, const std::string &extUriData, const std::string &backup) { + tokenId_ = meta.tokenId; + bundleName_ = meta.bundleName; + storeName_ = meta.storeId; + extUri_ = extUriData; + haMode_ = meta.haMode; + backup_ = backup; + RdbStoreConfig config = GetConfig(meta, registerFunction); DefaultOpenCallback callback; store_ = RdbHelper::GetRdbStore(config, version, callback, errCode_); if (errCode_ != E_OK) { ZLOGW("GetRdbStore failed, errCode is %{public}d, dir is %{public}s", errCode_, DistributedData::Anonymous::Change(meta.dataDir).c_str()); + RdbDelegate::TryAndSend(errCode_); } } -int64_t RdbDelegate::Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) +void RdbDelegate::TryAndSend(int errCode) +{ + if (errCode != E_SQLITE_CORRUPT || (haMode_ == HAMode::SINGLE && (backup_ != DUAL_WRITE && backup_ != PERIODIC))) { + return; + } + ZLOGE("Database corruption. BundleName: %{public}s. StoreName: %{public}s. ExtUri: %{public}s", + bundleName_.c_str(), storeName_.c_str(), DistributedData::Anonymous::Change(extUri_).c_str()); + AAFwk::WantParams params; + params.SetParam("BundleName", AAFwk::String::Box(bundleName_)); + params.SetParam("StoreName", AAFwk::String::Box(storeName_)); + params.SetParam("StoreStatus", AAFwk::Integer::Box(1)); + ExtensionConnectAdaptor::TryAndWait(extUri_, bundleName_, params); +} + +std::pair RdbDelegate::InsertEx(const std::string &tableName, + const DataShareValuesBucket &valuesBucket) { if (store_ == nullptr) { ZLOGE("store is null"); - return 0; + return std::make_pair(E_DB_ERROR, 0); } int64_t rowId = 0; ValuesBucket bucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(valuesBucket); @@ -100,15 +132,21 @@ int64_t RdbDelegate::Insert(const std::string &tableName, const DataShareValuesB ZLOGE("Insert failed %{public}s %{public}d", tableName.c_str(), ret); RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::INSERT_RDB_ERROR); + if (ret == E_SQLITE_ERROR) { + EraseStoreCache(tokenId_); + } + RdbDelegate::TryAndSend(ret); + return std::make_pair(E_DB_ERROR, rowId); } - return rowId; + return std::make_pair(E_OK, rowId); } -int64_t RdbDelegate::Update( + +std::pair RdbDelegate::UpdateEx( const std::string &tableName, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) { if (store_ == nullptr) { ZLOGE("store is null"); - return 0; + return std::make_pair(E_DB_ERROR, 0); } int changeCount = 0; ValuesBucket bucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(valuesBucket); @@ -118,14 +156,20 @@ int64_t RdbDelegate::Update( ZLOGE("Update failed %{public}s %{public}d", tableName.c_str(), ret); RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::UPDATE_RDB_ERROR); + if (ret == E_SQLITE_ERROR) { + EraseStoreCache(tokenId_); + } + RdbDelegate::TryAndSend(ret); + return std::make_pair(E_DB_ERROR, changeCount); } - return changeCount; + return std::make_pair(E_OK, changeCount); } -int64_t RdbDelegate::Delete(const std::string &tableName, const DataSharePredicates &predicate) + +std::pair RdbDelegate::DeleteEx(const std::string &tableName, const DataSharePredicates &predicate) { if (store_ == nullptr) { ZLOGE("store is null"); - return 0; + return std::make_pair(E_DB_ERROR, 0); } int changeCount = 0; RdbPredicates predicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicate, tableName); @@ -134,9 +178,15 @@ int64_t RdbDelegate::Delete(const std::string &tableName, const DataSharePredica ZLOGE("Delete failed %{public}s %{public}d", tableName.c_str(), ret); RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::DELETE_RDB_ERROR); + if (ret == E_SQLITE_ERROR) { + EraseStoreCache(tokenId_); + } + RdbDelegate::TryAndSend(ret); + return std::make_pair(E_DB_ERROR, changeCount); } - return changeCount; + return std::make_pair(E_OK, changeCount); } + std::pair> RdbDelegate::Query(const std::string &tableName, const DataSharePredicates &predicates, const std::vector &columns, const int32_t callingPid) @@ -147,20 +197,29 @@ std::pair> RdbDelegate::Query(const std } int count = resultSetCount.fetch_add(1); ZLOGD("start query %{public}d", count); - if (count > MAX_RESULTSET_COUNT) { - ZLOGE("resultSetCount is full"); + if (count > MAX_RESULTSET_COUNT && IsLimit(count, callingPid)) { resultSetCount--; - return std::make_pair(E_ERROR, nullptr); + return std::make_pair(E_RESULTSET_BUSY, nullptr); } RdbPredicates rdbPredicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicates, tableName); std::shared_ptr resultSet = store_->QueryByStep(rdbPredicates, columns); if (resultSet == nullptr) { RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::QUERY_RDB_ERROR); - ZLOGE("Query failed %{public}s", tableName.c_str()); + ZLOGE("Query failed %{public}s, pid: %{public}d", tableName.c_str(), callingPid); resultSetCount--; return std::make_pair(E_ERROR, nullptr); } + int err = resultSet->GetRowCount(count); + RdbDelegate::TryAndSend(err); + if (err == E_SQLITE_ERROR) { + ZLOGE("query failed, err:%{public}d, pid:%{public}d", E_SQLITE_ERROR, callingPid); + EraseStoreCache(tokenId_); + } + resultSetCallingPids.Compute(callingPid, [](const uint32_t &, int32_t &value) { + ++value; + return true; + }); int64_t beginTime = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); auto bridge = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(resultSet); @@ -173,6 +232,10 @@ std::pair> RdbDelegate::Query(const std ZLOGE("pid %{public}d query time is %{public}" PRId64 ", %{public}d resultSet is used.", callingPid, (endTime - beginTime), resultSetCount.load()); } + resultSetCallingPids.ComputeIfPresent(callingPid, [](const uint32_t &, int32_t &value) { + --value; + return value > 0; + }); delete p; }}; return std::make_pair(E_OK, result); @@ -189,6 +252,11 @@ std::string RdbDelegate::Query(const std::string &sql, const std::vectorGetRowCount(rowCount) == E_SQLITE_ERROR) { + ZLOGE("query failed, err:%{public}d", E_SQLITE_ERROR); + EraseStoreCache(tokenId_); + } ResultSetJsonFormatter formatter(std::move(resultSet)); return DistributedData::Serializable::Marshall(formatter); } @@ -199,6 +267,43 @@ std::shared_ptr RdbDelegate::QuerySql(const std::string &s ZLOGE("store is null"); return nullptr; } - return store_->QuerySql(sql); + auto resultSet = store_->QuerySql(sql); + if (resultSet == nullptr) { + ZLOGE("Query failed %{private}s", sql.c_str()); + return resultSet; + } + int rowCount; + if (resultSet->GetRowCount(rowCount) == E_SQLITE_ERROR) { + ZLOGE("query failed, err:%{public}d", E_SQLITE_ERROR); + EraseStoreCache(tokenId_); + } + return resultSet; +} + +bool RdbDelegate::IsInvalid() +{ + return store_ == nullptr; +} + +bool RdbDelegate::IsLimit(int count, const int32_t callingPid) +{ + bool isFull = true; + for (int32_t retryCount = 0; retryCount < RETRY; retryCount++) { + std::this_thread::sleep_for(WAIT_TIME); + if (resultSetCount.load() <= MAX_RESULTSET_COUNT) { + isFull = false; + break; + } + } + if (!isFull) { + return false; + } + std::string logStr; + resultSetCallingPids.ForEach([&logStr](const uint32_t &key, const int32_t &value) { + logStr += std::to_string(key) + ":" + std::to_string(value) + ";"; + return false; + }); + ZLOGE("resultSetCount is full, pid: %{public}d, owner is %{public}s", callingPid, logStr.c_str()); + return true; } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.h b/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.h index cef51a9c..adb3d3b1 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.h @@ -31,22 +31,38 @@ namespace OHOS::DataShare { using namespace OHOS::NativeRdb; class RdbDelegate final : public DBDelegate { public: - explicit RdbDelegate(const DistributedData::StoreMetaData &meta, int version, bool registerFunction); - int64_t Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) override; - int64_t Update(const std::string &tableName, const DataSharePredicates &predicate, - const DataShareValuesBucket &valuesBucket) override; - int64_t Delete(const std::string &tableName, const DataSharePredicates &predicate) override; + explicit RdbDelegate(const DistributedData::StoreMetaData &meta, int version, + bool registerFunction, const std::string &extUri, const std::string &backup); std::pair> Query(const std::string &tableName, const DataSharePredicates &predicates, const std::vector &columns, const int32_t callingPid) override; std::string Query(const std::string &sql, const std::vector &selectionArgs) override; std::shared_ptr QuerySql(const std::string &sql) override; - + bool IsInvalid() override; + std::pair InsertEx(const std::string &tableName, + const DataShareValuesBucket &valuesBucket) override; + std::pair UpdateEx(const std::string &tableName, + const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) override; + std::pair DeleteEx(const std::string &tableName, + const DataSharePredicates &predicate) override; private: + void TryAndSend(int errCode); RdbStoreConfig GetConfig(const DistributedData::StoreMetaData &meta, bool registerFunction); + bool IsLimit(int count, const int32_t callingPid); static std::atomic resultSetCount; + static ConcurrentMap resultSetCallingPids; + static constexpr std::chrono::milliseconds WAIT_TIME = std::chrono::milliseconds(50); std::shared_ptr store_; int errCode_ = E_OK; + static constexpr int RETRY = 3; + static constexpr const char *DUAL_WRITE = "dualWrite"; + static constexpr const char *PERIODIC = "periodic"; + uint32_t tokenId_; + std::string bundleName_; + std::string storeName_; + int32_t haMode_; + std::string extUri_; + std::string backup_; }; class DefaultOpenCallback : public RdbOpenCallback { public: diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/uri_utils.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/uri_utils.cpp index 8fb91826..26447121 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/uri_utils.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/uri_utils.cpp @@ -72,7 +72,7 @@ void URIUtils::FormatUri(std::string &uri) uri.resize(pos); } -UriConfig URIUtils::GetUriConfig(const std::string &uri) +__attribute__((no_sanitize("cfi"))) UriConfig URIUtils::GetUriConfig(const std::string &uri) { UriConfig uriConfig; Uri uriTemp(uri); @@ -107,7 +107,7 @@ std::pair URIUtils::Strtoul(const std::string &str) char* end = nullptr; errno = 0; data = strtoul(str.c_str(), &end, 10); - if (errno == ERANGE || end == str || *end != '\0') { + if (errno == ERANGE || end == nullptr || end == str || *end != '\0') { return std::make_pair(false, data); } return std::make_pair(true, data); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data/template_data.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data/template_data.cpp index 4236f4d7..eb63f411 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data/template_data.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data/template_data.cpp @@ -132,6 +132,7 @@ bool TemplateData::Delete(const std::string &bundleName, const int32_t userId) ZLOGE("db DeleteById failed, %{public}d", status); return false; } + delegate->NotifyBackup(); return true; } @@ -149,6 +150,7 @@ bool TemplateData::Add(const std::string &uri, const int32_t userId, const std:: ZLOGE("db Upsert failed, %{public}d", status); return false; } + delegate->NotifyBackup(); return true; } @@ -166,6 +168,7 @@ bool TemplateData::Delete( ZLOGE("db DeleteById failed, %{public}d", status); return false; } + delegate->NotifyBackup(); return true; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.cpp index 4d951df5..98783ade 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.cpp @@ -41,9 +41,9 @@ DataProviderConfig::DataProviderConfig(const std::string &uri, uint32_t callerTo uriConfig_ = URIUtils::GetUriConfig(providerInfo_.uri); } -std::pair DataProviderConfig::GetBundleInfo() +std::pair DataProviderConfig::GetBundleInfo() { - BundleInfo bundleInfo; + BundleConfig bundleInfo; providerInfo_.bundleName = uriConfig_.authority; if (providerInfo_.bundleName.empty()) { if (uriConfig_.pathSegments.empty()) { @@ -51,11 +51,9 @@ std::pair DataProviderConfig::GetBundleInfo() } providerInfo_.bundleName = uriConfig_.pathSegments[0]; } - if (!BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS( - providerInfo_.bundleName, providerInfo_.currentUserId, bundleInfo)) { - return std::make_pair(E_BUNDLE_NAME_NOT_EXIST, bundleInfo); - } - return std::make_pair(E_OK, bundleInfo); + auto ret = BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS( + providerInfo_.bundleName, providerInfo_.currentUserId, bundleInfo); + return std::make_pair(ret, bundleInfo); } int DataProviderConfig::GetFromProxyData() @@ -77,8 +75,8 @@ int DataProviderConfig::GetFromProxyData() } for (auto &hapModuleInfo : bundleInfo.hapModuleInfos) { auto &proxyDatas = hapModuleInfo.proxyDatas; - std::sort(proxyDatas.begin(), proxyDatas.end(), [](const AppExecFwk::ProxyData &curr, - const AppExecFwk::ProxyData &prev) { + std::sort(proxyDatas.begin(), proxyDatas.end(), [](const ProxyData &curr, + const ProxyData &prev) { return curr.uri.length() > prev.uri.length(); }); for (auto &data : proxyDatas) { @@ -88,17 +86,15 @@ int DataProviderConfig::GetFromProxyData() } providerInfo_.readPermission = std::move(data.requiredReadPermission); providerInfo_.writePermission = std::move(data.requiredWritePermission); - auto [ret, profileInfo] = DataShareProfileConfig::GetDataProperties( - std::vector{data.metadata}, hapModuleInfo.resourcePath, - hapModuleInfo.hapPath, DATA_SHARE_PROPERTIES_META); - if (ret == NOT_FOUND) { + auto profileInfo = data.profileInfo; + if (profileInfo.resultCode == NOT_FOUND) { return E_OK; } - if (ret == ERROR) { + if (profileInfo.resultCode == ERROR) { ZLOGE("Profile unmarshall error.uri: %{public}s", URIUtils::Anonymous(providerInfo_.uri).c_str()); return E_ERROR; } - return GetFromDataProperties(profileInfo, hapModuleInfo.moduleName); + return GetFromDataProperties(profileInfo.profile, hapModuleInfo.moduleName); } } return E_URI_NOT_EXIST; @@ -114,6 +110,8 @@ int DataProviderConfig::GetFromDataProperties(const ProfileInfo &profileInfo, providerInfo_.tableName = profileInfo.tableName; providerInfo_.type = profileInfo.type; providerInfo_.storeMetaDataFromUri = profileInfo.storeMetaDataFromUri; + providerInfo_.backup = profileInfo.backup; + providerInfo_.extensionUri = profileInfo.extUri; if (profileInfo.tableConfig.empty()) { return E_OK; } @@ -144,11 +142,12 @@ int DataProviderConfig::GetFromExtension() ZLOGE("Uri path failed! uri:%{public}s", URIUtils::Anonymous(providerInfo_.uri).c_str()); return E_URI_NOT_EXIST; } - BundleInfo bundleInfo; - if (!BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS( - providerInfo_.bundleName, providerInfo_.currentUserId, bundleInfo)) { + BundleConfig bundleInfo; + auto ret = BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS( + providerInfo_.bundleName, providerInfo_.currentUserId, bundleInfo); + if (ret != E_OK) { ZLOGE("BundleInfo failed! bundleName: %{public}s", providerInfo_.bundleName.c_str()); - return E_BUNDLE_NAME_NOT_EXIST; + return ret; } providerInfo_.singleton = bundleInfo.singleton; providerInfo_.allowEmptyPermission = true; @@ -159,16 +158,15 @@ int DataProviderConfig::GetFromExtension() providerInfo_.hasExtension = true; providerInfo_.readPermission = std::move(item.readPermission); providerInfo_.writePermission = std::move(item.writePermission); - auto [ret, profileInfo] = DataShareProfileConfig::GetDataProperties( - item.metadata, item.resourcePath, item.hapPath, DATA_SHARE_EXTENSION_META); - if (ret == NOT_FOUND) { + auto profileInfo = item.profileInfo; + if (profileInfo.resultCode == NOT_FOUND) { return E_OK; } - if (ret == ERROR) { + if (profileInfo.resultCode == ERROR) { ZLOGE("Profile Unmarshall failed! uri:%{public}s", URIUtils::Anonymous(providerInfo_.uri).c_str()); return E_ERROR; } - return GetFromExtensionProperties(profileInfo, providerInfo_.moduleName); + return GetFromExtensionProperties(profileInfo.profile, providerInfo_.moduleName); } return E_URI_NOT_EXIST; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.h b/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.h index dd2f5966..794cfe06 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.h @@ -18,6 +18,7 @@ #include #include +#include "common/bundle_mgr_proxy.h" #include "account/account_delegate.h" #include "bundle_mgr_proxy.h" #include "data_share_profile_config.h" @@ -25,7 +26,6 @@ #include "uri_utils.h" namespace OHOS::DataShare { -using BundleInfo = OHOS::AppExecFwk::BundleInfo; using ExtensionAbility = OHOS::AppExecFwk::ExtensionAbilityInfo; class DataProviderConfig { public: @@ -41,6 +41,8 @@ public: std::string readPermission; std::string writePermission; std::string type = "rdb"; + std::string backup; + std::string extensionUri; bool singleton = false; bool hasExtension = false; bool allowEmptyPermission = false; @@ -56,7 +58,7 @@ private: int GetFromDataProperties(const ProfileInfo &profileInfo, const std::string &moduleName); int GetFromExtensionProperties(const ProfileInfo &profileInfo, const std::string &moduleName); void GetMetaDataFromUri(); - std::pair GetBundleInfo(); + std::pair GetBundleInfo(); enum class PATH_PARAM : int32_t { BUNDLE_NAME = 0, MODULE_NAME, diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.cpp index d604a832..b8c2927a 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.cpp @@ -50,7 +50,8 @@ std::pair DataShareDbConfig::GetMetaData(co if (!hasExtension) { return std::pair(NativeRdb::E_DB_NOT_EXIST, metaData); } - ExtensionConnectAdaptor::TryAndWait(uri, bundleName); + AAFwk::WantParams wantParams; + ExtensionConnectAdaptor::TryAndWait(uri, bundleName, wantParams); auto [succ, meta] = QueryMetaData(bundleName, storeName, userId); if (!succ) { return std::pair(NativeRdb::E_DB_NOT_EXIST, meta); @@ -61,21 +62,22 @@ std::pair DataShareDbConfig::GetMetaData(co } std::tuple> DataShareDbConfig::GetDbConfig( - const std::string &uri, bool hasExtension, const std::string &bundleName, const std::string &storeName, - int32_t userId) + DbConfig &dbConfig) { - auto [errCode, metaData] = GetMetaData(uri, bundleName, storeName, userId, hasExtension); + auto [errCode, metaData] = GetMetaData(dbConfig.uri, dbConfig.bundleName, dbConfig.storeName, + dbConfig.userId, dbConfig.hasExtension); if (errCode != E_OK) { ZLOGE("DB not exist,bundleName:%{public}s,storeName:%{public}s,user:%{public}d,err:%{public}d,uri:%{public}s", - bundleName.c_str(), storeName.c_str(), userId, errCode, URIUtils::Anonymous(uri).c_str()); + dbConfig.bundleName.c_str(), dbConfig.storeName.c_str(), dbConfig.userId, errCode, + URIUtils::Anonymous(dbConfig.uri).c_str()); RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_MATEDATA_EXISTS, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::META_DATA_NOT_EXISTS); return std::make_tuple(errCode, metaData, nullptr); } - auto dbDelegate = DBDelegate::Create(metaData); + auto dbDelegate = DBDelegate::Create(metaData, dbConfig.extUri, dbConfig.backup); if (dbDelegate == nullptr) { ZLOGE("Create delegate fail, bundleName:%{public}s, userId:%{public}d, uri:%{public}s", - bundleName.c_str(), userId, URIUtils::Anonymous(uri).c_str()); + dbConfig.bundleName.c_str(), dbConfig.userId, URIUtils::Anonymous(dbConfig.uri).c_str()); return std::make_tuple(E_ERROR, metaData, nullptr); } return std::make_tuple(E_OK, metaData, dbDelegate); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.h b/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.h index 441e9cfe..c038a4cb 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.h @@ -28,9 +28,16 @@ namespace OHOS::DataShare { class DataShareDbConfig { public: - std::tuple> GetDbConfig( - const std::string &uri, bool hasExtension, const std::string &bundleName, - const std::string &storeName, int32_t userId); + struct DbConfig { + std::string uri; + std::string extUri; + std::string bundleName; + std::string storeName; + std::string backup; + int32_t userId; + bool hasExtension; + }; + std::tuple> GetDbConfig(DbConfig &dbConfig); std::pair GetMetaData(const std::string &uri, const std::string &bundleName, const std::string &storeName, int32_t userId, bool hasExtension); private: diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.cpp index f179186d..fde20bd1 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.cpp @@ -24,6 +24,7 @@ #include #include "bundle_mgr_proxy.h" +#include "datashare_errno.h" #include "log_print.h" #include "uri_utils.h" #include "utils/anonymous.h" @@ -75,6 +76,9 @@ bool ProfileInfo::Marshal(json &node) const SetValue(node[GET_NAME(type)], type); SetValue(node[GET_NAME(launchInfos)], launchInfos); SetValue(node[GET_NAME(storeMetaDataFromUri)], storeMetaDataFromUri); + SetValue(node[GET_NAME(launchForCleanData)], launchForCleanData); + SetValue(node[GET_NAME(backup)], backup); + SetValue(node[GET_NAME(extUri)], extUri); return true; } @@ -86,6 +90,9 @@ bool ProfileInfo::Unmarshal(const json &node) GetValue(node, GET_NAME(type), type); GetValue(node, GET_NAME(launchInfos), launchInfos); GetValue(node, GET_NAME(storeMetaDataFromUri), storeMetaDataFromUri); + GetValue(node, GET_NAME(launchForCleanData), launchForCleanData); + GetValue(node, GET_NAME(backup), backup); + GetValue(node, GET_NAME(extUri), extUri); std::string path; auto ret = GetValue(node, GET_NAME(path), path); if (ret) { @@ -243,8 +250,9 @@ std::string DataShareProfileConfig::ReadProfile(const std::string &resPath) bool DataShareProfileConfig::GetProfileInfo(const std::string &calledBundleName, int32_t currentUserId, std::map &profileInfos) { - AppExecFwk::BundleInfo bundleInfo; - if (!BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS(calledBundleName, currentUserId, bundleInfo)) { + BundleConfig bundleInfo; + if (BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS(calledBundleName, + currentUserId, bundleInfo) != E_OK) { ZLOGE("data share GetBundleInfoFromBMS failed! bundleName: %{public}s, currentUserId = %{public}d", calledBundleName.c_str(), currentUserId); return false; @@ -253,12 +261,11 @@ bool DataShareProfileConfig::GetProfileInfo(const std::string &calledBundleName, if (item.type != AppExecFwk::ExtensionAbilityType::DATASHARE) { continue; } - auto [ret, profileInfo] = GetDataProperties(item.metadata, item.resourcePath, - item.hapPath, DATA_SHARE_EXTENSION_META); - if (ret == ERROR || ret == NOT_FOUND) { + auto profileInfo = item.profileInfo; + if (profileInfo.resultCode == ERROR || profileInfo.resultCode == NOT_FOUND) { continue; } - profileInfos[item.uri] = profileInfo; + profileInfos[item.uri] = profileInfo.profile; } return true; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.h b/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.h index fb5e631a..9fc6df89 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.h @@ -50,8 +50,11 @@ struct ProfileInfo : public DistributedData::Serializable { std::string tableName; std::string scope = "module"; std::string type = "rdb"; + std::string backup; + std::string extUri; std::vector launchInfos; bool storeMetaDataFromUri = false; + bool launchForCleanData = false; bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; }; @@ -63,7 +66,7 @@ enum AccessCrossMode : uint8_t { USER_MAX, }; -class API_EXPORT DataShareProfileConfig { +class DataShareProfileConfig { public: constexpr static int8_t TABLE_MATCH_PRIORITY = 3; constexpr static int8_t STORE_MATCH_PRIORITY = 2; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp index 57e06390..c57d403d 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp @@ -38,7 +38,9 @@ #include "dump/dump_manager.h" #include "extension_ability_manager.h" #include "hap_token_info.h" +#include "if_system_ability_manager.h" #include "ipc_skeleton.h" +#include "iservice_registry.h" #include "log_print.h" #include "metadata/auto_launch_meta_data.h" #include "metadata/meta_data_manager.h" @@ -48,6 +50,8 @@ #include "scheduler_manager.h" #include "subscriber_managers/published_data_subscriber_manager.h" #include "sys_event_subscriber.h" +#include "system_ability_definition.h" +#include "system_ability_status_change_stub.h" #include "template_data.h" #include "utils/anonymous.h" #include "xcollie.h" @@ -58,6 +62,29 @@ using DumpManager = OHOS::DistributedData::DumpManager; using ProviderInfo = DataProviderConfig::ProviderInfo; using namespace OHOS::DistributedData; __attribute__((used)) DataShareServiceImpl::Factory DataShareServiceImpl::factory_; +class DataShareServiceImpl::SystemAbilityStatusChangeListener + : public SystemAbilityStatusChangeStub { +public: + SystemAbilityStatusChangeListener() + { + } + ~SystemAbilityStatusChangeListener() = default; + void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; + void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override + { + } +}; + +void DataShareServiceImpl::SystemAbilityStatusChangeListener::OnAddSystemAbility( + int32_t systemAbilityId, const std::string &deviceId) +{ + if (systemAbilityId != COMMON_EVENT_SERVICE_ID) { + return; + } + ZLOGI("Common event service start. saId:%{public}d", systemAbilityId); + InitSubEvent(); +} + DataShareServiceImpl::Factory::Factory() { FeatureSystem::GetInstance().RegisterCreator("data_share", []() { @@ -69,24 +96,24 @@ DataShareServiceImpl::Factory::Factory() DataShareServiceImpl::Factory::~Factory() {} -int32_t DataShareServiceImpl::Insert(const std::string &uri, const DataShareValuesBucket &valuesBucket) +std::pair DataShareServiceImpl::InsertEx(const std::string &uri, const std::string &extUri, + const DataShareValuesBucket &valuesBucket) { - ZLOGD("Insert enter."); XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); if (GetSilentProxyStatus(uri, false) != E_OK) { ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); - return ERROR; + return std::make_pair(ERROR, 0); } - auto callBack = [&uri, &valuesBucket, this](ProviderInfo &providerInfo, - DistributedData::StoreMetaData &metaData, std::shared_ptr dbDelegate) -> int32_t { - auto ret = dbDelegate->Insert(providerInfo.tableName, valuesBucket); - if (ret > 0) { + auto callBack = [&uri, &valuesBucket, this](ProviderInfo &providerInfo, DistributedData::StoreMetaData &metaData, + std::shared_ptr dbDelegate) -> std::pair { + auto [errCode, ret] = dbDelegate->InsertEx(providerInfo.tableName, valuesBucket); + if (errCode == E_OK && ret > 0) { NotifyChange(uri); RdbSubscriberManager::GetInstance().Emit(uri, providerInfo.currentUserId, metaData); } - return ret; + return std::make_pair(errCode, ret); }; - return Execute(uri, IPCSkeleton::GetCallingTokenID(), false, callBack); + return ExecuteEx(uri, extUri, IPCSkeleton::GetCallingTokenID(), false, callBack); } bool DataShareServiceImpl::NotifyChange(const std::string &uri) @@ -109,51 +136,52 @@ bool DataShareServiceImpl::NotifyChange(const std::string &uri) return true; } -int32_t DataShareServiceImpl::Update(const std::string &uri, const DataSharePredicates &predicate, - const DataShareValuesBucket &valuesBucket) +std::pair DataShareServiceImpl::UpdateEx(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) { - ZLOGD("Update enter."); XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); if (GetSilentProxyStatus(uri, false) != E_OK) { ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); - return ERROR; + return std::make_pair(ERROR, 0); } auto callBack = [&uri, &predicate, &valuesBucket, this](ProviderInfo &providerInfo, - DistributedData::StoreMetaData &metaData, std::shared_ptr dbDelegate) -> int32_t { - auto ret = dbDelegate->Update(providerInfo.tableName, predicate, valuesBucket); - if (ret > 0) { + DistributedData::StoreMetaData &metaData, + std::shared_ptr dbDelegate) -> std::pair { + auto [errCode, ret] = dbDelegate->UpdateEx(providerInfo.tableName, predicate, valuesBucket); + if (errCode == E_OK && ret > 0) { NotifyChange(uri); RdbSubscriberManager::GetInstance().Emit(uri, providerInfo.currentUserId, metaData); } - return ret; + return std::make_pair(errCode, ret); }; - return Execute(uri, IPCSkeleton::GetCallingTokenID(), false, callBack); + return ExecuteEx(uri, extUri, IPCSkeleton::GetCallingTokenID(), false, callBack); } -int32_t DataShareServiceImpl::Delete(const std::string &uri, const DataSharePredicates &predicate) +std::pair DataShareServiceImpl::DeleteEx(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicate) { XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); if (GetSilentProxyStatus(uri, false) != E_OK) { ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); - return ERROR; + return std::make_pair(ERROR, 0); } - auto callBack = [&uri, &predicate, this](ProviderInfo &providerInfo, - DistributedData::StoreMetaData &metaData, std::shared_ptr dbDelegate) -> int32_t { - auto ret = dbDelegate->Delete(providerInfo.tableName, predicate); - if (ret > 0) { + auto callBack = [&uri, &predicate, this](ProviderInfo &providerInfo, DistributedData::StoreMetaData &metaData, + std::shared_ptr dbDelegate) -> std::pair { + auto [errCode, ret] = dbDelegate->DeleteEx(providerInfo.tableName, predicate); + if (errCode == E_OK && ret > 0) { NotifyChange(uri); RdbSubscriberManager::GetInstance().Emit(uri, providerInfo.currentUserId, metaData); } - return ret; + return std::make_pair(errCode, ret); }; - return Execute(uri, IPCSkeleton::GetCallingTokenID(), false, callBack); + return ExecuteEx(uri, extUri, IPCSkeleton::GetCallingTokenID(), false, callBack); } -std::shared_ptr DataShareServiceImpl::Query(const std::string &uri, +std::shared_ptr DataShareServiceImpl::Query(const std::string &uri, const std::string &extUri, const DataSharePredicates &predicates, const std::vector &columns, int &errCode) { - ZLOGD("Query enter."); - XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); + XCollie xcollie(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__), + HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); if (GetSilentProxyStatus(uri, false) != E_OK) { ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); return nullptr; @@ -161,13 +189,14 @@ std::shared_ptr DataShareServiceImpl::Query(const std::strin std::shared_ptr resultSet; auto callingPid = IPCSkeleton::GetCallingPid(); auto callBack = [&uri, &predicates, &columns, &resultSet, &callingPid](ProviderInfo &providerInfo, - DistributedData::StoreMetaData &, std::shared_ptr dbDelegate) -> int32_t { + DistributedData::StoreMetaData &, std::shared_ptr dbDelegate) -> std::pair { auto [err, result] = dbDelegate->Query(providerInfo.tableName, predicates, columns, callingPid); resultSet = std::move(result); - return err; + return std::make_pair(err, E_OK); }; - errCode = Execute(uri, IPCSkeleton::GetCallingTokenID(), true, callBack); + auto [errVal, status] = ExecuteEx(uri, extUri, IPCSkeleton::GetCallingTokenID(), true, callBack); + errCode = errVal; return resultSet; } @@ -498,13 +527,25 @@ int32_t DataShareServiceImpl::OnBind(const BindInfo &binderInfo) KvDBDelegate::GetInstance(false, saveMeta.dataDir, binderInfo.executors); SchedulerManager::GetInstance().SetExecutorPool(binderInfo.executors); ExtensionAbilityManager::GetInstance().SetExecutorPool(binderInfo.executors); - InitSubEvent(); + DBDelegate::SetExecutorPool(binderInfo.executors); + SubscribeCommonEvent(); SubscribeTimeChanged(); SubscribeChange(); ZLOGI("end"); return E_OK; } +void DataShareServiceImpl::SubscribeCommonEvent() +{ + sptr systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemManager == nullptr) { + ZLOGE("System mgr is nullptr"); + return; + } + sptr callback(new SystemAbilityStatusChangeListener()); + systemManager->SubscribeSystemAbility(COMMON_EVENT_SERVICE_ID, callback); +} + void DataShareServiceImpl::SubscribeChange() { EventCenter::GetInstance().Subscribe(RemoteChangeEvent::RDB_META_SAVE, [this](const Event &event) { @@ -535,16 +576,36 @@ void DataShareServiceImpl::SaveLaunchInfo(const std::string &bundleName, const s } std::string extUri = uri; extUri.insert(strlen(EXT_URI_SCHEMA), "/"); + StoreMetaData meta = MakeMetaData(bundleName, userId, deviceId); + if (value.launchInfos.empty()) { + meta.storeId = ""; + AutoLaunchMetaData autoLaunchMetaData = {}; + std::vector tempData = {}; + autoLaunchMetaData.datas.emplace(extUri, tempData); + autoLaunchMetaData.launchForCleanData = value.launchForCleanData; + MetaDataManager::GetInstance().SaveMeta(meta.GetAutoLaunchKey(), autoLaunchMetaData, true); + ZLOGI("Without launchInfos, save meta end, bundleName = %{public}s.", bundleName.c_str()); + continue; + } for (const auto &launchInfo : value.launchInfos) { - AutoLaunchMetaData &autoLaunchMetaData = maps[launchInfo.storeId]; + AutoLaunchMetaData autoLaunchMetaData = {}; autoLaunchMetaData.datas.emplace(extUri, launchInfo.tableNames); + autoLaunchMetaData.launchForCleanData = value.launchForCleanData; + meta.storeId = launchInfo.storeId; + MetaDataManager::GetInstance().SaveMeta(meta.GetAutoLaunchKey(), autoLaunchMetaData, true); } } - StoreMetaData meta = MakeMetaData(bundleName, userId, deviceId); - for (const auto &[storeId, value] : maps) { - meta.storeId = storeId; - MetaDataManager::GetInstance().SaveMeta(meta.GetAutoLaunchKey(), value, true); +} + +bool DataShareServiceImpl::AllowCleanDataLaunchApp(const Event &event, bool launchForCleanData) +{ + auto &evt = static_cast(event); + auto dataInfo = evt.GetDataInfo(); + // 1 means CLOUD_DATA_CLEAN + if (dataInfo.changeType == 1) { + return launchForCleanData; // Applications can be started by default } + return true; } void DataShareServiceImpl::AutoLaunch(const Event &event) @@ -554,21 +615,30 @@ void DataShareServiceImpl::AutoLaunch(const Event &event) StoreMetaData meta = MakeMetaData(dataInfo.bundleName, dataInfo.userId, dataInfo.deviceId, dataInfo.storeId); AutoLaunchMetaData autoLaunchMetaData; if (!MetaDataManager::GetInstance().LoadMeta(std::move(meta.GetAutoLaunchKey()), autoLaunchMetaData, true)) { - return; + meta.storeId = ""; + if (!MetaDataManager::GetInstance().LoadMeta(std::move(meta.GetAutoLaunchKey()), autoLaunchMetaData, true)) { + ZLOGE("No launch meta without storeId, bundleName = %{public}s.", dataInfo.bundleName.c_str()); + return; + } } - if (autoLaunchMetaData.datas.empty()) { + if (autoLaunchMetaData.datas.empty() || !AllowCleanDataLaunchApp(event, autoLaunchMetaData.launchForCleanData)) { return; } - std::vector uris; for (const auto &[uri, metaTables] : autoLaunchMetaData.datas) { - for (const auto &table : dataInfo.tables) - if (std::find(metaTables.begin(), metaTables.end(), table) != metaTables.end()) { - uris.emplace_back(uri); - break; + if (dataInfo.tables.empty() && dataInfo.changeType == 1) { + ZLOGI("Start to connect extension, bundlename = %{public}s.", dataInfo.bundleName.c_str()); + AAFwk::WantParams wantParams; + ExtensionConnectAdaptor::TryAndWait(uri, dataInfo.bundleName, wantParams); + return; + } + for (const auto &table : dataInfo.tables) { + if (std::find(metaTables.begin(), metaTables.end(), table) != metaTables.end()) { + ZLOGI("Find table, start to connect extension, bundlename = %{public}s.", dataInfo.bundleName.c_str()); + AAFwk::WantParams wantParams; + ExtensionConnectAdaptor::TryAndWait(uri, dataInfo.bundleName, wantParams); + break; + } } - } - for (const auto &uri : uris) { - ExtensionConnectAdaptor::TryAndWait(uri, dataInfo.bundleName); } } @@ -602,6 +672,8 @@ int32_t DataShareServiceImpl::DataShareStatic::OnAppUninstall(const std::string TemplateData::Delete(bundleName, user); NativeRdb::RdbHelper::ClearCache(); BundleMgrProxy::GetInstance()->Delete(bundleName, user); + uint32_t tokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(user, bundleName, index); + DBDelegate::EraseStoreCache(tokenId); return E_OK; } @@ -630,6 +702,15 @@ int32_t DataShareServiceImpl::DataShareStatic::OnAppUpdate(const std::string &bu return E_OK; } +int32_t DataShareServiceImpl::DataShareStatic::OnClearAppStorage(const std::string &bundleName, + int32_t user, int32_t index, int32_t tokenId) +{ + ZLOGI("ClearAppStorage user=%{public}d, index=%{public}d, token:0x%{public}x, bundleName=%{public}s", + user, index, tokenId, bundleName.c_str()); + DBDelegate::EraseStoreCache(tokenId); + return E_OK; +} + int32_t DataShareServiceImpl::OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index) { ZLOGI("AppUninstall user=%{public}d, index=%{public}d, bundleName=%{public}s", @@ -745,7 +826,8 @@ int32_t DataShareServiceImpl::EnableSilentProxy(const std::string &uri, bool ena int32_t DataShareServiceImpl::GetSilentProxyStatus(const std::string &uri, bool isCreateHelper) { - XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); + XCollie xcollie(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__), + HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); uint32_t callerTokenId = IPCSkeleton::GetCallingTokenID(); if (isCreateHelper) { auto errCode = GetBMSAndMetaDataStatus(uri, callerTokenId); @@ -776,7 +858,8 @@ int32_t DataShareServiceImpl::GetSilentProxyStatus(const std::string &uri, bool int32_t DataShareServiceImpl::RegisterObserver(const std::string &uri, const sptr &remoteObj) { - XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG); + XCollie xcollie(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__), + HiviewDFX::XCOLLIE_FLAG_LOG); auto callerTokenId = IPCSkeleton::GetCallingTokenID(); DataProviderConfig providerConfig(uri, callerTokenId); auto [errCode, providerInfo] = providerConfig.GetProviderInfo(); @@ -809,7 +892,8 @@ int32_t DataShareServiceImpl::RegisterObserver(const std::string &uri, int32_t DataShareServiceImpl::UnregisterObserver(const std::string &uri, const sptr &remoteObj) { - XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG); + XCollie xcollie(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__), + HiviewDFX::XCOLLIE_FLAG_LOG); auto callerTokenId = IPCSkeleton::GetCallingTokenID(); DataProviderConfig providerConfig(uri, callerTokenId); auto [errCode, providerInfo] = providerConfig.GetProviderInfo(); @@ -839,37 +923,42 @@ int32_t DataShareServiceImpl::UnregisterObserver(const std::string &uri, return obsMgrClient->UnregisterObserver(Uri(uri), obServer); } -int32_t DataShareServiceImpl::Execute(const std::string &uri, const int32_t tokenId, - bool isRead, ExecuteCallback callback) +std::pair DataShareServiceImpl::ExecuteEx(const std::string &uri, const std::string &extUri, + const int32_t tokenId, bool isRead, ExecuteCallbackEx callback) { DataProviderConfig providerConfig(uri, tokenId); - auto [errCode, provider] = providerConfig.GetProviderInfo(); + auto [errCode, providerInfo] = providerConfig.GetProviderInfo(); if (errCode != E_OK) { ZLOGE("Provider failed! token:0x%{public}x,ret:%{public}d,uri:%{public}s", tokenId, - errCode, URIUtils::Anonymous(provider.uri).c_str()); + errCode, URIUtils::Anonymous(providerInfo.uri).c_str()); RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_GET_SUPPLIER, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::SUPPLIER_ERROR); - return errCode; + return std::make_pair(errCode, 0); } - std::string permission = isRead ? provider.readPermission : provider.writePermission; + std::string permission = isRead ? providerInfo.readPermission : providerInfo.writePermission; if (!permission.empty() && !PermitDelegate::VerifyPermission(permission, tokenId)) { ZLOGE("Permission denied! token:0x%{public}x, permission:%{public}s, uri:%{public}s", - tokenId, permission.c_str(), URIUtils::Anonymous(provider.uri).c_str()); + tokenId, permission.c_str(), URIUtils::Anonymous(providerInfo.uri).c_str()); RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_PERMISSION, RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::PERMISSION_DENIED_ERROR); - return ERROR_PERMISSION_DENIED; + return std::make_pair(ERROR_PERMISSION_DENIED, 0); } DataShareDbConfig dbConfig; - auto [code, metaData, dbDelegate] = dbConfig.GetDbConfig(provider.uri, - provider.hasExtension, provider.bundleName, provider.storeName, - provider.singleton ? 0 : provider.currentUserId); + std::string extensionUri = extUri; + if (extensionUri.empty()) { + extensionUri = providerInfo.extensionUri; + } + DataShareDbConfig::DbConfig config {providerInfo.uri, extensionUri, providerInfo.bundleName, + providerInfo.storeName, providerInfo.backup, + providerInfo.singleton ? 0 : providerInfo.currentUserId, providerInfo.hasExtension}; + auto [code, metaData, dbDelegate] = dbConfig.GetDbConfig(config); if (code != E_OK) { ZLOGE("Get dbConfig fail,bundleName:%{public}s,tableName:%{public}s,tokenId:0x%{public}x, uri:%{public}s", - provider.bundleName.c_str(), provider.tableName.c_str(), tokenId, - URIUtils::Anonymous(provider.uri).c_str()); - return code; + providerInfo.bundleName.c_str(), providerInfo.tableName.c_str(), tokenId, + URIUtils::Anonymous(providerInfo.uri).c_str()); + return std::make_pair(code, 0); } - return callback(provider, metaData, dbDelegate); + return callback(providerInfo, metaData, dbDelegate); } int32_t DataShareServiceImpl::GetBMSAndMetaDataStatus(const std::string &uri, const int32_t tokenId) @@ -884,7 +973,7 @@ int32_t DataShareServiceImpl::GetBMSAndMetaDataStatus(const std::string &uri, co if (errCode != E_OK) { ZLOGE("CalledInfo failed! token:0x%{public}x,ret:%{public}d,uri:%{public}s", tokenId, errCode, URIUtils::Anonymous(calledInfo.uri).c_str()); - return E_BMS_NOT_READY; + return errCode; } DataShareDbConfig dbConfig; auto [code, metaData] = dbConfig.GetMetaData(calledInfo.uri, calledInfo.bundleName, diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.h b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.h index 261f51c7..634322cc 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.h @@ -42,19 +42,15 @@ #include "visibility.h" namespace OHOS::DataShare { -class API_EXPORT DataShareServiceImpl : public DataShareServiceStub { +class DataShareServiceImpl : public DataShareServiceStub { public: using Handler = std::function> &)>; - using ExecuteCallback = std::function(DataProviderConfig::ProviderInfo &, DistributedData::StoreMetaData &, std::shared_ptr)>; DataShareServiceImpl() = default; virtual ~DataShareServiceImpl(); - int32_t Insert(const std::string &uri, const DataShareValuesBucket &valuesBucket) override; - int32_t Update(const std::string &uri, const DataSharePredicates &predicate, - const DataShareValuesBucket &valuesBucket) override; - int32_t Delete(const std::string &uri, const DataSharePredicates &predicate) override; - std::shared_ptr Query(const std::string &uri, const DataSharePredicates &predicates, - const std::vector &columns, int &errCode) override; + std::shared_ptr Query(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicates, const std::vector &columns, int &errCode) override; int32_t AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt) override; int32_t DelTemplate(const std::string &uri, const int64_t subscriberId) override; std::vector Publish(const Data &data, const std::string &bundleNameOfProvider) override; @@ -87,14 +83,21 @@ public: int32_t GetSilentProxyStatus(const std::string &uri, bool isCreateHelper) override; int32_t RegisterObserver(const std::string &uri, const sptr &remoteObj) override; int32_t UnregisterObserver(const std::string &uri, const sptr &remoteObj) override; - + std::pair InsertEx(const std::string &uri, const std::string &extUri, + const DataShareValuesBucket &valuesBucket) override; + std::pair UpdateEx(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) override; + std::pair DeleteEx(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicate) override; private: + class SystemAbilityStatusChangeListener; using StaticActs = DistributedData::StaticActs; class DataShareStatic : public StaticActs { public: ~DataShareStatic() override {}; int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index) override; int32_t OnAppUpdate(const std::string &bundleName, int32_t user, int32_t index) override; + int32_t OnClearAppStorage(const std::string &bundleName, int32_t user, int32_t index, int32_t tokenId) override; }; class Factory { public: @@ -108,18 +111,21 @@ private: TimerReceiver() = default; explicit TimerReceiver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo); virtual ~TimerReceiver() = default; - virtual void OnReceiveEvent(const EventFwk::CommonEventData &eventData) override; + void OnReceiveEvent(const EventFwk::CommonEventData &eventData) override; }; void RegisterDataShareServiceInfo(); void RegisterHandler(); bool SubscribeTimeChanged(); bool NotifyChange(const std::string &uri); bool GetCallerBundleName(std::string &bundleName); - int32_t Execute(const std::string &uri, const int32_t tokenId, bool isRead, ExecuteCallback callback); + std::pair ExecuteEx(const std::string &uri, const std::string &extUri, const int32_t tokenId, + bool isRead, ExecuteCallbackEx callback); int32_t GetBMSAndMetaDataStatus(const std::string &uri, const int32_t tokenId); - void InitSubEvent(); + void SubscribeCommonEvent(); + static void InitSubEvent(); void AutoLaunch(const DistributedData::Event &event); void SubscribeChange(); + bool AllowCleanDataLaunchApp(const DistributedData::Event &event, bool launchForCleanData); static void SaveLaunchInfo(const std::string &bundleName, const std::string &userId, const std::string &deviceId); static DistributedData::StoreMetaData MakeMetaData(const std::string &bundleName, const std::string &userId, diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.cpp index acad4229..df4b59e5 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.cpp @@ -38,52 +38,55 @@ bool DataShareServiceStub::CheckInterfaceToken(MessageParcel &data) return true; } -int32_t DataShareServiceStub::OnInsert(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnInsertEx(MessageParcel &data, MessageParcel &reply) { std::string uri; + std::string extUri; DataShareValuesBucket bucket; - if (!ITypesUtil::Unmarshal(data, uri, bucket.valuesMap)) { + if (!ITypesUtil::Unmarshal(data, uri, extUri, bucket.valuesMap)) { ZLOGE("Unmarshal uri:%{public}s bucket size:%{public}zu", DistributedData::Anonymous::Change(uri).c_str(), bucket.valuesMap.size()); return IPC_STUB_INVALID_DATA_ERR; } - int32_t status = Insert(uri, bucket); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Marshal status:0x%{public}x", status); + auto [errCode, status] = InsertEx(uri, extUri, bucket); + if (!ITypesUtil::Marshal(reply, errCode, status)) { + ZLOGE("Marshal errCode: 0x%{public}x, status: 0x%{public}x", errCode, status); return IPC_STUB_WRITE_PARCEL_ERR; } return 0; } -int32_t DataShareServiceStub::OnUpdate(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnUpdateEx(MessageParcel &data, MessageParcel &reply) { std::string uri; + std::string extUri; DataSharePredicates predicate; DataShareValuesBucket bucket; - if (!ITypesUtil::Unmarshal(data, uri, predicate, bucket.valuesMap)) { + if (!ITypesUtil::Unmarshal(data, uri, extUri, predicate, bucket.valuesMap)) { ZLOGE("Unmarshal uri:%{public}s bucket size:%{public}zu", DistributedData::Anonymous::Change(uri).c_str(), bucket.valuesMap.size()); return IPC_STUB_INVALID_DATA_ERR; } - int32_t status = Update(uri, predicate, bucket); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Marshal status:0x%{public}x", status); + auto [errCode, status] = UpdateEx(uri, extUri, predicate, bucket); + if (!ITypesUtil::Marshal(reply, errCode, status)) { + ZLOGE("Marshal errCode: 0x%{public}x, status: 0x%{public}x", errCode, status); return IPC_STUB_WRITE_PARCEL_ERR; } return 0; } -int32_t DataShareServiceStub::OnDelete(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnDeleteEx(MessageParcel &data, MessageParcel &reply) { std::string uri; + std::string extUri; DataSharePredicates predicate; - if (!ITypesUtil::Unmarshal(data, uri, predicate)) { + if (!ITypesUtil::Unmarshal(data, uri, extUri, predicate)) { ZLOGE("Unmarshal uri:%{public}s", DistributedData::Anonymous::Change(uri).c_str()); return IPC_STUB_INVALID_DATA_ERR; } - int32_t status = Delete(uri, predicate); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Marshal status:0x%{public}x", status); + auto [errCode, status] = DeleteEx(uri, extUri, predicate); + if (!ITypesUtil::Marshal(reply, errCode, status)) { + ZLOGE("Marshal errCode: 0x%{public}x, status: 0x%{public}x", errCode, status); return IPC_STUB_WRITE_PARCEL_ERR; } return 0; @@ -92,15 +95,16 @@ int32_t DataShareServiceStub::OnDelete(MessageParcel &data, MessageParcel &reply int32_t DataShareServiceStub::OnQuery(MessageParcel &data, MessageParcel &reply) { std::string uri; + std::string extUri; DataSharePredicates predicate; std::vector columns; - if (!ITypesUtil::Unmarshal(data, uri, predicate, columns)) { + if (!ITypesUtil::Unmarshal(data, uri, extUri, predicate, columns)) { ZLOGE("Unmarshal uri:%{public}s columns size:%{public}zu", DistributedData::Anonymous::Change(uri).c_str(), columns.size()); return IPC_STUB_INVALID_DATA_ERR; } int status = 0; - auto result = ISharedResultSet::WriteToParcel(Query(uri, predicate, columns, status), reply); + auto result = ISharedResultSet::WriteToParcel(Query(uri, extUri, predicate, columns, status), reply); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x", status); return IPC_STUB_WRITE_PARCEL_ERR; @@ -327,7 +331,7 @@ int DataShareServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Me std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME)); } auto callingPid = IPCSkeleton::GetCallingPid(); - if (code != DATA_SHARE_SERVICE_CMD_QUERY) { + if (code != DATA_SHARE_SERVICE_CMD_QUERY && code != DATA_SHARE_SERVICE_CMD_GET_SILENT_PROXY_STATUS) { ZLOGI("code:%{public}u, callingPid:%{public}d", code, callingPid); } if (!CheckInterfaceToken(data)) { diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.h b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.h index 9daede97..d13b2099 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.h @@ -29,9 +29,6 @@ public: private: static constexpr std::chrono::milliseconds TIME_THRESHOLD = std::chrono::milliseconds(500); static bool CheckInterfaceToken(MessageParcel& data); - int32_t OnInsert(MessageParcel& data, MessageParcel& reply); - int32_t OnUpdate(MessageParcel& data, MessageParcel& reply); - int32_t OnDelete(MessageParcel& data, MessageParcel& reply); int32_t OnQuery(MessageParcel& data, MessageParcel& reply); int32_t OnAddTemplate(MessageParcel& data, MessageParcel& reply); int32_t OnDelTemplate(MessageParcel& data, MessageParcel& reply); @@ -51,11 +48,11 @@ private: int32_t OnGetSilentProxyStatus(MessageParcel& data, MessageParcel& reply); int32_t OnRegisterObserver(MessageParcel& data, MessageParcel& reply); int32_t OnUnregisterObserver(MessageParcel& data, MessageParcel& reply); + int32_t OnInsertEx(MessageParcel& data, MessageParcel& reply); + int32_t OnUpdateEx(MessageParcel& data, MessageParcel& reply); + int32_t OnDeleteEx(MessageParcel& data, MessageParcel& reply); using RequestHandle = int (DataShareServiceStub::*)(MessageParcel &, MessageParcel &); static constexpr RequestHandle HANDLERS[DATA_SHARE_SERVICE_CMD_MAX] = { - &DataShareServiceStub::OnInsert, - &DataShareServiceStub::OnDelete, - &DataShareServiceStub::OnUpdate, &DataShareServiceStub::OnQuery, &DataShareServiceStub::OnAddTemplate, &DataShareServiceStub::OnDelTemplate, @@ -74,7 +71,10 @@ private: &DataShareServiceStub::OnSetSilentSwitch, &DataShareServiceStub::OnGetSilentProxyStatus, &DataShareServiceStub::OnRegisterObserver, - &DataShareServiceStub::OnUnregisterObserver}; + &DataShareServiceStub::OnUnregisterObserver, + &DataShareServiceStub::OnInsertEx, + &DataShareServiceStub::OnDeleteEx, + &DataShareServiceStub::OnUpdateEx}; static constexpr int SLEEP_TIME = 300; static constexpr int TRY_TIMES = 5; std::atomic isReady_ = false; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/idata_share_service.h b/datamgr_service/services/distributeddataservice/service/data_share/idata_share_service.h index aa2da754..e57489fe 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/idata_share_service.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/idata_share_service.h @@ -30,9 +30,6 @@ namespace OHOS::DataShare { class IDataShareService { public: enum { - DATA_SHARE_SERVICE_CMD_INSERT, - DATA_SHARE_SERVICE_CMD_DELETE, - DATA_SHARE_SERVICE_CMD_UPDATE, DATA_SHARE_SERVICE_CMD_QUERY, DATA_SHARE_SERVICE_CMD_ADD_TEMPLATE, DATA_SHARE_SERVICE_CMD_DEL_TEMPLATE, @@ -52,18 +49,17 @@ public: DATA_SHARE_SERVICE_CMD_GET_SILENT_PROXY_STATUS, DATA_SHARE_SERVICE_CMD_REGISTER_OBSERVER, DATA_SHARE_SERVICE_CMD_UNREGISTER_OBSERVER, + DATA_SHARE_SERVICE_CMD_INSERTEX, + DATA_SHARE_SERVICE_CMD_DELETEEX, + DATA_SHARE_SERVICE_CMD_UPDATEEX, DATA_SHARE_SERVICE_CMD_MAX }; enum { DATA_SHARE_ERROR = -1, DATA_SHARE_OK = 0 }; DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DataShare.IDataShareService"); - virtual int32_t Insert(const std::string &uri, const DataShareValuesBucket &valuesBucket) = 0; - virtual int32_t Update( - const std::string &uri, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) = 0; - virtual int32_t Delete(const std::string &uri, const DataSharePredicates &predicate) = 0; - virtual std::shared_ptr Query(const std::string &uri, const DataSharePredicates &predicates, - const std::vector &columns, int &errCode) = 0; + virtual std::shared_ptr Query(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicates, const std::vector &columns, int &errCode) = 0; virtual int32_t AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt) = 0; virtual int32_t DelTemplate(const std::string &uri, const int64_t subscriberId) = 0; virtual std::vector Publish(const Data &data, const std::string &bundleNameOfProvider) = 0; @@ -91,6 +87,12 @@ public: virtual int32_t RegisterObserver(const std::string &uri, const sptr &remoteObj) = 0; virtual int32_t UnregisterObserver(const std::string &uri, const sptr &remoteObj) = 0; + virtual std::pair InsertEx( + const std::string &uri, const std::string &extUri, const DataShareValuesBucket &valuesBucket) = 0; + virtual std::pair UpdateEx(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) = 0; + virtual std::pair DeleteEx(const std::string &uri, const std::string &extUri, + const DataSharePredicates &predicate) = 0; }; } // namespace OHOS::DataShare #endif // DISTRIBUTEDDATAFWK_IDATA_SHARE_SERVICE_H diff --git a/datamgr_service/services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp index 17f74366..c796152c 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/strategies/data_proxy/load_config_from_data_proxy_node_strategy.cpp @@ -30,8 +30,8 @@ bool LoadConfigFromDataProxyNodeStrategy::operator()(std::shared_ptr co return false; } context->type = PUBLISHED_DATA_TYPE; - if (!BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS( - context->calledBundleName, context->currentUserId, context->bundleInfo)) { + if (BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS( + context->calledBundleName, context->currentUserId, context->bundleInfo) != E_OK) { ZLOGE("GetBundleInfoFromBMS failed! bundleName: %{public}s", context->calledBundleName.c_str()); context->errCode = E_BUNDLE_NAME_NOT_EXIST; return false; @@ -40,9 +40,9 @@ bool LoadConfigFromDataProxyNodeStrategy::operator()(std::shared_ptr co context->permission = "reject"; return true; } - for (auto &hapModuleInfo : context->bundleInfo.hapModuleInfos) { + for (auto const &hapModuleInfo : context->bundleInfo.hapModuleInfos) { auto proxyDatas = hapModuleInfo.proxyDatas; - for (auto &proxyData : proxyDatas) { + for (auto const &proxyData : proxyDatas) { if (proxyData.uri != context->uri) { continue; } @@ -51,13 +51,11 @@ bool LoadConfigFromDataProxyNodeStrategy::operator()(std::shared_ptr co if (context->permission.empty()) { context->permission = "reject"; } - auto [ret, properties] = DataShareProfileConfig::GetDataProperties( - std::vector{proxyData.metadata}, hapModuleInfo.resourcePath, - hapModuleInfo.hapPath, DATA_SHARE_PROPERTIES_META); - if (ret == ERROR || ret == NOT_FOUND) { + auto properties = proxyData.profileInfo; + if (properties.resultCode == ERROR || properties.resultCode == NOT_FOUND) { return true; } - GetContextInfoFromDataProperties(properties, hapModuleInfo.moduleName, context); + GetContextInfoFromDataProperties(properties.profile, hapModuleInfo.moduleName, context); return true; } } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp index f9b2c72d..edec38ac 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/strategies/data_share/load_config_from_data_share_bundle_info_strategy.cpp @@ -18,6 +18,7 @@ #include "bundle_mgr_proxy.h" #include "data_share_profile_config.h" +#include "datashare_errno.h" #include "log_print.h" #include "uri_utils.h" #include "utils/anonymous.h" @@ -79,25 +80,24 @@ bool LoadConfigFromDataShareBundleInfoStrategy::operator()(std::shared_ptrcalledBundleName.c_str()); return false; } - if (!BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS( - context->calledBundleName, context->currentUserId, context->bundleInfo)) { + if (BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS( + context->calledBundleName, context->currentUserId, context->bundleInfo) != E_OK) { ZLOGE("GetBundleInfoFromBMS failed! bundleName: %{public}s", context->calledBundleName.c_str()); return false; } - for (auto &item : context->bundleInfo.extensionInfos) { + for (auto const &item : context->bundleInfo.extensionInfos) { if (item.type == AppExecFwk::ExtensionAbilityType::DATASHARE) { context->permission = context->isRead ? item.readPermission : item.writePermission; - auto [ret, profileInfo] = DataShareProfileConfig::GetDataProperties(item.metadata, - item.resourcePath, item.hapPath, DATA_SHARE_EXTENSION_META); - if (ret == NOT_FOUND) { + auto profileInfo = item.profileInfo; + if (profileInfo.resultCode == NOT_FOUND) { return true; // optional meta data config } - if (ret == ERROR) { + if (profileInfo.resultCode == ERROR) { ZLOGE("parse failed! %{public}s", context->calledBundleName.c_str()); return false; } - LoadConfigFromProfile(profileInfo, context); + LoadConfigFromProfile(profileInfo.profile, context); return true; } } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp index f47d62e3..a48ad89a 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_data_info_strategy.cpp @@ -54,7 +54,8 @@ bool LoadConfigNormalDataInfoStrategy::operator()(std::shared_ptr conte DistributedData::StoreMetaData metaData; if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, context->currentUserId)) { // connect extension and retry - ExtensionConnectAdaptor::TryAndWait(context->uri, context->calledBundleName); + AAFwk::WantParams wantParams; + ExtensionConnectAdaptor::TryAndWait(context->uri, context->calledBundleName, wantParams); if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, context->currentUserId)) { ZLOGE("QueryMetaData fail, %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); context->errCode = NativeRdb::E_DB_NOT_EXIST; @@ -74,7 +75,8 @@ bool LoadConfigSingleDataInfoStrategy::operator()(std::shared_ptr conte DistributedData::StoreMetaData metaData; if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, 0)) { // connect extension and retry - ExtensionConnectAdaptor::TryAndWait(context->uri, context->calledBundleName); + AAFwk::WantParams wantParams; + ExtensionConnectAdaptor::TryAndWait(context->uri, context->calledBundleName, wantParams); if (!QueryMetaData(context->calledBundleName, context->calledStoreName, metaData, 0)) { ZLOGE("QueryMetaData fail, %{public}s", DistributedData::Anonymous::Change(context->uri).c_str()); context->errCode = NativeRdb::E_DB_NOT_EXIST; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp b/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp index 1ff14c39..3ad175de 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp @@ -248,14 +248,19 @@ void RdbSubscriberManager::Emit(const std::string &uri, int32_t userId, if (!URIUtils::IsDataProxyURI(uri)) { return; } - rdbCache_.ForEach([&uri, &userId, &metaData, this](const Key &key, std::vector &val) { + bool hasObserver = false; + rdbCache_.ForEach([&uri, &userId, &metaData, &hasObserver, this](const Key &key, std::vector &val) { if (key.uri != uri) { return false; } + hasObserver = true; Notify(key, userId, val, metaData.dataDir, metaData.version); SetObserverNotifyOnEnabled(val); return false; }); + if (!hasObserver) { + return; + } SchedulerManager::GetInstance().Execute( uri, userId, metaData.dataDir, metaData.version, metaData.bundleName); } @@ -321,7 +326,7 @@ int RdbSubscriberManager::Notify(const Key &key, int32_t userId, const std::vect DistributedData::StoreMetaData meta; meta.dataDir = rdbDir; meta.bundleName = key.bundleName; - auto delegate = DBDelegate::Create(meta); + auto delegate = DBDelegate::Create(meta, key.uri); if (delegate == nullptr) { ZLOGE("Create fail %{public}s %{public}s", DistributedData::Anonymous::Change(key.uri).c_str(), key.bundleName.c_str()); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/sys_event_subscriber.cpp b/datamgr_service/services/distributeddataservice/service/data_share/sys_event_subscriber.cpp index e802950a..b0fe15ee 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/sys_event_subscriber.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/sys_event_subscriber.cpp @@ -47,7 +47,9 @@ void SysEventSubscriber::NotifyDataShareReady() AAFwk::Want want; want.SetAction("usual.event.DATA_SHARE_READY"); EventFwk::CommonEventData CommonEventData { want }; - if (!EventFwk::CommonEventManager::PublishCommonEvent(CommonEventData)) { + EventFwk::CommonEventPublishInfo publishInfo; + publishInfo.SetSticky(true); + if (!EventFwk::CommonEventManager::PublishCommonEvent(CommonEventData, publishInfo)) { ZLOGE("Notify dataShare ready failed."); return; } diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.cpp index c50f1236..fc72e1cf 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.cpp @@ -23,132 +23,24 @@ #include "log_print.h" #include "user_delegate.h" #include "utils/anonymous.h" - +#include "metadata/store_meta_data.h" +#include "metadata/meta_data_manager.h" namespace OHOS::DistributedData { +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; class AuthHandlerStub : public AuthHandler { public: // override for mock auth in current version, need remove in the future bool CheckAccess( - int localUserId, int peerUserId, const std::string &peerDeviceId, const std::string &appId) override; - + int localUserId, int peerUserId, const std::string &peerDeviceId, + int32_t authType, bool isSend = true) override; private: bool IsUserActive(const std::vector &users, int32_t userId); + bool CheckUsers(int localUserId, int peerUserId, const std::string &peerDeviceId); static constexpr pid_t UID_CAPACITY = 10000; static constexpr int SYSTEM_USER = 0; }; -bool AuthHandler::CheckAccess( - int localUserId, int peerUserId, const std::string &peerDeviceId, const std::string &appId) -{ - auto group = GetGroupInfo(localUserId, appId, peerDeviceId); - if (group.groupType < GroupType::ALL_GROUP) { - ZLOGE("failed to parse group %{public}s)", group.groupId.c_str()); - return false; - } - auto groupManager = GetGmInstance(); - if (groupManager == nullptr || groupManager->checkAccessToGroup == nullptr) { - ZLOGE("failed to get group manager"); - return false; - } - auto ret = groupManager->checkAccessToGroup(localUserId, appId.c_str(), group.groupId.c_str()); - ZLOGD("check access to group ret:%{public}d", ret); - return ret == HC_SUCCESS; -} - -int32_t AuthHandler::GetGroupType( - int localUserId, int peerUserId, const std::string &peerDeviceId, const std::string &appId) -{ - auto group = GetGroupInfo(localUserId, appId, peerDeviceId); - if (group.groupType < GroupType::ALL_GROUP) { - ZLOGE("failed to parse group json(%{public}d)", group.groupType); - } - return group.groupType; -} - -AuthHandler::RelatedGroup AuthHandler::GetGroupInfo( - int32_t localUserId, const std::string &appId, const std::string &peerDeviceId) -{ - auto groupManager = GetGmInstance(); - if (groupManager == nullptr || groupManager->getRelatedGroups == nullptr || groupManager->destroyInfo == nullptr) { - ZLOGE("failed to get group manager"); - return {}; - } - char *groupInfo = nullptr; - uint32_t groupNum = 0; - ZLOGI("get related groups, user:%{public}d, app:%{public}s", localUserId, appId.c_str()); - auto ret = groupManager->getRelatedGroups(localUserId, appId.c_str(), peerDeviceId.c_str(), &groupInfo, &groupNum); - if (groupInfo == nullptr) { - ZLOGE("failed to get related groups, ret:%{public}d", ret); - return {}; - } - ZLOGI("get related group json :%{public}s", groupInfo); - std::vector groups; - RelatedGroup::Unmarshall(groupInfo, groups); - groupManager->destroyInfo(&groupInfo); - - // same account has priority - std::sort(groups.begin(), groups.end(), - [](const RelatedGroup &group1, const RelatedGroup &group2) { return group1.groupType < group2.groupType; }); - if (!groups.empty()) { - ZLOGI("get group type:%{public}d", groups.front().groupType); - return groups.front(); - } - ZLOGD("there is no group to access to peer device:%{public}s", Anonymous::Change(peerDeviceId).c_str()); - return {}; -} - -std::vector AuthHandler::GetTrustedDevicesByType( - AUTH_GROUP_TYPE type, int32_t localUserId, const std::string &appId) -{ - auto groupManager = GetGmInstance(); - if (groupManager == nullptr || groupManager->getRelatedGroups == nullptr - || groupManager->getTrustedDevices == nullptr || groupManager->destroyInfo == nullptr) { - ZLOGE("failed to get group manager"); - return {}; - } - - char *groupsJson = nullptr; - uint32_t groupNum = 0; - ZLOGI("get joined groups, user:%{public}d, app:%{public}s, type:%{public}d", localUserId, appId.c_str(), type); - auto ret = groupManager->getJoinedGroups(localUserId, appId.c_str(), type, &groupsJson, &groupNum); - if (groupsJson == nullptr) { - ZLOGE("failed to get joined groups, ret:%{public}d", ret); - return {}; - } - ZLOGI("get joined group json :%{public}s", groupsJson); - std::vector groups; - RelatedGroup::Unmarshall(groupsJson, groups); - groupManager->destroyInfo(&groupsJson); - - std::vector trustedDevices; - for (const auto &group : groups) { - if (group.groupType != type) { - continue; - } - char *devicesJson = nullptr; - uint32_t devNum = 0; - ret = groupManager->getTrustedDevices(localUserId, appId.c_str(), group.groupId.c_str(), &devicesJson, &devNum); - if (devicesJson == nullptr) { - ZLOGE("failed to get trusted devicesJson, ret:%{public}d", ret); - return {}; - } - ZLOGI("get trusted device json:%{public}s", devicesJson); - std::vector devices; - TrustDevice::Unmarshall(devicesJson, devices); - groupManager->destroyInfo(&devicesJson); - for (const auto &item : devices) { - auto &dmAdapter = DeviceManagerAdapter::GetInstance(); - auto networkId = dmAdapter.ToNetworkID(item.authId); - auto uuid = dmAdapter.GetUuidByNetworkId(networkId); - trustedDevices.push_back(uuid); - } - } - - return trustedDevices; -} - -bool AuthHandlerStub::CheckAccess( - int localUserId, int peerUserId, const std::string &peerDeviceId, const std::string &appId) +bool AuthHandlerStub::CheckUsers(int localUserId, int peerUserId, const std::string &peerDeviceId) { if (localUserId == SYSTEM_USER) { return peerUserId == SYSTEM_USER; @@ -159,6 +51,17 @@ bool AuthHandlerStub::CheckAccess( return peerUserId != SYSTEM_USER && IsUserActive(localUsers, localUserId) && IsUserActive(peerUsers, peerUserId); } +bool AuthHandlerStub::CheckAccess( + int localUserId, int peerUserId, const std::string &peerDeviceId, int32_t authType, bool isSend) +{ + if (authType == static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT) && + !DmAdapter::GetInstance().IsSameAccount(peerDeviceId)) { + ZLOGE("CheckAccess failed."); + return false; + } + return CheckUsers(localUserId, peerUserId, peerDeviceId); +} + bool AuthHandlerStub::IsUserActive(const std::vector &users, int32_t userId) { for (const auto &user : users) { diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.h b/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.h index e6335c07..11a93199 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.h @@ -32,57 +32,7 @@ enum AUTH_GROUP_TYPE { class AuthHandler { public: virtual bool CheckAccess( - int localUserId, int peerUserId, const std::string &peerDeviceId, const std::string &appId); - virtual int32_t GetGroupType( - int localUserId, int peerUserId, const std::string &peerDeviceId, const std::string &appId); - virtual std::vector GetTrustedDevicesByType( - AUTH_GROUP_TYPE type, int32_t localUserId, const std::string &appId); - -private: - struct RelatedGroup final : public Serializable { - int32_t groupType = -1; - std::string groupId; - RelatedGroup() - { - } - ~RelatedGroup() - { - } - RelatedGroup(const RelatedGroup &) = default; - RelatedGroup &operator=(const RelatedGroup &) = default; - bool Marshal(json &node) const override - { - SetValue(node[GET_NAME(groupType)], groupType); - SetValue(node[GET_NAME(groupId)], groupId); - return true; - } - - bool Unmarshal(const json &node) override - { - GetValue(node, GET_NAME(groupType), groupType); - GetValue(node, GET_NAME(groupId), groupId); - return true; - } - }; - - struct TrustDevice final : public Serializable { - std::string authId; // udid - TrustDevice() = default; - TrustDevice(const TrustDevice &) = default; - TrustDevice &operator=(const TrustDevice &) = default; - bool Marshal(json &node) const override - { - SetValue(node[GET_NAME(authId)], authId); - return true; - } - - bool Unmarshal(const json &node) override - { - GetValue(node, GET_NAME(authId), authId); - return true; - } - }; - static RelatedGroup GetGroupInfo(int32_t localUserId, const std::string &appId, const std::string &peerDeviceId); + int localUserId, int peerUserId, const std::string &peerDeviceId, int32_t authType, bool isSend = true); }; class AuthDelegate { diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp index be9c07e4..9d24138d 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp @@ -37,7 +37,7 @@ #include "utils/anonymous.h" #include "water_version_manager.h" #include "device_manager_adapter.h" -#include "utils/anonymous.h" +#include "app_id_mapping/app_id_mapping_config_manager.h" namespace OHOS::DistributedKv { using namespace DistributedData; @@ -49,6 +49,31 @@ using ClearMode = DistributedDB::ClearMode; using DMAdapter = DistributedData::DeviceManagerAdapter; using DBInterceptedData = DistributedDB::InterceptedData; constexpr int UUID_WIDTH = 4; +const std::map KVDBGeneralStore::dbStatusMap_ = { + { DBStatus::OK, GenErr::E_OK }, + { DBStatus::CLOUD_NETWORK_ERROR, GenErr::E_NETWORK_ERROR }, + { DBStatus::CLOUD_LOCK_ERROR, GenErr::E_LOCKED_BY_OTHERS }, + { DBStatus::CLOUD_FULL_RECORDS, GenErr::E_RECODE_LIMIT_EXCEEDED }, + { DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT, GenErr::E_NO_SPACE_FOR_ASSET }, + { DBStatus::CLOUD_SYNC_TASK_MERGED, GenErr::E_SYNC_TASK_MERGED }, + { DBStatus::BUSY, GenErr::E_DB_ERROR }, + { DBStatus::DB_ERROR, GenErr::E_DB_ERROR }, + { DBStatus::INVALID_ARGS, GenErr::E_INVALID_ARGS }, + { DBStatus::NOT_FOUND, GenErr::E_RECORD_NOT_FOUND }, + { DBStatus::INVALID_VALUE_FIELDS, GenErr::E_INVALID_VALUE_FIELDS }, + { DBStatus::INVALID_FIELD_TYPE, GenErr::E_INVALID_FIELD_TYPE }, + { DBStatus::CONSTRAIN_VIOLATION, GenErr::E_CONSTRAIN_VIOLATION }, + { DBStatus::INVALID_FORMAT, GenErr::E_INVALID_FORMAT }, + { DBStatus::INVALID_QUERY_FORMAT, GenErr::E_INVALID_QUERY_FORMAT }, + { DBStatus::INVALID_QUERY_FIELD, GenErr::E_INVALID_QUERY_FIELD }, + { DBStatus::NOT_SUPPORT, GenErr::E_NOT_SUPPORT }, + { DBStatus::TIME_OUT, GenErr::E_TIME_OUT }, + { DBStatus::OVER_MAX_LIMITS, GenErr::E_OVER_MAX_LIMITS }, + { DBStatus::EKEYREVOKED_ERROR, GenErr::E_SECURITY_LEVEL_ERROR }, + { DBStatus::SECURITY_OPTION_CHECK_ERROR, GenErr::E_SECURITY_LEVEL_ERROR }, +}; + +constexpr uint32_t LOCK_TIMEOUT = 3600; // second static DBSchema GetDBSchema(const Database &database) { DBSchema schema; @@ -136,6 +161,9 @@ KVDBGeneralStore::KVDBGeneralStore(const StoreMetaData &meta) meta.instanceId) { observer_.storeId_ = meta.storeId; + StoreMetaDataLocal local; + MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), local, true); + isPublic_ = local.isPublic; DBStatus status = DBStatus::NOT_FOUND; manager_.SetKvStoreConfig({ meta.dataDir }); std::unique_lock lock(rwMutex_); @@ -153,7 +181,6 @@ KVDBGeneralStore::KVDBGeneralStore(const StoreMetaData &meta) SetDBReceiveDataInterceptor(meta.storeType); delegate_->RegisterObserver({}, DistributedDB::OBSERVER_CHANGES_FOREIGN, &observer_); delegate_->RegisterObserver({}, DistributedDB::OBSERVER_CHANGES_CLOUD, &observer_); - InitWaterVersion(meta); if (DeviceMatrix::GetInstance().IsDynamic(meta) || DeviceMatrix::GetInstance().IsStatics(meta)) { delegate_->SetRemotePushFinishedNotify([meta](const DistributedDB::RemotePushNotifyInfo &info) { DeviceMatrix::GetInstance().OnExchanged(info.deviceId, meta, DeviceMatrix::ChangeType::CHANGE_REMOTE); @@ -238,14 +265,17 @@ bool KVDBGeneralStore::IsBound() return isBound_; } -int32_t KVDBGeneralStore::Close() +int32_t KVDBGeneralStore::Close(bool isForce) { - std::unique_lock lock(rwMutex_); + std::unique_lock lock(rwMutex_, std::chrono::seconds(isForce ? LOCK_TIMEOUT : 0)); + if (!lock) { + return GeneralError::E_BUSY; + } + if (delegate_ == nullptr) { return GeneralError::E_OK; } - int32_t count = delegate_->GetTaskCount(); - if (count > 0) { + if (!isForce && delegate_->GetTaskCount() > 0) { return GeneralError::E_BUSY; } if (delegate_ != nullptr) { @@ -285,15 +315,15 @@ int32_t KVDBGeneralStore::Replace(const std::string &table, VBucket &&value) return GeneralError::E_NOT_SUPPORT; } -std::shared_ptr KVDBGeneralStore::Query( +std::pair> KVDBGeneralStore::Query( __attribute__((unused)) const std::string &table, const std::string &sql, Values &&args) { - return nullptr; + return { GeneralError::E_NOT_SUPPORT, nullptr }; } -std::shared_ptr KVDBGeneralStore::Query(const std::string &table, GenQuery &query) +std::pair> KVDBGeneralStore::Query(const std::string &table, GenQuery &query) { - return nullptr; + return { GeneralError::E_NOT_SUPPORT, nullptr }; } int32_t KVDBGeneralStore::MergeMigratedData(const std::string &tableName, VBuckets &&values) @@ -320,20 +350,14 @@ KVDBGeneralStore::DBSyncCallback KVDBGeneralStore::GetDBSyncCompleteCB(DetailAsy }; } -DBStatus KVDBGeneralStore::CloudSync(const Devices &devices, int32_t mode, DetailAsync async, int64_t wait) +DBStatus KVDBGeneralStore::CloudSync( + const Devices &devices, DistributedDB::SyncMode cloudSyncMode, DetailAsync async, int64_t wait) { - auto syncMode = GeneralStore::GetSyncMode(static_cast(mode)); - if (syncMode < CLOUD_BEGIN || syncMode >= CLOUD_END) { - ZLOGE("Do not need to cloud sync! devices count:%{public}zu, the 1st:%{public}s, syncMode:%{public}d", - devices.size(), devices.empty() ? "null" : Anonymous::Change(*devices.begin()).c_str(), syncMode); - return DBStatus::DB_ERROR; - } DistributedDB::CloudSyncOption syncOption; syncOption.devices = devices; - syncOption.mode = DistributedDB::SyncMode(syncMode); + syncOption.mode = cloudSyncMode; syncOption.waitTime = wait; syncOption.lockAction = DistributedDB::LockAction::NONE; - syncOption.merge = GeneralStore::GetHighMode(static_cast(mode)) == HighMode::AUTO_SYNC_MODE; if (storeInfo_.user == 0) { std::vector users; AccountDelegate::GetInstance()->QueryUsers(users); @@ -346,6 +370,7 @@ DBStatus KVDBGeneralStore::CloudSync(const Devices &devices, int32_t mode, Detai int32_t KVDBGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) { + auto syncMode = GeneralStore::GetSyncMode(syncParm.mode); std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { ZLOGE("store already closed! devices count:%{public}zu, the 1st:%{public}s, mode:%{public}d", devices.size(), @@ -353,12 +378,12 @@ int32_t KVDBGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAs return GeneralError::E_ALREADY_CLOSED; } DBStatus dbStatus; - auto syncMode = GeneralStore::GetSyncMode(syncParm.mode); + auto dbMode = DistributedDB::SyncMode(syncMode); if (syncMode > NEARBY_END && syncMode < CLOUD_END) { if (!enableCloud_) { return GeneralError::E_NOT_SUPPORT; } - dbStatus = CloudSync(devices, syncParm.mode, async, syncParm.wait); + dbStatus = CloudSync(devices, dbMode, async, syncParm.wait); } else { if (devices.empty()) { ZLOGE("Devices is empty! mode:%{public}d", syncParm.mode); @@ -378,7 +403,6 @@ int32_t KVDBGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAs dbStatus = delegate_->UnSubscribeRemoteQuery(devices, GetDBSyncCompleteCB(std::move(async)), dbQuery, false); } else if (syncMode < NEARBY_END) { - auto dbMode = DistributedDB::SyncMode(syncMode); if (kvQuery->IsEmpty()) { dbStatus = delegate_->Sync(devices, dbMode, GetDBSyncCompleteCB(std::move(async)), false); } else { @@ -394,6 +418,12 @@ int32_t KVDBGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAs void KVDBGeneralStore::SetEqualIdentifier(const std::string &appId, const std::string &storeId) { + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("store already closed! appId:%{public}s storeId:%{public}s", appId.c_str(), + Anonymous::Change(storeId).c_str()); + return; + } std::vector sameAccountDevs {}; std::vector defaultAccountDevs {}; auto uuids = DMAdapter::ToUUID(DMAdapter::GetInstance().GetRemoteDevices()); @@ -401,18 +431,20 @@ void KVDBGeneralStore::SetEqualIdentifier(const std::string &appId, const std::s GetIdentifierParams(defaultAccountDevs, uuids, NO_ACCOUNT); if (!sameAccountDevs.empty()) { auto accountId = AccountDelegate::GetInstance()->GetUnencryptedAccountId(); - auto syncIdentifier = KvManager::GetKvStoreIdentifier(accountId, appId, storeId); - ZLOGI("same account set compatible identifier store:%{public}s, user:%{public}s, device:%{public}.10s", - Anonymous::Change(storeId).c_str(), Anonymous::Change(accountId).c_str(), - DistributedData::Serializable::Marshall(sameAccountDevs).c_str()); - delegate_->SetEqualIdentifier(syncIdentifier, sameAccountDevs); + auto convertedIds = AppIdMappingConfigManager::GetInstance().Convert(appId, accountId); + auto identifier = KvManager::GetKvStoreIdentifier(convertedIds.second, convertedIds.first, storeId); + ZLOGI("same account store:%{public}s, user:%{public}s, device:%{public}.10s, appId:%{public}s", + Anonymous::Change(storeId).c_str(), Anonymous::Change(convertedIds.second).c_str(), + DistributedData::Serializable::Marshall(sameAccountDevs).c_str(), convertedIds.first.c_str()); + delegate_->SetEqualIdentifier(identifier, sameAccountDevs); } if (!defaultAccountDevs.empty()) { - auto syncIdentifier = KvManager::GetKvStoreIdentifier(defaultAccountId, appId, storeId); - ZLOGI("no account set compatible identifier store:%{public}s, device:%{public}.10s", + auto convertedIds = AppIdMappingConfigManager::GetInstance().Convert(appId, defaultAccountId); + auto identifier = KvManager::GetKvStoreIdentifier(convertedIds.second, convertedIds.first, storeId); + ZLOGI("no account store:%{public}s, device:%{public}.10s, appId:%{public}s", Anonymous::Change(storeId).c_str(), - DistributedData::Serializable::Marshall(defaultAccountDevs).c_str()); - delegate_->SetEqualIdentifier(syncIdentifier, defaultAccountDevs); + DistributedData::Serializable::Marshall(defaultAccountDevs).c_str(), convertedIds.first.c_str()); + delegate_->SetEqualIdentifier(identifier, defaultAccountDevs); } } @@ -431,9 +463,9 @@ void KVDBGeneralStore::GetIdentifierParams(std::vector &devices, ZLOGI("devices size: %{public}zu", devices.size()); } -std::shared_ptr KVDBGeneralStore::PreSharing(GenQuery &query) +std::pair> KVDBGeneralStore::PreSharing(GenQuery &query) { - return nullptr; + return { GeneralError::E_NOT_SUPPORT, nullptr }; } int32_t KVDBGeneralStore::Clean(const std::vector &devices, int32_t mode, const std::string &tableName) @@ -450,7 +482,8 @@ int32_t KVDBGeneralStore::Clean(const std::vector &devices, int32_t DBStatus status = OK; switch (mode) { case CLOUD_INFO: - status = delegate_->RemoveDeviceData("", static_cast(CLOUD_INFO)); + status = delegate_->RemoveDeviceData( + "", isPublic_ ? static_cast(CLOUD_DATA) : static_cast(CLOUD_INFO)); break; case CLOUD_DATA: status = delegate_->RemoveDeviceData("", static_cast(CLOUD_DATA)); @@ -467,7 +500,7 @@ int32_t KVDBGeneralStore::Clean(const std::vector &devices, int32_t default: return GeneralError::E_ERROR; } - return status == DistributedDB::OK ? GeneralError::E_OK : GeneralError::E_ERROR; + return ConvertStatus(status); } int32_t KVDBGeneralStore::Watch(int32_t origin, Watcher &watcher) @@ -530,23 +563,11 @@ int32_t KVDBGeneralStore::SetTrackerTable( KVDBGeneralStore::GenErr KVDBGeneralStore::ConvertStatus(DistributedDB::DBStatus status) { - switch (status) { - case DBStatus::OK: - return GenErr::E_OK; - case DBStatus::CLOUD_NETWORK_ERROR: - return GenErr::E_NETWORK_ERROR; - case DBStatus::CLOUD_LOCK_ERROR: - return GenErr::E_LOCKED_BY_OTHERS; - case DBStatus::CLOUD_FULL_RECORDS: - return GenErr::E_RECODE_LIMIT_EXCEEDED; - case DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT: - return GenErr::E_NO_SPACE_FOR_ASSET; - case DBStatus::CLOUD_SYNC_TASK_MERGED: - return GenErr::E_SYNC_TASK_MERGED; - default: - ZLOGI("status:0x%{public}x", status); - break; + auto it = dbStatusMap_.find(status); + if (it != dbStatusMap_.end()) { + return it->second; } + ZLOGI("status:0x%{public}x", status); return GenErr::E_ERROR; } @@ -584,23 +605,6 @@ std::vector KVDBGeneralStore::GetWaterVersion(const std::string &de return res; } -void KVDBGeneralStore::InitWaterVersion(const StoreMetaData &meta) -{ - CheckerManager::StoreInfo info = { atoi(meta.user.c_str()), meta.tokenId, meta.bundleName, meta.storeId }; - bool isDynamic = CheckerManager::GetInstance().IsDynamic(info); - bool isStatic = CheckerManager::GetInstance().IsStatic(info); - if (!isDynamic && !isStatic) { - return; - } - delegate_->SetGenCloudVersionCallback([info](auto &originVersion) { - return WaterVersionManager::GetInstance().GetWaterVersion(info.bundleName, info.storeId); - }); - callback_ = [meta]() { - auto event = std::make_unique(CloudEvent::CLOUD_SYNC_FINISHED, meta); - EventCenter::GetInstance().PostEvent(std::move(event)); - }; -} - void KVDBGeneralStore::ObserverProxy::OnChange(DBOrigin origin, const std::string &originalId, DBChangeData &&data) { if (!HasWatcher()) { @@ -651,12 +655,11 @@ void KVDBGeneralStore::ObserverProxy::ConvertChangeData(const std::list KVDBGeneralStore::DBProcessCB KVDBGeneralStore::GetDBProcessCB(DetailAsync async) { - return [async, callback = callback_](const std::map &processes) { - if (!async && !callback) { + return [async](const std::map &processes) { + if (!async) { return; } DistributedData::GenDetails details; - bool downloadFinished = false; for (auto &[id, process] : processes) { auto &detail = details[id]; detail.progress = process.process; @@ -672,16 +675,15 @@ KVDBGeneralStore::DBProcessCB KVDBGeneralStore::GetDBProcessCB(DetailAsync async table.download.success = value.downLoadInfo.successCount; table.download.failed = value.downLoadInfo.failCount; table.download.untreated = table.download.total - table.download.success - table.download.failed; - downloadFinished = downloadFinished || - (process.process == FINISHED && value.downLoadInfo.successCount > 0); + detail.changeCount = (process.process == FINISHED) + ? value.downLoadInfo.insertCount + value.downLoadInfo.updateCount + + value.downLoadInfo.deleteCount + : 0; } } if (async) { async(details); } - if (downloadFinished && callback) { - callback(); - } }; } @@ -773,4 +775,19 @@ void KVDBGeneralStore::SetConfig(const GeneralStore::StoreConfig &storeConfig) { enableCloud_ = storeConfig.enableCloud_; } + +std::pair KVDBGeneralStore::LockCloudDB() +{ + return { GeneralError::E_NOT_SUPPORT, 0 }; +} + +int32_t KVDBGeneralStore::UnLockCloudDB() +{ + return GeneralError::E_NOT_SUPPORT; +} + +void KVDBGeneralStore::SetExecutor(std::shared_ptr executor) +{ + return; +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.h b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.h index b9ad8360..a21efc30 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.h @@ -57,16 +57,17 @@ public: Values &&conditions) override; int32_t Replace(const std::string &table, VBucket &&value) override; int32_t Delete(const std::string &table, const std::string &sql, Values &&args) override; - std::shared_ptr Query(const std::string &table, const std::string &sql, Values &&args) override; - std::shared_ptr Query(const std::string &table, GenQuery &query) override; + std::pair> Query(const std::string &table, const std::string &sql, + Values &&args) override; + std::pair> Query(const std::string &table, GenQuery &query) override; int32_t Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) override; - std::shared_ptr PreSharing(GenQuery &query) override; + std::pair> PreSharing(GenQuery &query) override; int32_t Clean(const std::vector &devices, int32_t mode, const std::string &tableName) override; int32_t Watch(int32_t origin, Watcher &watcher) override; int32_t Unwatch(int32_t origin, Watcher &watcher) override; int32_t RegisterDetailProgressObserver(DetailAsync async) override; int32_t UnregisterDetailProgressObserver() override; - int32_t Close() override; + int32_t Close(bool isForce = false) override; int32_t AddRef() override; int32_t Release() override; int32_t BindSnapshots(std::shared_ptr>> bindAssets) override; @@ -74,10 +75,12 @@ public: std::vector GetWaterVersion(const std::string &deviceId) override; void SetEqualIdentifier(const std::string &appId, const std::string &storeId) override; void SetConfig(const StoreConfig &storeConfig) override; - + void SetExecutor(std::shared_ptr executor) override; static DBPassword GetDBPassword(const StoreMetaData &data); static DBOption GetDBOption(const StoreMetaData &data, const DBPassword &password); static DBSecurity GetDBSecurity(int32_t secLevel); + virtual std::pair LockCloudDB() override; + virtual int32_t UnLockCloudDB() override; private: using KvDelegate = DistributedDB::KvStoreNbDelegate; @@ -91,8 +94,7 @@ private: std::vector GetNewKey(std::vector &key, const std::string &uuid); DBSyncCallback GetDBSyncCompleteCB(DetailAsync async); DBProcessCB GetDBProcessCB(DetailAsync async); - DBStatus CloudSync(const Devices &devices, int32_t mode, DetailAsync async, int64_t wait); - void InitWaterVersion(const StoreMetaData &meta); + DBStatus CloudSync(const Devices &devices, DistributedDB::SyncMode cloudSyncMode, DetailAsync async, int64_t wait); void GetIdentifierParams(std::vector &devices, const std::vector &uuids, int32_t authType); class ObserverProxy : public DistributedDB::KvStoreObserver { @@ -125,14 +127,15 @@ private: std::atomic isBound_ = false; std::mutex mutex_; int32_t ref_ = 1; - mutable std::shared_mutex rwMutex_; + mutable std::shared_timed_mutex rwMutex_; StoreInfo storeInfo_; - std::function callback_; static constexpr int32_t NO_ACCOUNT = 0; static constexpr int32_t IDENTICAL_ACCOUNT = 1; - static constexpr const char *defaultAccountId = "default"; + static constexpr const char *defaultAccountId = "ohosAnonymousUid"; bool enableCloud_ = false; + bool isPublic_ = false; + static const std::map dbStatusMap_; }; } // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_KVDB_GENERAL_STORE_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp index ee0f35f0..b225490d 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp @@ -20,7 +20,6 @@ #include "accesstoken_kit.h" #include "account/account_delegate.h" -#include "auto_sync_matrix.h" #include "backup_manager.h" #include "bootstrap.h" #include "checker/checker_manager.h" @@ -100,10 +99,7 @@ void KVDBServiceImpl::Init() auto process = [this](const Event &event) { const auto &evt = static_cast(event); const auto &storeInfo = evt.GetStoreInfo(); - StoreMetaData meta; - meta.storeId = storeInfo.storeName; - meta.bundleName = storeInfo.bundleName; - meta.user = std::to_string(storeInfo.user); + StoreMetaData meta(storeInfo); meta.deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid; if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { if (meta.user == "0") { @@ -133,6 +129,7 @@ void KVDBServiceImpl::Init() store->RegisterDetailProgressObserver(nullptr); }; EventCenter::GetInstance().Subscribe(CloudEvent::CLOUD_SYNC, process); + EventCenter::GetInstance().Subscribe(CloudEvent::CLEAN_DATA, process); } void KVDBServiceImpl::RegisterKvServiceInfo() @@ -258,42 +255,14 @@ Status KVDBServiceImpl::Sync(const AppId &appId, const StoreId &storeId, SyncInf syncInfo.syncId = ++syncId_; RADAR_REPORT(STANDARD_DEVICE_SYNC, ADD_SYNC_TASK, RADAR_SUCCESS, BIZ_STATE, START, SYNC_STORE_ID, Anonymous::Change(storeId.storeId), SYNC_APP_ID, appId.appId, CONCURRENT_ID, - std::to_string(syncInfo.syncId), DATA_TYPE, metaData.dataType, SYNC_TYPE, SYNC); + std::to_string(syncInfo.syncId), DATA_TYPE, metaData.dataType, SYNC_TYPE, + SYNC, OS_TYPE, IsOHOSType(syncInfo.devices)); return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), delay, std::bind(&KVDBServiceImpl::DoSyncInOrder, this, metaData, syncInfo, std::placeholders::_1, ACTION_SYNC), std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, RefCount(), std::placeholders::_1)); } -Status KVDBServiceImpl::SyncExt(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) -{ - if (syncInfo.devices.empty()) { - return Status::INVALID_ARGUMENT; - } - StoreMetaData metaData = GetStoreMetaData(appId, storeId); - MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData); - auto device = DMAdapter::GetInstance().ToUUID(syncInfo.devices[0]); - if (device.empty()) { - ZLOGE("invalid deviceId, appId:%{public}s storeId:%{public}s deviceId:%{public}s", - metaData.bundleName.c_str(), Anonymous::Change(metaData.storeId).c_str(), - Anonymous::Change(syncInfo.devices[0]).c_str()); - return Status::INVALID_ARGUMENT; - } - if (DeviceMatrix::GetInstance().IsSupportMatrix() && - ((!DeviceMatrix::GetInstance().IsStatics(metaData) && !DeviceMatrix::GetInstance().IsDynamic(metaData)) || - !IsRemoteChange(metaData, device))) { - ZLOGD("no change, do not need sync, appId:%{public}s storeId:%{public}s", - metaData.bundleName.c_str(), Anonymous::Change(metaData.storeId).c_str()); - DBResult dbResult = { {syncInfo.devices[0], DBStatus::OK} }; - DoComplete(metaData, syncInfo, RefCount(), std::move(dbResult)); - return SUCCESS; - } - syncInfo.syncId = ++syncId_; - return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), 0, - std::bind(&KVDBServiceImpl::DoSyncInOrder, this, metaData, syncInfo, std::placeholders::_1, ACTION_SYNC), - std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, RefCount(), std::placeholders::_1)); -} - -Status KVDBServiceImpl::NotifyDataChange(const AppId &appId, const StoreId &storeId) +Status KVDBServiceImpl::NotifyDataChange(const AppId &appId, const StoreId &storeId, uint64_t delay) { StoreMetaData meta = GetStoreMetaData(appId, storeId); if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) { @@ -301,58 +270,20 @@ Status KVDBServiceImpl::NotifyDataChange(const AppId &appId, const StoreId &stor appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str()); return Status::INVALID_ARGUMENT; } - if (!DeviceMatrix::GetInstance().IsSupportMatrix()) { - if (meta.cloudAutoSync) { - DoCloudSync(meta, {}); - } - if (meta.isAutoSync) { - TryToSync(meta, true); - } - return SUCCESS; - } - if (DeviceMatrix::GetInstance().IsStatics(meta) || DeviceMatrix::GetInstance().IsDynamic(meta)) { + if (DeviceMatrix::GetInstance().IsSupportMatrix() && + (DeviceMatrix::GetInstance().IsStatics(meta) || DeviceMatrix::GetInstance().IsDynamic(meta))) { WaterVersionManager::GetInstance().GenerateWaterVersion(meta.bundleName, meta.storeId); DeviceMatrix::GetInstance().OnChanged(meta); - if (meta.cloudAutoSync) { - DoCloudSync(meta, {}); - } - return SUCCESS; - } - if (meta.cloudAutoSync) { - DoCloudSync(meta, {}); - } - if (meta.isAutoSync) { - AutoSyncMatrix::GetInstance().OnChanged(meta); - TryToSync(meta); } - return SUCCESS; -} -void KVDBServiceImpl::TryToSync(const StoreMetaData &metaData, bool force) -{ - auto devices = DMAdapter::ToUUID(DMAdapter::GetInstance().GetRemoteDevices()); - if (devices.empty()) { - return; - } - SyncInfo syncInfo; - syncInfo.mode = SyncMode::PUSH; - for (const auto &device : devices) { - if (!force && (!CommContext::GetInstance().IsSessionReady(device) || - !DMAdapter::GetInstance().IsDeviceReady(device))) { - continue; - } - ZLOGI("[TryToSync] appId:%{public}s, storeId:%{public}s", metaData.bundleName.c_str(), - Anonymous::Change(metaData.storeId).c_str()); - syncInfo.devices = { device }; - syncInfo.syncId = ++syncId_; - RADAR_REPORT(STANDARD_DEVICE_SYNC, ADD_SYNC_TASK, RADAR_SUCCESS, BIZ_STATE, START, - SYNC_STORE_ID, Anonymous::Change(metaData.storeId), SYNC_APP_ID, metaData.bundleName, - CONCURRENT_ID, std::to_string(syncInfo.syncId), DATA_TYPE, metaData.dataType, - SYNC_TYPE, REUSE_SOCKET_AUTO_SYNC); - KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), 0, - std::bind(&KVDBServiceImpl::DoSyncInOrder, this, metaData, syncInfo, std::placeholders::_1, ACTION_SYNC), - std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, RefCount(), std::placeholders::_1)); + if (executors_ != nullptr && (meta.cloudAutoSync)) { + executors_->Schedule(std::chrono::milliseconds(delay), [this, meta]() { + if (meta.cloudAutoSync) { + DoCloudSync(meta, {}); + } + }); } + return SUCCESS; } Status KVDBServiceImpl::PutSwitch(const AppId &appId, const SwitchData &data) @@ -416,76 +347,6 @@ Status KVDBServiceImpl::RegServiceNotifier(const AppId &appId, sptr mask) { - auto networkId = DMAdapter::GetInstance().ToNetworkID(device); - if (networkId.empty()) { - return; - } - OnDynamicChange(mask); - OnStaticsChange(mask); - }); -} - -void KVDBServiceImpl::OnStaticsChange(std::pair mask) -{ - bool isChanged = false; - syncAgents_.ForEach([mask, &isChanged](const auto &key, auto &value) { - StoreMetaData meta; - meta.appId = value.appId_; - meta.tokenId = key; - meta.bundleName = value.appId_; - meta.dataType = DataType::TYPE_STATICS; - if (!DeviceMatrix::GetInstance().IsStatics(meta)) { - return false; - } - uint16_t code = DeviceMatrix::GetInstance().GetCode(meta); - std::map clientMask; - bool changed = ((mask.first & code) == code); - if ((value.staticsChanged_ && changed) || (!value.staticsChanged_ && !changed)) { - return false; - } - value.staticsChanged_ = changed; - isChanged = true; - return false; - }); - if (isChanged) { - DoCloudSync(true); - } -} - -void KVDBServiceImpl::OnDynamicChange(std::pair mask) -{ - bool isChanged = false; - syncAgents_.ForEach([mask, &isChanged](const auto &key, auto &value) { - StoreMetaData meta; - meta.appId = value.appId_; - meta.tokenId = key; - meta.bundleName = value.appId_; - meta.dataType = DataType::TYPE_DYNAMICAL; - if (!DeviceMatrix::GetInstance().IsDynamic(meta)) { - return false; - } - uint16_t code = DeviceMatrix::GetInstance().GetCode(meta); - std::map clientMask; - bool changed = ((mask.second & code) == code); - if ((value.dynamicChanged_ && changed) || (!value.dynamicChanged_ && !changed)) { - return false; - } - value.dynamicChanged_ = changed; - isChanged = true; - return false; - }); - if (isChanged) { - DoCloudSync(false); - } -} - Status KVDBServiceImpl::UnregServiceNotifier(const AppId &appId) { syncAgents_.ComputeIfPresent(IPCSkeleton::GetCallingTokenID(), [&appId](const auto &key, SyncAgent &value) { @@ -780,20 +641,20 @@ Status KVDBServiceImpl::BeforeCreate(const AppId &appId, const StoreId &storeId, StoreMetaDataLocal oldLocal; MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), oldLocal, true); // when user is 0, old store no "isPublic" attr, as well as new store's "isPublic" is true, do not intercept. - if (old.storeType != meta.storeType || Constant::NotEqual(old.isEncrypt, meta.isEncrypt) || - old.area != meta.area || !options.persistent || + if (old.storeType != meta.storeType || Constant::NotEqual(old.isEncrypt, meta.isEncrypt) || old.area != meta.area || + !options.persistent || (meta.securityLevel != NO_LABEL && (old.securityLevel > meta.securityLevel)) || (Constant::NotEqual(oldLocal.isPublic, options.isPublic) && (old.user != DEFAULT_USER_ID || !options.isPublic))) { ZLOGE("meta appId:%{public}s storeId:%{public}s user:%{public}s type:%{public}d->%{public}d " - "encrypt:%{public}d->%{public}d " - "area:%{public}d->%{public}d persistent:%{public}d isPublic:%{public}d->%{public}d", - appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), old.user.c_str(), old.storeType, - meta.storeType, old.isEncrypt, meta.isEncrypt, old.area, meta.area, options.persistent, oldLocal.isPublic, - options.isPublic); + "encrypt:%{public}d->%{public}d area:%{public}d->%{public}d persistent:%{public}d " + "securityLevel:%{public}d->%{public}d isPublic:%{public}d->%{public}d", + appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), old.user.c_str(), old.storeType, + meta.storeType, old.isEncrypt, meta.isEncrypt, old.area, meta.area, options.persistent, + old.securityLevel, meta.securityLevel, oldLocal.isPublic, options.isPublic); return Status::STORE_META_CHANGED; } - if (options.cloudConfig.enableCloud && (!isCreated || !meta.enableCloud) && executors_ != nullptr) { + if (options.cloudConfig.enableCloud && !meta.enableCloud && executors_ != nullptr) { DistributedData::StoreInfo storeInfo; storeInfo.bundleName = appId.appId; storeInfo.instanceId = GetInstIndex(storeInfo.tokenId, appId); @@ -922,36 +783,6 @@ int32_t KVDBServiceImpl::OnUserChange(uint32_t code, const std::string &user, co return SUCCESS; } -int32_t KVDBServiceImpl::OnReady(const std::string &device) -{ - return SUCCESS; -} - -int32_t KVDBServiceImpl::OnSessionReady(const std::string &device) -{ - ZLOGI("session ready, device:%{public}s", Anonymous::Change(device).c_str()); - if (!DMAdapter::GetInstance().IsDeviceReady(device)) { - return SUCCESS; - } - - auto stores = AutoSyncMatrix::GetInstance().GetChangedStore(device); - for (const auto &store : stores) { - ZLOGI("[OnSessionReady] appId:%{public}s, storeId:%{public}s", - store.bundleName.c_str(), Anonymous::Change(store.storeId).c_str()); - SyncInfo syncInfo; - syncInfo.mode = SyncMode::PUSH; - syncInfo.devices = { device }; - syncInfo.syncId = ++syncId_; - RADAR_REPORT(STANDARD_DEVICE_SYNC, ADD_SYNC_TASK, RADAR_SUCCESS, BIZ_STATE, START, - SYNC_STORE_ID, Anonymous::Change(store.storeId), SYNC_APP_ID, store.bundleName, - CONCURRENT_ID, std::to_string(syncInfo.syncId), SYNC_TYPE, AUTOSYNC); - KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(store.tokenId), 0, - std::bind(&KVDBServiceImpl::DoSyncInOrder, this, store, syncInfo, std::placeholders::_1, ACTION_SYNC), - std::bind(&KVDBServiceImpl::DoComplete, this, store, syncInfo, RefCount(), std::placeholders::_1)); - } - return SUCCESS; -} - bool KVDBServiceImpl::IsRemoteChange(const StoreMetaData &metaData, const std::string &device) { auto code = DeviceMatrix::GetInstance().GetCode(metaData); @@ -970,12 +801,6 @@ bool KVDBServiceImpl::IsRemoteChange(const StoreMetaData &metaData, const std::s return (mask & code) == code; } -int32_t KVDBServiceImpl::Online(const std::string &device) -{ - AutoSyncMatrix::GetInstance().Online(device); - return SUCCESS; -} - void KVDBServiceImpl::AddOptions(const Options &options, StoreMetaData &metaData) { metaData.isAutoSync = options.autoSync; @@ -994,6 +819,7 @@ void KVDBServiceImpl::AddOptions(const Options &options, StoreMetaData &metaData metaData.dataType = options.dataType; metaData.enableCloud = options.cloudConfig.enableCloud; metaData.cloudAutoSync = options.cloudConfig.autoSync; + metaData.authType = static_cast(options.authType); } void KVDBServiceImpl::SaveLocalMetaData(const Options &options, const StoreMetaData &metaData) @@ -1067,33 +893,6 @@ KVDBServiceImpl::DBResult KVDBServiceImpl::HandleGenBriefDetails(const GenDetail return dbResults; } -void KVDBServiceImpl::DoCloudSync(bool isStatic) -{ - if (isStatic) { - auto staticStores = CheckerManager::GetInstance().GetStaticStores(); - for (auto &staticStore : staticStores) { - AppId appId = { staticStore.bundleName }; - StoreId storeId = { staticStore.storeId }; - auto status = CloudSync(appId, storeId, {}); - if (status != SUCCESS) { - ZLOGW("cloud sync failed:%{public}d, appId:%{public}s storeId:%{public}s", status, - staticStore.bundleName.c_str(), Anonymous::Change(staticStore.storeId).c_str()); - } - } - return; - } - auto dynamicStores = CheckerManager::GetInstance().GetDynamicStores(); - for (auto &dynamicStore : dynamicStores) { - AppId appId = { dynamicStore.bundleName }; - StoreId storeId = { dynamicStore.storeId }; - auto status = CloudSync(appId, storeId, {}); - if (status != SUCCESS) { - ZLOGW("cloud sync failed:%{public}d, appId:%{public}s storeId:%{public}s", status, - dynamicStore.bundleName.c_str(), Anonymous::Change(dynamicStore.storeId).c_str()); - } - } -} - Status KVDBServiceImpl::DoCloudSync(const StoreMetaData &meta, const SyncInfo &syncInfo) { if (!meta.enableCloud) { @@ -1134,7 +933,7 @@ Status KVDBServiceImpl::DoCloudSync(const StoreMetaData &meta, const SyncInfo &s }; auto mixMode = static_cast(GeneralStore::MixMode(GeneralStore::CLOUD_TIME_FIRST, meta.isAutoSync ? GeneralStore::AUTO_SYNC_MODE : GeneralStore::MANUAL_SYNC_MODE)); - auto info = ChangeEvent::EventInfo(mixMode, 0, false, nullptr, syncCallback); + auto info = ChangeEvent::EventInfo({ mixMode, 0, false, syncInfo.triggerMode }, false, nullptr, syncCallback); auto evt = std::make_unique(std::move(storeInfo), std::move(info)); EventCenter::GetInstance().PostEvent(std::move(evt)); return SUCCESS; @@ -1203,7 +1002,10 @@ bool KVDBServiceImpl::IsNeedMetaSync(const StoreMetaData &meta, const std::vecto metaData.deviceId = uuid; CapMetaData capMeta; auto capKey = CapMetaRow::GetKeyFor(uuid); - if (!MetaDataManager::GetInstance().LoadMeta(std::string(capKey.begin(), capKey.end()), capMeta) || + auto devInfo = DMAdapter::GetInstance().GetDeviceInfo(uuid); + if ((!MetaDataManager::GetInstance().LoadMeta(std::string(capKey.begin(), capKey.end()), capMeta) && + !(devInfo.osType != OH_OS_TYPE && + devInfo.deviceType == static_cast(DistributedHardware::DmDeviceType::DEVICE_TYPE_CAR))) || !MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData)) { isAfterMeta = true; break; @@ -1313,7 +1115,6 @@ Status KVDBServiceImpl::DoComplete(const StoreMetaData &meta, const SyncInfo &in for (const auto &device : info.devices) { auto it = result.find(device); if (it != result.end() && it->second == SUCCESS) { - AutoSyncMatrix::GetInstance().OnExchanged(device, meta); DeviceMatrix::GetInstance().OnExchanged(device, meta, ConvertType(static_cast(info.mode))); } } @@ -1392,6 +1193,43 @@ Status KVDBServiceImpl::ConvertDbStatus(DBStatus status) const return Status::ERROR; } +Status KVDBServiceImpl::ConvertGeneralErr(GeneralError error) const +{ + switch (error) { + case GeneralError::E_DB_ERROR: + return Status::DB_ERROR; + case GeneralError::E_OK: + return Status::SUCCESS; + case GeneralError::E_INVALID_ARGS: + return Status::INVALID_ARGUMENT; + case GeneralError::E_RECORD_NOT_FOUND: + return Status::KEY_NOT_FOUND; + case GeneralError::E_INVALID_VALUE_FIELDS: + return Status::INVALID_VALUE_FIELDS; + case GeneralError::E_INVALID_FIELD_TYPE: + return Status::INVALID_FIELD_TYPE; + case GeneralError::E_CONSTRAIN_VIOLATION: + return Status::CONSTRAIN_VIOLATION; + case GeneralError::E_INVALID_FORMAT: + return Status::INVALID_FORMAT; + case GeneralError::E_INVALID_QUERY_FORMAT: + return Status::INVALID_QUERY_FORMAT; + case GeneralError::E_INVALID_QUERY_FIELD: + return Status::INVALID_QUERY_FIELD; + case GeneralError::E_NOT_SUPPORT: + return Status::NOT_SUPPORT; + case GeneralError::E_TIME_OUT: + return Status::TIME_OUT; + case GeneralError::E_OVER_MAX_LIMITS: + return Status::OVER_MAX_LIMITS; + case GeneralError::E_SECURITY_LEVEL_ERROR: + return Status::SECURITY_LEVEL_ERROR; + default: + break; + } + return Status::ERROR; +} + KVDBServiceImpl::DBMode KVDBServiceImpl::ConvertDBMode(SyncMode syncMode) const { DBMode dbMode; @@ -1513,7 +1351,43 @@ int32_t KVDBServiceImpl::OnInitialize() RegisterKvServiceInfo(); RegisterHandler(); Init(); - RegisterMatrixChange(); return SUCCESS; } + +bool KVDBServiceImpl::IsOHOSType(const std::vector &ids) +{ + if (ids.empty()) { + ZLOGI("ids is empty"); + return true; + } + bool isOHOSType = true; + for (auto &id : ids) { + if (!DMAdapter::GetInstance().IsOHOSType(id)) { + isOHOSType = false; + break; + } + } + return isOHOSType; +} + +Status KVDBServiceImpl::RemoveDeviceData(const AppId &appId, const StoreId &storeId, const std::string &device) +{ + StoreMetaData metaData = GetStoreMetaData(appId, storeId); + MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData); + auto watcher = GetWatchers(metaData.tokenId, metaData.storeId); + auto store = AutoCache::GetInstance().GetStore(metaData, watcher); + if (store == nullptr) { + ZLOGE("GetStore failed! appId:%{public}s storeId:%{public}s dir:%{public}s", metaData.bundleName.c_str(), + Anonymous::Change(metaData.storeId).c_str(), metaData.dataDir.c_str()); + return Status::ERROR; + } + + int32_t ret; + if (device.empty()) { + ret = store->Clean({}, KVDBGeneralStore::NEARBY_DATA, ""); + } else { + ret = store->Clean({ DMAdapter::GetInstance().ToUUID(device) }, KVDBGeneralStore::NEARBY_DATA, ""); + } + return ConvertGeneralErr(GeneralError(ret)); +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h index a43b2045..38038ba2 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h @@ -49,7 +49,6 @@ public: Status Close(const AppId &appId, const StoreId &storeId) override; Status CloudSync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; Status Sync(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) override; - Status SyncExt(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) override; Status RegServiceNotifier(const AppId &appId, sptr notifier) override; Status UnregServiceNotifier(const AppId &appId) override; Status SetSyncParam(const AppId &appId, const StoreId &storeId, const KvSyncParam &syncParam) override; @@ -63,7 +62,7 @@ public: Status Subscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status Unsubscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status GetBackupPassword(const AppId &appId, const StoreId &storeId, std::vector &password) override; - Status NotifyDataChange(const AppId &appId, const StoreId &storeId) override; + Status NotifyDataChange(const AppId &appId, const StoreId &storeId, uint64_t delay) override; Status PutSwitch(const AppId &appId, const SwitchData &data) override; Status GetSwitch(const AppId &appId, const std::string &networkId, SwitchData &data) override; Status SubscribeSwitchData(const AppId &appId) override; @@ -74,9 +73,7 @@ public: int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &appId) override; int32_t ResolveAutoLaunch(const std::string &identifier, DBLaunchParam ¶m) override; int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; - int32_t Online(const std::string &device) override; - int32_t OnReady(const std::string &device) override; - int32_t OnSessionReady(const std::string &device) override; + Status RemoveDeviceData(const AppId &appId, const StoreId &storeId, const std::string &device) override; private: using StoreMetaData = OHOS::DistributedData::StoreMetaData; @@ -90,6 +87,7 @@ private: using DBStatus = DistributedDB::DBStatus; using DBMode = DistributedDB::SyncMode; using Action = OHOS::DistributedData::MetaDataManager::Action; + using GeneralError = DistributedData::GeneralError; enum SyncAction { ACTION_SYNC, ACTION_SUBSCRIBE, @@ -122,7 +120,7 @@ private: int32_t GetInstIndex(uint32_t tokenId, const AppId &appId); bool IsNeedMetaSync(const StoreMetaData &meta, const std::vector &uuids); Status DoCloudSync(const StoreMetaData &meta, const SyncInfo &syncInfo); - void DoCloudSync(bool isStatic); + void DoCloudSync(bool statics, bool dynamic); Status DoSync(const StoreMetaData &meta, const SyncInfo &info, const SyncEnd &complete, int32_t type); Status DoSyncInOrder(const StoreMetaData &meta, const SyncInfo &info, const SyncEnd &complete, int32_t type); Status DoSyncBegin(const std::vector &devices, const StoreMetaData &meta, @@ -130,6 +128,7 @@ private: Status DoComplete(const StoreMetaData &meta, const SyncInfo &info, RefCount refCount, const DBResult &dbResult); uint32_t GetSyncDelayTime(uint32_t delay, const StoreId &storeId); Status ConvertDbStatus(DBStatus status) const; + Status ConvertGeneralErr(GeneralError error) const; DBMode ConvertDBMode(SyncMode syncMode) const; ChangeType ConvertType(SyncMode syncMode) const; SwitchState ConvertAction(Action action) const; @@ -145,16 +144,15 @@ private: void SaveLocalMetaData(const Options &options, const StoreMetaData &metaData); void RegisterKvServiceInfo(); void RegisterHandler(); - void RegisterMatrixChange(); void DumpKvServiceInfo(int fd, std::map> ¶ms); void TryToSync(const StoreMetaData &metaData, bool force = false); - void OnStaticsChange(std::pair mask); - void OnDynamicChange(std::pair mask); bool IsRemoteChange(const StoreMetaData &metaData, const std::string &device); + bool IsOHOSType(const std::vector &ids); static Factory factory_; ConcurrentMap syncAgents_; std::shared_ptr executors_; std::atomic_uint64_t syncId_ = 0; + static constexpr int32_t OH_OS_TYPE = 10; }; } // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_SERVICE_KVDB_SERVICE_IMPL_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp index c224ccaa..cf7761ae 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp @@ -41,7 +41,6 @@ const KVDBServiceStub::Handler &KVDBServiceStub::OnSubscribe, &KVDBServiceStub::OnUnsubscribe, &KVDBServiceStub::OnGetBackupPassword, - &KVDBServiceStub::OnSyncExt, &KVDBServiceStub::OnCloudSync, &KVDBServiceStub::OnNotifyDataChange, &KVDBServiceStub::OnSetConfig, @@ -50,6 +49,7 @@ const KVDBServiceStub::Handler &KVDBServiceStub::OnSubscribeSwitchData, &KVDBServiceStub::OnUnsubscribeSwitchData, &KVDBServiceStub::OnClose, + &KVDBServiceStub::OnRemoveDeviceData, }; int KVDBServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) @@ -108,7 +108,7 @@ std::pair KVDBServiceStub::GetStoreInfo(uin bool KVDBServiceStub::CheckPermission(uint32_t code, const StoreInfo &storeInfo) { if (code >= static_cast(KVDBServiceInterfaceCode::TRANS_PUT_SWITCH) && - code < static_cast(KVDBServiceInterfaceCode::TRANS_BUTT)) { + code <= static_cast(KVDBServiceInterfaceCode::TRANS_UNSUBSCRIBE_SWITCH_DATA)) { return CheckerManager::GetInstance().IsSwitches(storeInfo); } return CheckerManager::GetInstance().IsValid(storeInfo); @@ -221,29 +221,16 @@ int32_t KVDBServiceStub::OnCloudSync( return ERR_NONE; } -int32_t KVDBServiceStub::OnSyncExt( +int32_t KVDBServiceStub::OnNotifyDataChange( const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) { - SyncInfo syncInfo; - if (!ITypesUtil::Unmarshal( - data, syncInfo.seqId, syncInfo.mode, syncInfo.devices, syncInfo.delay, syncInfo.query)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", - appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str()); + uint64_t delay = 0; + if (!ITypesUtil::Unmarshal(data, delay)) { + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_INVALID_DATA_ERR; } - int32_t status = SyncExt(appId, storeId, syncInfo); - if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, - appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str()); - return IPC_STUB_WRITE_PARCEL_ERR; - } - return ERR_NONE; -} - -int32_t KVDBServiceStub::OnNotifyDataChange( - const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) -{ - int32_t status = NotifyDataChange(appId, storeId); + int32_t status = NotifyDataChange(appId, storeId, delay); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str()); @@ -519,4 +506,21 @@ int32_t KVDBServiceStub::OnSetConfig(const AppId &appId, const StoreId &storeId, } return ERR_NONE; } + +int32_t KVDBServiceStub::OnRemoveDeviceData(const AppId &appId, const StoreId &storeId, MessageParcel &data, + MessageParcel &reply) +{ + std::string device; + if (!ITypesUtil::Unmarshal(data, device)) { + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + int32_t status = RemoveDeviceData(appId, storeId, device); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x appId:%{public}s", status, appId.appId.c_str()); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return ERR_NONE; +} } // namespace OHOS::DistributedKv diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.h b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.h index 71abe634..a5deeaf1 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.h @@ -50,7 +50,6 @@ private: int32_t OnSubscribe(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnUnsubscribe(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnGetBackupPassword(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); - int32_t OnSyncExt(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnNotifyDataChange(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnPutSwitch(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnGetSwitch(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); @@ -59,6 +58,7 @@ private: int32_t OnUnsubscribeSwitchData(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnSetConfig(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); + int32_t OnRemoveDeviceData(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); static const Handler HANDLERS[static_cast(KVDBServiceInterfaceCode::TRANS_BUTT)]; bool CheckPermission(uint32_t code, const StoreInfo &storeInfo); diff --git a/datamgr_service/services/distributeddataservice/service/matrix/include/auto_sync_matrix.h b/datamgr_service/services/distributeddataservice/service/matrix/include/auto_sync_matrix.h index 75445a8d..d875a235 100644 --- a/datamgr_service/services/distributeddataservice/service/matrix/include/auto_sync_matrix.h +++ b/datamgr_service/services/distributeddataservice/service/matrix/include/auto_sync_matrix.h @@ -19,6 +19,7 @@ #include #include #include + #include "metadata/store_meta_data.h" namespace OHOS::DistributedData { diff --git a/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h b/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h index 4fd6bc5c..6fb60685 100644 --- a/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h +++ b/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h @@ -16,6 +16,7 @@ #define OHOS_DISTRIBUTED_DATA_SERVICE_MATRIX_DEVICE_MATRIX_H #include #include + #include "eventcenter/event.h" #include "executor_pool.h" #include "lru_bucket.h" @@ -24,6 +25,7 @@ #include "metadata/store_meta_data.h" #include "utils/ref_count.h" #include "visibility.h" + namespace OHOS::DistributedData { class API_EXPORT DeviceMatrix { public: @@ -74,7 +76,6 @@ public: const StoreMetaData &metaData, ChangeType type = ChangeType::CHANGE_ALL); void UpdateLevel(const std::string &device, uint16_t level, LevelType type, bool isConsistent = false); void Clear(); - void RegRemoteChange(std::function)> observer); void SetExecutor(std::shared_ptr executors); uint16_t GetCode(const StoreMetaData &metaData); std::pair GetMask(const std::string &device, LevelType type = LevelType::DYNAMIC); @@ -87,6 +88,7 @@ public: bool IsDynamic(const StoreMetaData &metaData); bool IsStatics(const StoreMetaData &metaData); bool IsSupportMatrix(); + bool IsConsistent(); private: static constexpr uint32_t RESET_MASK_DELAY = 10; // min @@ -133,12 +135,13 @@ private: void UpdateMask(Mask &mask); void UpdateConsistentMeta(const std::string &device, const Mask &remote); void SaveSwitches(const std::string &device, const DataLevel &dataLevel); - void UpdateRemoteMeta(const std::string &device, Mask &mask); + void UpdateRemoteMeta(const std::string &device, Mask &mask, MatrixMetaData &newMeta); Task GenResetTask(); std::pair ConvertMask(const std::string &device, const DataLevel &dataLevel); uint16_t ConvertDynamic(const MatrixMetaData &meta, uint16_t mask); uint16_t ConvertStatics(const MatrixMetaData &meta, uint16_t mask); MatrixMetaData GetMatrixInfo(const std::string &device); + MatrixMetaData GetMatrixMetaData(const std::string &device, const Mask &mask); static inline uint16_t ConvertIndex(uint16_t code); MatrixEvent::MatrixData lasts_; @@ -155,9 +158,9 @@ private: std::map remotes_; std::vector dynamicApps_; std::vector staticsApps_; - std::function)> observer_; + std::function observer_; LRUBucket matrices_{ MAX_DEVICES }; LRUBucket versions_{ MAX_DEVICES }; }; } // namespace OHOS::DistributedData -#endif // OHOS_DISTRIBUTED_DATA_SERVICE_MATRIX_DEVICE_MATRIX_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICE_MATRIX_DEVICE_MATRIX_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/matrix/src/auto_sync_matrix.cpp b/datamgr_service/services/distributeddataservice/service/matrix/src/auto_sync_matrix.cpp index c9986722..4b6b38b5 100644 --- a/datamgr_service/services/distributeddataservice/service/matrix/src/auto_sync_matrix.cpp +++ b/datamgr_service/services/distributeddataservice/service/matrix/src/auto_sync_matrix.cpp @@ -16,10 +16,11 @@ #define LOG_TAG "AutoSyncMatrix" #include "auto_sync_matrix.h" + #include "bootstrap.h" #include "checker/checker_manager.h" -#include "device_matrix.h" #include "device_manager_adapter.h" +#include "device_matrix.h" #include "log_print.h" #include "metadata/meta_data_manager.h" #include "utils/anonymous.h" @@ -64,7 +65,7 @@ AutoSyncMatrix::AutoSyncMatrix() break; } return true; - }); + }); } AutoSyncMatrix::~AutoSyncMatrix() diff --git a/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp b/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp index da5c1ba5..337ae786 100644 --- a/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp +++ b/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp @@ -48,7 +48,7 @@ DeviceMatrix::DeviceMatrix() return true; } auto deviceId = std::move(metaData.deviceId); - ZLOGI("Matrix ver:%{public}u origin:%{public}d device:%{public}s", + ZLOGI("matrix version:%{public}u origin:%{public}d device:%{public}s", metaData.version, metaData.origin, Anonymous::Change(deviceId).c_str()); if (metaData.origin == MatrixMetaData::Origin::REMOTE_CONSISTENT) { return true; @@ -69,7 +69,7 @@ DeviceMatrix::DeviceMatrix() } auto deviceId = std::move(metaData.deviceId); versions_.Set(deviceId, metaData); - ZLOGI("Matrix ver:%{public}u device:%{public}s", + ZLOGI("matrix version:%{public}u device:%{public}s", metaData.version, Anonymous::Change(deviceId).c_str()); return true; }); @@ -118,7 +118,7 @@ bool DeviceMatrix::Initialize(uint32_t token, std::string storeId) newMeta.dynamic = Merge(oldMeta.dynamic, newMeta.dynamic); newMeta.statics = Merge(oldMeta.statics, newMeta.statics); } - ZLOGI("Save Matrix ver:%{public}u -> %{public}u ", oldMeta.version, newMeta.version); + ZLOGI("Save Matrix, oldMeta.version:%{public}u , newMeta.version:%{public}u ", oldMeta.version, newMeta.version); MetaDataManager::GetInstance().SaveMeta(newMeta.GetKey(), newMeta, true); return MetaDataManager::GetInstance().SaveMeta(newMeta.GetKey(), newMeta); } @@ -205,7 +205,8 @@ std::pair DeviceMatrix::OnBroadcast(const std::string &devic } else { mask.statics &= ~dataLevel.statics; } - UpdateRemoteMeta(device, mask); + auto meta = GetMatrixMetaData(device, mask); + UpdateRemoteMeta(device, mask, meta); { std::lock_guard lockGuard(mutex_); auto it = remotes_.find(device); @@ -215,9 +216,6 @@ std::pair DeviceMatrix::OnBroadcast(const std::string &devic } remotes_.insert_or_assign(device, mask); } - if (observer_) { - observer_(device, { mask.statics, mask.dynamic }); - } return { mask.dynamic, mask.statics }; } @@ -288,15 +286,20 @@ uint16_t DeviceMatrix::ConvertIndex(uint16_t code) return index; } -void DeviceMatrix::UpdateRemoteMeta(const std::string &device, Mask &mask) +MatrixMetaData DeviceMatrix::GetMatrixMetaData(const std::string &device, const Mask &mask) +{ + MatrixMetaData meta; + meta.dynamic = mask.dynamic; + meta.statics = mask.statics; + meta.deviceId = device; + meta.origin = Origin::REMOTE_RECEIVED; + meta.dynamicInfo = dynamicApps_; + meta.staticsInfo = staticsApps_; + return meta; +} + +void DeviceMatrix::UpdateRemoteMeta(const std::string &device, Mask &mask, MatrixMetaData &newMeta) { - MatrixMetaData newMeta; - newMeta.dynamic = mask.dynamic; - newMeta.statics = mask.statics; - newMeta.deviceId = device; - newMeta.origin = Origin::REMOTE_RECEIVED; - newMeta.dynamicInfo = dynamicApps_; - newMeta.staticsInfo = staticsApps_; auto [exist, oldMeta] = GetMatrixMeta(device); if (exist && oldMeta == newMeta) { return; @@ -364,15 +367,15 @@ void DeviceMatrix::Broadcast(const DataLevel &dataLevel) } matrix.dynamic |= Low(lasts_.dynamic); matrix.statics |= Low(lasts_.statics); - if (High(matrix.dynamic) != INVALID_HIGH && High(lasts_.dynamic)!= INVALID_HIGH && + if (High(matrix.dynamic) != INVALID_HIGH && High(lasts_.dynamic) != INVALID_HIGH && High(matrix.dynamic) < High(lasts_.dynamic)) { - matrix.dynamic &= 0x000F; - matrix.dynamic |= High(matrix.dynamic); + matrix.dynamic &= 0x000F; + matrix.dynamic |= High(matrix.dynamic); } - if (High(matrix.statics) != INVALID_HIGH && High(lasts_.statics)!= INVALID_HIGH && + if (High(matrix.statics) != INVALID_HIGH && High(lasts_.statics) != INVALID_HIGH && High(matrix.statics) < High(lasts_.statics)) { - matrix.statics &= 0x000F; - matrix.statics |= High(matrix.statics); + matrix.statics &= 0x000F; + matrix.statics |= High(matrix.statics); } EventCenter::GetInstance().PostEvent(std::make_unique(MATRIX_BROADCAST, "", matrix)); lasts_ = matrix; @@ -458,7 +461,7 @@ void DeviceMatrix::OnChanged(const StoreMetaData &metaData) void DeviceMatrix::OnExchanged(const std::string &device, uint16_t code, LevelType type, ChangeType changeType) { if (device.empty() || type < LevelType::STATICS || type > LevelType::DYNAMIC) { - ZLOGE("Invalid args.device:%{public}s, code:%{public}d, type:%{public}d", Anonymous::Change(device).c_str(), + ZLOGE("invalid args, device:%{public}s, code:%{public}d, type:%{public}d", Anonymous::Change(device).c_str(), code, type); return; } @@ -486,9 +489,6 @@ void DeviceMatrix::OnExchanged(const std::string &device, uint16_t code, LevelTy it->second.statics &= ~codes[LevelType::STATICS]; it->second.dynamic &= ~codes[LevelType::DYNAMIC]; UpdateConsistentMeta(device, it->second); - if (observer_) { - observer_(device, { it->second.statics, it->second.dynamic }); - } } } @@ -675,7 +675,7 @@ void DeviceMatrix::UpdateLevel(const std::string &device, uint16_t level, Device bool isConsistent) { if (device.empty() || type < 0 || type >= LevelType::BUTT) { - ZLOGE("Invalid args.device:%{public}s, level:%{public}d, type:%{public}d", Anonymous::Change(device).c_str(), + ZLOGE("invalid args, device:%{public}s, level:%{public}d, type:%{public}d", Anonymous::Change(device).c_str(), level, type); return; } @@ -713,15 +713,6 @@ MatrixMetaData DeviceMatrix::GetMatrixInfo(const std::string &device) return meta; } -void DeviceMatrix::RegRemoteChange(std::function)> observer) -{ - if (observer_) { - ZLOGD("duplicate register"); - return; - } - observer_ = std::move(observer); -} - bool DeviceMatrix::IsDynamic(const StoreMetaData &metaData) { if (metaData.dataType != LevelType::DYNAMIC) { @@ -771,4 +762,26 @@ bool DeviceMatrix::IsSupportMatrix() { return isSupportBroadcast_; } + +bool DeviceMatrix::IsConsistent() +{ + std::vector metas; + if (!MetaDataManager::GetInstance().LoadMeta(MatrixMetaData::GetPrefix({}), metas, true)) { + return true; + } + for (const auto &meta : metas) { + if (meta.origin == MatrixMetaData::Origin::REMOTE_RECEIVED) { + MatrixMetaData consistentMeta; + consistentMeta.deviceId = meta.deviceId; + if (!MetaDataManager::GetInstance().LoadMeta(consistentMeta.GetConsistentKey(), consistentMeta, true)) { + return false; + } + if ((High(meta.statics) > High(consistentMeta.statics)) || + (High(meta.dynamic) > High(consistentMeta.dynamic))) { + return false; + } + } + } + return true; +} } // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.cpp b/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.cpp index acafa07b..c3d582e6 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.cpp @@ -67,7 +67,6 @@ bool ObjectAssetLoader::Transfer(const int32_t userId, const std::string& bundle void ObjectAssetLoader::TransferAssetsAsync(const int32_t userId, const std::string& bundleName, const std::string& deviceId, const std::vector& assets, const TransferFunc& callback) { - RADAR_REPORT(ObjectStore::CREATE, ObjectStore::TRANSFER, ObjectStore::IDLE); if (executors_ == nullptr) { ZLOGE("executors is null, bundleName: %{public}s, deviceId: %{public}s, userId: %{public}d", bundleName.c_str(), DistributedData::Anonymous::Change(deviceId).c_str(), userId); @@ -124,9 +123,6 @@ void ObjectAssetLoader::FinishTask(const std::string& uri, bool result) if (task.downloadAssets.size() == 0 && task.callback != nullptr) { task.callback(result); finishedTasks.emplace_back(seq); - if (result) { - RADAR_REPORT(ObjectStore::CREATE, ObjectStore::TRANSFER, ObjectStore::RADAR_SUCCESS); - } } return false; }); @@ -171,7 +167,8 @@ bool ObjectAssetLoader::IsDownloaded(const DistributedData::Asset& asset) int32_t ObjectAssetLoader::PushAsset(int32_t userId, const sptr &assetObj, const sptr &sendCallback) { - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::PUSH_ASSETS, ObjectStore::IDLE); + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::PUSH_ASSETS, ObjectStore::IDLE); ZLOGI("PushAsset start, asset size:%{public}zu, bundleName:%{public}s, sessionId:%{public}s", assetObj->uris_.size(), assetObj->dstBundleName_.c_str(), assetObj->sessionId_.c_str()); auto status = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().PushAsset(userId, assetObj, @@ -179,20 +176,27 @@ int32_t ObjectAssetLoader::PushAsset(int32_t userId, const sptr &asset if (status != OBJECT_SUCCESS) { ZLOGE("PushAsset err status: %{public}d, asset size:%{public}zu, bundleName:%{public}s, sessionId:%{public}s", status, assetObj->uris_.size(), assetObj->dstBundleName_.c_str(), assetObj->sessionId_.c_str()); - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, status); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_FAILED, status, ObjectStore::FINISHED); } return status; } int32_t ObjectAssetsSendListener::OnSendResult(const sptr &assetObj, int32_t result) { + if (assetObj == nullptr) { + ZLOGE("OnSendResult error! status:%{public}d", result); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_FAILED, result, ObjectStore::FINISHED); + return result; + } ZLOGI("OnSendResult, status:%{public}d, asset size:%{public}zu", result, assetObj->uris_.size()); if (result == OBJECT_SUCCESS) { - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_SUCCESS); + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_SUCCESS); } else { - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, result); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_FAILED, result, ObjectStore::FINISHED); } return result; } diff --git a/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.cpp b/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.cpp index ce67d4df..b15277a6 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.cpp @@ -125,7 +125,7 @@ static const DFAAction AssetDFA[STATUS_BUTT][EVENT_BUTT] = { { STATUS_STABLE, nullptr, (Action)CompensateSync }, // transfer_finished { STATUS_WAIT_UPLOAD, nullptr, (Action)ChangeAssetToNormal }, // upload { STATUS_NO_CHANGE, nullptr, (Action)Recover }, // upload_finished - { STATUS_WAIT_DOWNLOAD, nullptr, (Action)STATUS_WAIT_DOWNLOAD }, // download + { STATUS_WAIT_DOWNLOAD, nullptr, (Action)ChangeAssetToNormal }, // download { STATUS_NO_CHANGE, nullptr, (Action)Recover }, // download_finished } }; @@ -201,8 +201,8 @@ static VBuckets GetMigratedData(AutoCache::Store& store, AssetBindInfo& assetBin Values args; VBuckets vBuckets; auto sql = BuildSql(assetBindInfo, args); - auto cursor = store->Query(assetBindInfo.tableName, sql, std::move(args)); - if (cursor == nullptr) { + auto [errCode, cursor] = store->Query(assetBindInfo.tableName, sql, std::move(args)); + if (errCode != E_OK || cursor == nullptr) { return vBuckets; } int32_t count = cursor->GetCount(); diff --git a/datamgr_service/services/distributeddataservice/service/object/object_data_listener.cpp b/datamgr_service/services/distributeddataservice/service/object/object_data_listener.cpp index 4bd3c3d5..1c58fb49 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_data_listener.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_data_listener.cpp @@ -18,6 +18,8 @@ #include "object_data_listener.h" #include "log_print.h" #include "object_manager.h" +#include "object_radar_reporter.h" +#include "utils/anonymous.h" namespace OHOS { namespace DistributedObject { ObjectDataListener::ObjectDataListener() @@ -56,10 +58,17 @@ int32_t ObjectAssetsRecvListener::OnStart(const std::string &srcNetworkId, const int32_t ObjectAssetsRecvListener::OnFinished(const std::string &srcNetworkId, const sptr &assetObj, int32_t result) { + if (assetObj == nullptr) { + ZLOGE("OnFinished error! status:%{public}d, srcNetworkId:%{public}s", result, + DistributedData::Anonymous::Change(srcNetworkId).c_str()); + ObjectStore::RadarReporter::ReportStageError(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::ASSETS_RECV, ObjectStore::RADAR_FAILED, result); + return result; + } auto objectKey = assetObj->dstBundleName_+assetObj->sessionId_; ZLOGI("OnFinished, status:%{public}d objectKey:%{public}s, asset size:%{public}zu", result, objectKey.c_str(), assetObj->uris_.size()); - ObjectStoreManager::GetInstance()->NotifyAssetsReady(objectKey, srcNetworkId); + ObjectStoreManager::GetInstance()->NotifyAssetsReady(objectKey, assetObj->dstBundleName_, srcNetworkId); return OBJECT_SUCCESS; } } // namespace DistributedObject diff --git a/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp b/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp index c4c231e2..2089491a 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp @@ -47,6 +47,7 @@ using Account = OHOS::DistributedKv::AccountDelegate; using AccessTokenKit = Security::AccessToken::AccessTokenKit; using ValueProxy = OHOS::DistributedData::ValueProxy; using DistributedFileDaemonManager = Storage::DistributedFile::DistributedFileDaemonManager; +constexpr const char *SAVE_INFO = "p_###SAVEINFO###"; ObjectStoreManager::ObjectStoreManager() { ZLOGI("ObjectStoreManager construct"); @@ -150,8 +151,8 @@ int32_t ObjectStoreManager::Save(const std::string &appId, const std::string &se if (result != OBJECT_SUCCESS) { ZLOGE("Open failed, errCode = %{public}d", result); proxy->Completed(std::map()); - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, ObjectStore::GETKV_FAILED, ObjectStore::BIZ_STATE, ObjectStore::FINISHED); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_FAILED, ObjectStore::GETKV_FAILED, ObjectStore::FINISHED); return STORE_NOT_OPEN; } @@ -160,6 +161,8 @@ int32_t ObjectStoreManager::Save(const std::string &appId, const std::string &se result = SaveToStore(appId, sessionId, deviceId, data); if (result != OBJECT_SUCCESS) { ZLOGE("Save failed, errCode = %{public}d", result); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_FAILED, result, ObjectStore::FINISHED); Close(); proxy->Completed(std::map()); return result; @@ -168,14 +171,15 @@ int32_t ObjectStoreManager::Save(const std::string &appId, const std::string &se proxy->Completed(results); ProcessSyncCallback(results, appId, sessionId, deviceId); }; - ZLOGD("start SyncOnStore"); + ZLOGI("Sync data, bundleName: %{public}s, sessionId: %{public}s, deviceId: %{public}s", appId.c_str(), + sessionId.c_str(), Anonymous::Change(deviceId).c_str()); std::vector deviceList = {deviceId}; result = SyncOnStore(GetPropertyPrefix(appId, sessionId, deviceId), deviceList, tmp); if (result != OBJECT_SUCCESS) { ZLOGE("sync failed, errCode = %{public}d", result); proxy->Completed(std::map()); - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, result, ObjectStore::BIZ_STATE, ObjectStore::FINISHED); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SYNC_DATA, ObjectStore::RADAR_FAILED, result, ObjectStore::FINISHED); } result = PushAssets(std::stoi(GetCurrentUser()), appId, sessionId, data, deviceId); Close(); @@ -268,13 +272,16 @@ int32_t ObjectStoreManager::Retrieve( allReady = true; } else { auto objectKey = bundleName + sessionId; - restoreStatus_.ComputeIfAbsent( - objectKey, [](const std::string& key) -> auto { - return RestoreStatus::NONE; + restoreStatus_.ComputeIfPresent(objectKey, [&allReady](const auto &key, auto &value) { + if (value == RestoreStatus::ALL_READY) { + allReady = true; + return false; + } + if (value == RestoreStatus::DATA_READY) { + value = RestoreStatus::DATA_NOTIFIED; + } + return true; }); - if (restoreStatus_[objectKey] == RestoreStatus::ALL_READY) { - allReady = true; - } } // delete local data status = RevokeSaveToStore(GetPrefixWithoutDeviceId(bundleName, sessionId)); @@ -286,8 +293,10 @@ int32_t ObjectStoreManager::Retrieve( } Close(); proxy->Completed(results, allReady); - RADAR_REPORT(ObjectStore::CREATE, ObjectStore::RESTORE, ObjectStore::RADAR_SUCCESS, ObjectStore::BIZ_STATE, - ObjectStore::FINISHED); + if (allReady) { + ObjectStore::RadarReporter::ReportStateFinished(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::NOTIFY, ObjectStore::RADAR_SUCCESS, ObjectStore::FINISHED); + } return status; } @@ -399,61 +408,113 @@ void ObjectStoreManager::UnregisterRemoteCallback(const std::string &bundleName, void ObjectStoreManager::NotifyChange(std::map> &changedData) { ZLOGI("OnChange start, size:%{public}zu", changedData.size()); - std::map> changedAssets = GetAssetsFromStore(changedData); - std::map>> data; bool hasAsset = false; - for (const auto &item : changedData) { - std::vector splitKeys = SplitEntryKey(item.first); - if (splitKeys.empty()) { - continue; - } - std::string prefix = splitKeys[BUNDLE_NAME_INDEX] + splitKeys[SESSION_ID_INDEX]; - std::string propertyName = splitKeys[PROPERTY_NAME_INDEX]; - data[prefix].insert_or_assign(propertyName, item.second); - if (IsAssetKey(propertyName)) { - hasAsset = true; + SaveInfo saveInfo; + for (const auto &[key, value] : changedData) { + if (key.find(SAVE_INFO) != std::string::npos) { + DistributedData::Serializable::Unmarshall(std::string(value.begin(), value.end()), saveInfo); + break; } } + auto data = GetObjectData(changedData, saveInfo, hasAsset); if (!hasAsset) { + ObjectStore::RadarReporter::ReportStateStart(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::DATA_RECV, ObjectStore::RADAR_SUCCESS, ObjectStore::START, saveInfo.bundleName); callbacks_.ForEach([this, &data](uint32_t tokenId, const CallbackInfo& value) { DoNotify(tokenId, value, data, true); // no asset, data ready means all ready return false; }); return; } - NotifyDataChanged(data); + NotifyDataChanged(data, saveInfo); SaveUserToMeta(); } -void ObjectStoreManager::NotifyDataChanged(std::map>>& data) +std::map>> ObjectStoreManager::GetObjectData( + const std::map>& changedData, SaveInfo& saveInfo, bool& hasAsset) { - for (auto const& [objectKey, results] : data) { - restoreStatus_.ComputeIfAbsent( - objectKey, [](const std::string& key) -> auto { - return RestoreStatus::NONE; - }); - if (restoreStatus_[objectKey] == RestoreStatus::ASSETS_READY) { - restoreStatus_[objectKey] = RestoreStatus::ALL_READY; + std::map>> data; + std::string keyPrefix = saveInfo.ToPropertyPrefix(); + if (!keyPrefix.empty()) { + std::string observerKey = saveInfo.bundleName + saveInfo.sessionId; + for (const auto &[key, value] : changedData) { + if (key.size() < keyPrefix.size() || key.find(SAVE_INFO) != std::string::npos) { + continue; + } + std::string propertyName = key.substr(keyPrefix.size()); + data[observerKey].insert_or_assign(propertyName, value); + if (!hasAsset && IsAssetKey(propertyName)) { + hasAsset = true; + } + } + } else { + for (const auto &item : changedData) { + std::vector splitKeys = SplitEntryKey(item.first); + if (splitKeys.size() <= PROPERTY_NAME_INDEX) { + continue; + } + if (saveInfo.sourceDeviceId.empty() || saveInfo.bundleName.empty()) { + saveInfo.sourceDeviceId = splitKeys[SOURCE_DEVICE_UDID_INDEX]; + saveInfo.bundleName = splitKeys[BUNDLE_NAME_INDEX]; + saveInfo.sessionId = splitKeys[SESSION_ID_INDEX]; + saveInfo.timestamp = splitKeys[TIME_INDEX]; + } + std::string prefix = splitKeys[BUNDLE_NAME_INDEX] + splitKeys[SESSION_ID_INDEX]; + std::string propertyName = splitKeys[PROPERTY_NAME_INDEX]; + data[prefix].insert_or_assign(propertyName, item.second); + if (IsAssetKey(propertyName)) { + hasAsset = true; + } + } + } + return data; +} + +void ObjectStoreManager::ComputeStatus(const std::string& objectKey, const SaveInfo& saveInfo, + const std::map>>& data) +{ + restoreStatus_.Compute(objectKey, [this, &data, saveInfo] (const auto &key, auto &value) { + if (value == RestoreStatus::ASSETS_READY) { + value = RestoreStatus::ALL_READY; + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::DATA_RECV, ObjectStore::RADAR_SUCCESS); callbacks_.ForEach([this, &data](uint32_t tokenId, const CallbackInfo& value) { DoNotify(tokenId, value, data, true); return false; }); } else { - restoreStatus_[objectKey] = RestoreStatus::DATA_READY; + value = RestoreStatus::DATA_READY; + ObjectStore::RadarReporter::ReportStateStart(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::DATA_RECV, ObjectStore::RADAR_SUCCESS, ObjectStore::START, saveInfo.bundleName); callbacks_.ForEach([this, &data](uint32_t tokenId, const CallbackInfo& value) { DoNotify(tokenId, value, data, false); return false; }); - WaitAssets(objectKey); + WaitAssets(key, saveInfo, data); } + return true; + }); +} + +void ObjectStoreManager::NotifyDataChanged( + const std::map>>& data, const SaveInfo& saveInfo) +{ + for (auto const& [objectKey, results] : data) { + restoreStatus_.ComputeIfAbsent( + objectKey, [](const std::string& key) -> auto { + return RestoreStatus::NONE; + }); + ComputeStatus(objectKey, saveInfo, data); } } -int32_t ObjectStoreManager::WaitAssets(const std::string& objectKey) +int32_t ObjectStoreManager::WaitAssets(const std::string& objectKey, const SaveInfo& saveInfo, + const std::map>>& data) { - auto taskId = executors_->Schedule(std::chrono::seconds(WAIT_TIME), [this, objectKey]() { - ZLOGE("wait assets finisehd timeout, objectKey:%{public}s", objectKey.c_str()); - NotifyAssetsReady(objectKey); + auto taskId = executors_->Schedule(std::chrono::seconds(WAIT_TIME), [this, objectKey, data, saveInfo]() { + ZLOGE("wait assets finisehd timeout, try pull assets, objectKey:%{public}s", objectKey.c_str()); + PullAssets(data, saveInfo); + DoNotifyWaitAssetTimeout(objectKey); }); objectTimer_.ComputeIfAbsent( @@ -463,73 +524,66 @@ int32_t ObjectStoreManager::WaitAssets(const std::string& objectKey) return OBJECT_SUCCESS; } -void ObjectStoreManager::NotifyAssetsReady(const std::string& objectKey, const std::string& srcNetworkId) +void ObjectStoreManager::PullAssets(const std::map>>& data, + const SaveInfo& saveInfo) { - restoreStatus_.ComputeIfAbsent( - objectKey, [](const std::string& key) -> auto { - return RestoreStatus::NONE; - }); - if (restoreStatus_[objectKey] == RestoreStatus::DATA_READY) { - restoreStatus_[objectKey] = RestoreStatus::ALL_READY; - callbacks_.ForEach([this, objectKey](uint32_t tokenId, const CallbackInfo& value) { - DoNotifyAssetsReady(tokenId, value, objectKey, true); - return false; + std::map changedAssets; + for (auto const& [objectId, result] : data) { + changedAssets[objectId] = GetAssetsFromDBRecords(result); + } + for (const auto& [objectId, assets] : changedAssets) { + std::string networkId = DmAdaper::GetInstance().ToNetworkID(saveInfo.sourceDeviceId); + auto block = std::make_shared>>(WAIT_TIME, std::tuple{ true, true }); + ObjectAssetLoader::GetInstance()->TransferAssetsAsync(std::stoi(GetCurrentUser()), + saveInfo.bundleName, networkId, assets, [this, block](bool success) { + block->SetValue({ false, success }); }); - } else { - restoreStatus_[objectKey] = RestoreStatus::ASSETS_READY; + auto [timeout, success] = block->GetValue(); + ZLOGI("Pull assets end, timeout: %{public}d, success: %{public}d, size:%{public}zu, deviceId: %{public}s", + timeout, success, assets.size(), DistributedData::Anonymous::Change(networkId).c_str()); } } -void ObjectStoreManager::NotifyAssetsStart(const std::string& objectKey, const std::string& srcNetworkId) +void ObjectStoreManager::NotifyAssetsReady(const std::string& objectKey, const std::string& bundleName, + const std::string& srcNetworkId) { restoreStatus_.ComputeIfAbsent( objectKey, [](const std::string& key) -> auto { return RestoreStatus::NONE; }); + restoreStatus_.Compute(objectKey, [this, &bundleName] (const auto &key, auto &value) { + if (value == RestoreStatus::DATA_NOTIFIED) { + value = RestoreStatus::ALL_READY; + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::ASSETS_RECV, ObjectStore::RADAR_SUCCESS); + callbacks_.ForEach([this, key](uint32_t tokenId, const CallbackInfo& value) { + DoNotifyAssetsReady(tokenId, value, key, true); + return false; + }); + } else if (value == RestoreStatus::DATA_READY) { + value = RestoreStatus::ALL_READY; + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::ASSETS_RECV, ObjectStore::RADAR_SUCCESS); + auto [has, taskId] = objectTimer_.Find(key); + if (has) { + executors_->Remove(taskId); + objectTimer_.Erase(key); + } + } else { + value = RestoreStatus::ASSETS_READY; + ObjectStore::RadarReporter::ReportStateStart(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::ASSETS_RECV, ObjectStore::RADAR_SUCCESS, ObjectStore::START, bundleName); + } + return true; + }); } -std::map> ObjectStoreManager::GetAssetsFromStore( - const std::map>& changedData) +void ObjectStoreManager::NotifyAssetsStart(const std::string& objectKey, const std::string& srcNetworkId) { - std::set assetKeyPrefix; - for (const auto& item : changedData) { - if (IsAssetKey(GetPropertyName(item.first))) { - assetKeyPrefix.insert(item.first.substr(0, item.first.find_last_of(ObjectStore::ASSET_DOT))); - } - } - std::map>>> results; - for (const auto& keyPrefix : assetKeyPrefix) { - std::vector entries; - auto status = delegate_->GetEntries(std::vector(keyPrefix.begin(), keyPrefix.end()), entries); - if (status != DistributedDB::DBStatus::OK) { - ZLOGE("GetEntries fail. keyPrefix = %{public}s", keyPrefix.c_str()); - continue; - } - std::map> result{}; - std::for_each(entries.begin(), entries.end(), [&result, this](const DistributedDB::Entry entry) { - std::string key(entry.key.begin(), entry.key.end()); - result[GetPropertyName(key)] = entry.value; - }); - std::vector splitKeys = SplitEntryKey(keyPrefix); - if (splitKeys.empty() || !IsAssetComplete(result, splitKeys[PROPERTY_NAME_INDEX])) { - continue; - } - std::string bundleName = splitKeys[BUNDLE_NAME_INDEX]; - std::string networkId = DmAdaper::GetInstance().ToNetworkID(splitKeys[SOURCE_DEVICE_UDID_INDEX]); - for (const auto &[key, value] : result) { - results[bundleName][networkId][key] = value; - } - } - std::map> changedAssets{}; - for (const auto& resultOfBundle : results) { - std::string bundleName = resultOfBundle.first; - for (const auto& resultOfDevice : resultOfBundle.second) { - std::string deviceId = resultOfDevice.first; - Assets assets = GetAssetsFromDBRecords(resultOfDevice.second); - changedAssets[bundleName][deviceId] = assets; - } - } - return changedAssets; + restoreStatus_.ComputeIfAbsent( + objectKey, [](const std::string& key) -> auto { + return RestoreStatus::NONE; + }); } bool ObjectStoreManager::IsAssetKey(const std::string& key) @@ -601,6 +655,13 @@ void ObjectStoreManager::DoNotify(uint32_t tokenId, const CallbackInfo& value, observer.second->Completed((*it).second, allReady); if (allReady) { restoreStatus_.Erase(observer.first); + ObjectStore::RadarReporter::ReportStateFinished(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::NOTIFY, ObjectStore::RADAR_SUCCESS, ObjectStore::FINISHED); + } else { + restoreStatus_.ComputeIfPresent(observer.first, [](const auto &key, auto &value) { + value = RestoreStatus::DATA_NOTIFIED; + return true; + }); } } } @@ -615,6 +676,8 @@ void ObjectStoreManager::DoNotifyAssetsReady(uint32_t tokenId, const CallbackInf observer.second->Completed(std::map>(), allReady); if (allReady) { restoreStatus_.Erase(objectKey); + ObjectStore::RadarReporter::ReportStateFinished(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::NOTIFY, ObjectStore::RADAR_SUCCESS, ObjectStore::FINISHED); } auto [has, taskId] = objectTimer_.Find(objectKey); if (has) { @@ -624,6 +687,29 @@ void ObjectStoreManager::DoNotifyAssetsReady(uint32_t tokenId, const CallbackInf } } +void ObjectStoreManager::DoNotifyWaitAssetTimeout(const std::string &objectKey) +{ + ObjectStore::RadarReporter::ReportStageError(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::ASSETS_RECV, ObjectStore::RADAR_FAILED, ObjectStore::TIMEOUT); + callbacks_.ForEach([this, &objectKey](uint32_t tokenId, const CallbackInfo &value) { + for (const auto& observer : value.observers_) { + if (objectKey != observer.first) { + continue; + } + observer.second->Completed(std::map>(), true); + restoreStatus_.Erase(objectKey); + auto [has, taskId] = objectTimer_.Find(objectKey); + if (has) { + executors_->Remove(taskId); + objectTimer_.Erase(objectKey); + } + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::DATA_RESTORE, + ObjectStore::NOTIFY, ObjectStore::RADAR_FAILED, ObjectStore::TIMEOUT, ObjectStore::FINISHED); + } + return false; + }); +} + void ObjectStoreManager::SetData(const std::string &dataDir, const std::string &userId) { ZLOGI("enter %{public}s", dataDir.c_str()); @@ -662,6 +748,12 @@ void ObjectStoreManager::Close() if (delegate_ == nullptr) { return; } + int32_t taskCount = delegate_->GetTaskCount(); + if (taskCount > 0 && syncCount_ == 1) { + CloseAfterMinute(); + ZLOGW("Store is busy, close after a minute, task count: %{public}d", taskCount); + return; + } syncCount_--; ZLOGI("closed a store, syncCount = %{public}d", syncCount_); FlushClosedStore(); @@ -677,8 +769,19 @@ void ObjectStoreManager::SyncCompleted( SetSyncStatus(false); FlushClosedStore(); } + for (const auto &item : results) { + if (item.second == DistributedDB::DBStatus::OK) { + ZLOGI("Sync success, sequenceId: 0x%{public}" PRIx64 "", sequenceId); + ObjectStore::RadarReporter::ReportStateFinished(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SYNC_DATA, ObjectStore::RADAR_SUCCESS, ObjectStore::FINISHED); + } else { + ZLOGE("Sync failed, sequenceId: 0x%{public}" PRIx64 ", status: %{public}d", sequenceId, item.second); + ObjectStore::RadarReporter::ReportStateError(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SYNC_DATA, ObjectStore::RADAR_FAILED, item.second, ObjectStore::FINISHED); + } + } } - + void ObjectStoreManager::FlushClosedStore() { std::lock_guard lock(kvStoreMutex_); @@ -719,14 +822,15 @@ void ObjectStoreManager::ProcessOldEntry(const std::string &appId) if (splitKeys.empty()) { continue; } - std::string id = splitKeys[SESSION_ID_INDEX]; - if (sessionIds.count(id) == 0) { + std::string bundleName = splitKeys[BUNDLE_NAME_INDEX]; + std::string sessionId = splitKeys[SESSION_ID_INDEX]; + if (sessionIds.count(sessionId) == 0) { char *end = nullptr; - sessionIds[id] = strtol(splitKeys[TIME_INDEX].c_str(), &end, DECIMAL_BASE); + sessionIds[sessionId] = strtol(splitKeys[TIME_INDEX].c_str(), &end, DECIMAL_BASE); } - if (oldestTime == 0 || oldestTime > sessionIds[id]) { - oldestTime = sessionIds[id]; - deleteKey = GetPrefixWithoutDeviceId(appId, id); + if (oldestTime == 0 || oldestTime > sessionIds[sessionId]) { + oldestTime = sessionIds[sessionId]; + deleteKey = GetPrefixWithoutDeviceId(bundleName, sessionId); } } if (sessionIds.size() < MAX_OBJECT_SIZE_PER_APP) { @@ -747,6 +851,13 @@ int32_t ObjectStoreManager::SaveToStore(const std::string &appId, const std::str RevokeSaveToStore(GetPropertyPrefix(appId, sessionId, toDeviceId)); std::string timestamp = std::to_string(GetSecondsSince1970ToNow()); std::vector entries; + DistributedDB::Entry saveInfoEntry; + std::string saveInfoKey = GetPropertyPrefix(appId, sessionId, toDeviceId) + timestamp + SEPERATOR + SAVE_INFO; + saveInfoEntry.key = std::vector(saveInfoKey.begin(), saveInfoKey.end()); + SaveInfo saveInfo(appId, sessionId, DmAdaper::GetInstance().GetLocalDevice().udid, toDeviceId, timestamp); + std::string saveInfoValue = DistributedData::Serializable::Marshall(saveInfo); + saveInfoEntry.value = std::vector(saveInfoValue.begin(), saveInfoValue.end()); + entries.emplace_back(saveInfoEntry); for (auto &item : data) { DistributedDB::Entry entry; std::string tmp = GetPropertyPrefix(appId, sessionId, toDeviceId) + timestamp + SEPERATOR + item.first; @@ -757,8 +868,6 @@ int32_t ObjectStoreManager::SaveToStore(const std::string &appId, const std::str auto status = delegate_->PutBatch(entries); if (status != DistributedDB::DBStatus::OK) { ZLOGE("putBatch fail %{public}d", status); - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, status, ObjectStore::BIZ_STATE, ObjectStore::FINISHED); } return status; } @@ -782,7 +891,7 @@ int32_t ObjectStoreManager::SyncOnStore( uint64_t sequenceId = SequenceSyncManager::GetInstance()->AddNotifier(userId_, callback); DistributedDB::Query dbQuery = DistributedDB::Query::Select(); dbQuery.PrefixKey(std::vector(prefix.begin(), prefix.end())); - ZLOGD("start sync"); + ZLOGI("Start sync, sequenceId: 0x%{public}" PRIx64 "", sequenceId); auto status = delegate_->Sync( syncDevices, DistributedDB::SyncMode::SYNC_MODE_PUSH_ONLY, [this, sequenceId](const std::map &devicesMap) { @@ -855,28 +964,69 @@ int32_t ObjectStoreManager::RetrieveFromStore( return DB_ERROR; } ZLOGI("GetEntries successfully"); - std::for_each(entries.begin(), entries.end(), [&results, this](const DistributedDB::Entry &entry) { + for (const auto &entry : entries) { std::string key(entry.key.begin(), entry.key.end()); - results[GetPropertyName(key)] = entry.value; - }); + if (key.find(SAVE_INFO) != std::string::npos) { + continue; + } + auto splitKeys = SplitEntryKey(key); + if (!splitKeys.empty()) { + results[splitKeys[PROPERTY_NAME_INDEX]] = entry.value; + } + } return OBJECT_SUCCESS; } +ObjectStoreManager::SaveInfo::SaveInfo(const std::string &bundleName, const std::string &sessionId, + const std::string &sourceDeviceId, const std::string &targetDeviceId, const std::string ×tamp) + : bundleName(bundleName), sessionId(sessionId), sourceDeviceId(sourceDeviceId), targetDeviceId(targetDeviceId), + timestamp(timestamp) {} + +bool ObjectStoreManager::SaveInfo::Marshal(json &node) const +{ + SetValue(node[GET_NAME(bundleName)], bundleName); + SetValue(node[GET_NAME(sessionId)], sessionId); + SetValue(node[GET_NAME(sourceDeviceId)], sourceDeviceId); + SetValue(node[GET_NAME(targetDeviceId)], targetDeviceId); + SetValue(node[GET_NAME(timestamp)], timestamp); + return true; +} + +bool ObjectStoreManager::SaveInfo::Unmarshal(const json &node) +{ + GetValue(node, GET_NAME(bundleName), bundleName); + GetValue(node, GET_NAME(sessionId), sessionId); + GetValue(node, GET_NAME(sourceDeviceId), sourceDeviceId); + GetValue(node, GET_NAME(targetDeviceId), targetDeviceId); + GetValue(node, GET_NAME(timestamp), timestamp); + return true; +} + +std::string ObjectStoreManager::SaveInfo::ToPropertyPrefix() +{ + if (bundleName.empty() || sessionId.empty() || sourceDeviceId.empty() || targetDeviceId.empty() || + timestamp.empty()) { + return ""; + } + return bundleName + SEPERATOR + sessionId + SEPERATOR + sourceDeviceId + SEPERATOR + targetDeviceId + SEPERATOR + + timestamp + SEPERATOR; +} + std::vector ObjectStoreManager::SplitEntryKey(const std::string &key) { std::smatch match; std::regex timeRegex(TIME_REGEX); if (!std::regex_search(key, match, timeRegex)) { - ZLOGE("Format error, key.size = %{public}zu", key.size()); + ZLOGW("Format error, key.size = %{public}zu", key.size()); return {}; } - size_t timePos = match.position(); + auto timePos = match.position(); std::string fromTime = key.substr(timePos + 1); std::string beforeTime = key.substr(0, timePos); size_t targetDevicePos = beforeTime.find_last_of(SEPERATOR); if (targetDevicePos == std::string::npos) { - ZLOGE("Format error, key.size = %{public}zu", key.size()); + ZLOGW("Format error, key.size = %{public}zu", key.size()); return {}; } std::string targetDevice = beforeTime.substr(targetDevicePos + 1); @@ -884,7 +1034,7 @@ std::vector ObjectStoreManager::SplitEntryKey(const std::string &ke size_t sourceDeviceUdidPos = beforeTargetDevice.find_last_of(SEPERATOR); if (sourceDeviceUdidPos == std::string::npos) { - ZLOGE("Format error, key.size = %{public}zu", key.size()); + ZLOGW("Format error, key.size = %{public}zu", key.size()); return {}; } std::string sourceDeviceUdid = beforeTargetDevice.substr(sourceDeviceUdidPos + 1); @@ -892,7 +1042,7 @@ std::vector ObjectStoreManager::SplitEntryKey(const std::string &ke size_t sessionIdPos = beforeSourceDeviceUdid.find_last_of(SEPERATOR); if (sessionIdPos == std::string::npos) { - ZLOGE("Format error, key.size = %{public}zu", key.size()); + ZLOGW("Format error, key.size = %{public}zu", key.size()); return {}; } std::string sessionId = beforeSourceDeviceUdid.substr(sessionIdPos + 1); @@ -900,7 +1050,7 @@ std::vector ObjectStoreManager::SplitEntryKey(const std::string &ke size_t propertyNamePos = fromTime.find_first_of(SEPERATOR); if (propertyNamePos == std::string::npos) { - ZLOGE("Format error, key.size = %{public}zu", key.size()); + ZLOGW("Format error, key.size = %{public}zu", key.size()); return {}; } std::string propertyName = fromTime.substr(propertyNamePos + 1); @@ -909,12 +1059,6 @@ std::vector ObjectStoreManager::SplitEntryKey(const std::string &ke return { bundleName, sessionId, sourceDeviceUdid, targetDevice, time, propertyName }; } -std::string ObjectStoreManager::GetPropertyName(const std::string &key) -{ - std::vector splitKeys = SplitEntryKey(key); - return splitKeys.empty() ? "" : splitKeys[PROPERTY_NAME_INDEX]; -} - std::string ObjectStoreManager::GetCurrentUser() { std::vector users; @@ -1026,7 +1170,11 @@ int32_t ObjectStoreManager::BindAsset(const uint32_t tokenId, const std::string& storeKey, [](const std::string& key) -> auto { return std::make_shared>>(); }); - bindSnapshots_[storeKey]->emplace(std::pair{asset.uri, snapshots_[snapshotKey]}); + auto snapshots = snapshots_.Find(snapshotKey).second; + bindSnapshots_.Compute(storeKey, [this, &asset, snapshots] (const auto &key, auto &value) { + value->emplace(std::pair{asset.uri, snapshots}); + return true; + }); HapTokenInfo tokenInfo; auto status = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); @@ -1041,7 +1189,10 @@ int32_t ObjectStoreManager::BindAsset(const uint32_t tokenId, const std::string& storeInfo.user = tokenInfo.userID; storeInfo.storeName = bindInfo.storeName; - snapshots_[snapshotKey]->BindAsset(ValueProxy::Convert(std::move(asset)), ConvertBindInfo(bindInfo), storeInfo); + snapshots_.Compute(snapshotKey, [this, &asset, &bindInfo, &storeInfo] (const auto &key, auto &value) { + value->BindAsset(ValueProxy::Convert(std::move(asset)), ConvertBindInfo(bindInfo), storeInfo); + return true; + }); return OBJECT_SUCCESS; } @@ -1063,8 +1214,16 @@ int32_t ObjectStoreManager::OnAssetChanged(const uint32_t tokenId, const std::st auto objectAsset = asset; Asset dataAsset = ValueProxy::Convert(std::move(objectAsset)); auto snapshotKey = appId + SEPERATOR + sessionId; - if (snapshots_.Contains(snapshotKey) && snapshots_[snapshotKey]->IsBoundAsset(dataAsset)) { - return snapshots_[snapshotKey]->OnDataChanged(dataAsset, deviceId); // needChange + int32_t res = OBJECT_SUCCESS; + bool exist = snapshots_.ComputeIfPresent(snapshotKey, + [&res, &dataAsset, &deviceId](const std::string &key, std::shared_ptr snapshot) { + if (snapshot != nullptr) { + res = snapshot->OnDataChanged(dataAsset, deviceId); // needChange + } + return snapshot != nullptr; + }); + if (exist) { + return res; } auto block = std::make_shared>>(WAIT_TIME, std::tuple{ true, true }); @@ -1088,17 +1247,17 @@ ObjectStoreManager::UriToSnapshot ObjectStoreManager::GetSnapShots(const std::st storeKey, [](const std::string& key) -> auto { return std::make_shared>>(); }); - return bindSnapshots_[storeKey]; + return bindSnapshots_.Find(storeKey).second; } void ObjectStoreManager::DeleteSnapshot(const std::string& bundleName, const std::string& sessionId) { auto snapshotKey = bundleName + SEPERATOR + sessionId; - if (!snapshots_.Contains(snapshotKey)) { + auto snapshot = snapshots_.Find(snapshotKey).second; + if (snapshot == nullptr) { ZLOGD("Not find snapshot, don't need delete"); return; } - auto snapshot = snapshots_[snapshotKey]; bindSnapshots_.ForEach([snapshot](auto& key, auto& value) { for (auto pos = value->begin(); pos != value->end();) { if (pos->second == snapshot) { diff --git a/datamgr_service/services/distributeddataservice/service/object/object_manager.h b/datamgr_service/services/distributeddataservice/service/object/object_manager.h index 8ff416a5..e9279123 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_manager.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_manager.h @@ -28,6 +28,7 @@ #include "object_data_listener.h" #include "object_snapshot.h" #include "object_types.h" +#include "serializable/serializable.h" #include "types.h" #include "value_proxy.h" namespace OHOS { @@ -67,6 +68,7 @@ public: enum RestoreStatus : int32_t { NONE = 0, DATA_READY, + DATA_NOTIFIED, ASSETS_READY, ALL_READY, STATUS_BUTT @@ -95,7 +97,8 @@ public: void UnregisterRemoteCallback(const std::string &bundleName, pid_t pid, uint32_t tokenId, const std::string &sessionId = ""); void NotifyChange(std::map> &changedData); - void NotifyAssetsReady(const std::string& objectKey, const std::string& srcNetworkId = ""); + void NotifyAssetsReady(const std::string& objectKey, const std::string& bundleName, + const std::string& srcNetworkId = ""); void NotifyAssetsStart(const std::string& objectKey, const std::string& srcNetworkId = ""); void CloseAfterMinute(); int32_t Open(); @@ -132,6 +135,19 @@ private: return false; } }; + struct SaveInfo : DistributedData::Serializable { + std::string bundleName; + std::string sessionId; + std::string sourceDeviceId; + std::string targetDeviceId; + std::string timestamp; + SaveInfo() = default; + SaveInfo(const std::string &bundleName, const std::string &sessionId, const std::string &sourceDeviceId, + const std::string &targetDeviceId, const std::string ×tamp); + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + std::string ToPropertyPrefix(); + }; DistributedDB::KvStoreNbDelegate *OpenObjectKvStore(); void FlushClosedStore(); void Close(); @@ -144,7 +160,6 @@ private: const std::string &appId, const std::string &sessionId, std::map> &results); void SyncCompleted(const std::map &results, uint64_t sequenceId); std::vector SplitEntryKey(const std::string &key); - std::string GetPropertyName(const std::string &key); void ProcessOldEntry(const std::string &appId); void ProcessSyncCallback(const std::map &results, const std::string &appId, const std::string &sessionId, const std::string &deviceId); @@ -153,6 +168,7 @@ private: void DoNotify(uint32_t tokenId, const CallbackInfo& value, const std::map>>& data, bool allReady); void DoNotifyAssetsReady(uint32_t tokenId, const CallbackInfo& value, const std::string& objectKey, bool allReady); + void DoNotifyWaitAssetTimeout(const std::string &objectKey); std::map> GetAssetsFromStore( const std::map>& changedData); static bool IsAssetKey(const std::string& key); @@ -160,10 +176,19 @@ private: const std::string& assetPrefix); Assets GetAssetsFromDBRecords(const std::map>& result); bool RegisterAssetsLister(); - void NotifyDataChanged(std::map>>& data); + void ComputeStatus(const std::string& objectKey, const SaveInfo& saveInfo, + const std::map>>& data); + void NotifyDataChanged(const std::map>>& data, + const SaveInfo& saveInfo); int32_t PushAssets(int32_t userId, const std::string &appId, const std::string &sessionId, const std::map> &data, const std::string &deviceId); - int32_t WaitAssets(const std::string& objectKey); + int32_t WaitAssets(const std::string& objectKey, const SaveInfo& saveInfo, + const std::map>>& data); + void PullAssets(const std::map>>& data, + const SaveInfo& saveInfo); + std::map>> GetObjectData( + const std::map>& changedData, SaveInfo& saveInfo, bool& hasAsset); + inline std::string GetPropertyPrefix(const std::string &appId, const std::string &sessionId) { return appId + SEPERATOR + sessionId + SEPERATOR + DmAdaper::GetInstance().GetLocalDevice().udid + SEPERATOR; diff --git a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp index 4b225813..206dd106 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp @@ -63,7 +63,8 @@ int32_t ObjectServiceImpl::ObjectStoreSave(const std::string &bundleName, const sptr callback) { ZLOGI("begin."); - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::IDLE); + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SAVE_TO_STORE, ObjectStore::IDLE); uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); if (status != OBJECT_SUCCESS) { @@ -73,8 +74,8 @@ int32_t ObjectServiceImpl::ObjectStoreSave(const std::string &bundleName, const if (status != OBJECT_SUCCESS) { ZLOGE("save fail %{public}d", status); } - RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_SUCCESS, ObjectStore::BIZ_STATE, - ObjectStore::FINISHED); + ObjectStore::RadarReporter::ReportStage(std::string(__FUNCTION__), ObjectStore::SAVE, + ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_SUCCESS); return status; } @@ -196,8 +197,6 @@ int32_t ObjectServiceImpl::ObjectStoreRetrieve( status = ObjectStoreManager::GetInstance()->Retrieve(bundleName, sessionId, callback, tokenId); if (status != OBJECT_SUCCESS) { ZLOGE("retrieve fail %{public}d", status); - RADAR_REPORT(ObjectStore::CREATE, ObjectStore::RESTORE, ObjectStore::RADAR_FAILED, - ObjectStore::ERROR_CODE, status, ObjectStore::BIZ_STATE, ObjectStore::FINISHED); return status; } return OBJECT_SUCCESS; @@ -251,8 +250,8 @@ int32_t ObjectServiceImpl::IsBundleNameEqualTokenId( storeInfo.storeId = sessionId; std::string appId = DistributedData::CheckerManager::GetInstance().GetAppId(storeInfo); if (appId.empty()) { - ZLOGE("object bundleName wrong, bundleName = %{public}s, uid = %{public}d, tokenId = 0x%{public}x", - bundleName.c_str(), storeInfo.uid, storeInfo.tokenId); + ZLOGE("object bundleName wrong, bundleName = %{public}s, uid = %{public}d, tokenId = %{public}s", + bundleName.c_str(), storeInfo.uid, Anonymous::Change(std::to_string(storeInfo.tokenId)).c_str()); return OBJECT_PERMISSION_DENIED; } return OBJECT_SUCCESS; @@ -308,6 +307,7 @@ int32_t ObjectServiceImpl::ResolveAutoLaunch(const std::string &identifier, Dist continue; } DistributedObject::ObjectStoreManager::GetInstance()->CloseAfterMinute(); + ZLOGI("Auto launch, close after a minute"); return OBJECT_SUCCESS; } } diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp index 0dd0afda..096d3fc6 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp @@ -42,6 +42,7 @@ DBStatus RdbCloud::BatchInsert( VBuckets temp = records; auto error = cloudDB_->BatchInsert(tableName, std::move(records), extends); PostEvent(temp, skipAssets, extends, DistributedData::AssetEvent::UPLOAD_FINISHED); + ConvertErrorField(extends); extend = ValueProxy::Convert(std::move(extends)); return ConvertStatus(static_cast(error)); } @@ -57,6 +58,7 @@ DBStatus RdbCloud::BatchUpdate( VBuckets temp = records; auto error = cloudDB_->BatchUpdate(tableName, std::move(records), extends); PostEvent(temp, skipAssets, extends, DistributedData::AssetEvent::UPLOAD_FINISHED); + ConvertErrorField(extends); extend = ValueProxy::Convert(std::move(extends)); return ConvertStatus(static_cast(error)); } @@ -65,6 +67,7 @@ DBStatus RdbCloud::BatchDelete(const std::string &tableName, std::vectorBatchDelete(tableName, extends); + ConvertErrorField(extends); extend = ValueProxy::Convert(std::move(extends)); return ConvertStatus(static_cast(error)); } @@ -115,15 +118,13 @@ DistributedData::GeneralError RdbCloud::PreSharing(const std::string& tableName, std::pair RdbCloud::Lock() { - auto error = cloudDB_->Lock(); - return std::make_pair( // int64_t <-> uint32_t, s <-> ms - ConvertStatus(static_cast(error)), cloudDB_->AliveTime() * TO_MS); + auto result = InnerLock(FLAG::SYSTEM_ABILITY); + return { ConvertStatus(result.first), result.second }; } DBStatus RdbCloud::UnLock() { - auto error = cloudDB_->Unlock(); - return ConvertStatus(static_cast(error)); + return ConvertStatus(InnerUnLock(FLAG::SYSTEM_ABILITY)); } DBStatus RdbCloud::HeartBeat() @@ -138,6 +139,34 @@ DBStatus RdbCloud::Close() return ConvertStatus(static_cast(error)); } +std::pair RdbCloud::InnerLock(FLAG flag) +{ + std::lock_guard lock(mutex_); + flag_ |= flag; + // int64_t <-> uint32_t, s <-> ms + return std::make_pair(static_cast(cloudDB_->Lock()), cloudDB_->AliveTime() * TO_MS); +} + +GeneralError RdbCloud::InnerUnLock(FLAG flag) +{ + std::lock_guard lock(mutex_); + flag_ &= ~flag; + if (flag_ == 0) { + return static_cast(cloudDB_->Unlock()); + } + return GeneralError::E_OK; +} + +std::pair RdbCloud::LockCloudDB(FLAG flag) +{ + return InnerLock(flag); +} + +GeneralError RdbCloud::UnLockCloudDB(FLAG flag) +{ + return InnerUnLock(flag); +} + std::pair RdbCloud::GetEmptyCursor(const std::string &tableName) { auto [error, cursor] = cloudDB_->GetEmptyCursor(tableName); @@ -157,8 +186,18 @@ DBStatus RdbCloud::ConvertStatus(DistributedData::GeneralError error) return DBStatus::CLOUD_FULL_RECORDS; case GeneralError::E_NO_SPACE_FOR_ASSET: return DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT; + case GeneralError::E_VERSION_CONFLICT: + return DBStatus::CLOUD_VERSION_CONFLICT; case GeneralError::E_RECORD_EXIST_CONFLICT: return DBStatus::CLOUD_RECORD_EXIST_CONFLICT; + case GeneralError::E_RECORD_NOT_FOUND: + return DBStatus::CLOUD_RECORD_NOT_FOUND; + case GeneralError::E_RECORD_ALREADY_EXISTED: + return DBStatus::CLOUD_RECORD_ALREADY_EXISTED; + case GeneralError::E_FILE_NOT_EXIST: + return DBStatus::LOCAL_ASSET_NOT_FOUND; + case GeneralError::E_TIME_OUT: + return DBStatus::TIME_OUT; default: ZLOGI("error:0x%{public}x", error); break; @@ -286,4 +325,24 @@ void RdbCloud::PostEventAsset(DistributedData::Asset& asset, DataBucket& extend, it->second->Uploaded(asset); } } -} // namespace OHOS::DistributedRdb + +uint8_t RdbCloud::GetLockFlag() const +{ + return flag_; +} + +void RdbCloud::ConvertErrorField(DistributedData::VBuckets& extends) +{ + for (auto& extend : extends) { + auto errorField = extend.find(SchemaMeta::ERROR_FIELD); + if (errorField == extend.end()) { + continue; + } + auto errCode = Traits::get_if(&(errorField->second)); + if (errCode == nullptr) { + continue; + } + errorField->second = ConvertStatus(static_cast(*errCode)); + } +} +} // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h index be8b1179..0478110c 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h @@ -15,6 +15,9 @@ #ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_H #define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_H + +#include + #include "cloud/cloud_db.h" #include "cloud/cloud_store_types.h" #include "cloud/icloud_db.h" @@ -24,11 +27,16 @@ namespace OHOS::DistributedRdb { class RdbCloud : public DistributedDB::ICloudDb { public: + enum FLAG : uint8_t { + SYSTEM_ABILITY = 1, + APPLICATION + }; using DBStatus = DistributedDB::DBStatus; using DBVBucket = DistributedDB::VBucket; using DBQueryNodes = std::vector; using DataBucket = DistributedData::VBucket; using BindAssets = DistributedData::BindAssets; + using GeneralError = DistributedData::GeneralError; explicit RdbCloud(std::shared_ptr cloudDB, BindAssets* bindAssets); virtual ~RdbCloud() = default; @@ -45,6 +53,9 @@ public: DBStatus Close() override; std::pair GetEmptyCursor(const std::string &tableName) override; static DBStatus ConvertStatus(DistributedData::GeneralError error); + uint8_t GetLockFlag() const; + std::pair LockCloudDB(FLAG flag); + GeneralError UnLockCloudDB(FLAG flag); private: static constexpr const char *TYPE_FIELD = "#_type"; @@ -52,9 +63,12 @@ private: using QueryNodes = std::vector; static std::pair ConvertQuery(DBVBucket& extend); static QueryNodes ConvertQuery(DBQueryNodes&& nodes); + static void ConvertErrorField(DistributedData::VBuckets& extends); static constexpr int32_t TO_MS = 1000; // s > ms std::shared_ptr cloudDB_; BindAssets* snapshots_; + uint8_t flag_ = 0; + std::mutex mutex_; void PostEvent(DistributedData::VBuckets& records, std::set& skipAssets, DistributedData::VBuckets& extend, DistributedData::AssetEvent eventId); @@ -62,6 +76,8 @@ private: DistributedData::AssetEvent eventId); void PostEventAsset(DistributedData::Asset& asset, DataBucket& extend, std::set& skipAssets, DistributedData::AssetEvent eventId); + std::pair InnerLock(FLAG flag); + GeneralError InnerUnLock(FLAG flag); }; } // namespace OHOS::DistributedRdb #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CLOUD_H diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp index 05d7d580..833474bd 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud_data_translate.cpp @@ -138,7 +138,7 @@ size_t RdbCloudDataTranslate::ParserRawData(const uint8_t *data, size_t length, break; } used += dataLen; - assets.push_back(ValueProxy::Convert(asset)); + assets.push_back(std::move(asset)); count++; } return used; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp index cc1bfb6e..b5be9c58 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp @@ -20,6 +20,7 @@ #include #include "cache_cursor.h" +#include "changeevent/remote_change_event.h" #include "cloud/asset_loader.h" #include "cloud/cloud_db.h" #include "cloud/cloud_store_types.h" @@ -57,11 +58,13 @@ using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; constexpr const char *INSERT = "INSERT INTO "; constexpr const char *REPLACE = "REPLACE INTO "; constexpr const char *VALUES = " VALUES "; +constexpr const char *LOGOUT_DELETE_FLAG = "DELETE#ALL_CLOUDDATA"; constexpr const LockAction LOCK_ACTION = static_cast(static_cast(LockAction::INSERT) | static_cast(LockAction::UPDATE) | static_cast(LockAction::DELETE) | static_cast(LockAction::DOWNLOAD)); constexpr uint32_t CLOUD_SYNC_FLAG = 1; constexpr uint32_t SEARCHABLE_FLAG = 2; +constexpr uint32_t LOCK_TIMEOUT = 3600; // second static DBSchema GetDBSchema(const Database &database) { @@ -84,9 +87,11 @@ static DBSchema GetDBSchema(const Database &database) return schema; } -RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appId, meta.user, meta.instanceId) +RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) + : manager_(meta.appId, meta.user, meta.instanceId), tasks_(std::make_shared>()) { observer_.storeId_ = meta.storeId; + observer_.meta_ = meta; RelationalStoreDelegate::Option option; option.observer = &observer_; if (meta.isEncrypt) { @@ -106,11 +111,13 @@ RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appI break; } manager_.CloseStore(delegate_); + delegate_ = nullptr; } } else { auto ret = manager_.OpenStore(meta.dataDir, meta.storeId, option, delegate_); if (ret != DBStatus::OK || delegate_ == nullptr) { manager_.CloseStore(delegate_); + delegate_ = nullptr; } } @@ -142,6 +149,9 @@ RdbGeneralStore::~RdbGeneralStore() bindInfo_.db_ = nullptr; rdbCloud_ = nullptr; rdbLoader_ = nullptr; + RemoveTasks(); + tasks_ = nullptr; + executor_ = nullptr; } int32_t RdbGeneralStore::BindSnapshots(std::shared_ptr>> bindAssets) @@ -177,8 +187,11 @@ int32_t RdbGeneralStore::Bind(Database &database, const std::map(BindEvent::BIND_SNAPSHOT, std::move(eventInfo)); EventCenter::GetInstance().PostEvent(std::move(evt)); bindInfo_ = std::move(bindInfo); - rdbCloud_ = std::make_shared(bindInfo_.db_, &snapshots_); - rdbLoader_ = std::make_shared(bindInfo_.loader_, &snapshots_); + { + std::unique_lock lock(rdbCloudMutex_); + rdbCloud_ = std::make_shared(bindInfo_.db_, &snapshots_); + rdbLoader_ = std::make_shared(bindInfo_.loader_, &snapshots_); + } DistributedDB::CloudSyncConfig dbConfig; dbConfig.maxUploadCount = config.maxNumber; @@ -204,28 +217,37 @@ bool RdbGeneralStore::IsBound() return isBound_; } -int32_t RdbGeneralStore::Close() +int32_t RdbGeneralStore::Close(bool isForce) { - std::unique_lock lock(rwMutex_); - if (delegate_ == nullptr) { - return 0; - } - int32_t count = delegate_->GetCloudSyncTaskCount(); - if (count > 0) { - return GeneralError::E_BUSY; - } - auto status = manager_.CloseStore(delegate_); - if (status != DBStatus::OK) { - return status; + { + std::unique_lock lock(rwMutex_, std::chrono::seconds(isForce ? LOCK_TIMEOUT : 0)); + if (!lock) { + return GeneralError::E_BUSY; + } + + if (delegate_ == nullptr) { + return GeneralError::E_OK; + } + if (!isForce && delegate_->GetCloudSyncTaskCount() > 0) { + return GeneralError::E_BUSY; + } + auto status = manager_.CloseStore(delegate_); + if (status != DBStatus::OK) { + return status; + } + delegate_ = nullptr; } - delegate_ = nullptr; + RemoveTasks(); bindInfo_.loader_ = nullptr; if (bindInfo_.db_ != nullptr) { bindInfo_.db_->Close(); } bindInfo_.db_ = nullptr; - rdbCloud_ = nullptr; - rdbLoader_ = nullptr; + { + std::unique_lock lock(rdbCloudMutex_); + rdbCloud_ = nullptr; + rdbLoader_ = nullptr; + } return GeneralError::E_OK; } @@ -414,40 +436,40 @@ int32_t RdbGeneralStore::Delete(const std::string &table, const std::string &sql return 0; } -std::shared_ptr RdbGeneralStore::Query(__attribute__((unused))const std::string &table, +std::pair> RdbGeneralStore::Query(__attribute__((unused))const std::string &table, const std::string &sql, Values &&args) { std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { ZLOGE("Database already closed! database:%{public}s", Anonymous::Change(storeInfo_.storeName).c_str()); - return nullptr; + return { GeneralError::E_ALREADY_CLOSED, nullptr }; } - std::vector records = QuerySql(sql, std::move(args)); - return std::make_shared(std::move(records)); + auto [errCode, records] = QuerySql(sql, std::move(args)); + return { errCode, std::make_shared(std::move(records)) }; } -std::shared_ptr RdbGeneralStore::Query(const std::string &table, GenQuery &query) +std::pair> RdbGeneralStore::Query(const std::string &table, GenQuery &query) { RdbQuery *rdbQuery = nullptr; auto ret = query.QueryInterface(rdbQuery); if (ret != GeneralError::E_OK || rdbQuery == nullptr) { ZLOGE("not RdbQuery!"); - return nullptr; + return { GeneralError::E_INVALID_ARGS, nullptr }; } std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { ZLOGE("Database already closed! database:%{public}s, table:%{public}s", Anonymous::Change(storeInfo_.storeName).c_str(), Anonymous::Change(table).c_str()); - return nullptr; + return { GeneralError::E_ALREADY_CLOSED, nullptr }; } if (rdbQuery->IsRemoteQuery()) { if (rdbQuery->GetDevices().size() != 1) { ZLOGE("RemoteQuery: devices size error! size:%{public}zu", rdbQuery->GetDevices().size()); - return nullptr; + return { GeneralError::E_ERROR, nullptr }; } - return RemoteQuery(*rdbQuery->GetDevices().begin(), rdbQuery->GetRemoteCondition()); + return { GeneralError::E_OK, RemoteQuery(*rdbQuery->GetDevices().begin(), rdbQuery->GetRemoteCondition()) }; } - return nullptr; + return { GeneralError::E_ERROR, nullptr }; } int32_t RdbGeneralStore::MergeMigratedData(const std::string &tableName, VBuckets &&values) @@ -470,7 +492,7 @@ int32_t RdbGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAsy bool isPriority = false; auto ret = query.QueryInterface(rdbQuery); if (ret != GeneralError::E_OK || rdbQuery == nullptr) { - dbQuery.FromTable(query.GetTables()); + dbQuery.FromTable(GetIntersection(query.GetTables(), GetTables())); } else { dbQuery = rdbQuery->GetQuery(); isPriority = rdbQuery->IsPriority(); @@ -485,30 +507,47 @@ int32_t RdbGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAsy return GeneralError::E_ALREADY_CLOSED; } auto highMode = GetHighMode(static_cast(syncParam.mode)); - auto status = (syncMode < NEARBY_END) - ? delegate_->Sync(devices, dbMode, dbQuery, GetDBBriefCB(std::move(async), syncMode), syncParam.wait != 0) - : (syncMode > NEARBY_END && syncMode < CLOUD_END) - ? delegate_->Sync({ devices, dbMode, dbQuery, syncParam.wait, (isPriority || highMode == MANUAL_SYNC_MODE), - syncParam.isCompensation, {}, highMode == AUTO_SYNC_MODE, LOCK_ACTION }, - GetDBProcessCB(std::move(async), syncMode, highMode)) - : DistributedDB::INVALID_ARGS; - OnSyncStart(storeInfo_, syncNotifyFlag_, syncMode, status); - return status; + SyncId syncId = ++syncTaskId_; + auto dbStatus = DistributedDB::INVALID_ARGS; + if (syncMode < NEARBY_END) { + dbStatus = delegate_->Sync(devices, dbMode, dbQuery, GetDBBriefCB(std::move(async)), syncParam.wait != 0); + } else if (syncMode > NEARBY_END && syncMode < CLOUD_END) { + auto callback = GetDBProcessCB(std::move(async), syncMode, syncId, highMode); + if (executor_ != nullptr && tasks_ != nullptr) { + auto id = executor_->Schedule(GetFinishTask(syncId), std::chrono::minutes(INTERVAL), + std::chrono::minutes(INTERVAL)); + tasks_->Insert(syncId, { id, callback }); + } + dbStatus = + delegate_->Sync({ devices, dbMode, dbQuery, syncParam.wait, (isPriority || highMode == MANUAL_SYNC_MODE), + syncParam.isCompensation, {}, highMode == AUTO_SYNC_MODE, LOCK_ACTION }, + tasks_ != nullptr ? GetCB(syncId) : callback, syncId); + if (dbStatus == DBStatus::OK || tasks_ == nullptr) { + return ConvertStatus(dbStatus); + } + tasks_->ComputeIfPresent(syncId, [executor = executor_](SyncId syncId, const FinishTask &task) { + if (executor != nullptr) { + executor->Remove(task.taskId); + } + return false; + }); + } + return ConvertStatus(dbStatus); } -std::shared_ptr RdbGeneralStore::PreSharing(GenQuery &query) +std::pair> RdbGeneralStore::PreSharing(GenQuery &query) { RdbQuery *rdbQuery = nullptr; auto ret = query.QueryInterface(rdbQuery); if (ret != GeneralError::E_OK || rdbQuery == nullptr) { ZLOGE("not RdbQuery!"); - return nullptr; + return { GeneralError::E_INVALID_ARGS, nullptr }; } auto tables = rdbQuery->GetTables(); auto statement = rdbQuery->GetStatement(); if (statement.empty() || tables.empty()) { ZLOGE("statement size:%{public}zu, tables size:%{public}zu", statement.size(), tables.size()); - return nullptr; + return { GeneralError::E_INVALID_ARGS, nullptr }; } std::string sql = BuildSql(*tables.begin(), statement, rdbQuery->GetColumns()); VBuckets values; @@ -516,23 +555,25 @@ std::shared_ptr RdbGeneralStore::PreSharing(GenQuery &query) std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { ZLOGE("Database already closed! database:%{public}s", Anonymous::Change(storeInfo_.storeName).c_str()); - return nullptr; + return { GeneralError::E_ALREADY_CLOSED, nullptr }; } - values = QuerySql(sql, rdbQuery->GetBindArgs()); + auto [errCode, ret] = QuerySql(sql, rdbQuery->GetBindArgs()); + values = std::move(ret); } - if (rdbCloud_ == nullptr || values.empty()) { - ZLOGW("rdbCloud is %{public}s, values size:%{public}zu", rdbCloud_ == nullptr ? "nullptr" : "not nullptr", + auto rdbCloud = GetRdbCloud(); + if (rdbCloud == nullptr || values.empty()) { + ZLOGW("rdbCloud is %{public}s, values size:%{public}zu", rdbCloud == nullptr ? "nullptr" : "not nullptr", values.size()); - return nullptr; + return { GeneralError::E_CLOUD_DISABLED, nullptr }; } VBuckets extends = ExtractExtend(values); - rdbCloud_->PreSharing(*tables.begin(), extends); + rdbCloud->PreSharing(*tables.begin(), extends); for (auto value = values.begin(), extend = extends.begin(); value != values.end() && extend != extends.end(); ++value, ++extend) { value->insert_or_assign(DistributedRdb::Field::SHARING_RESOURCE_FIELD, (*extend)[SchemaMeta::SHARING_RESOURCE]); value->erase(CLOUD_GID); } - return std::make_shared(std::move(values)); + return { GeneralError::E_OK, std::make_shared(std::move(values)) }; } VBuckets RdbGeneralStore::ExtractExtend(VBuckets &values) const @@ -636,21 +677,18 @@ int32_t RdbGeneralStore::Unwatch(int32_t origin, Watcher &watcher) return GeneralError::E_OK; } -RdbGeneralStore::DBBriefCB RdbGeneralStore::GetDBBriefCB(DetailAsync async, uint32_t syncMode) +RdbGeneralStore::DBBriefCB RdbGeneralStore::GetDBBriefCB(DetailAsync async) { if (!async) { - return [storeInfo = storeInfo_, flag = syncNotifyFlag_, syncMode](auto &) { - RdbGeneralStore::OnSyncFinish(storeInfo, flag, syncMode); - }; + return [](auto &) {}; } - return [async = std::move(async), storeInfo = storeInfo_, flag = syncNotifyFlag_, syncMode]( + return [async = std::move(async)]( const std::map> &result) { DistributedData::GenDetails details; for (auto &[key, tables] : result) { auto &value = details[key]; value.progress = FINISHED; value.code = GeneralError::E_OK; - RdbGeneralStore::OnSyncFinish(storeInfo, flag, syncMode); for (auto &table : tables) { if (table.status != DBStatus::OK) { value.code = GeneralError::E_ERROR; @@ -661,35 +699,47 @@ RdbGeneralStore::DBBriefCB RdbGeneralStore::GetDBBriefCB(DetailAsync async, uint }; } -RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async, uint32_t syncMode, uint32_t highMode) +RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async, uint32_t syncMode, SyncId syncId, + uint32_t highMode) { - if (!async && (highMode == MANUAL_SYNC_MODE || !async_)) { - return [storeInfo = storeInfo_, flag = syncNotifyFlag_, syncMode](auto &) { - RdbGeneralStore::OnSyncFinish(storeInfo, flag, syncMode); - }; - } - - return [async, autoAsync = async_, highMode, storeInfo = storeInfo_, flag = syncNotifyFlag_, syncMode]( - const std::map &processes) { + std::shared_lock lock(asyncMutex_); + return [async, autoAsync = async_, highMode, storeInfo = storeInfo_, flag = syncNotifyFlag_, syncMode, syncId, + rdbCloud = GetRdbCloud()](const std::map &processes) { DistributedData::GenDetails details; for (auto &[id, process] : processes) { + bool isDownload = false; auto &detail = details[id]; detail.progress = process.process; detail.code = ConvertStatus(process.errCode); detail.dbCode = DB_ERR_OFFSET + process.errCode; - if (process.process == FINISHED) { - RdbGeneralStore::OnSyncFinish(storeInfo, flag, syncMode); - } + uint32_t totalCount = 0; for (auto [key, value] : process.tableProcess) { auto &table = detail.details[key]; table.upload.total = value.upLoadInfo.total; table.upload.success = value.upLoadInfo.successCount; table.upload.failed = value.upLoadInfo.failCount; table.upload.untreated = table.upload.total - table.upload.success - table.upload.failed; + totalCount += table.upload.total; + isDownload = table.download.total > 0; table.download.total = value.downLoadInfo.total; table.download.success = value.downLoadInfo.successCount; table.download.failed = value.downLoadInfo.failCount; table.download.untreated = table.download.total - table.download.success - table.download.failed; + detail.changeCount = (process.process == FINISHED) + ? value.downLoadInfo.insertCount + value.downLoadInfo.updateCount + + value.downLoadInfo.deleteCount + : 0; + totalCount += table.download.total; + } + if (process.process == FINISHED) { + RdbGeneralStore::OnSyncFinish(storeInfo, flag, syncMode, syncId); + } else { + RdbGeneralStore::OnSyncStart(storeInfo, flag, syncMode, syncId, totalCount); + } + + if (isDownload && (process.process == FINISHED || process.process == PROCESSING) && rdbCloud != nullptr && + (rdbCloud->GetLockFlag() & RdbCloud::FLAG::APPLICATION)) { + rdbCloud->LockCloudDB(RdbCloud::FLAG::APPLICATION); } } if (async) { @@ -827,17 +877,19 @@ bool RdbGeneralStore::IsValid() int32_t RdbGeneralStore::RegisterDetailProgressObserver(GeneralStore::DetailAsync async) { + std::unique_lock lock(asyncMutex_); async_ = std::move(async); return GenErr::E_OK; } int32_t RdbGeneralStore::UnregisterDetailProgressObserver() { + std::unique_lock lock(asyncMutex_); async_ = nullptr; return GenErr::E_OK; } -VBuckets RdbGeneralStore::QuerySql(const std::string &sql, Values &&args) +std::pair RdbGeneralStore::QuerySql(const std::string &sql, Values &&args) { std::vector changedData; std::vector bindArgs = ValueProxy::Convert(std::move(args)); @@ -845,9 +897,9 @@ VBuckets RdbGeneralStore::QuerySql(const std::string &sql, Values &&args) if (status != DBStatus::OK) { ZLOGE("Failed! ret:%{public}d, sql:%{public}s, data size:%{public}zu", status, Anonymous::Change(sql).c_str(), changedData.size()); - return {}; + return { GenErr::E_ERROR, {} }; } - return ValueProxy::Convert(std::move(changedData)); + return { GenErr::E_OK, ValueProxy::Convert(std::move(changedData)) }; } std::vector RdbGeneralStore::GetWaterVersion(const std::string &deviceId) @@ -855,28 +907,77 @@ std::vector RdbGeneralStore::GetWaterVersion(const std::string &dev return {}; } -void RdbGeneralStore::OnSyncStart(const StoreInfo &storeInfo, uint32_t flag, uint32_t syncMode, int status) +void RdbGeneralStore::OnSyncStart(const StoreInfo &storeInfo, uint32_t flag, uint32_t syncMode, uint32_t traceId, + uint32_t syncCount) { uint32_t requiredFlag = (CLOUD_SYNC_FLAG | SEARCHABLE_FLAG); if (requiredFlag != (requiredFlag & flag)) { return; } - if (status != GeneralError::E_OK) { - return; - } StoreInfo info = storeInfo; - auto evt = std::make_unique(std::move(info), syncMode, DataSyncEvent::DataSyncStatus::START); + auto evt = std::make_unique(std::move(info), syncMode, DataSyncEvent::DataSyncStatus::START, + traceId, syncCount); EventCenter::GetInstance().PostEvent(std::move(evt)); } -void RdbGeneralStore::OnSyncFinish(const StoreInfo &storeInfo, uint32_t flag, uint32_t syncMode) +void RdbGeneralStore::OnSyncFinish(const StoreInfo &storeInfo, uint32_t flag, uint32_t syncMode, uint32_t traceId) { uint32_t requiredFlag = (CLOUD_SYNC_FLAG | SEARCHABLE_FLAG); if (requiredFlag != (requiredFlag & flag)) { return; } StoreInfo info = storeInfo; - auto evt = std::make_unique(std::move(info), syncMode, DataSyncEvent::DataSyncStatus::FINISH); + auto evt = std::make_unique(std::move(info), syncMode, DataSyncEvent::DataSyncStatus::FINISH, + traceId); + EventCenter::GetInstance().PostEvent(std::move(evt)); +} + +std::set RdbGeneralStore::GetTables() +{ + std::set tables; + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("Database already closed! database:%{public}s", Anonymous::Change(storeInfo_.storeName).c_str()); + return tables; + } + auto [errCode, res] = QuerySql(QUERY_TABLES_SQL, {}); + if (errCode != GenErr::E_OK) { + return tables; + } + for (auto &table : res) { + auto it = table.find("name"); + if (it == table.end() || TYPE_INDEX != it->second.index()) { + ZLOGW("error res! database:%{public}s", Anonymous::Change(storeInfo_.storeName).c_str()); + continue; + } + tables.emplace(std::move(*std::get_if(&(it->second)))); + } + return tables; +} + +std::vector RdbGeneralStore::GetIntersection(std::vector &&syncTables, + const std::set &localTables) +{ + std::vector res; + for (auto &it : syncTables) { + if (localTables.count(it)) { + res.push_back(std::move(it)); + } + } + return res; +} + +void RdbGeneralStore::ObserverProxy::PostDataChange(const StoreMetaData &meta, + const std::vector &tables, ChangeType type) +{ + RemoteChangeEvent::DataInfo info; + info.userId = meta.user; + info.storeId = meta.storeId; + info.deviceId = meta.deviceId; + info.bundleName = meta.bundleName; + info.tables = tables; + info.changeType = type; + auto evt = std::make_unique(RemoteChangeEvent::DATA_CHANGE, std::move(info)); EventCenter::GetInstance().PostEvent(std::move(evt)); } @@ -917,17 +1018,143 @@ void RdbGeneralStore::ObserverProxy::OnChange(DBOrigin origin, const std::string genOrigin.store = storeId_; Watcher::PRIFields fields; Watcher::ChangeInfo changeInfo; + bool notifyFlag = false; for (uint32_t i = 0; i < DistributedDB::OP_BUTT; ++i) { auto &info = changeInfo[data.tableName][i]; for (auto &priData : data.primaryData[i]) { Watcher::PRIValue value; Convert(std::move(*(priData.begin())), value); + if (notifyFlag || origin != DBOrigin::ORIGIN_CLOUD || i != DistributedDB::OP_DELETE) { + info.push_back(std::move(value)); + continue; + } + auto deleteKey = std::get_if(&value); + if (deleteKey != nullptr && (*deleteKey == LOGOUT_DELETE_FLAG)) { + // notify to start app + notifyFlag = true; + } info.push_back(std::move(value)); } } + if (notifyFlag) { + ZLOGI("post data change for cleaning cloud data"); + PostDataChange(meta_, {}, CLOUD_DATA_CLEAN); + } if (!data.field.empty()) { fields[std::move(data.tableName)] = std::move(*(data.field.begin())); } watcher_->OnChange(genOrigin, fields, std::move(changeInfo)); } + +std::pair RdbGeneralStore::LockCloudDB() +{ + auto rdbCloud = GetRdbCloud(); + if (rdbCloud == nullptr) { + return { GeneralError::E_ERROR, 0 }; + } + return rdbCloud->LockCloudDB(RdbCloud::FLAG::APPLICATION); +} + +int32_t RdbGeneralStore::UnLockCloudDB() +{ + auto rdbCloud = GetRdbCloud(); + if (rdbCloud == nullptr) { + return GeneralError::E_ERROR; + } + return rdbCloud->UnLockCloudDB(RdbCloud::FLAG::APPLICATION); +} + +std::shared_ptr RdbGeneralStore::GetRdbCloud() const +{ + std::shared_lock lock(rdbCloudMutex_); + return rdbCloud_; +} + +bool RdbGeneralStore::IsFinished(SyncId syncId) const +{ + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("database already closed! database:%{public}s", Anonymous::Change(storeInfo_.storeName).c_str()); + return true; + } + return delegate_->GetCloudTaskStatus(syncId).process == DistributedDB::FINISHED; +} + +Executor::Task RdbGeneralStore::GetFinishTask(SyncId syncId) +{ + return [this, syncId]() { + if (!IsFinished(syncId)) { + return; + } + DBProcessCB cb; + ZLOGW("database:%{public}s syncId:%{public}" PRIu64 " miss finished. ", + Anonymous::Change(storeInfo_.storeName).c_str(), syncId); + tasks_->ComputeIfPresent(syncId, [&cb, executor = executor_](SyncId syncId, const FinishTask &task) { + cb = task.cb; + if (executor != nullptr) { + executor->Remove(task.taskId); + } + return false; + }); + if (cb != nullptr) { + std::map result; + result.insert({ "", { DistributedDB::FINISHED, DBStatus::DB_ERROR } }); + cb(result); + } + }; +} + +void RdbGeneralStore::SetExecutor(std::shared_ptr executor) +{ + if (executor_ == nullptr) { + executor_ = executor; + } +} + +void RdbGeneralStore::RemoveTasks() +{ + if (tasks_ == nullptr) { + return; + } + std::list cbs; + tasks_->ForEach([&cbs, executor = executor_, store = storeInfo_.storeName](SyncId syncId, const FinishTask &task) { + cbs.push_back(std::move(task.cb)); + ZLOGW("database:%{public}s syncId:%{public}" PRIu64 " miss finished. ", + Anonymous::Change(store).c_str(), syncId); + if (executor != nullptr) { + executor->Remove(task.taskId); + } + return false; + }); + tasks_->Clear(); + std::map result; + result.insert({ "", { DistributedDB::FINISHED, DBStatus::DB_ERROR } }); + for (auto &cb : cbs) { + if (cb != nullptr) { + cb(result); + } + } +} + +RdbGeneralStore::DBProcessCB RdbGeneralStore::GetCB(SyncId syncId) +{ + return [task = tasks_, executor = executor_, syncId](const std::map &progress) { + if (task == nullptr) { + return; + } + DBProcessCB cb; + task->ComputeIfPresent(syncId, [&cb, &progress, executor](SyncId syncId, const FinishTask &finishTask) { + cb = finishTask.cb; + bool isFinished = !progress.empty() && progress.begin()->second.process == DistributedDB::FINISHED; + if (isFinished && executor != nullptr) { + executor->Remove(finishTask.taskId); + } + return !isFinished; + }); + if (cb != nullptr) { + cb(progress); + } + return; + }; +} } // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h index 567177c0..f096b6c3 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h @@ -19,6 +19,7 @@ #include #include +#include "concurrent_map.h" #include "metadata/store_meta_data.h" #include "rdb_asset_loader.h" #include "rdb_cloud.h" @@ -48,8 +49,11 @@ public: explicit RdbGeneralStore(const StoreMetaData &meta); ~RdbGeneralStore(); - static void OnSyncStart(const DistributedData::StoreInfo &storeInfo, uint32_t flag, uint32_t syncMode, int status); - static void OnSyncFinish(const DistributedData::StoreInfo &storeInfo, uint32_t flag, uint32_t syncMode); + static void OnSyncStart(const DistributedData::StoreInfo &storeInfo, uint32_t flag, uint32_t syncMode, + uint32_t traceId, uint32_t syncCount); + static void OnSyncFinish(const DistributedData::StoreInfo &storeInfo, uint32_t flag, uint32_t syncMode, + uint32_t traceId); + void SetExecutor(std::shared_ptr executor) override; int32_t Bind(Database &database, const std::map &bindInfos, const CloudConfig &config) override; bool IsBound() override; @@ -64,22 +68,25 @@ public: Values &&conditions) override; int32_t Replace(const std::string &table, VBucket &&value) override; int32_t Delete(const std::string &table, const std::string &sql, Values &&args) override; - std::shared_ptr Query(const std::string &table, const std::string &sql, Values &&args) override; - std::shared_ptr Query(const std::string &table, GenQuery &query) override; + std::pair> Query(const std::string &table, const std::string &sql, + Values &&args) override; + std::pair> Query(const std::string &table, GenQuery &query) override; int32_t Sync( const Devices &devices, GenQuery &query, DetailAsync async, DistributedData::SyncParam &syncParam) override; - std::shared_ptr PreSharing(GenQuery &query) override; + std::pair> PreSharing(GenQuery &query) override; int32_t Clean(const std::vector &devices, int32_t mode, const std::string &tableName) override; int32_t Watch(int32_t origin, Watcher &watcher) override; int32_t Unwatch(int32_t origin, Watcher &watcher) override; int32_t RegisterDetailProgressObserver(DetailAsync async) override; int32_t UnregisterDetailProgressObserver() override; - int32_t Close() override; + int32_t Close(bool isForce = false) override; int32_t AddRef() override; int32_t Release() override; int32_t BindSnapshots(std::shared_ptr>> bindAssets) override; int32_t MergeMigratedData(const std::string &tableName, VBuckets&& values) override; std::vector GetWaterVersion(const std::string &deviceId) override; + std::pair LockCloudDB() override; + int32_t UnLockCloudDB() override; private: RdbGeneralStore(const RdbGeneralStore& rdbGeneralStore); @@ -89,10 +96,18 @@ private: using SyncProcess = DistributedDB::SyncProcess; using DBBriefCB = DistributedDB::SyncStatusCallback; using DBProcessCB = std::function &processes)>; + using TaskId = ExecutorPool::TaskId; + using Time = std::chrono::steady_clock::time_point; + using SyncId = uint64_t; static GenErr ConvertStatus(DistributedDB::DBStatus status); + // GetIntersection and return results in the order of collecter1 + static std::vector GetIntersection(std::vector &&syncTables, + const std::set &localTables); static constexpr inline uint64_t REMOTE_QUERY_TIME_OUT = 30 * 1000; + static constexpr int64_t INTERVAL = 1; static constexpr const char* CLOUD_GID = "cloud_gid"; static constexpr const char* DATE_KEY = "data_key"; + static constexpr const char* QUERY_TABLES_SQL = "select name from sqlite_master where type = 'table';"; static constexpr uint32_t ITER_V0 = 10000; static constexpr uint32_t ITER_V1 = 5000; static constexpr uint32_t ITERS[] = {ITER_V0, ITER_V1}; @@ -110,20 +125,33 @@ private: return watcher_ != nullptr; } private: + enum ChangeType { + CLOUD_DATA_CHANGE = 0, + CLOUD_DATA_CLEAN + }; + void PostDataChange(const StoreMetaData &meta, const std::vector &tables, ChangeType type); friend RdbGeneralStore; Watcher *watcher_ = nullptr; std::string storeId_; + StoreMetaData meta_; }; - DBBriefCB GetDBBriefCB(DetailAsync async, uint32_t syncMode); - DBProcessCB GetDBProcessCB(DetailAsync async, uint32_t syncMode, uint32_t highMode = AUTO_SYNC_MODE); + DBBriefCB GetDBBriefCB(DetailAsync async); + DBProcessCB GetCB(SyncId syncId); + DBProcessCB GetDBProcessCB(DetailAsync async, uint32_t syncMode, SyncId syncId, + uint32_t highMode = AUTO_SYNC_MODE); + Executor::Task GetFinishTask(SyncId syncId); std::shared_ptr RemoteQuery(const std::string &device, const DistributedDB::RemoteCondition &remoteCondition); std::string BuildSql(const std::string& table, const std::string& statement, const std::vector& columns) const; - VBuckets QuerySql(const std::string& sql, Values &&args); + std::pair QuerySql(const std::string& sql, Values &&args); + std::set GetTables(); VBuckets ExtractExtend(VBuckets& values) const; size_t SqlConcatenate(VBucket &value, std::string &strColumnSql, std::string &strRowValueSql); bool IsPrintLog(DistributedDB::DBStatus status); + std::shared_ptr GetRdbCloud() const; + bool IsFinished(uint64_t syncId) const; + void RemoveTasks(); ObserverProxy observer_; RdbManager manager_; @@ -135,7 +163,7 @@ private: std::atomic isBound_ = false; std::mutex mutex_; int32_t ref_ = 1; - mutable std::shared_mutex rwMutex_; + mutable std::shared_timed_mutex rwMutex_; BindAssets snapshots_; DistributedData::StoreInfo storeInfo_; @@ -144,6 +172,15 @@ private: static constexpr uint32_t PRINT_ERROR_CNT = 150; uint32_t lastErrCnt_ = 0; uint32_t syncNotifyFlag_ = 0; + std::atomic syncTaskId_ = 0; + std::shared_mutex asyncMutex_ {}; + mutable std::shared_mutex rdbCloudMutex_; + struct FinishTask { + TaskId taskId = Executor::INVALID_TASK_ID; + DBProcessCB cb = nullptr; + }; + std::shared_ptr executor_ = nullptr; + std::shared_ptr> tasks_; }; } // namespace OHOS::DistributedRdb #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_GENERAL_STORE_H diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_notifier_proxy.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_notifier_proxy.cpp index eba9b47b..ceb200a3 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_notifier_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_notifier_proxy.cpp @@ -62,7 +62,7 @@ int32_t RdbNotifierProxy::OnChange(const Origin &origin, const PrimaryFields &pr } MessageParcel reply; - MessageOption option; + MessageOption option(MessageOption::TF_ASYNC); if (Remote()->SendRequest( static_cast(NotifierIFCode::RDB_NOTIFIER_CMD_DATA_CHANGE), data, reply, option) != 0) { ZLOGE("storeName:%{public}s, send request failed", DistributedData::Anonymous::Change(origin.store).c_str()); diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp index 4b3a16c7..e8730147 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -21,8 +21,10 @@ #include "changeevent/remote_change_event.h" #include "cloud/change_event.h" #include "cloud/cloud_share_event.h" +#include "cloud/cloud_lock_event.h" #include "cloud/make_query_event.h" #include "commonevent/data_change_event.h" +#include "commonevent/set_searchable_event.h" #include "communicator/device_manager_adapter.h" #include "crypto_manager.h" #include "directory/directory_manager.h" @@ -47,6 +49,8 @@ #include "rdb_general_store.h" #include "rdb_result_set_impl.h" #include "xcollie.h" +#include "device_matrix.h" +#include "metadata/capability_meta_data.h" using OHOS::DistributedKv::AccountDelegate; using OHOS::DistributedData::CheckerManager; using OHOS::DistributedData::MetaDataManager; @@ -116,6 +120,7 @@ RdbServiceImpl::RdbServiceImpl() store->RegisterDetailProgressObserver(GetCallbacks(meta.tokenId, storeInfo.storeName)); }; EventCenter::GetInstance().Subscribe(CloudEvent::CLOUD_SYNC, process); + EventCenter::GetInstance().Subscribe(CloudEvent::CLEAN_DATA, process); EventCenter::GetInstance().Subscribe(CloudEvent::MAKE_QUERY, [](const Event& event) { auto& evt = static_cast(event); @@ -170,7 +175,7 @@ int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, Distrib if (entry.isEncrypt) { param.option.iterateTimes = ITERATE_TIMES; param.option.cipher = DistributedDB::CipherType::AES_256_GCM; - GetPassword(entry, param.option.passwd); + GetDBPassword(entry, param.option.passwd); } AutoCache::GetInstance().GetStore(entry, GetWatchers(entry.tokenId, entry.storeId)); return true; @@ -182,22 +187,28 @@ int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, Distrib int32_t RdbServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) { ZLOGI("client dead, tokenId:%{public}d, pid:%{public}d ", tokenId, pid); - syncAgents_.EraseIf([pid](auto& key, SyncAgent& agent) { - if (agent.pid_ != pid) { - return false; + bool destroyed = false; + syncAgents_.ComputeIfPresent(tokenId, [pid, &destroyed](auto &key, SyncAgents &agents) { + auto it = agents.find(pid); + if (it != agents.end()) { + it->second.SetNotifier(nullptr); + agents.erase(it); } - if (agent.watcher_ != nullptr) { - agent.watcher_->SetNotifier(nullptr); + if (!agents.empty()) { + return true; } - auto stores = AutoCache::GetInstance().GetStoresIfPresent(key); + destroyed = true; + return false; + }); + if (destroyed) { + auto stores = AutoCache::GetInstance().GetStoresIfPresent(tokenId); for (auto store : stores) { if (store != nullptr) { store->UnregisterDetailProgressObserver(); } } - return true; - }); - AutoCache::GetInstance().Enable(tokenId); + AutoCache::GetInstance().Enable(tokenId); + } return E_OK; } @@ -241,15 +252,15 @@ int32_t RdbServiceImpl::InitNotifier(const RdbSyncerParam ¶m, const sptr(notifier); pid_t pid = IPCSkeleton::GetCallingPid(); uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); - syncAgents_.Compute(tokenId, [¶m, notifierProxy, pid](auto, SyncAgent &agent) { - if (pid != agent.pid_) { - agent.ReInit(pid, param.bundleName_); + syncAgents_.Compute(tokenId, [bundleName = param.bundleName_, notifierProxy, pid](auto, SyncAgents &agents) { + auto [it, success] = agents.try_emplace(pid, SyncAgent(bundleName)); + if (it == agents.end()) { + return true; } - agent.SetNotifier(notifierProxy); + it->second.SetNotifier(notifierProxy); return true; }); ZLOGI("success tokenId:%{public}x, pid=%{public}d", tokenId, pid); - return RDB_OK; } @@ -307,12 +318,19 @@ int32_t RdbServiceImpl::SetDistributedTables(const RdbSyncerParam ¶m, const return store->SetDistributedTables(tables, type, relationships); } -void RdbServiceImpl::OnAsyncComplete(uint32_t tokenId, uint32_t seqNum, Details &&result) +void RdbServiceImpl::OnAsyncComplete(uint32_t tokenId, pid_t pid, uint32_t seqNum, Details &&result) { - ZLOGI("tokenId=%{public}x seqnum=%{public}u", tokenId, seqNum); - auto [success, agent] = syncAgents_.Find(tokenId); - if (success && agent.notifier_ != nullptr) { - agent.notifier_->OnComplete(seqNum, std::move(result)); + ZLOGI("tokenId=%{public}x, pid=%{public}d, seqnum=%{public}u", tokenId, pid, seqNum); + sptr notifier = nullptr; + syncAgents_.ComputeIfPresent(tokenId, [¬ifier, pid](auto, SyncAgents &syncAgents) { + auto it = syncAgents.find(pid); + if (it != syncAgents.end()) { + notifier = it->second.notifier_; + } + return true; + }); + if (notifier != nullptr) { + notifier->OnComplete(seqNum, std::move(result)); } } @@ -333,28 +351,37 @@ std::string RdbServiceImpl::TransferStringToHex(const std::string &origStr) AutoCache::Watchers RdbServiceImpl::GetWatchers(uint32_t tokenId, const std::string &storeName) { - auto [success, agent] = syncAgents_.Find(tokenId); - if (agent.watcher_ == nullptr) { - return {}; - } - return { agent.watcher_ }; + AutoCache::Watchers watchers; + syncAgents_.ComputeIfPresent(tokenId, [&watchers](auto, SyncAgents &syncAgents) { + std::for_each(syncAgents.begin(), syncAgents.end(), [&watchers](const auto &item) { + if (item.second.watcher_ != nullptr) { + watchers.insert(item.second.watcher_); + } + }); + return true; + }); + return watchers; } -RdbServiceImpl::DetailAsync RdbServiceImpl::GetCallbacks(uint32_t tokenId, const std::string& storeName) +RdbServiceImpl::DetailAsync RdbServiceImpl::GetCallbacks(uint32_t tokenId, const std::string &storeName) { - sptr notifier = nullptr; - syncAgents_.ComputeIfPresent(tokenId, [&storeName, ¬ifier](auto, SyncAgent& syncAgent) { - if (syncAgent.callBackStores_.count(storeName) != 0) { - notifier = syncAgent.notifier_; - } + std::list> notifiers; + syncAgents_.ComputeIfPresent(tokenId, [&storeName, ¬ifiers](auto, SyncAgents &syncAgents) { + std::for_each(syncAgents.begin(), syncAgents.end(), [&storeName, ¬ifiers](const auto &item) { + if (item.second.callBackStores_.count(storeName) != 0) { + notifiers.push_back(item.second.notifier_); + } + }); return true; }); - if (notifier == nullptr) { + if (notifiers.empty()) { return nullptr; } - return [notifier, storeName](const GenDetails& details) { - if (notifier != nullptr) { - notifier->OnComplete(storeName, HandleGenDetails(details)); + return [notifiers, storeName](const GenDetails &details) { + for (const auto ¬ifier : notifiers) { + if (notifier != nullptr) { + notifier->OnComplete(storeName, HandleGenDetails(details)); + } } }; } @@ -374,7 +401,10 @@ std::pair> RdbServiceImpl::R } RdbQuery rdbQuery; rdbQuery.MakeRemoteQuery(DmAdapter::GetInstance().ToUUID(device), sql, ValueProxy::Convert(selectionArgs)); - auto cursor = store->Query("", rdbQuery); + auto [errCode, cursor] = store->Query("", rdbQuery); + if (errCode != GeneralError::E_OK) { + return { RDB_ERROR, nullptr }; + } return { RDB_OK, std::make_shared(cursor) }; } @@ -405,33 +435,71 @@ int RdbServiceImpl::DoSync(const RdbSyncerParam ¶m, const RdbService::Option rdbQuery.MakeQuery(predicates); auto devices = rdbQuery.GetDevices().empty() ? DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices()) : DmAdapter::ToUUID(rdbQuery.GetDevices()); - if (!option.isAsync) { - SyncParam syncParam = { option.mode, 1, option.isCompensation }; - Details details = {}; - auto status = store->Sync( - devices, rdbQuery, - [&details, ¶m](const GenDetails &result) mutable { - ZLOGD("Sync complete, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(), - Anonymous::Change(param.storeName_).c_str()); - details = HandleGenDetails(result); + auto pid = IPCSkeleton::GetCallingPid(); + SyncParam syncParam = { option.mode, 0, option.isCompensation }; + StoreMetaData meta = GetStoreMetaData(param); + auto tokenId = IPCSkeleton::GetCallingTokenID(); + ZLOGD("seqNum=%{public}u", option.seqNum); + auto complete = [this, rdbQuery, store, pid, syncParam, tokenId, async, seq = option.seqNum]( + const auto &results) mutable { + auto ret = ProcessResult(results); + store->Sync( + ret.first, rdbQuery, + [this, tokenId, seq, pid](const GenDetails &result) mutable { + OnAsyncComplete(tokenId, pid, seq, HandleGenDetails(result)); }, syncParam); - if (async != nullptr) { - async(std::move(details)); - } - return status; + }; + if (IsNeedMetaSync(meta, devices)) { + auto result = MetaDataManager::GetInstance().Sync(devices, complete); + return result ? GeneralError::E_OK : GeneralError::E_ERROR; } - ZLOGD("seqNum=%{public}u", option.seqNum); - auto tokenId = IPCSkeleton::GetCallingTokenID(); - SyncParam syncParam = { option.mode, 0, option.isCompensation }; return store->Sync( devices, rdbQuery, - [this, tokenId, seqNum = option.seqNum](const GenDetails &result) mutable { - OnAsyncComplete(tokenId, seqNum, HandleGenDetails(result)); + [this, tokenId, pid, seqNum = option.seqNum](const GenDetails &result) mutable { + OnAsyncComplete(tokenId, pid, seqNum, HandleGenDetails(result)); }, syncParam); } +bool RdbServiceImpl::IsNeedMetaSync(const StoreMetaData &meta, const std::vector &uuids) +{ + bool isAfterMeta = false; + for (const auto &uuid : uuids) { + auto metaData = meta; + metaData.deviceId = uuid; + CapMetaData capMeta; + auto capKey = CapMetaRow::GetKeyFor(uuid); + if (!MetaDataManager::GetInstance().LoadMeta(std::string(capKey.begin(), capKey.end()), capMeta) || + !MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData)) { + isAfterMeta = true; + break; + } + auto [exist, mask] = DeviceMatrix::GetInstance().GetRemoteMask(uuid); + if ((mask & DeviceMatrix::META_STORE_MASK) == DeviceMatrix::META_STORE_MASK) { + isAfterMeta = true; + break; + } + } + return isAfterMeta; +} + +RdbServiceImpl::SyncResult RdbServiceImpl::ProcessResult(const std::map &results) +{ + std::map dbResults; + std::vector devices; + for (const auto &[uuid, status] : results) { + dbResults.insert_or_assign(uuid, static_cast(status)); + if (static_cast(status) != DBStatus::OK) { + continue; + } + DeviceMatrix::GetInstance().OnExchanged(uuid, DeviceMatrix::META_STORE_MASK); + devices.emplace_back(uuid); + } + ZLOGD("meta sync finish, total size:%{public}zu, success size:%{public}zu", dbResults.size(), devices.size()); + return { devices, dbResults }; +} + void RdbServiceImpl::DoCompensateSync(const BindEvent& event) { auto bindInfo = event.GetBindInfo(); @@ -471,9 +539,10 @@ void RdbServiceImpl::DoCloudSync(const RdbSyncerParam ¶m, const RdbService:: query = std::make_shared(); query->MakeCloudQuery(predicates); } - GenAsync asyncCallback = [this, tokenId = storeInfo.tokenId, seqNum = option.seqNum]( + auto pid = IPCSkeleton::GetCallingPid(); + GenAsync asyncCallback = [this, tokenId = storeInfo.tokenId, seqNum = option.seqNum, pid]( const GenDetails &result) mutable { - OnAsyncComplete(tokenId, seqNum, HandleGenDetails(result)); + OnAsyncComplete(tokenId, pid, seqNum, HandleGenDetails(result)); }; GenAsync syncCallback = [async, ¶m](const GenDetails &details) { ZLOGD("Cloud Sync complete, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(), @@ -484,7 +553,7 @@ void RdbServiceImpl::DoCloudSync(const RdbSyncerParam ¶m, const RdbService:: }; auto mixMode = static_cast(GeneralStore::MixMode(option.mode, option.isAutoSync ? GeneralStore::AUTO_SYNC_MODE : GeneralStore::MANUAL_SYNC_MODE)); - SyncParam syncParam = { mixMode, (option.isAsync ? 0 : static_cast(WAIT_TIME)), option.isCompensation }; + SyncParam syncParam = { mixMode, (option.isAsync ? 0 : WAIT_TIME), option.isCompensation }; auto info = ChangeEvent::EventInfo(syncParam, option.isAutoSync, query, option.isAutoSync ? nullptr : option.isAsync ? asyncCallback @@ -503,15 +572,16 @@ int32_t RdbServiceImpl::Subscribe(const RdbSyncerParam ¶m, const SubscribeOp pid_t pid = IPCSkeleton::GetCallingPid(); auto tokenId = IPCSkeleton::GetCallingTokenID(); bool isCreate = false; - syncAgents_.Compute(tokenId, [pid, ¶m, &isCreate](auto &key, SyncAgent &agent) { - if (pid != agent.pid_) { - agent.ReInit(pid, param.bundleName_); + syncAgents_.Compute(tokenId, [pid, ¶m, &isCreate](auto &key, SyncAgents &agents) { + auto [it, _] = agents.try_emplace(pid, param.bundleName_); + if (it == agents.end()) { + return !agents.empty(); } - if (agent.watcher_ == nullptr) { + if (it->second.watcher_ == nullptr) { isCreate = true; - agent.SetWatcher(std::make_shared()); + it->second.SetWatcher(std::make_shared()); } - agent.count_++; + it->second.count_++; return true; }); if (isCreate) { @@ -530,13 +600,16 @@ int32_t RdbServiceImpl::UnSubscribe(const RdbSyncerParam ¶m, const Subscribe } bool destroyed = false; auto tokenId = IPCSkeleton::GetCallingTokenID(); - syncAgents_.ComputeIfPresent(tokenId, [&destroyed](auto &key, SyncAgent &agent) { - if (agent.count_ > 0) { - agent.count_--; + auto pid = IPCSkeleton::GetCallingPid(); + syncAgents_.ComputeIfPresent(tokenId, [pid, &destroyed](auto, SyncAgents &agents) { + auto it = agents.find(pid); + if (it == agents.end()) { + return !agents.empty(); } - if (agent.count_ == 0) { + it->second.count_--; + if (it->second.count_ <= 0) { destroyed = true; - agent.SetWatcher(nullptr); + it->second.SetWatcher(nullptr); } return true; }); @@ -553,25 +626,17 @@ int32_t RdbServiceImpl::RegisterAutoSyncCallback(const RdbSyncerParam& param, pid_t pid = IPCSkeleton::GetCallingPid(); auto tokenId = IPCSkeleton::GetCallingTokenID(); auto storeName = RemoveSuffix(param.storeName_); - bool isCreate = false; - syncAgents_.Compute(tokenId, [pid, ¶m, &storeName, &isCreate](auto, SyncAgent& agent) { - if (pid != agent.pid_) { - agent.ReInit(pid, param.bundleName_); + syncAgents_.Compute(tokenId, [pid, ¶m, &storeName](auto, SyncAgents &agents) { + auto [it, success] = agents.try_emplace(pid, param.bundleName_); + if (it == agents.end()) { + return !agents.empty(); } - auto it = agent.callBackStores_.find(storeName); - if (it == agent.callBackStores_.end()) { - agent.callBackStores_.insert(std::make_pair(storeName, 0)); - isCreate = true; + if (success) { + it->second.callBackStores_.insert(std::make_pair(storeName, 0)); } - agent.callBackStores_[storeName]++; + it->second.callBackStores_[storeName]++; return true; }); - if (isCreate) { - auto stores = AutoCache::GetInstance().GetStoresIfPresent(tokenId, storeName); - if (!stores.empty() && *stores.begin() != nullptr) { - (*stores.begin())->RegisterDetailProgressObserver(GetCallbacks(tokenId, storeName)); - } - } return RDB_OK; } @@ -579,26 +644,23 @@ int32_t RdbServiceImpl::UnregisterAutoSyncCallback(const RdbSyncerParam& param, std::shared_ptr observer) { auto tokenId = IPCSkeleton::GetCallingTokenID(); + auto pid = IPCSkeleton::GetCallingPid(); auto storeName = RemoveSuffix(param.storeName_); - bool destroyed = false; - syncAgents_.ComputeIfPresent(tokenId, [&storeName, &destroyed](auto, SyncAgent& agent) { - auto it = agent.callBackStores_.find(storeName); - if (it == agent.callBackStores_.end()) { - return true; + syncAgents_.ComputeIfPresent(tokenId, [pid, &storeName](auto, SyncAgents &agents) { + auto agent = agents.find(pid); + if (agent == agents.end()) { + return !agents.empty(); + } + auto it = agent->second.callBackStores_.find(storeName); + if (it == agent->second.callBackStores_.end()) { + return !agents.empty(); } it->second--; if (it->second <= 0) { - agent.callBackStores_.erase(it); - destroyed = true; + agent->second.callBackStores_.erase(it); } - return true; + return !agents.empty(); }); - if (destroyed) { - auto stores = AutoCache::GetInstance().GetStoresIfPresent(tokenId, storeName); - if (!stores.empty() && *stores.begin() != nullptr) { - (*stores.begin())->UnregisterDetailProgressObserver(); - } - } return RDB_OK; } @@ -688,6 +750,7 @@ void RdbServiceImpl::SetReturnParam(StoreMetaData &metadata, RdbSyncerParam &par param.isEncrypt_ = metadata.isEncrypt; param.isAutoClean_ = !metadata.isManualClean; param.isSearchable_ = metadata.isSearchable; + param.haMode_ = metadata.haMode; } int32_t RdbServiceImpl::AfterOpen(const RdbSyncerParam ¶m) @@ -782,6 +845,7 @@ StoreMetaData RdbServiceImpl::GetStoreMetaData(const RdbSyncerParam ¶m) metaData.isEncrypt = param.isEncrypt_; metaData.isManualClean = !param.isAutoClean_; metaData.isSearchable = param.isSearchable_; + metaData.haMode = param.haMode_; return metaData; } @@ -828,7 +892,7 @@ Details RdbServiceImpl::HandleGenDetails(const GenDetails &details) return dbDetails; } -bool RdbServiceImpl::GetPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password) +bool RdbServiceImpl::GetDBPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password) { if (!metaData.isEncrypt) { return true; @@ -881,18 +945,6 @@ int32_t RdbServiceImpl::OnBind(const BindInfo &bindInfo) return 0; } -void RdbServiceImpl::SyncAgent::ReInit(pid_t pid, const std::string &bundleName) -{ - pid_ = pid; - count_ = 0; - callBackStores_.clear(); - bundleName_ = bundleName; - notifier_ = nullptr; - if (watcher_ != nullptr) { - watcher_->SetNotifier(nullptr); - } -} - void RdbServiceImpl::SyncAgent::SetNotifier(sptr notifier) { notifier_ = notifier; @@ -911,6 +963,14 @@ void RdbServiceImpl::SyncAgent::SetWatcher(std::shared_ptr watcher) } } +RdbServiceImpl::SyncAgent::SyncAgent(const std::string &bundleName) : bundleName_(bundleName) +{ + notifier_ = nullptr; + watcher_ = nullptr; + count_ = 0; + callBackStores_.clear(); +} + int32_t RdbServiceImpl::RdbStatic::CloseStore(const std::string &bundleName, int32_t user, int32_t index, int32_t tokenId) const { @@ -990,7 +1050,8 @@ RdbServiceImpl::~RdbServiceImpl() DumpManager::GetInstance().RemoveHandler("FEATURE_INFO", uintptr_t(this)); } -int32_t RdbServiceImpl::NotifyDataChange(const RdbSyncerParam ¶m, const RdbChangedData &rdbChangedData) +int32_t RdbServiceImpl::NotifyDataChange(const RdbSyncerParam ¶m, const RdbChangedData &rdbChangedData, + const RdbNotifyConfig &rdbNotifyConfig) { XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); if (!CheckAccess(param.bundleName_, param.storeName_)) { @@ -1008,13 +1069,67 @@ int32_t RdbServiceImpl::NotifyDataChange(const RdbSyncerParam ¶m, const RdbC storeInfo.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; DataChangeEvent::EventInfo eventInfo; + eventInfo.isFull = rdbNotifyConfig.isFull_; for (const auto& [key, value] : rdbChangedData.tableData) { DataChangeEvent::TableChangeProperties tableChangeProperties = {value.isTrackedDataChange}; eventInfo.tableProperties.insert_or_assign(key, std::move(tableChangeProperties)); } - auto evt = std::make_unique(std::move(storeInfo), std::move(eventInfo)); + bool postImmediately = false; + heartbeatTaskIds_.Compute(param.storeName_, [this, &postImmediately, &rdbNotifyConfig, &storeInfo, &eventInfo] + (const std::string &key, ExecutorPool::TaskId &value) { + if (rdbNotifyConfig.delay_ == 0) { + if (value != ExecutorPool::INVALID_TASK_ID && executors_ != nullptr) { + executors_->Remove(value); + } + postImmediately = true; + return false; + } + + if (executors_ != nullptr) { + auto task = [storeInfoInner = storeInfo, eventInfoInner = eventInfo]() { + auto evt = std::make_unique(std::move(storeInfoInner), std::move(eventInfoInner)); + EventCenter::GetInstance().PostEvent(std::move(evt)); + }; + if (value == ExecutorPool::INVALID_TASK_ID) { + value = executors_->Schedule(std::chrono::milliseconds(rdbNotifyConfig.delay_), task); + } else { + value = executors_->Reset(value, std::chrono::milliseconds(rdbNotifyConfig.delay_)); + } + } + return true; + }); + + if (postImmediately) { + auto evt = std::make_unique(std::move(storeInfo), std::move(eventInfo)); + EventCenter::GetInstance().PostEvent(std::move(evt)); + } + + return RDB_OK; +} + +int32_t RdbServiceImpl::SetSearchable(const RdbSyncerParam& param, bool isSearchable) +{ + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); + if (!CheckAccess(param.bundleName_, param.storeName_)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_ERROR; + } + StoreInfo storeInfo; + storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); + storeInfo.bundleName = param.bundleName_; + storeInfo.storeName = RemoveSuffix(param.storeName_); + auto [instanceId, user]= GetInstIndexAndUser(storeInfo.tokenId, param.bundleName_); + storeInfo.instanceId = instanceId; + storeInfo.user = user; + storeInfo.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + + SetSearchableEvent::EventInfo eventInfo; + eventInfo.isSearchable = isSearchable; + auto evt = std::make_unique(std::move(storeInfo), std::move(eventInfo)); EventCenter::GetInstance().PostEvent(std::move(evt)); + return RDB_OK; } @@ -1023,13 +1138,91 @@ int32_t RdbServiceImpl::Disable(const RdbSyncerParam& param) auto tokenId = IPCSkeleton::GetCallingTokenID(); auto storeId = RemoveSuffix(param.storeName_); AutoCache::GetInstance().Disable(tokenId, storeId); - return E_OK; + return RDB_OK; } + int32_t RdbServiceImpl::Enable(const RdbSyncerParam& param) { auto tokenId = IPCSkeleton::GetCallingTokenID(); auto storeId = RemoveSuffix(param.storeName_); AutoCache::GetInstance().Enable(tokenId, storeId); - return E_OK; + return RDB_OK; +} + +int32_t RdbServiceImpl::GetPassword(const RdbSyncerParam ¶m, std::vector &password) +{ + if (!CheckAccess(param.bundleName_, param.storeName_)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_ERROR; + } + auto meta = GetStoreMetaData(param); + SecretKeyMetaData secretKey; + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetSecretKey(), secretKey, true)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. no meta", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_NO_META; + } + + if (!CryptoManager::GetInstance().Decrypt(secretKey.sKey, password)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. decrypt err", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return RDB_ERROR; + } + return RDB_OK; +} + +StoreInfo RdbServiceImpl::GetStoreInfo(const RdbSyncerParam ¶m) +{ + StoreInfo storeInfo; + storeInfo.bundleName = param.bundleName_; + storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); + storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(storeInfo.tokenId); + storeInfo.storeName = RemoveSuffix(param.storeName_); + return storeInfo; +} + +std::pair RdbServiceImpl::LockCloudContainer(const RdbSyncerParam ¶m) +{ + std::pair result { RDB_ERROR, 0 }; + if (!CheckAccess(param.bundleName_, param.storeName_)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return result; + } + ZLOGI("start to lock cloud db: bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + + auto storeInfo = GetStoreInfo(param); + + CloudLockEvent::Callback callback = [&result](int32_t status, uint32_t expiredTime) { + result.first = status; + result.second = expiredTime; + }; + auto evt = std::make_unique(CloudEvent::LOCK_CLOUD_CONTAINER, std::move(storeInfo), callback); + EventCenter::GetInstance().PostEvent(std::move(evt)); + return result; +} + +int32_t RdbServiceImpl::UnlockCloudContainer(const RdbSyncerParam ¶m) +{ + int32_t result = RDB_ERROR; + if (!CheckAccess(param.bundleName_, param.storeName_)) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return result; + } + ZLOGI("start to unlock cloud db: bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + + auto storeInfo = GetStoreInfo(param); + + CloudLockEvent::Callback callback = [&result](int32_t status, uint32_t expiredTime) { + (void)expiredTime; + result = status; + }; + auto evt = std::make_unique(CloudEvent::UNLOCK_CLOUD_CONTAINER, std::move(storeInfo), callback); + EventCenter::GetInstance().PostEvent(std::move(evt)); + return result; } } // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h index 344bf3bf..c110a4d7 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h @@ -85,7 +85,9 @@ public: int32_t OnInitialize() override; - int32_t NotifyDataChange(const RdbSyncerParam ¶m, const RdbChangedData &rdbChangedData) override; + int32_t NotifyDataChange(const RdbSyncerParam ¶m, const RdbChangedData &rdbChangedData, + const RdbNotifyConfig &rdbNotifyConfig) override; + int32_t SetSearchable(const RdbSyncerParam& param, bool isSearchable) override; int32_t Disable(const RdbSyncerParam& param) override; int32_t Enable(const RdbSyncerParam& param) override; @@ -93,20 +95,29 @@ public: int32_t AfterOpen(const RdbSyncerParam ¶m) override; + int32_t GetPassword(const RdbSyncerParam ¶m, std::vector &password) override; + + std::pair LockCloudContainer(const RdbSyncerParam ¶m) override; + + int32_t UnlockCloudContainer(const RdbSyncerParam ¶m) override; + private: using Watchers = DistributedData::AutoCache::Watchers; using StaticActs = DistributedData::StaticActs; + using DBStatus = DistributedDB::DBStatus; + using SyncResult = std::pair, std::map>; struct SyncAgent { - pid_t pid_ = 0; + SyncAgent() = default; + explicit SyncAgent(const std::string &bundleName); int32_t count_ = 0; std::map callBackStores_; std::string bundleName_; sptr notifier_ = nullptr; std::shared_ptr watcher_ = nullptr; - void ReInit(pid_t pid, const std::string &bundleName); void SetNotifier(sptr notifier); void SetWatcher(std::shared_ptr watcher); }; + using SyncAgents = std::map; class RdbStatic : public StaticActs { public: @@ -154,7 +165,7 @@ private: std::shared_ptr GetStore(const RdbSyncerParam& param); - void OnAsyncComplete(uint32_t tokenId, uint32_t seqNum, Details &&result); + void OnAsyncComplete(uint32_t tokenId, pid_t pid, uint32_t seqNum, Details &&result); StoreMetaData GetStoreMetaData(const RdbSyncerParam ¶m); @@ -173,15 +184,22 @@ private: static std::pair GetInstIndexAndUser(uint32_t tokenId, const std::string &bundleName); - static bool GetPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password); + static bool GetDBPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password); void GetCloudSchema(const RdbSyncerParam ¶m); void SetReturnParam(StoreMetaData &metadata, RdbSyncerParam ¶m); + bool IsNeedMetaSync(const StoreMetaData &meta, const std::vector &uuids); + + SyncResult ProcessResult(const std::map &results); + + StoreInfo GetStoreInfo(const RdbSyncerParam ¶m); + static Factory factory_; - ConcurrentMap syncAgents_; + ConcurrentMap syncAgents_; std::shared_ptr executors_; + ConcurrentMap heartbeatTaskIds_; }; } // namespace OHOS::DistributedRdb #endif \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp index 49274e87..a6736520 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp @@ -284,13 +284,32 @@ int32_t RdbServiceStub::OnRemoteNotifyDataChange(MessageParcel &data, MessagePar { RdbSyncerParam param; RdbChangedData rdbChangedData; - if (!ITypesUtil::Unmarshal(data, param, rdbChangedData)) { + RdbNotifyConfig rdbNotifyConfig; + if (!ITypesUtil::Unmarshal(data, param, rdbChangedData, rdbNotifyConfig)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s ", param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str()); return IPC_STUB_INVALID_DATA_ERR; } - auto status = NotifyDataChange(param, rdbChangedData); + auto status = NotifyDataChange(param, rdbChangedData, rdbNotifyConfig); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return RDB_OK; +} + +int32_t RdbServiceStub::OnRemoteSetSearchable(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + bool isSearchable = true; + if (!ITypesUtil::Unmarshal(data, param, isSearchable)) { + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s ", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + + auto status = SetSearchable(param, isSearchable); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x", status); return IPC_STUB_WRITE_PARCEL_ERR; @@ -351,4 +370,53 @@ int32_t RdbServiceStub::OnEnable(MessageParcel& data, MessageParcel& reply) } return RDB_OK; } + +int32_t RdbServiceStub::OnGetPassword(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + if (!ITypesUtil::Unmarshal(data, param)) { + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + + std::vector key; + auto status = GetPassword(param, key); + if (!ITypesUtil::Marshal(reply, status, key)) { + key.assign(key.size(), 0); + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + key.assign(key.size(), 0); + return RDB_OK; +} + +int32_t RdbServiceStub::OnLockCloudContainer(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + uint32_t expiredTime = 0; + if (!ITypesUtil::Unmarshal(data, param, expiredTime)) { + ZLOGE("Unmarshal failed"); + return IPC_STUB_INVALID_DATA_ERR; + } + + auto result = LockCloudContainer(param); + return ITypesUtil::Marshal(reply, result.first, result.second) ? RDB_OK : IPC_STUB_WRITE_PARCEL_ERR; +} + +int32_t RdbServiceStub::OnUnlockCloudContainer(MessageParcel &data, MessageParcel &reply) +{ + RdbSyncerParam param; + if (!ITypesUtil::Unmarshal(data, param)) { + ZLOGE("Unmarshal failed"); + return IPC_STUB_INVALID_DATA_ERR; + } + + auto status = UnlockCloudContainer(param); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x", status); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return RDB_OK; +} } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.h index eef8b94d..a8ac6b9b 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.h @@ -56,6 +56,8 @@ private: int32_t OnRemoteNotifyDataChange(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteSetSearchable(MessageParcel& data, MessageParcel& reply); + int32_t OnRemoteQuerySharingResource(MessageParcel& data, MessageParcel& reply); int32_t OnBeforeOpen(MessageParcel& data, MessageParcel& reply); @@ -65,6 +67,12 @@ private: int32_t OnDisable(MessageParcel& data, MessageParcel& reply); int32_t OnEnable(MessageParcel& data, MessageParcel& reply); + + int32_t OnGetPassword(MessageParcel& data, MessageParcel& reply); + + int32_t OnLockCloudContainer(MessageParcel& data, MessageParcel& reply); + + int32_t OnUnlockCloudContainer(MessageParcel& data, MessageParcel& reply); using RequestHandle = int (RdbServiceStub::*)(MessageParcel &, MessageParcel &); static constexpr RequestHandle HANDLERS[static_cast(RdbServiceCode::RDB_SERVICE_CMD_MAX)] = { @@ -85,12 +93,19 @@ private: &RdbServiceStub::OnRemoteUnregisterDetailProgressObserver, [static_cast(RdbServiceCode::RDB_SERVICE_CMD_NOTIFY_DATA_CHANGE)] = &RdbServiceStub::OnRemoteNotifyDataChange, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_SET_SEARCHABLE)] = + &RdbServiceStub::OnRemoteSetSearchable, [static_cast(RdbServiceCode::RDB_SERVICE_CMD_QUERY_SHARING_RESOURCE)] = &RdbServiceStub::OnRemoteQuerySharingResource, [static_cast(RdbServiceCode::RDB_SERVICE_CMD_DISABLE)] = &RdbServiceStub::OnDisable, [static_cast(RdbServiceCode::RDB_SERVICE_CMD_ENABLE)] = &RdbServiceStub::OnEnable, [static_cast(RdbServiceCode::RDB_SERVICE_CMD_BEFORE_OPEN)] = &RdbServiceStub::OnBeforeOpen, - [static_cast(RdbServiceCode::RDB_SERVICE_CMD_AFTER_OPEN)] = &RdbServiceStub::OnAfterOpen + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_AFTER_OPEN)] = &RdbServiceStub::OnAfterOpen, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_GET_PASSWORD)] = &RdbServiceStub::OnGetPassword, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_LOCK_CLOUD_CONTAINER)] = + &RdbServiceStub::OnLockCloudContainer, + [static_cast(RdbServiceCode::RDB_SERVICE_CMD_UNLOCK_CLOUD_CONTAINER)] = + &RdbServiceStub::OnUnlockCloudContainer }; }; } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/test/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/BUILD.gn index 5aac474e..6e351661 100644 --- a/datamgr_service/services/distributeddataservice/service/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/BUILD.gn @@ -46,6 +46,8 @@ config("module_private_config") { "${data_service_path}/service/waterversion", "${dataobject_path}/interfaces/innerkits", "${dataobject_path}/frameworks/innerkitsimpl/include", + "${kv_store_distributeddb_path}/interfaces/include/", + "${kv_store_distributeddb_path}/include/", "${relational_store_path}/interfaces/inner_api/cloud_data/include", "${relational_store_path}/interfaces/inner_api/common_type/include", ] @@ -76,6 +78,7 @@ ohos_unittest("CloudDataTest") { "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/common/xcollie.cpp", "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/app_id_mapping_config.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", "${data_service_path}/service/config/src/model/cloud_config.cpp", @@ -129,6 +132,94 @@ ohos_unittest("CloudDataTest") { "mock:distributeddata_mock_static", "//third_party/googletest:gtest_main", ] + + cflags = [ + "-fno-access-control", # Ignore Private Member Access Control + ] + + cflags_cc = cflags +} + +ohos_unittest("CloudServiceImplTest") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + module_out_path = module_output_path + sources = [ + "${data_service_path}/service/backup/src/backup_manager.cpp", + "${data_service_path}/service/bootstrap/src/bootstrap.cpp", + "${data_service_path}/service/cloud/cloud_service_impl.cpp", + "${data_service_path}/service/cloud/cloud_service_stub.cpp", + "${data_service_path}/service/cloud/cloud_types_util.cpp", + "${data_service_path}/service/cloud/cloud_value_util.cpp", + "${data_service_path}/service/cloud/sync_manager.cpp", + "${data_service_path}/service/cloud/sync_strategies/network_sync_strategy.cpp", + "${data_service_path}/service/common/common_types_utils.cpp", + "${data_service_path}/service/common/value_proxy.cpp", + "${data_service_path}/service/common/xcollie.cpp", + "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/app_id_mapping_config.cpp", + "${data_service_path}/service/config/src/model/backup_config.cpp", + "${data_service_path}/service/config/src/model/checker_config.cpp", + "${data_service_path}/service/config/src/model/cloud_config.cpp", + "${data_service_path}/service/config/src/model/component_config.cpp", + "${data_service_path}/service/config/src/model/directory_config.cpp", + "${data_service_path}/service/config/src/model/global_config.cpp", + "${data_service_path}/service/config/src/model/network_config.cpp", + "${data_service_path}/service/config/src/model/protocol_config.cpp", + "${data_service_path}/service/crypto/src/crypto_manager.cpp", + "${data_service_path}/service/matrix/src/device_matrix.cpp", + "${data_service_path}/service/matrix/src/matrix_event.cpp", + "${data_service_path}/service/rdb/cache_cursor.cpp", + "${data_service_path}/service/rdb/rdb_asset_loader.cpp", + "${data_service_path}/service/rdb/rdb_cloud.cpp", + "${data_service_path}/service/rdb/rdb_cloud_data_translate.cpp", + "${data_service_path}/service/rdb/rdb_cursor.cpp", + "${data_service_path}/service/rdb/rdb_general_store.cpp", + "${data_service_path}/service/rdb/rdb_notifier_proxy.cpp", + "${data_service_path}/service/rdb/rdb_query.cpp", + "${data_service_path}/service/rdb/rdb_result_set_impl.cpp", + "${data_service_path}/service/rdb/rdb_result_set_stub.cpp", + "${data_service_path}/service/rdb/rdb_service_impl.cpp", + "${data_service_path}/service/rdb/rdb_service_stub.cpp", + "${data_service_path}/service/rdb/rdb_watcher.cpp", + "${data_service_path}/service/test/mock/checker_mock.cpp", + "${data_service_path}/service/waterversion/water_version_manager.cpp", + "cloud_service_impl_test.cpp", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "access_token:libaccesstoken_sdk", + "access_token:libtoken_setproc", + "access_token:libtokenid_sdk", + "c_utils:utils", + "hicollie:libhicollie", + "hilog:libhilog", + "huks:libhukssdk", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "kv_store:distributeddb", + "relational_store:native_rdb", + ] + + deps = [ + "../../adapter:distributeddata_adapter", + "../../framework:distributeddatasvcfwk", + "mock:distributeddata_mock_static", + "//third_party/googletest:gtest_main", + ] + + cflags = [ + "-fno-access-control", # Ignore Private Member Access Control + ] + + cflags_cc = cflags } ohos_unittest("CloudTest") { @@ -156,7 +247,7 @@ ohos_unittest("CloudTest") { ] } -ohos_unittest("ValueProxyTest") { +ohos_unittest("ValueProxyServiceTest") { module_out_path = module_output_path sources = [ "../common/value_proxy.cpp", @@ -170,6 +261,13 @@ ohos_unittest("ValueProxyTest") { configs = [ ":module_private_config" ] + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + "-Wno-multichar", + "-Wno-c99-designator", + ] + external_deps = [ "ability_base:base", "ability_base:want", @@ -294,45 +392,6 @@ ohos_unittest("DeviceMatrixTest") { ] } -ohos_unittest("AutoSyncMatrixTest") { - module_out_path = module_output_path - sources = [ - "${data_service_path}/app/src/kvstore_meta_manager.cpp", - "auto_sync_matrix_test.cpp", - ] - - include_dirs = [ - "${data_service_path}/app/src", - "${data_service_path}/service/kvdb", - "${data_service_path}/adapter/include/account", - "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", - "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", - "${kv_store_path}/frameworks/innerkitsimpl/distributeddatasvc/include", - ] - - configs = [ ":module_private_config" ] - - external_deps = [ - "access_token:libaccesstoken_sdk", - "access_token:libnativetoken", - "access_token:libtoken_setproc", - "c_utils:utils", - "dataclassification:data_transit_mgr", - "hilog:libhilog", - "hisysevent:libhisysevent", - "ipc:ipc_core", - "kv_store:distributeddata_inner", - ] - - deps = [ - "${data_service_path}/adapter:distributeddata_adapter", - "${data_service_path}/framework:distributeddatasvcfwk", - "${data_service_path}/service:distributeddatasvc", - "${kv_store_distributeddb_path}:distributeddb", - "//third_party/googletest:gtest_main", - ] -} - ohos_unittest("KVDBGeneralStoreTest") { module_out_path = module_output_path sources = [ @@ -344,6 +403,8 @@ ohos_unittest("KVDBGeneralStoreTest") { "kvdb_general_store_test.cpp", "mock/db_change_data_mock.cpp", "mock/db_store_mock.cpp", + "mock/general_watcher_mock.cpp", + "mock/kv_store_nb_delegate_mock.cpp", ] include_dirs = [ @@ -357,6 +418,11 @@ ohos_unittest("KVDBGeneralStoreTest") { configs = [ ":module_private_config" ] + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] + external_deps = [ "ability_base:base", "ability_base:want", @@ -437,7 +503,9 @@ ohos_unittest("RdbServiceTest") { "${data_service_path}/service/rdb/rdb_query.cpp", "${data_service_path}/service/rdb/rdb_result_set_impl.cpp", "${data_service_path}/service/rdb/rdb_result_set_stub.cpp", + "${data_service_path}/service/rdb/rdb_watcher.cpp", "cache_cursor_test.cpp", + "mock/general_watcher_mock.cpp", "rdb_asset_loader_test.cpp", "rdb_cloud_test.cpp", "rdb_cursor_test.cpp", @@ -484,6 +552,46 @@ ohos_unittest("RdbServiceTest") { ] } +ohos_unittest("ObjectAssetLoaderTest") { + module_out_path = module_output_path + sources = [ + "../object/object_asset_loader.cpp", + "../object/object_asset_machine.cpp", + "../object/object_snapshot.cpp", + "object_asset_loader_test.cpp", + ] + + include_dirs = [ + "${dataobject_path}/frameworks/innerkitsimpl/include/common", + "${dataobject_path}/interfaces/innerkits", + "${relational_store_path}/interfaces/inner_api/common_type/include", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "dfs_service:cloudsync_asset_kit_inner", + "dfs_service:distributed_file_daemon_kit_inner", + "hilog:libhilog", + "hisysevent:libhisysevent", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "//third_party/googletest:gtest_main", + ] + + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] +} + ohos_unittest("ObjectAssetMachineTest") { module_out_path = module_output_path sources = [ @@ -518,6 +626,91 @@ ohos_unittest("ObjectAssetMachineTest") { ] } +ohos_unittest("ObjectManagerTest") { + module_out_path = module_output_path + sources = [ + "${data_service_path}/service/common/value_proxy.cpp", + "../object/object_asset_loader.cpp", + "../object/object_asset_machine.cpp", + "../object/object_callback_proxy.cpp", + "../object/object_data_listener.cpp", + "../object/object_manager.cpp", + "../object/object_snapshot.cpp", + "mock/kv_store_nb_delegate_mock.cpp", + "object_manager_test.cpp", + ] + + include_dirs = [ + "${dataobject_path}/frameworks/innerkitsimpl/include", + "${data_service_path}/service/common", + "${dataobject_path}/frameworks/innerkitsimpl/include/common", + "${dataobject_path}/interfaces/innerkits", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "c_utils:utils", + "dfs_service:cloudsync_asset_kit_inner", + "dfs_service:distributed_file_daemon_kit_inner", + "hilog:libhilog", + "hisysevent:libhisysevent", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "kv_store:distributeddb", + "relational_store:native_rdb", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "//third_party/googletest:gtest_main", + ] + + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] +} + +ohos_unittest("ObjectSnapshotTest") { + module_out_path = module_output_path + sources = [ + "../object/object_asset_loader.cpp", + "../object/object_asset_machine.cpp", + "../object/object_snapshot.cpp", + "object_snapshot_test.cpp", + ] + + include_dirs = [ + "${dataobject_path}/frameworks/innerkitsimpl/include/common", + "${dataobject_path}/interfaces/innerkits", + "${relational_store_path}/interfaces/inner_api/common_type/include", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "dfs_service:cloudsync_asset_kit_inner", + "dfs_service:distributed_file_daemon_kit_inner", + "hilog:libhilog", + "hisysevent:libhisysevent", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "//third_party/googletest:gtest_main", + ] +} + ohos_unittest("MetaDataTest") { module_out_path = module_output_path sources = [ @@ -623,6 +816,7 @@ ohos_unittest("WaterVersionManagerTest") { "${data_service_path}/service/backup/src/backup_manager.cpp", "${data_service_path}/service/bootstrap/src/bootstrap.cpp", "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/app_id_mapping_config.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", "${data_service_path}/service/config/src/model/cloud_config.cpp", @@ -804,7 +998,19 @@ ohos_unittest("KvdbServiceImplTest") { module_out_path = module_output_path sources = [ "${data_service_path}/app/src/kvstore_meta_manager.cpp", + "${data_service_path}/service/common/value_proxy.cpp", + "${data_service_path}/service/kvdb/auth_delegate.cpp", + "${data_service_path}/service/kvdb/kvdb_general_store.cpp", + "${data_service_path}/service/kvdb/kvdb_notifier_proxy.cpp", + "${data_service_path}/service/kvdb/kvdb_watcher.cpp", + "${data_service_path}/service/kvdb/query_helper.cpp", + "${data_service_path}/service/kvdb/upgrade.cpp", + "${data_service_path}/service/kvdb/user_delegate.cpp", + "${data_service_path}/service/rdb/rdb_cloud.cpp", + "${data_service_path}/service/rdb/rdb_query.cpp", + "${data_service_path}/service/waterversion/water_version_manager.cpp", "kvdb_service_impl_test.cpp", + "kvdb_service_test.cpp", ] include_dirs = [ @@ -818,16 +1024,23 @@ ohos_unittest("KvdbServiceImplTest") { configs = [ ":module_private_config" ] + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] + external_deps = [ "access_token:libaccesstoken_sdk", "access_token:libnativetoken", "access_token:libtoken_setproc", "c_utils:utils", "dataclassification:data_transit_mgr", + "device_auth:deviceauth_sdk", "hilog:libhilog", "hisysevent:libhisysevent", "ipc:ipc_core", "kv_store:distributeddata_inner", + "relational_store:native_rdb", ] deps = [ @@ -839,6 +1052,37 @@ ohos_unittest("KvdbServiceImplTest") { ] } +ohos_unittest("DumpHelperTest") { + module_out_path = module_output_path + sources = [ + "${data_service_path}/service/dumper/src/dump_helper.cpp", + "dump_helper_test.cpp", + ] + + include_dirs = [ "${data_service_path}/service/dumper/include" ] + + configs = [ ":module_private_config" ] + + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "kv_store:distributeddata_inner", + "kv_store:distributeddb", + "relational_store:native_rdb", + ] + + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "//third_party/googletest:gtest_main", + ] +} + ############################################################################### group("unittest") { testonly = true @@ -850,21 +1094,25 @@ group("unittest") { } deps += [ - ":AutoSyncMatrixTest", ":CloudDataTest", + ":CloudServiceImplTest", ":CloudTest", ":CryptoManagerTest", ":DataShareServiceImplTest", ":DeviceMatrixTest", ":DirectoryManagerTest", + ":DumpHelperTest", ":KVDBGeneralStoreTest", ":KvdbServiceImplTest", ":MetaDataTest", + ":ObjectAssetLoaderTest", ":ObjectAssetMachineTest", + ":ObjectManagerTest", + ":ObjectSnapshotTest", ":RdbResultSetImplTest", ":RdbServiceTest", ":UdmfRunTimeStoreTest", - ":ValueProxyTest", + ":ValueProxyServiceTest", ":WaterVersionManagerTest", ] } diff --git a/datamgr_service/services/distributeddataservice/service/test/auto_sync_matrix_test.cpp b/datamgr_service/services/distributeddataservice/service/test/auto_sync_matrix_test.cpp deleted file mode 100644 index adc50222..00000000 --- a/datamgr_service/services/distributeddataservice/service/test/auto_sync_matrix_test.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2024 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 "auto_sync_matrix.h" - -#include -#include "block_data.h" -#include "bootstrap.h" -#include "device_manager_adapter.h" -#include "eventcenter/event_center.h" -#include "executor_pool.h" -#include "feature/feature_system.h" -#include "gtest/gtest.h" -#include "ipc_skeleton.h" -#include "kvstore_meta_manager.h" -#include "matrix_event.h" -#include "metadata/meta_data_manager.h" -#include "metadata/store_meta_data.h" -#include "types.h" -using namespace testing::ext; -using namespace OHOS::DistributedData; -using DMAdapter = DeviceManagerAdapter; -using namespace DistributedDB; -namespace OHOS::Test { -namespace DistributedDataTest { -class AutoSyncMatrixTest : public testing::Test { -public: - static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(); - void TearDown(); - -protected: - static constexpr const char *TEST_DEVICE = "14a0a92a428005db27c40bad46bf145fede38ec37effe0347cd990fcb031f320"; - static constexpr const char *TEST_BUNDLE = "auto_sync_matrix_test"; - static constexpr const char *TEST_STORE = "auto_sync_matrix_store"; - static constexpr const char *TEST_USER = "0"; - void InitMetaData(); - - StoreMetaData metaData_; -}; - -void AutoSyncMatrixTest::SetUpTestCase(void) -{ - auto executors = std::make_shared(12, 5); - Bootstrap::GetInstance().LoadComponents(); - Bootstrap::GetInstance().LoadDirectory(); - Bootstrap::GetInstance().LoadCheckers(); - DMAdapter::GetInstance().Init(executors); - DistributedKv::KvStoreMetaManager::GetInstance().BindExecutor(executors); - DistributedKv::KvStoreMetaManager::GetInstance().InitMetaParameter(); - DistributedKv::KvStoreMetaManager::GetInstance().InitMetaListener(); - StoreMetaData meta; - meta.deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid; - meta.appId = TEST_BUNDLE; - meta.bundleName = TEST_BUNDLE; - meta.user = TEST_USER; - meta.area = DistributedKv::EL1; - meta.tokenId = IPCSkeleton::GetCallingTokenID(); - meta.instanceId = 0; - meta.isAutoSync = true; - meta.storeType = 1; - meta.storeId = "auto_sync_matrix_default_store"; - meta.dataType = 1; - MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta); - AutoSyncMatrix::GetInstance().Initialize(); -} - -void AutoSyncMatrixTest::TearDownTestCase(void) -{ -} - -void AutoSyncMatrixTest::SetUp() -{ - InitMetaData(); -} - -void AutoSyncMatrixTest::TearDown() -{ -} - -void AutoSyncMatrixTest::InitMetaData() -{ - metaData_.deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid; - metaData_.appId = TEST_BUNDLE; - metaData_.bundleName = TEST_BUNDLE; - metaData_.user = TEST_USER; - metaData_.area = DistributedKv::EL1; - metaData_.tokenId = IPCSkeleton::GetCallingTokenID(); - metaData_.instanceId = 0; - metaData_.isAutoSync = true; - metaData_.storeType = 1; - metaData_.storeId = TEST_STORE; - metaData_.dataType = 1; -} - -/** -* @tc.name: GetChangedStore -* @tc.desc: get changed store on init. -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ -HWTEST_F(AutoSyncMatrixTest, GetChangedStore, TestSize.Level0) -{ - auto metas = AutoSyncMatrix::GetInstance().GetChangedStore(""); - ASSERT_EQ(metas.size(), 0); - metas = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_EQ(metas.size(), 0); -} - -/** -* @tc.name: AutoSyncMatrixOnline -* @tc.desc: auto sync matrix online. -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ -HWTEST_F(AutoSyncMatrixTest, AutoSyncMatrixOnline, TestSize.Level0) -{ - AutoSyncMatrix::GetInstance().Online(""); - auto metas = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_EQ(metas.size(), 0); - AutoSyncMatrix::GetInstance().Online(TEST_DEVICE); - metas = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_GE(metas.size(), 0); - AutoSyncMatrix::GetInstance().Offline(TEST_DEVICE); - metas = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_EQ(metas.size(), 0); -} - -/** -* @tc.name: AutoSyncMatrixOffline -* @tc.desc: auto sync matrix offline. -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ -HWTEST_F(AutoSyncMatrixTest, AutoSyncMatrixOffline, TestSize.Level0) -{ - AutoSyncMatrix::GetInstance().Online(TEST_DEVICE); - auto before = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_GE(before.size(), 0); - MetaDataManager::GetInstance().SaveMeta(metaData_.GetKey(), metaData_); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - auto after = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_GE(after.size(), before.size()); - AutoSyncMatrix::GetInstance().Offline(TEST_DEVICE); - auto metas = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_EQ(metas.size(), 0); -} - -/** -* @tc.name: AutoSyncMatrixOnChanged -* @tc.desc: auto sync matrix on changed. -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ -HWTEST_F(AutoSyncMatrixTest, AutoSyncMatrixOnChanged, TestSize.Level0) -{ - AutoSyncMatrix::GetInstance().Online(TEST_DEVICE); - auto metas = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_GE(metas.size(), 0); - AutoSyncMatrix::GetInstance().OnChanged(metaData_); - metas = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_GE(metas.size(), 0); - AutoSyncMatrix::GetInstance().Offline(TEST_DEVICE); - metas = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_EQ(metas.size(), 0); -} - -/** -* @tc.name: AutoSyncMatrixOnExchanged -* @tc.desc: auto sync matrix on exchanged. -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ -HWTEST_F(AutoSyncMatrixTest, AutoSyncMatrixOnExchanged, TestSize.Level0) -{ - AutoSyncMatrix::GetInstance().Online(TEST_DEVICE); - auto metas1 = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_GE(metas1.size(), 0); - AutoSyncMatrix::GetInstance().OnExchanged(TEST_DEVICE, metaData_); - auto metas2 = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_EQ(metas2.size(), metas1.size() - 1); - AutoSyncMatrix::GetInstance().Offline(TEST_DEVICE); - AutoSyncMatrix::GetInstance().OnChanged(metaData_); - auto metas3 = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_EQ(metas3.size(), 0); - AutoSyncMatrix::GetInstance().Online(TEST_DEVICE); - auto metas4 = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_GE(metas4.size(), metas1.size()); -} - -/** -* @tc.name: AutoSyncMatrixDeleteMeta -* @tc.desc: auto sync matrix on delete Meta. -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ -HWTEST_F(AutoSyncMatrixTest, AutoSyncMatrixDeleteMeta, TestSize.Level0) -{ - AutoSyncMatrix::GetInstance().Online(TEST_DEVICE); - AutoSyncMatrix::GetInstance().OnChanged(metaData_); - auto metas1 = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_GE(metas1.size(), 0); - MetaDataManager::GetInstance().DelMeta(metaData_.GetKey()); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - auto metas2 = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); - ASSERT_GE(metas2.size(), metas1.size() -1); - for (auto meta : metas2) { - ASSERT_NE(metaData_.GetKey(), meta.GetKey()); - } -} -} // namespace DistributedDataTest -} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp b/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp index 010d9994..be76bb4d 100644 --- a/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp @@ -23,9 +23,13 @@ #include "cloud/change_event.h" #include "cloud/cloud_event.h" #include "cloud/cloud_server.h" +#include "cloud/cloud_share_event.h" +#include "cloud/make_query_event.h" #include "cloud/schema_meta.h" #include "cloud_service_impl.h" #include "cloud_types.h" +#include "cloud_types_util.h" +#include "cloud_value_util.h" #include "communicator/device_manager_adapter.h" #include "device_matrix.h" #include "eventcenter/event_center.h" @@ -51,7 +55,11 @@ using namespace OHOS::Security::AccessToken; using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; using Querykey = OHOS::CloudData::QueryKey; using CloudSyncInfo = OHOS::CloudData::CloudSyncInfo; - +using SharingCfm = OHOS::CloudData::SharingUtil::SharingCfm; +using Confirmation = OHOS::CloudData::Confirmation; +using CenterCode = OHOS::DistributedData::SharingCenter::SharingCode; +using Status = OHOS::CloudData::CloudService::Status; +using GenErr = OHOS::DistributedData::GeneralError; uint64_t g_selfTokenID = 0; void AllocHapToken(const HapPolicyParams &policy) @@ -75,6 +83,32 @@ static constexpr const char *TEST_CLOUD_STORE = "test_cloud_store"; static constexpr const char *TEST_CLOUD_ID = "test_cloud_id"; static constexpr const char *TEST_CLOUD_DATABASE_ALIAS_1 = "test_cloud_database_alias_1"; static constexpr const char *TEST_CLOUD_DATABASE_ALIAS_2 = "test_cloud_database_alias_2"; +static constexpr const char *PERMISSION_CLOUDDATA_CONFIG = "ohos.permission.CLOUDDATA_CONFIG"; +static constexpr const char *PERMISSION_GET_NETWORK_INFO = "ohos.permission.GET_NETWORK_INFO"; +static constexpr const char *PERMISSION_DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC"; +static constexpr const char *PERMISSION_ACCESS_SERVICE_DM = "ohos.permission.ACCESS_SERVICE_DM"; +PermissionDef GetPermissionDef(const std::string &permission) +{ + PermissionDef def = { .permissionName = permission, + .bundleName = "test_cloud_bundleName", + .grantMode = 1, + .availableLevel = APL_SYSTEM_BASIC, + .label = "label", + .labelId = 1, + .description = "test_cloud_bundleName", + .descriptionId = 1 }; + return def; +} + +PermissionStateFull GetPermissionStateFull(const std::string &permission) +{ + PermissionStateFull stateFull = { .permissionName = permission, + .isGeneral = true, + .resDeviceID = { "local" }, + .grantStatus = { PermissionState::PERMISSION_GRANTED }, + .grantFlags = { 1 } }; + return stateFull; +} class CloudDataTest : public testing::Test { public: static void SetUpTestCase(void); @@ -102,6 +136,7 @@ public: virtual ~CloudServerMock() = default; static constexpr uint64_t REMAINSPACE = 1000; static constexpr uint64_t TATALSPACE = 2000; + static constexpr int32_t INVALID_USER_ID = -1; }; CloudInfo CloudServerMock::GetServerInfo(int32_t userId, bool needSpaceInfo) @@ -125,6 +160,14 @@ CloudInfo CloudServerMock::GetServerInfo(int32_t userId, bool needSpaceInfo) std::pair CloudServerMock::GetAppSchema(int32_t userId, const std::string &bundleName) { + if (userId == INVALID_USER_ID) { + return { E_ERROR, CloudDataTest::schemaMeta_ }; + } + + if (bundleName.empty()) { + SchemaMeta schemaMeta; + return { E_OK, schemaMeta }; + } return { E_OK, CloudDataTest::schemaMeta_ }; } @@ -202,46 +245,29 @@ void CloudDataTest::SetUpTestCase(void) auto cloudServerMock = new CloudServerMock(); CloudServer::RegisterCloudInstance(cloudServerMock); - HapPolicyParams policy = { .apl = APL_SYSTEM_BASIC, .domain = "test.domain", - .permList = { - { - .permissionName = "ohos.permission.CLOUDDATA_CONFIG", - .bundleName = "test_cloud_bundleName", - .grantMode = 1, - .availableLevel = APL_SYSTEM_BASIC, - .label = "label", - .labelId = 1, - .description = "test_cloud_bundleName", - .descriptionId = 1 - } - }, - .permStateList = { - { - .permissionName = "ohos.permission.CLOUDDATA_CONFIG", - .isGeneral = true, - .resDeviceID = { "local" }, - .grantStatus = { PermissionState::PERMISSION_GRANTED }, - .grantFlags = { 1 } - } - } - }; + .permList = { GetPermissionDef(PERMISSION_CLOUDDATA_CONFIG), GetPermissionDef(PERMISSION_GET_NETWORK_INFO), + GetPermissionDef(PERMISSION_DISTRIBUTED_DATASYNC), GetPermissionDef(PERMISSION_ACCESS_SERVICE_DM) }, + .permStateList = { GetPermissionStateFull(PERMISSION_CLOUDDATA_CONFIG), + GetPermissionStateFull(PERMISSION_GET_NETWORK_INFO), + GetPermissionStateFull(PERMISSION_DISTRIBUTED_DATASYNC), + GetPermissionStateFull(PERMISSION_ACCESS_SERVICE_DM) } }; g_selfTokenID = GetSelfTokenID(); AllocHapToken(policy); - - InitCloudInfo(); - InitMetaData(); - InitSchemaMeta(); - size_t max = 12; size_t min = 5; auto executor = std::make_shared(max, min); cloudServiceImpl_->OnBind( { "CloudDataTest", static_cast(IPCSkeleton::GetSelfTokenID()), std::move(executor) }); - Bootstrap::GetInstance().LoadCheckers(); + auto dmExecutor = std::make_shared(max, min); + DeviceManagerAdapter::GetInstance().Init(dmExecutor); + InitCloudInfo(); + InitMetaData(); + InitSchemaMeta(); + DeviceManagerAdapter::GetInstance().SetNet(DeviceManagerAdapter::WIFI); } void CloudDataTest::TearDownTestCase() @@ -282,7 +308,8 @@ HWTEST_F(CloudDataTest, GetSchema, TestSize.Level0) StoreInfo storeInfo{ OHOS::IPCSkeleton::GetCallingTokenID(), TEST_CLOUD_BUNDLE, TEST_CLOUD_STORE, 0 }; auto event = std::make_unique(CloudEvent::GET_SCHEMA, storeInfo); EventCenter::GetInstance().PostEvent(std::move(event)); - ASSERT_FALSE(MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true)); + auto ret = MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true); + ASSERT_TRUE(ret); } /** @@ -455,17 +482,7 @@ HWTEST_F(CloudDataTest, QueryLastSyncInfo004, TestSize.Level0) ZLOGI("CloudDataTest QueryLastSyncInfo004 start"); auto ret = cloudServiceImpl_->DisableCloud(TEST_CLOUD_ID); EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); - - auto rdbServiceImpl = std::make_shared(); - DistributedRdb::RdbSyncerParam param; - param.bundleName_ = TEST_CLOUD_BUNDLE; - param.storeName_ = TEST_CLOUD_DATABASE_ALIAS_1; - DistributedRdb::RdbService::Option option; - option.mode = DistributedRdb::SyncMode::CLOUD_FIRST; - option.isAutoSync = true; - option.isAsync = false; - DistributedRdb::PredicatesMemo memo; - rdbServiceImpl->Sync(param, option, memo, nullptr); + cloudServiceImpl_->OnReady(DeviceManagerAdapter::CLOUD_DEVICE_UUID); sleep(1); @@ -487,23 +504,11 @@ HWTEST_F(CloudDataTest, QueryLastSyncInfo005, TestSize.Level0) ZLOGI("CloudDataTest QueryLastSyncInfo005 start"); std::map switches; switches.emplace(TEST_CLOUD_ID, true); - auto ret = cloudServiceImpl_->EnableCloud(TEST_CLOUD_ID, switches); - EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); - - ret = cloudServiceImpl_->ChangeAppSwitch(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, false); - EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); - - auto rdbServiceImpl = std::make_shared(); - DistributedRdb::RdbSyncerParam param; - param.bundleName_ = TEST_CLOUD_BUNDLE; - param.storeName_ = TEST_CLOUD_DATABASE_ALIAS_1; - DistributedRdb::RdbService::Option option; - option.mode = DistributedRdb::SyncMode::CLOUD_FIRST; - option.isAutoSync = true; - option.isAsync = false; - DistributedRdb::PredicatesMemo memo; - rdbServiceImpl->Sync(param, option, memo, nullptr); - + CloudInfo info; + MetaDataManager::GetInstance().LoadMeta(cloudInfo_.GetKey(), info, true); + info.apps[TEST_CLOUD_BUNDLE].cloudSwitch = false; + MetaDataManager::GetInstance().SaveMeta(info.GetKey(), info, true); + cloudServiceImpl_->OnReady(DeviceManagerAdapter::CLOUD_DEVICE_UUID); sleep(1); auto [status, result] = @@ -512,5 +517,1458 @@ HWTEST_F(CloudDataTest, QueryLastSyncInfo005, TestSize.Level0) EXPECT_TRUE(!result.empty()); EXPECT_TRUE(result[TEST_CLOUD_DATABASE_ALIAS_1].code = E_CLOUD_DISABLED); } + +/** +* @tc.name: QueryLastSyncInfo006 +* @tc.desc: The query last sync info interface failed when schema is invalid. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, QueryLastSyncInfo006, TestSize.Level0) +{ + ZLOGI("CloudDataTest QueryLastSyncInfo006 start"); + MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetSchemaKey(TEST_CLOUD_BUNDLE), true); + auto [status, result] = + cloudServiceImpl_->QueryLastSyncInfo(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, TEST_CLOUD_DATABASE_ALIAS_1); + EXPECT_EQ(status, CloudData::CloudService::ERROR); + EXPECT_TRUE(result.empty()); + SchemaMeta meta; + meta.bundleName = "test"; + MetaDataManager::GetInstance().SaveMeta(cloudInfo_.GetSchemaKey(TEST_CLOUD_BUNDLE), meta, true); + std::tie(status, result) = + cloudServiceImpl_->QueryLastSyncInfo(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, TEST_CLOUD_DATABASE_ALIAS_1); + EXPECT_EQ(status, CloudData::CloudService::SUCCESS); + EXPECT_TRUE(result.empty()); +} + +/** +* @tc.name: Share +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, Share001, TestSize.Level0) +{ + std::string sharingRes = ""; + CloudData::Participants participants{}; + CloudData::Results results; + auto ret = cloudServiceImpl_->Share(sharingRes, participants, results); + EXPECT_EQ(ret, CloudData::CloudService::NOT_SUPPORT); +} + +/** +* @tc.name: Unshare +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, Unshare001, TestSize.Level0) +{ + std::string sharingRes = ""; + CloudData::Participants participants{}; + CloudData::Results results; + auto ret = cloudServiceImpl_->Unshare(sharingRes, participants, results); + EXPECT_EQ(ret, CloudData::CloudService::NOT_SUPPORT); +} + +/** +* @tc.name: ChangePrivilege +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, ChangePrivilege001, TestSize.Level0) +{ + std::string sharingRes = ""; + CloudData::Participants participants{}; + CloudData::Results results; + auto ret = cloudServiceImpl_->ChangePrivilege(sharingRes, participants, results); + EXPECT_EQ(ret, CloudData::CloudService::NOT_SUPPORT); +} + +/** +* @tc.name: ChangeConfirmation +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, ChangeConfirmation001, TestSize.Level0) +{ + std::string sharingRes = ""; + int32_t confirmation = 0; + std::pair result; + auto ret = cloudServiceImpl_->ChangeConfirmation(sharingRes, confirmation, result); + EXPECT_EQ(ret, CloudData::CloudService::NOT_SUPPORT); +} + +/** +* @tc.name: ConfirmInvitation +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, ConfirmInvitation001, TestSize.Level0) +{ + std::string sharingRes = ""; + int32_t confirmation = 0; + std::tuple result; + auto ret = cloudServiceImpl_->ConfirmInvitation(sharingRes, confirmation, result); + EXPECT_EQ(ret, CloudData::CloudService::NOT_SUPPORT); +} + +/** +* @tc.name: Exit +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, Exit001, TestSize.Level0) +{ + std::string sharingRes = ""; + std::pair result; + auto ret = cloudServiceImpl_->Exit(sharingRes, result); + EXPECT_EQ(ret, CloudData::CloudService::NOT_SUPPORT); +} + +/** +* @tc.name: Query +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, Query001, TestSize.Level0) +{ + std::string sharingRes = ""; + CloudData::QueryResults result; + auto ret = cloudServiceImpl_->Query(sharingRes, result); + EXPECT_EQ(ret, CloudData::CloudService::NOT_SUPPORT); +} + +/** +* @tc.name: QueryByInvitation +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, QueryByInvitation001, TestSize.Level0) +{ + std::string invitation = ""; + CloudData::QueryResults result; + auto ret = cloudServiceImpl_->QueryByInvitation(invitation, result); + EXPECT_EQ(ret, CloudData::CloudService::NOT_SUPPORT); +} + +/** +* @tc.name: AllocResourceAndShare +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, AllocResourceAndShare001, TestSize.Level0) +{ + DistributedRdb::PredicatesMemo predicates; + predicates.tables_.push_back(TEST_CLOUD_BUNDLE); + std::vector columns; + CloudData::Participants participants; + auto [ret, _] = cloudServiceImpl_->AllocResourceAndShare(TEST_CLOUD_STORE, predicates, columns, participants); + EXPECT_EQ(ret, E_ERROR); + EventCenter::GetInstance().Subscribe(CloudEvent::MAKE_QUERY, [](const Event& event) { + auto& evt = static_cast(event); + auto callback = evt.GetCallback(); + if (!callback) { + return; + } + auto predicate = evt.GetPredicates(); + auto rdbQuery = std::make_shared(); + rdbQuery->MakeQuery(*predicate); + rdbQuery->SetColumns(evt.GetColumns()); + callback(rdbQuery); + }); + std::tie(ret, _) = cloudServiceImpl_->AllocResourceAndShare(TEST_CLOUD_STORE, predicates, columns, participants); + EXPECT_EQ(ret, E_ERROR); +} + +/** +* @tc.name: SetGlobalCloudStrategy +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, SetGlobalCloudStrategy001, TestSize.Level0) +{ + std::vector values; + values.push_back(CloudData::NetWorkStrategy::WIFI); + CloudData::Strategy strategy = CloudData::Strategy::STRATEGY_BUTT; + auto ret = cloudServiceImpl_->SetGlobalCloudStrategy(strategy, values); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + strategy = CloudData::Strategy::STRATEGY_NETWORK; + ret = cloudServiceImpl_->SetGlobalCloudStrategy(strategy, values); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: SetCloudStrategy +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, SetCloudStrategy001, TestSize.Level0) +{ + std::vector values; + values.push_back(CloudData::NetWorkStrategy::WIFI); + CloudData::Strategy strategy = CloudData::Strategy::STRATEGY_BUTT; + auto ret = cloudServiceImpl_->SetCloudStrategy(strategy, values); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + strategy = CloudData::Strategy::STRATEGY_NETWORK; + ret = cloudServiceImpl_->SetCloudStrategy(strategy, values); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: Clean +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, Clean001, TestSize.Level0) +{ + std::map actions; + actions.insert_or_assign(TEST_CLOUD_BUNDLE, CloudData::CloudService::Action::CLEAR_CLOUD_BUTT); + std::string id = "testId"; + std::string bundleName = "testBundleName"; + auto ret = cloudServiceImpl_->Clean(id, actions); + EXPECT_EQ(ret, CloudData::CloudService::ERROR); + ret = cloudServiceImpl_->Clean(TEST_CLOUD_ID, actions); + EXPECT_EQ(ret, CloudData::CloudService::ERROR); + actions.insert_or_assign(TEST_CLOUD_BUNDLE, CloudData::CloudService::Action::CLEAR_CLOUD_INFO); + actions.insert_or_assign(bundleName, CloudData::CloudService::Action::CLEAR_CLOUD_DATA_AND_INFO); + ret = cloudServiceImpl_->Clean(TEST_CLOUD_ID, actions); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: Clean +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, Clean002, TestSize.Level0) +{ + MetaDataManager::GetInstance().DelMeta(metaData_.GetKey(), true); + std::map actions; + actions.insert_or_assign(TEST_CLOUD_BUNDLE, CloudData::CloudService::Action::CLEAR_CLOUD_INFO); + auto ret = cloudServiceImpl_->Clean(TEST_CLOUD_ID, actions); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + StoreMetaDataLocal localMeta; + localMeta.isPublic = false; + MetaDataManager::GetInstance().SaveMeta(metaData_.GetKeyLocal(), localMeta, true); + ret = cloudServiceImpl_->Clean(TEST_CLOUD_ID, actions); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + localMeta.isPublic = true; + MetaDataManager::GetInstance().SaveMeta(metaData_.GetKeyLocal(), localMeta, true); + ret = cloudServiceImpl_->Clean(TEST_CLOUD_ID, actions); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + metaData_.user = "0"; + MetaDataManager::GetInstance().SaveMeta(metaData_.GetKey(), metaData_, true); + ret = cloudServiceImpl_->Clean(TEST_CLOUD_ID, actions); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + MetaDataManager::GetInstance().DelMeta(metaData_.GetKey(), true); + metaData_.user = std::to_string(DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(metaData_.tokenId)); + MetaDataManager::GetInstance().DelMeta(metaData_.GetKeyLocal(), true); +} + +/** +* @tc.name: NotifyDataChange +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, NotifyDataChange001, TestSize.Level0) +{ + auto ret = cloudServiceImpl_->NotifyDataChange(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: NotifyDataChange +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, NotifyDataChange002, TestSize.Level0) +{ + constexpr const int32_t invalidUserId = -1; + std::string extraData; + auto ret = cloudServiceImpl_->NotifyDataChange("", extraData, invalidUserId); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + ret = cloudServiceImpl_->NotifyDataChange(CloudData::DATA_CHANGE_EVENT_ID, extraData, invalidUserId); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + extraData = "{data:test}"; + ret = cloudServiceImpl_->NotifyDataChange(CloudData::DATA_CHANGE_EVENT_ID, extraData, invalidUserId); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + extraData = "{\"data\":\"{\\\"accountId\\\":\\\"id\\\",\\\"bundleName\\\":\\\"test_cloud_" + "bundleName\\\",\\\"containerName\\\":\\\"test_cloud_database_alias_1\\\", \\\"databaseScopes\\\": " + "\\\"[\\\\\\\"private\\\\\\\", " + "\\\\\\\"shared\\\\\\\"]\\\",\\\"recordTypes\\\":\\\"[\\\\\\\"test_cloud_table_alias\\\\\\\"]\\\"}\"}"; + ret = cloudServiceImpl_->NotifyDataChange(CloudData::DATA_CHANGE_EVENT_ID, extraData, invalidUserId); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + extraData = "{\"data\":\"{\\\"accountId\\\":\\\"test_cloud_id\\\",\\\"bundleName\\\":\\\"cloud_" + "bundleName_test\\\",\\\"containerName\\\":\\\"test_cloud_database_alias_1\\\", " + "\\\"databaseScopes\\\": " + "\\\"[\\\\\\\"private\\\\\\\", " + "\\\\\\\"shared\\\\\\\"]\\\",\\\"recordTypes\\\":\\\"[\\\\\\\"test_cloud_table_alias\\\\\\\"]\\\"}\"}"; + ret = cloudServiceImpl_->NotifyDataChange(CloudData::DATA_CHANGE_EVENT_ID, extraData, invalidUserId); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); +} + +/** +* @tc.name: NotifyDataChange +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, NotifyDataChange003, TestSize.Level0) +{ + constexpr const int32_t userId = 100; + constexpr const int32_t defaultUserId = 0; + std::string extraData = "{\"data\":\"{\\\"accountId\\\":\\\"test_cloud_id\\\",\\\"bundleName\\\":\\\"test_cloud_" + "bundleName\\\",\\\"containerName\\\":\\\"test_cloud_database_alias_1\\\", " + "\\\"databaseScopes\\\": " + "\\\"[\\\\\\\"private\\\\\\\", " + "\\\\\\\"shared\\\\\\\"]\\\",\\\"recordTypes\\\":\\\"[\\\\\\\"\\\\\\\"]\\\"}\"}"; + auto ret = cloudServiceImpl_->NotifyDataChange(CloudData::DATA_CHANGE_EVENT_ID, extraData, defaultUserId); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + extraData = "{\"data\":\"{\\\"accountId\\\":\\\"test_cloud_id\\\",\\\"bundleName\\\":\\\"test_cloud_" + "bundleName\\\",\\\"containerName\\\":\\\"test_cloud_database_alias_1\\\", \\\"databaseScopes\\\": " + "\\\"[\\\\\\\"private\\\\\\\", " + "\\\\\\\"shared\\\\\\\"]\\\",\\\"recordTypes\\\":\\\"[\\\\\\\"test_cloud_table_alias\\\\\\\"]\\\"}\"}"; + ret = cloudServiceImpl_->NotifyDataChange(CloudData::DATA_CHANGE_EVENT_ID, extraData, userId); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: OnReady +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnReady001, TestSize.Level0) +{ + std::string device = "test"; + auto ret = cloudServiceImpl_->OnReady(device); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + ret = cloudServiceImpl_->OnReady(DeviceManagerAdapter::CLOUD_DEVICE_UUID); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: Offline +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, Offline001, TestSize.Level0) +{ + std::string device = "test"; + auto ret = cloudServiceImpl_->Offline(device); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + ret = cloudServiceImpl_->Offline(DeviceManagerAdapter::CLOUD_DEVICE_UUID); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: CloudShare +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, CloudShare001, TestSize.Level0) +{ + ZLOGI("weisx CloudShare start"); + StoreInfo storeInfo{ OHOS::IPCSkeleton::GetCallingTokenID(), TEST_CLOUD_BUNDLE, TEST_CLOUD_STORE, 0 }; + std::pair> result; + CloudShareEvent::Callback asyncCallback = [&result](int32_t status, std::shared_ptr cursor) { + result.first = status; + result.second = cursor; + }; + auto event = std::make_unique(storeInfo, nullptr, nullptr); + EventCenter::GetInstance().PostEvent(std::move(event)); + auto event1 = std::make_unique(storeInfo, nullptr, asyncCallback); + EventCenter::GetInstance().PostEvent(std::move(event1)); + EXPECT_EQ(result.first, GeneralError::E_ERROR); + auto rdbQuery = std::make_shared(); + auto event2 = std::make_unique(storeInfo, rdbQuery, nullptr); + EventCenter::GetInstance().PostEvent(std::move(event2)); + auto event3 = std::make_unique(storeInfo, rdbQuery, asyncCallback); + EventCenter::GetInstance().PostEvent(std::move(event3)); + EXPECT_EQ(result.first, GeneralError::E_ERROR); +} + +/** +* @tc.name: OnUserChange +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnUserChange001, TestSize.Level0) +{ + constexpr const uint32_t ACCOUNT_DEFAULT = 2; + constexpr const uint32_t ACCOUNT_DELETE = 3; + constexpr const uint32_t ACCOUNT_SWITCHED = 4; + constexpr const uint32_t ACCOUNT_UNLOCKED = 5; + auto ret = cloudServiceImpl_->OnUserChange(ACCOUNT_DEFAULT, "0", "test"); + EXPECT_EQ(ret, GeneralError::E_OK); + ret = cloudServiceImpl_->OnUserChange(ACCOUNT_DELETE, "0", "test"); + EXPECT_EQ(ret, GeneralError::E_OK); + ret = cloudServiceImpl_->OnUserChange(ACCOUNT_SWITCHED, "0", "test"); + EXPECT_EQ(ret, GeneralError::E_OK); + ret = cloudServiceImpl_->OnUserChange(ACCOUNT_UNLOCKED, "0", "test"); + EXPECT_EQ(ret, GeneralError::E_OK); +} + +/** +* @tc.name: DisableCloud +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, DisableCloud001, TestSize.Level0) +{ + auto ret = cloudServiceImpl_->DisableCloud("test"); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + ret = cloudServiceImpl_->DisableCloud(TEST_CLOUD_ID); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: ChangeAppSwitch +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, ChangeAppSwitch, TestSize.Level0) +{ + std::string id = "testId"; + std::string bundleName = "testName"; + auto ret = cloudServiceImpl_->ChangeAppSwitch(id, bundleName, CloudData::CloudService::SWITCH_ON); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + ret = cloudServiceImpl_->ChangeAppSwitch(TEST_CLOUD_ID, bundleName, CloudData::CloudService::SWITCH_ON); + EXPECT_EQ(ret, CloudData::CloudService::INVALID_ARGUMENT); + ret = cloudServiceImpl_->ChangeAppSwitch(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, CloudData::CloudService::SWITCH_OFF); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: EnableCloud +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, EnableCloud, TestSize.Level0) +{ + std::string bundleName = "testName"; + std::map switches; + switches.insert_or_assign(TEST_CLOUD_BUNDLE, CloudData::CloudService::SWITCH_ON); + switches.insert_or_assign(bundleName, CloudData::CloudService::SWITCH_ON); + auto ret = cloudServiceImpl_->EnableCloud(TEST_CLOUD_ID, switches); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); +} + +/** +* @tc.name: OnEnableCloud +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnEnableCloud, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_ENABLE_CLOUD, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string id = "testId"; + std::map switches; + ITypesUtil::Marshal(data, id, switches); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_ENABLE_CLOUD, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnDisableCloud +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnDisableCloud, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_DISABLE_CLOUD, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + data.WriteString(TEST_CLOUD_ID); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_DISABLE_CLOUD, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnChangeAppSwitch +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnChangeAppSwitch, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CHANGE_APP_SWITCH, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + data.WriteString(TEST_CLOUD_ID); + data.WriteString(TEST_CLOUD_BUNDLE); + data.WriteInt32(CloudData::CloudService::SWITCH_ON); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CHANGE_APP_SWITCH, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnClean +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnClean, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CLEAN, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string id = TEST_CLOUD_ID; + std::map actions; + ITypesUtil::Marshal(data, id, actions); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CLEAN, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnNotifyDataChange +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnNotifyDataChange, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_NOTIFY_DATA_CHANGE, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + data.WriteString(TEST_CLOUD_ID); + data.WriteString(TEST_CLOUD_BUNDLE); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_NOTIFY_DATA_CHANGE, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnNotifyChange +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnNotifyChange, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_NOTIFY_DATA_CHANGE_EXT, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + data.WriteString(TEST_CLOUD_ID); + data.WriteString(TEST_CLOUD_BUNDLE); + int32_t userId = 100; + data.WriteInt32(userId); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_NOTIFY_DATA_CHANGE_EXT, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnQueryStatistics +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnQueryStatistics, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY_STATISTICS, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + data.WriteString(TEST_CLOUD_ID); + data.WriteString(TEST_CLOUD_BUNDLE); + data.WriteString(TEST_CLOUD_STORE); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY_STATISTICS, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnQueryLastSyncInfo +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnQueryLastSyncInfo, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY_LAST_SYNC_INFO, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + data.WriteString(TEST_CLOUD_ID); + data.WriteString(TEST_CLOUD_BUNDLE); + data.WriteString(TEST_CLOUD_STORE); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY_LAST_SYNC_INFO, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnSetGlobalCloudStrategy +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnSetGlobalCloudStrategy, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = + cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_SET_GLOBAL_CLOUD_STRATEGY, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + uint32_t strategy = 0; + std::vector values; + ITypesUtil::Marshal(data, strategy, values); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_SET_GLOBAL_CLOUD_STRATEGY, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnAllocResourceAndShare +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnAllocResourceAndShare, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_ALLOC_RESOURCE_AND_SHARE, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string storeId = "storeId"; + DistributedRdb::PredicatesMemo predicates; + std::vector columns; + std::vector participants; + ITypesUtil::Marshal(data, storeId, predicates, columns, participants); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_ALLOC_RESOURCE_AND_SHARE, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnShare +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnShare, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_SHARE, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string sharingRes; + CloudData::Participants participants; + CloudData::Results results; + ITypesUtil::Marshal(data, sharingRes, participants, results); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_SHARE, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnUnshare +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnUnshare, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_UNSHARE, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string sharingRes; + CloudData::Participants participants; + CloudData::Results results; + ITypesUtil::Marshal(data, sharingRes, participants, results); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_UNSHARE, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnExit +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnExit, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_EXIT, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string sharingRes; + std::pair result; + ITypesUtil::Marshal(data, sharingRes, result); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_EXIT, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnChangePrivilege +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnChangePrivilege, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CHANGE_PRIVILEGE, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string sharingRes; + CloudData::Participants participants; + CloudData::Results results; + ITypesUtil::Marshal(data, sharingRes, participants, results); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CHANGE_PRIVILEGE, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnQuery +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnQuery, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string sharingRes; + CloudData::QueryResults results; + ITypesUtil::Marshal(data, sharingRes, results); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnQueryByInvitation +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnQueryByInvitation, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY_BY_INVITATION, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string invitation; + CloudData::QueryResults results; + ITypesUtil::Marshal(data, invitation, results); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_QUERY_BY_INVITATION, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnConfirmInvitation +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnConfirmInvitation, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CONFIRM_INVITATION, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string invitation; + int32_t confirmation = 0; + std::tuple result; + ITypesUtil::Marshal(data, invitation, confirmation, result); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CONFIRM_INVITATION, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnChangeConfirmation +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnChangeConfirmation, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CHANGE_CONFIRMATION, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + std::string sharingRes; + int32_t confirmation = 0; + std::pair result; + ITypesUtil::Marshal(data, sharingRes, confirmation, result); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_CHANGE_CONFIRMATION, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: OnSetCloudStrategy +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnSetCloudStrategy, TestSize.Level0) +{ + MessageParcel reply; + MessageParcel data; + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + auto ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_SET_CLOUD_STRATEGY, data, reply); + EXPECT_EQ(ret, IPC_STUB_INVALID_DATA_ERR); + data.WriteInterfaceToken(cloudServiceImpl_->GetDescriptor()); + uint32_t strategy = 0; + std::vector values; + ITypesUtil::Marshal(data, strategy, values); + ret = cloudServiceImpl_->OnRemoteRequest(CloudData::CloudService::TRANS_SET_CLOUD_STRATEGY, data, reply); + EXPECT_EQ(ret, ERR_NONE); +} + +/** +* @tc.name: SharingUtil001 +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, SharingUtil001, TestSize.Level0) +{ + auto cfm = CloudData::SharingUtil::Convert(Confirmation::CFM_UNKNOWN); + EXPECT_EQ(cfm, SharingCfm::CFM_UNKNOWN); + cfm = CloudData::SharingUtil::Convert(Confirmation::CFM_ACCEPTED); + EXPECT_EQ(cfm, SharingCfm::CFM_ACCEPTED); + cfm = CloudData::SharingUtil::Convert(Confirmation::CFM_REJECTED); + EXPECT_EQ(cfm, SharingCfm::CFM_REJECTED); + cfm = CloudData::SharingUtil::Convert(Confirmation::CFM_SUSPENDED); + EXPECT_EQ(cfm, SharingCfm::CFM_SUSPENDED); + cfm = CloudData::SharingUtil::Convert(Confirmation::CFM_UNAVAILABLE); + EXPECT_EQ(cfm, SharingCfm::CFM_UNAVAILABLE); + cfm = CloudData::SharingUtil::Convert(Confirmation::CFM_BUTT); + EXPECT_EQ(cfm, SharingCfm::CFM_UNKNOWN); +} + +/** +* @tc.name: SharingUtil002 +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, SharingUtil002, TestSize.Level0) +{ + auto cfm = CloudData::SharingUtil::Convert(SharingCfm::CFM_UNKNOWN); + EXPECT_EQ(cfm, Confirmation::CFM_UNKNOWN); + cfm = CloudData::SharingUtil::Convert(SharingCfm::CFM_ACCEPTED); + EXPECT_EQ(cfm, Confirmation::CFM_ACCEPTED); + cfm = CloudData::SharingUtil::Convert(SharingCfm::CFM_REJECTED); + EXPECT_EQ(cfm, Confirmation::CFM_REJECTED); + cfm = CloudData::SharingUtil::Convert(SharingCfm::CFM_SUSPENDED); + EXPECT_EQ(cfm, Confirmation::CFM_SUSPENDED); + cfm = CloudData::SharingUtil::Convert(SharingCfm::CFM_UNAVAILABLE); + EXPECT_EQ(cfm, Confirmation::CFM_UNAVAILABLE); + cfm = CloudData::SharingUtil::Convert(SharingCfm::CFM_BUTT); + EXPECT_EQ(cfm, Confirmation::CFM_UNKNOWN); +} + +/** +* @tc.name: SharingUtil003 +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, SharingUtil003, TestSize.Level0) +{ + auto status = CloudData::SharingUtil::Convert(CenterCode::IPC_ERROR); + EXPECT_EQ(status, Status::IPC_ERROR); + status = CloudData::SharingUtil::Convert(CenterCode::NOT_SUPPORT); + EXPECT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: SharingUtil004 +* @tc.desc: +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, SharingUtil004, TestSize.Level0) +{ + auto status = CloudData::SharingUtil::Convert(GenErr::E_OK); + EXPECT_EQ(status, Status::SUCCESS); + status = CloudData::SharingUtil::Convert(GenErr::E_ERROR); + EXPECT_EQ(status, Status::ERROR); + status = CloudData::SharingUtil::Convert(GenErr::E_INVALID_ARGS); + EXPECT_EQ(status, Status::INVALID_ARGUMENT); + status = CloudData::SharingUtil::Convert(GenErr::E_BLOCKED_BY_NETWORK_STRATEGY); + EXPECT_EQ(status, Status::STRATEGY_BLOCKING); + status = CloudData::SharingUtil::Convert(GenErr::E_CLOUD_DISABLED); + EXPECT_EQ(status, Status::CLOUD_DISABLE); + status = CloudData::SharingUtil::Convert(GenErr::E_NETWORK_ERROR); + EXPECT_EQ(status, Status::NETWORK_ERROR); + status = CloudData::SharingUtil::Convert(GenErr::E_BUSY); + EXPECT_EQ(status, Status::ERROR); +} + +/** +* @tc.name: DoCloudSync +* @tc.desc: Test the executor_ uninitialized and initialized scenarios +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, DoCloudSync, TestSize.Level0) +{ + int32_t user = 100; + CloudData::SyncManager sync; + CloudData::SyncManager::SyncInfo info(user); + auto ret = sync.DoCloudSync(info); + EXPECT_EQ(ret, GenErr::E_NOT_INIT); + ret = sync.StopCloudSync(user); + EXPECT_EQ(ret, GenErr::E_NOT_INIT); + size_t max = 12; + size_t min = 5; + sync.executor_ = std::make_shared(max, min); + ret = sync.DoCloudSync(info); + EXPECT_EQ(ret, GenErr::E_OK); + int32_t invalidUser = -1; + sync.StopCloudSync(invalidUser); + ret = sync.StopCloudSync(user); + EXPECT_EQ(ret, GenErr::E_OK); +} + +/** +* @tc.name: GetPostEventTask +* @tc.desc: Test the interface to verify the package name and table name +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetPostEventTask, TestSize.Level0) +{ + std::vector schemas; + schemaMeta_.databases[0].name = "test"; + schemas.push_back(schemaMeta_); + schemaMeta_.bundleName = "test"; + schemas.push_back(schemaMeta_); + + int32_t user = 100; + CloudData::SyncManager::SyncInfo info(user); + std::vector value; + info.tables_.insert_or_assign(TEST_CLOUD_STORE, value); + + CloudData::SyncManager sync; + auto task = sync.GetPostEventTask(schemas, cloudInfo_, info, true); + auto ret = task(); + EXPECT_TRUE(ret); +} + +/** +* @tc.name: GetRetryer +* @tc.desc: Test the input parameters of different interfaces +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetRetryer, TestSize.Level0) +{ + int32_t user = 100; + CloudData::SyncManager::SyncInfo info(user); + CloudData::SyncManager sync; + CloudData::SyncManager::Duration duration; + auto ret = sync.GetRetryer(CloudData::SyncManager::RETRY_TIMES, info)(duration, E_OK, E_OK); + EXPECT_TRUE(ret); + ret = sync.GetRetryer(CloudData::SyncManager::RETRY_TIMES, info)(duration, E_SYNC_TASK_MERGED, E_SYNC_TASK_MERGED); + EXPECT_TRUE(ret); + ret = sync.GetRetryer(0, info)(duration, E_OK, E_OK); + EXPECT_TRUE(ret); + ret = sync.GetRetryer(0, info)(duration, E_SYNC_TASK_MERGED, E_SYNC_TASK_MERGED); + EXPECT_TRUE(ret); +} + +/** +* @tc.name: GetCallback +* @tc.desc: Test the processing logic of different progress callbacks +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetCallback, TestSize.Level0) +{ + int32_t user = 100; + CloudData::SyncManager::SyncInfo info(user); + CloudData::SyncManager sync; + DistributedData::GenDetails result; + StoreInfo storeInfo; + storeInfo.user = user; + storeInfo.bundleName = "testBundleName"; + int32_t triggerMode = MODE_DEFAULT; + GenAsync async = nullptr; + sync.GetCallback(async, storeInfo, triggerMode)(result); + int32_t process = 0; + async = [&process](const GenDetails &details) { process = details.begin()->second.progress; }; + GenProgressDetail detail; + detail.progress = GenProgress::SYNC_IN_PROGRESS; + result.insert_or_assign("test", detail); + sync.GetCallback(async, storeInfo, triggerMode)(result); + EXPECT_EQ(process, GenProgress::SYNC_IN_PROGRESS); + detail.progress = GenProgress::SYNC_FINISH; + result.insert_or_assign("test", detail); + storeInfo.user = -1; + sync.GetCallback(async, storeInfo, triggerMode)(result); + storeInfo.user = user; + sync.GetCallback(async, storeInfo, triggerMode)(result); + EXPECT_EQ(process, GenProgress::SYNC_FINISH); +} + +/** +* @tc.name: GetInterval +* @tc.desc: Test the Interval transformation logic of the interface +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetInterval, TestSize.Level0) +{ + CloudData::SyncManager sync; + + auto ret = sync.GetInterval(E_LOCKED_BY_OTHERS); + EXPECT_EQ(ret, CloudData::SyncManager::LOCKED_INTERVAL); + ret = sync.GetInterval(E_BUSY); + EXPECT_EQ(ret, CloudData::SyncManager::BUSY_INTERVAL); + ret = sync.GetInterval(E_OK); + EXPECT_EQ(ret, CloudData::SyncManager::RETRY_INTERVAL); +} + +/** +* @tc.name: GetCloudSyncInfo +* @tc.desc: Test get cloudInfo +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetCloudSyncInfo, TestSize.Level0) +{ + CloudData::SyncManager sync; + CloudInfo cloud; + cloud.user = cloudInfo_.user; + cloud.enableCloud = false; + CloudData::SyncManager::SyncInfo info(cloudInfo_.user); + MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetKey(), true); + info.bundleName_ = "test"; + auto ret = sync.GetCloudSyncInfo(info, cloud); + EXPECT_TRUE(!ret.empty()); +} + +/** +* @tc.name: RetryCallback +* @tc.desc: Test the retry logic +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, RetryCallback, TestSize.Level0) +{ + CloudData::SyncManager sync; + StoreInfo storeInfo; + int32_t retCode = -1; + CloudData::SyncManager::Retryer retry = [&retCode](CloudData::SyncManager::Duration interval, int32_t code, + int32_t dbCode) { + retCode = code; + return true; + }; + DistributedData::GenDetails result; + auto task = sync.RetryCallback(storeInfo, retry, MODE_DEFAULT); + task(result); + GenProgressDetail detail; + detail.progress = GenProgress::SYNC_IN_PROGRESS; + detail.code = 100; + result.insert_or_assign("test", detail); + task = sync.RetryCallback(storeInfo, retry, MODE_DEFAULT); + task(result); + EXPECT_EQ(retCode, detail.code); +} + +/** +* @tc.name: UpdateCloudInfoFromServer +* @tc.desc: Test updating cloudinfo from the server +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, UpdateCloudInfoFromServer, TestSize.Level0) +{ + auto ret = cloudServiceImpl_->UpdateCloudInfoFromServer(cloudInfo_.user); + EXPECT_EQ(ret, E_OK); +} + +/** +* @tc.name: GetCloudInfo +* @tc.desc: Test get cloudInfo +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetCloudInfo, TestSize.Level0) +{ + MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetKey(), true); + auto ret = cloudServiceImpl_->GetCloudInfo(cloudInfo_.user); + EXPECT_EQ(ret.first, CloudData::SUCCESS); +} + +/** +* @tc.name: SubTask +* @tc.desc: Test the subtask execution logic +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, SubTask, TestSize.Level0) +{ + DistributedData::Subscription sub; + cloudServiceImpl_->InitSubTask(sub, 0); + MetaDataManager::GetInstance().LoadMeta(Subscription::GetKey(cloudInfo_.user), sub, true); + cloudServiceImpl_->InitSubTask(sub, 0); + int32_t userId = 0; + CloudData::CloudServiceImpl::Task task = [&userId]() { userId = cloudInfo_.user; }; + cloudServiceImpl_->GenSubTask(task, cloudInfo_.user)(); + EXPECT_EQ(userId, cloudInfo_.user); +} + +/** +* @tc.name: ConvertCursor +* @tc.desc: Test the cursor conversion logic when the ResultSet is empty and non-null +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, ConvertCursor, TestSize.Level0) +{ + std::map entry; + entry.insert_or_assign("test", "entry"); + auto resultSet = std::make_shared(1, entry); + auto cursor = std::make_shared(resultSet); + auto result = cloudServiceImpl_->ConvertCursor(cursor); + EXPECT_TRUE(!result.empty()); + auto resultSet1 = std::make_shared(); + auto cursor1 = std::make_shared(resultSet1); + auto result1 = cloudServiceImpl_->ConvertCursor(cursor1); + EXPECT_TRUE(result1.empty()); +} + +/** +* @tc.name: GetDbInfoFromExtraData +* @tc.desc: Test the GetDbInfoFromExtraData function input parameters of different parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetDbInfoFromExtraData, TestSize.Level0) +{ + SchemaMeta::Database database; + database.name = TEST_CLOUD_STORE; + database.alias = TEST_CLOUD_DATABASE_ALIAS_1; + + SchemaMeta schemaMeta; + schemaMeta.databases.push_back(database); + + SchemaMeta::Table table; + table.name = "test_cloud_table_name"; + table.alias = "test_cloud_table_alias"; + database.tables.push_back(table); + SchemaMeta::Table table1; + table1.name = "test_cloud_table_name1"; + table1.alias = "test_cloud_table_alias1"; + table1.sharedTableName = "test_share_table_name1"; + database.tables.emplace_back(table1); + + database.alias = TEST_CLOUD_DATABASE_ALIAS_2; + schemaMeta.databases.push_back(database); + + ExtraData extraData; + extraData.info.containerName = TEST_CLOUD_DATABASE_ALIAS_2; + auto result = cloudServiceImpl_->GetDbInfoFromExtraData(extraData, schemaMeta); + EXPECT_EQ(result.begin()->first, TEST_CLOUD_STORE); + + std::string tableName = "test_cloud_table_alias2"; + extraData.info.tables.emplace_back(tableName); + result = cloudServiceImpl_->GetDbInfoFromExtraData(extraData, schemaMeta); + EXPECT_EQ(result.begin()->first, TEST_CLOUD_STORE); + + std::string tableName1 = "test_cloud_table_alias1"; + extraData.info.tables.emplace_back(tableName1); + extraData.info.scopes.emplace_back(DistributedData::ExtraData::SHARED_TABLE); + result = cloudServiceImpl_->GetDbInfoFromExtraData(extraData, schemaMeta); + EXPECT_EQ(result.begin()->first, TEST_CLOUD_STORE); +} + +/** +* @tc.name: QueryTableStatistic +* @tc.desc: Test the QueryTableStatistic function input parameters of different parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, QueryTableStatistic, TestSize.Level0) +{ + auto store = std::make_shared(); + if (store != nullptr) { + std::map entry = { { "inserted", "TEST" }, { "updated", "TEST" }, { "normal", "TEST" } }; + store->MakeCursor(entry); + } + auto [ret, result] = cloudServiceImpl_->QueryTableStatistic("test", store); + EXPECT_TRUE(ret); + if (store != nullptr) { + std::map entry = { { "Test", 1 } }; + store->MakeCursor(entry); + } + std::tie(ret, result) = cloudServiceImpl_->QueryTableStatistic("test", store); + EXPECT_TRUE(ret); + + if (store != nullptr) { + store->cursor_ = nullptr; + } + std::tie(ret, result) = cloudServiceImpl_->QueryTableStatistic("test", store); + EXPECT_FALSE(ret); +} + +/** +* @tc.name: GetSchemaMeta +* @tc.desc: Test the GetSchemaMeta function input parameters of different parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetSchemaMeta, TestSize.Level0) +{ + int32_t userId = 101; + int32_t instanceId = 0; + CloudInfo cloudInfo; + cloudInfo.user = userId; + cloudInfo.id = TEST_CLOUD_ID; + cloudInfo.enableCloud = true; + + CloudInfo::AppInfo appInfo; + appInfo.bundleName = TEST_CLOUD_BUNDLE; + appInfo.appId = TEST_CLOUD_APPID; + appInfo.version = 1; + appInfo.cloudSwitch = true; + + cloudInfo.apps[TEST_CLOUD_BUNDLE] = std::move(appInfo); + MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true); + std::string bundleName = "testName"; + auto [status, meta] = cloudServiceImpl_->GetSchemaMeta(userId, bundleName, instanceId); + EXPECT_EQ(status, CloudData::CloudService::ERROR); + bundleName = TEST_CLOUD_BUNDLE; + DistributedData::SchemaMeta schemeMeta; + schemeMeta.bundleName = TEST_CLOUD_BUNDLE; + schemeMeta.metaVersion = DistributedData::SchemaMeta::CURRENT_VERSION + 1; + MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE, instanceId), schemeMeta, true); + std::tie(status, meta) = cloudServiceImpl_->GetSchemaMeta(userId, bundleName, instanceId); + EXPECT_EQ(status, CloudData::CloudService::ERROR); + schemeMeta.metaVersion = DistributedData::SchemaMeta::CURRENT_VERSION; + MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE, instanceId), schemeMeta, true); + std::tie(status, meta) = cloudServiceImpl_->GetSchemaMeta(userId, bundleName, instanceId); + EXPECT_EQ(status, CloudData::CloudService::SUCCESS); + EXPECT_EQ(meta.metaVersion, DistributedData::SchemaMeta::CURRENT_VERSION); + MetaDataManager::GetInstance().DelMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE, instanceId), true); + MetaDataManager::GetInstance().DelMeta(cloudInfo.GetKey(), true); +} + +/** +* @tc.name: GetAppSchemaFromServer +* @tc.desc: Test the GetAppSchemaFromServer function input parameters of different parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetAppSchemaFromServer, TestSize.Level0) +{ + int32_t userId = CloudServerMock::INVALID_USER_ID; + std::string bundleName; + DeviceManagerAdapter::GetInstance().SetNet(DeviceManagerAdapter::NONE); + DeviceManagerAdapter::GetInstance().expireTime_ = + std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()) + .count() + + 1000; + auto [status, meta] = cloudServiceImpl_->GetAppSchemaFromServer(userId, bundleName); + EXPECT_EQ(status, CloudData::CloudService::NETWORK_ERROR); + DeviceManagerAdapter::GetInstance().SetNet(DeviceManagerAdapter::WIFI); + std::tie(status, meta) = cloudServiceImpl_->GetAppSchemaFromServer(userId, bundleName); + EXPECT_EQ(status, CloudData::CloudService::SCHEMA_INVALID); + userId = 100; + std::tie(status, meta) = cloudServiceImpl_->GetAppSchemaFromServer(userId, bundleName); + EXPECT_EQ(status, CloudData::CloudService::SCHEMA_INVALID); + bundleName = TEST_CLOUD_BUNDLE; + std::tie(status, meta) = cloudServiceImpl_->GetAppSchemaFromServer(userId, bundleName); + EXPECT_EQ(status, CloudData::CloudService::SUCCESS); + EXPECT_EQ(meta.bundleName, schemaMeta_.bundleName); +} + +/** +* @tc.name: OnAppUninstall +* @tc.desc: Test the OnAppUninstall function delete the subscription data +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, OnAppUninstall, TestSize.Level0) +{ + ZLOGI("weisx test OnAppUninstall 111"); + CloudData::CloudServiceImpl::CloudStatic cloudStatic; + int32_t userId = 1001; + Subscription sub; + sub.expiresTime.insert_or_assign(TEST_CLOUD_BUNDLE, 0); + MetaDataManager::GetInstance().SaveMeta(Subscription::GetKey(userId), sub, true); + CloudInfo cloudInfo; + cloudInfo.user = userId; + CloudInfo::AppInfo appInfo; + cloudInfo.apps.insert_or_assign(TEST_CLOUD_BUNDLE, appInfo); + MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true); + int32_t index = 1; + auto ret = cloudStatic.OnAppUninstall(TEST_CLOUD_BUNDLE, userId, index); + EXPECT_EQ(ret, E_OK); + Subscription sub1; + EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(Subscription::GetKey(userId), sub1, true)); + EXPECT_EQ(sub1.expiresTime.size(), 0); +} + +/** +* @tc.name: GetCloudInfo +* @tc.desc: Test the GetCloudInfo with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, GetCloudInfo001, TestSize.Level0) +{ + ZLOGI("weisx test OnAppUninstall 111"); + int32_t userId = 1000; + auto [status, cloudInfo] = cloudServiceImpl_->GetCloudInfo(userId); + EXPECT_EQ(status, CloudData::CloudService::ERROR); + DeviceManagerAdapter::GetInstance().SetNet(DeviceManagerAdapter::NONE); + DeviceManagerAdapter::GetInstance().expireTime_ = + std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()) + .count() + + 1000; + MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetKey(), true); + std::tie(status, cloudInfo) = cloudServiceImpl_->GetCloudInfo(cloudInfo_.user); + EXPECT_EQ(status, CloudData::CloudService::NETWORK_ERROR); + DeviceManagerAdapter::GetInstance().SetNet(DeviceManagerAdapter::WIFI); +} + +/** +* @tc.name: PreShare +* @tc.desc: Test the PreShare with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, PreShare, TestSize.Level0) +{ + int32_t userId = 1000; + StoreInfo info; + info.instanceId = 0; + info.bundleName = TEST_CLOUD_BUNDLE; + info.storeName = TEST_CLOUD_BUNDLE; + info.user = userId; + StoreMetaData meta(info); + meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true); + DistributedRdb::RdbQuery query; + auto [status, cursor] = cloudServiceImpl_->PreShare(info, query); + EXPECT_EQ(status, GeneralError::E_ERROR); +} + +/** +* @tc.name: InitSubTask +* @tc.desc: Test the InitSubTask with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, InitSubTask, TestSize.Level0) +{ + uint64_t minInterval = 0; + uint64_t expire = 24 * 60 * 60 * 1000; // 24hours, ms + ExecutorPool::TaskId taskId = 100; + Subscription sub; + sub.expiresTime.insert_or_assign(TEST_CLOUD_BUNDLE, expire); + std::shared_ptr executor = std::move(cloudServiceImpl_->executor_); + cloudServiceImpl_->executor_ = nullptr; + cloudServiceImpl_->InitSubTask(sub, minInterval); + EXPECT_EQ(sub.GetMinExpireTime(), expire); + cloudServiceImpl_->executor_ = std::move(executor); + cloudServiceImpl_->subTask_ = taskId; + cloudServiceImpl_->InitSubTask(sub, minInterval); + EXPECT_NE(cloudServiceImpl_->subTask_, taskId); + cloudServiceImpl_->subTask_ = taskId; + cloudServiceImpl_->expireTime_ = 0; + cloudServiceImpl_->InitSubTask(sub, minInterval); + EXPECT_EQ(cloudServiceImpl_->subTask_, taskId); + cloudServiceImpl_->subTask_ = ExecutorPool::INVALID_TASK_ID; + cloudServiceImpl_->InitSubTask(sub, minInterval); + EXPECT_NE(cloudServiceImpl_->subTask_, ExecutorPool::INVALID_TASK_ID); +} + +/** +* @tc.name: DoSubscribe +* @tc.desc: Test DoSubscribe functions with invalid parameter. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, DoSubscribe, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest DoSubscribe start"); + Subscription sub; + sub.userId = cloudInfo_.user; + MetaDataManager::GetInstance().SaveMeta(sub.GetKey(), sub, true); + int user = cloudInfo_.user; + auto status = cloudServiceImpl_->DoSubscribe(user); + EXPECT_FALSE(status); + sub.id = "testId"; + MetaDataManager::GetInstance().SaveMeta(sub.GetKey(), sub, true); + status = cloudServiceImpl_->DoSubscribe(user); + EXPECT_FALSE(status); + sub.id = TEST_CLOUD_APPID; + MetaDataManager::GetInstance().SaveMeta(sub.GetKey(), sub, true); + status = cloudServiceImpl_->DoSubscribe(user); + EXPECT_FALSE(status); + MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetKey(), true); + status = cloudServiceImpl_->DoSubscribe(user); + EXPECT_FALSE(status); +} } // namespace DistributedDataTest } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/cloud_service_impl_test.cpp b/datamgr_service/services/distributeddataservice/service/test/cloud_service_impl_test.cpp new file mode 100644 index 00000000..16c3bc7a --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/cloud_service_impl_test.cpp @@ -0,0 +1,488 @@ +/* +* Copyright (c) 2024 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 "CloudServiceImplTest" +#include "cloud_service_impl.h" + +#include +#include + +#include "accesstoken_kit.h" +#include "account/account_delegate.h" +#include "bootstrap.h" +#include "checker_mock.h" +#include "cloud/change_event.h" +#include "cloud/cloud_event.h" +#include "cloud/cloud_server.h" +#include "cloud/cloud_share_event.h" +#include "cloud/schema_meta.h" +#include "cloud_types.h" +#include "cloud_types_util.h" +#include "cloud_value_util.h" +#include "communicator/device_manager_adapter.h" +#include "device_matrix.h" +#include "eventcenter/event_center.h" +#include "feature/feature_system.h" +#include "ipc_skeleton.h" +#include "log_print.h" +#include "metadata/meta_data_manager.h" +#include "metadata/store_meta_data.h" +#include "metadata/store_meta_data_local.h" +#include "mock/db_store_mock.h" +#include "mock/general_store_mock.h" +#include "rdb_query.h" +#include "rdb_service.h" +#include "rdb_service_impl.h" +#include "rdb_types.h" +#include "store/auto_cache.h" +#include "store/store_info.h" +#include "token_setproc.h" + +using namespace testing::ext; +using namespace OHOS::DistributedData; +using namespace OHOS::Security::AccessToken; +using Confirmation = OHOS::CloudData::Confirmation; +using Status = OHOS::CloudData::CloudService::Status; + +namespace OHOS::Test { +namespace DistributedDataTest { +static constexpr const char *TEST_CLOUD_BUNDLE = "test_cloud_bundleName"; +static constexpr const char *TEST_CLOUD_APPID = "test_cloud_appid"; +static constexpr const char *TEST_CLOUD_STORE = "test_cloud_store"; +static constexpr const char *TEST_CLOUD_DATABASE_ALIAS_1 = "test_cloud_database_alias_1"; +class CloudServiceImplTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + static std::shared_ptr cloudServiceImpl_; +}; +std::shared_ptr CloudServiceImplTest::cloudServiceImpl_ = + std::make_shared(); + +void CloudServiceImplTest::SetUpTestCase(void) +{ + size_t max = 12; + size_t min = 5; + auto executor = std::make_shared(max, min); + DeviceManagerAdapter::GetInstance().Init(executor); +} + +void CloudServiceImplTest::TearDownTestCase() +{ +} + +void CloudServiceImplTest::SetUp() +{ +} + +void CloudServiceImplTest::TearDown() +{ +} + +/** +* @tc.name: EnableCloud001 +* @tc.desc: Test EnableCloud functions with user is invalid. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, EnableCloud001, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest EnableCloud001 start"); + std::map switches; + switches.insert_or_assign(TEST_CLOUD_BUNDLE, CloudData::CloudService::SWITCH_ON); + auto status = cloudServiceImpl_->EnableCloud(TEST_CLOUD_APPID, switches); + EXPECT_EQ(status, CloudData::CloudService::ERROR); +} + +/** +* @tc.name: DisableCloud001 +* @tc.desc: Test DisableCloud functions with user is invalid. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, DisableCloud001, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest DisableCloud001 start"); + auto status = cloudServiceImpl_->DisableCloud(TEST_CLOUD_APPID); + EXPECT_EQ(status, CloudData::CloudService::ERROR); +} + +/** +* @tc.name: ChangeAppSwitch001 +* @tc.desc: Test ChangeAppSwitch functions with user is invalid. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, ChangeAppSwitch001, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest ChangeAppSwitch001 start"); + auto status = + cloudServiceImpl_->ChangeAppSwitch(TEST_CLOUD_APPID, TEST_CLOUD_BUNDLE, CloudData::CloudService::SWITCH_ON); + EXPECT_EQ(status, CloudData::CloudService::ERROR); +} + +/** +* @tc.name: Clean001 +* @tc.desc: Test Clean functions with user is invalid. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, Clean001, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest Clean001 start"); + std::map actions; + actions.insert_or_assign(TEST_CLOUD_BUNDLE, CloudData::CloudService::SWITCH_ON); + auto status = cloudServiceImpl_->Clean(TEST_CLOUD_APPID, actions); + EXPECT_EQ(status, CloudData::CloudService::ERROR); +} + +/** +* @tc.name: NotifyDataChange001 +* @tc.desc: Test the EnableCloud function in case it doesn't get cloudInfo. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, NotifyDataChange001, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest NotifyDataChange001 start"); + auto status = cloudServiceImpl_->NotifyDataChange(TEST_CLOUD_APPID, TEST_CLOUD_BUNDLE); + EXPECT_EQ(status, CloudData::CloudService::INVALID_ARGUMENT); +} + +/** +* @tc.name: ExecuteStatistics001 +* @tc.desc: Test the ExecuteStatistics function if the package name does not support CloudSync. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, ExecuteStatistics001, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest ExecuteStatistics001 start"); + CloudInfo cloudInfo; + CloudInfo::AppInfo appInfo; + appInfo.bundleName = TEST_CLOUD_BUNDLE; + cloudInfo.apps[TEST_CLOUD_BUNDLE] = std::move(appInfo); + SchemaMeta::Database database; + database.name = TEST_CLOUD_STORE; + database.alias = TEST_CLOUD_DATABASE_ALIAS_1; + SchemaMeta schemaMeta; + schemaMeta.bundleName = "testBundle"; + schemaMeta.databases.emplace_back(database); + auto result = cloudServiceImpl_->ExecuteStatistics("", cloudInfo, schemaMeta); + EXPECT_TRUE(result.empty()); +} + +/** +* @tc.name: QueryStatistics001 +* @tc.desc: When metadata is not supported store test the QueryStatistics function. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, QueryStatistics001, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest QueryStatistics start"); + StoreMetaData metaData; + metaData.storeType = -1; + DistributedData::Database database; + auto result = cloudServiceImpl_->QueryStatistics(metaData, database); + EXPECT_TRUE(result.empty()); +} + +/** +* @tc.name: QueryLastSyncInfo001 +* @tc.desc: Test QueryLastSyncInfo functions with invalid parameter. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, QueryLastSyncInfo001, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest QueryLastSyncInfo start"); + auto [status, result] = cloudServiceImpl_->QueryLastSyncInfo(TEST_CLOUD_APPID, TEST_CLOUD_BUNDLE, TEST_CLOUD_STORE); + EXPECT_EQ(status, CloudData::CloudService::ERROR); + EXPECT_TRUE(result.empty()); +} + +/** +* @tc.name: OnBind001 +* @tc.desc: Test OnBind functions with invalid parameter. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, OnBind001, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest OnBind001 start"); + auto status = cloudServiceImpl_->OnBind({}); + EXPECT_EQ(status, GeneralError::E_INVALID_ARGS); +} + +/** +* @tc.name: UpdateSchema001 +* @tc.desc: Test UpdateSchema001 functions with invalid parameter. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, UpdateSchema001, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest UpdateSchema001 start"); + int user = -1; + auto status = cloudServiceImpl_->UpdateSchema(user); + EXPECT_FALSE(status); +} + +/** +* @tc.name: GetAppSchemaFromServer001 +* @tc.desc: Test GetAppSchemaFromServer functions not support CloudService. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, GetAppSchemaFromServer001, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest GetAppSchemaFromServer001 start"); + DeviceManagerAdapter::GetInstance().SetNet(DeviceManagerAdapter::WIFI); + int user = -1; + auto [status, result] = cloudServiceImpl_->GetAppSchemaFromServer(user, TEST_CLOUD_BUNDLE); + EXPECT_EQ(status, CloudData::CloudService::SERVER_UNAVAILABLE); +} + +/** +* @tc.name: GetCloudInfoFromServer001 +* @tc.desc: Test GetCloudInfoFromServer functions not support CloudService. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, GetCloudInfoFromServer001, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest GetCloudInfoFromServer001 start"); + DeviceManagerAdapter::GetInstance().SetNet(DeviceManagerAdapter::WIFI); + int user = -1; + auto [status, result] = cloudServiceImpl_->GetCloudInfoFromServer(user); + EXPECT_EQ(status, CloudData::CloudService::SERVER_UNAVAILABLE); +} + +/** +* @tc.name: ReleaseUserInfo001 +* @tc.desc: Test ReleaseUserInfo functions with invalid parameter. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, ReleaseUserInfo001, TestSize.Level0) +{ + ZLOGI("CloudServiceImplTest ReleaseUserInfo001 start"); + int user = 100; + auto status = cloudServiceImpl_->ReleaseUserInfo(user); + EXPECT_TRUE(status); +} + +/** +* @tc.name: DoSubscribe +* @tc.desc: Test the DoSubscribe with not support CloudService +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, DoSubscribe, TestSize.Level0) +{ + int32_t user = 100; + auto status = cloudServiceImpl_->DoSubscribe(user); + EXPECT_TRUE(status); +} + +/** +* @tc.name: Share001 +* @tc.desc: Test the Share with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, Share001, TestSize.Level0) +{ + std::string sharingRes; + CloudData::Participants participants; + CloudData::Results results; + auto status = cloudServiceImpl_->Share(sharingRes, participants, results); + EXPECT_EQ(status, GeneralError::E_ERROR); +} + +/** +* @tc.name: Unshare001 +* @tc.desc: Test the Unshare with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, Unshare001, TestSize.Level0) +{ + std::string sharingRes; + CloudData::Participants participants; + CloudData::Results results; + auto status = cloudServiceImpl_->Unshare(sharingRes, participants, results); + EXPECT_EQ(status, GeneralError::E_ERROR); +} + +/** +* @tc.name: Exit001 +* @tc.desc: Test the Exit with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, Exit001, TestSize.Level0) +{ + std::string sharingRes; + std::pair result; + auto status = cloudServiceImpl_->Exit(sharingRes, result); + EXPECT_EQ(status, GeneralError::E_ERROR); +} + +/** +* @tc.name: ChangePrivilege001 +* @tc.desc: Test the ChangePrivilege with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, ChangePrivilege001, TestSize.Level0) +{ + std::string sharingRes; + CloudData::Participants participants; + CloudData::Results results; + auto status = cloudServiceImpl_->ChangePrivilege(sharingRes, participants, results); + EXPECT_EQ(status, GeneralError::E_ERROR); +} + +/** +* @tc.name: Query001 +* @tc.desc: Test the Query with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, Query001, TestSize.Level0) +{ + std::string sharingRes; + CloudData::QueryResults results; + auto status = cloudServiceImpl_->Query(sharingRes, results); + EXPECT_EQ(status, GeneralError::E_ERROR); +} + +/** +* @tc.name: QueryByInvitation001 +* @tc.desc: Test the QueryByInvitation with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, QueryByInvitation001, TestSize.Level0) +{ + std::string invitation; + CloudData::QueryResults results; + auto status = cloudServiceImpl_->QueryByInvitation(invitation, results); + EXPECT_EQ(status, GeneralError::E_ERROR); +} + +/** +* @tc.name: ConfirmInvitation001 +* @tc.desc: Test the ConfirmInvitation with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, ConfirmInvitation001, TestSize.Level0) +{ + int32_t confirmation = 0; + std::tuple result{ 0, "", "" }; + std::string invitation; + auto status = cloudServiceImpl_->ConfirmInvitation(invitation, confirmation, result); + EXPECT_EQ(status, GeneralError::E_ERROR); +} + +/** +* @tc.name: ChangeConfirmation001 +* @tc.desc: Test the ChangeConfirmation with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, ChangeConfirmation001, TestSize.Level0) +{ + int32_t confirmation = 0; + std::string sharingRes; + std::pair result; + auto status = cloudServiceImpl_->ChangeConfirmation(sharingRes, confirmation, result); + EXPECT_EQ(status, GeneralError::E_ERROR); +} + +/** +* @tc.name: GetSharingHandle001 +* @tc.desc: Test the GetSharingHandle with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, GetSharingHandle001, TestSize.Level0) +{ + CloudData::CloudServiceImpl::HapInfo hapInfo; + auto status = cloudServiceImpl_->GetSharingHandle(hapInfo); + EXPECT_EQ(status, nullptr); +} + +/** +* @tc.name: SetCloudStrategy001 +* @tc.desc: Test the SetCloudStrategy with get hapInfo failed +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, SetCloudStrategy001, TestSize.Level0) +{ + CloudData::Strategy strategy = CloudData::Strategy::STRATEGY_NETWORK; + std::vector values; + values.push_back(CloudData::NetWorkStrategy::WIFI); + + auto status = cloudServiceImpl_->SetCloudStrategy(strategy, values); + EXPECT_EQ(status, CloudData::CloudService::ERROR); +} + +/** +* @tc.name: SetGlobalCloudStrategy001 +* @tc.desc: Test the SetGlobalCloudStrategy with get hapInfo failed +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, SetGlobalCloudStrategy001, TestSize.Level0) +{ + CloudData::Strategy strategy = CloudData::Strategy::STRATEGY_NETWORK; + std::vector values; + values.push_back(CloudData::NetWorkStrategy::WIFI); + + auto status = cloudServiceImpl_->SetGlobalCloudStrategy(strategy, values); + EXPECT_EQ(status, CloudData::CloudService::ERROR); +} + +/** +* @tc.name: CheckNotifyConditions001 +* @tc.desc: Test the CheckNotifyConditions with invalid parameters +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudServiceImplTest, CheckNotifyConditions, TestSize.Level0) +{ + CloudInfo cloudInfo; + cloudInfo.enableCloud = false; + cloudInfo.id = TEST_CLOUD_APPID; + + auto status = cloudServiceImpl_->CheckNotifyConditions(TEST_CLOUD_APPID, TEST_CLOUD_BUNDLE, cloudInfo); + EXPECT_EQ(status, CloudData::CloudService::CLOUD_DISABLE); + cloudInfo.enableCloud = true; + CloudInfo::AppInfo appInfo; + appInfo.bundleName = TEST_CLOUD_BUNDLE; + appInfo.cloudSwitch = false; + cloudInfo.apps.insert_or_assign(TEST_CLOUD_BUNDLE, appInfo); + status = cloudServiceImpl_->CheckNotifyConditions(TEST_CLOUD_APPID, TEST_CLOUD_BUNDLE, cloudInfo); + EXPECT_EQ(status, CloudData::CloudService::CLOUD_DISABLE_SWITCH); +} +} // namespace DistributedDataTest +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/cloud_test.cpp b/datamgr_service/services/distributeddataservice/service/test/cloud_test.cpp index 607179ab..e49c66ca 100644 --- a/datamgr_service/services/distributeddataservice/service/test/cloud_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/cloud_test.cpp @@ -35,8 +35,8 @@ public: void TearDown(){}; protected: - static constexpr const char* testCloudBundle = "test_cloud_bundleName"; - static constexpr const char* testCloudStore = "test_cloud_database_name"; + static constexpr const char* TEST_CLOUD_BUNDLE = "test_cloud_bundleName"; + static constexpr const char* TEST_CLOUD_STORE = "test_cloud_database_name"; static std::shared_ptr dbStoreMock_; }; std::shared_ptr CloudTest::dbStoreMock_ = std::make_shared(); @@ -65,7 +65,7 @@ HWTEST_F(CloudTest, EventInfo, TestSize.Level1) SyncEvent::EventInfo eventInfo1(mode, wait, retry, query, async); SyncEvent::EventInfo eventInfo2(std::move(eventInfo1)); SyncEvent::EventInfo eventInfo3 = std::move(eventInfo2); - StoreInfo storeInfo{ IPCSkeleton::GetCallingTokenID(), testCloudBundle, testCloudStore, 0 }; + StoreInfo storeInfo{ IPCSkeleton::GetCallingTokenID(), TEST_CLOUD_BUNDLE, TEST_CLOUD_STORE, 0 }; SyncEvent evt(storeInfo, eventInfo3); EXPECT_EQ(evt.GetMode(), mode); EXPECT_EQ(evt.GetWait(), wait); @@ -88,11 +88,11 @@ HWTEST_F(CloudTest, Serializable_Marshal, TestSize.Level1) EXPECT_EQ(false, ret); SchemaMeta::Database database; - database.name = testCloudStore; + database.name = TEST_CLOUD_STORE; database.alias = "database_alias_test"; schemaMeta.version = 1; - schemaMeta.bundleName = testCloudBundle; + schemaMeta.bundleName = TEST_CLOUD_BUNDLE; schemaMeta.databases.emplace_back(database); ret = schemaMeta.IsValid(); EXPECT_EQ(true, ret); @@ -103,8 +103,12 @@ HWTEST_F(CloudTest, Serializable_Marshal, TestSize.Level1) EXPECT_EQ(schemaMeta.version, schemaMeta2.version); EXPECT_EQ(schemaMeta.bundleName, schemaMeta2.bundleName); - Database database2 = schemaMeta2.GetDataBase(testCloudStore); + Database database2 = schemaMeta2.GetDataBase(TEST_CLOUD_STORE); EXPECT_EQ(database.alias, database2.alias); + + std::string storeId = "storeId"; + Database database3 = schemaMeta2.GetDataBase(storeId); + EXPECT_NE(database.alias, database3.alias); } /** @@ -149,7 +153,7 @@ HWTEST_F(CloudTest, Database_Marshal, TestSize.Level1) table2.alias = "test_cloud_table_alias2"; SchemaMeta::Database database1; - database1.name = testCloudStore; + database1.name = TEST_CLOUD_STORE; database1.alias = "test_cloud_database_alias"; database1.tables.emplace_back(table1); database1.tables.emplace_back(table2); @@ -177,8 +181,9 @@ HWTEST_F(CloudTest, Database_Marshal, TestSize.Level1) */ HWTEST_F(CloudTest, CloudInfoUpgrade, TestSize.Level0) { + int32_t defaultUser = 100; CloudInfo oldInfo; - auto user = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(OHOS::IPCSkeleton::GetCallingTokenID()); + auto user = defaultUser; oldInfo.user = user; EXPECT_NE(oldInfo.maxNumber, CloudInfo::DEFAULT_BATCH_NUMBER); EXPECT_NE(oldInfo.maxSize, CloudInfo::DEFAULT_BATCH_SIZE); diff --git a/datamgr_service/services/distributeddataservice/service/test/data_share_profile_config_test.cpp b/datamgr_service/services/distributeddataservice/service/test/data_share_profile_config_test.cpp index 3c2ec549..c8454845 100644 --- a/datamgr_service/services/distributeddataservice/service/test/data_share_profile_config_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/data_share_profile_config_test.cpp @@ -17,8 +17,6 @@ #include #include -#define private public -#include "data_share_profile_config.h" #include "datashare_errno.h" #include "data_share_db_config.h" #include "data_share_profile_config.h" @@ -49,18 +47,19 @@ public: HWTEST_F(DataShareProfileConfigTest, GetDbConfig, TestSize.Level1) { DataShareDbConfig dbConfig; - auto result = dbConfig.GetDbConfig("", false, "", "", 0); + DataShareDbConfig::DbConfig config {"", "", "", "", "", 0, false}; + auto result = dbConfig.GetDbConfig(config); EXPECT_EQ(std::get<0>(result), NativeRdb::E_DB_NOT_EXIST); - bool hasExtension = true; - result = dbConfig.GetDbConfig("", hasExtension, "", "", 0); + config.hasExtension = true; + result = dbConfig.GetDbConfig(config); EXPECT_EQ(std::get<0>(result), NativeRdb::E_DB_NOT_EXIST); - std::string uri = DATA_SHARE_URI; - std::string bundleName = "bundleName"; - std::string storeName = "storeName"; - int32_t userId = USER_TEST; - result = dbConfig.GetDbConfig(uri, hasExtension, bundleName, storeName, userId); + config.uri = DATA_SHARE_URI; + config.bundleName = "bundleName"; + config.storeName = "storeName"; + config.userId = USER_TEST; + result = dbConfig.GetDbConfig(config); EXPECT_NE(std::get<0>(result), DataShare::E_OK); } diff --git a/datamgr_service/services/distributeddataservice/service/test/data_share_service_impl_test.cpp b/datamgr_service/services/distributeddataservice/service/test/data_share_service_impl_test.cpp index d86bd4aa..9d7648f9 100644 --- a/datamgr_service/services/distributeddataservice/service/test/data_share_service_impl_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/data_share_service_impl_test.cpp @@ -16,7 +16,6 @@ #include #include -#define private public #include "log_print.h" #include "ipc_skeleton.h" #include "data_share_service_stub.h" @@ -95,7 +94,7 @@ void DataShareServiceImplTest::TearDown(void) /** * @tc.name: DataShareServiceImpl001 -* @tc.desc: test Insert Update Query Delete abnormal scene +* @tc.desc: test InsertEx UpdateEx Query DeleteEx abnormal scene * @tc.type: FUNC * @tc.require:SQL */ @@ -110,19 +109,19 @@ HWTEST_F(DataShareServiceImplTest, DataShareServiceImpl001, TestSize.Level1) DataShare::DataShareValuesBucket valuesBucket; std::string name0 = ""; valuesBucket.Put("", name0); - auto result = dataShareServiceImpl.Insert(uri, valuesBucket); - EXPECT_EQ((result > 0), true); + auto [errCode, result] = dataShareServiceImpl.InsertEx(uri, "", valuesBucket); + EXPECT_EQ((errCode != 0), true); DataShare::DataSharePredicates predicates; std::string selections = ""; predicates.SetWhereClause(selections); - result = dataShareServiceImpl.Update(uri, predicates, valuesBucket); - EXPECT_EQ((result > 0), true); + auto [errCode1, result1] = dataShareServiceImpl.UpdateEx(uri, "", predicates, valuesBucket); + EXPECT_EQ((errCode1 != 0), true); predicates.EqualTo("", ""); std::vector columns; - int errCode = 0; - auto resQuery = dataShareServiceImpl.Query(uri, predicates, columns, errCode); + int errVal = 0; + auto resQuery = dataShareServiceImpl.Query(uri, "", predicates, columns, errVal); int resultSet = 0; if (resQuery != nullptr) { resQuery->GetRowCount(resultSet); @@ -130,8 +129,8 @@ HWTEST_F(DataShareServiceImplTest, DataShareServiceImpl001, TestSize.Level1) EXPECT_EQ(resultSet, 0); predicates.SetWhereClause(selections); - result = dataShareServiceImpl.Delete(uri, predicates); - EXPECT_EQ((result > 0), true); + auto [errCode2, result2] = dataShareServiceImpl.DeleteEx(uri, "", predicates); + EXPECT_EQ((errCode2 != 0), true); } /** @@ -286,8 +285,8 @@ HWTEST_F(DataShareServiceImplTest, SubscribeRdbData001, TestSize.Level1) DataShare::DataShareValuesBucket valuesBucket1, valuesBucket2; std::string name0 = "wang"; valuesBucket1.Put(TBL_NAME0, name0); - auto result4 = dataShareServiceImpl.Insert(uri, valuesBucket1); - EXPECT_EQ((result4 > 0), true); + auto [errCode4, result4] = dataShareServiceImpl.InsertEx(uri, "", valuesBucket1); + EXPECT_EQ((errCode4 != 0), true); std::vector result5 = dataShareServiceImpl.UnsubscribeRdbData(uris, tplId); EXPECT_EQ(result5.size(), uris.size()); @@ -297,8 +296,8 @@ HWTEST_F(DataShareServiceImplTest, SubscribeRdbData001, TestSize.Level1) std::string name1 = "wu"; valuesBucket2.Put(TBL_NAME1, name1); - auto result6 = dataShareServiceImpl.Insert(uri, valuesBucket2); - EXPECT_EQ((result6 > 0), true); + auto [errCode6, result6] = dataShareServiceImpl.InsertEx(uri, "", valuesBucket2); + EXPECT_EQ((errCode6 != 0), true); std::vector result7 = dataShareServiceImpl.DisableRdbSubs(uris, tplId); for (auto const &operationResult : result7) { diff --git a/datamgr_service/services/distributeddataservice/service/test/data_share_service_stub_test.cpp b/datamgr_service/services/distributeddataservice/service/test/data_share_service_stub_test.cpp index 0adae040..d006a70b 100644 --- a/datamgr_service/services/distributeddataservice/service/test/data_share_service_stub_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/data_share_service_stub_test.cpp @@ -16,7 +16,6 @@ #include #include -#define private public #include "log_print.h" #include "ipc_skeleton.h" #include "data_share_service_impl.h" @@ -59,7 +58,7 @@ HWTEST_F(DataShareServiceStubTest, OnRemoteRequest001, TestSize.Level1) request.RewindRead(0); MessageParcel reply; auto result = dataShareServiceStub->OnRemoteRequest(code, request, reply); - EXPECT_NE(result, IDataShareService::DATA_SHARE_ERROR); + EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); result = dataShareServiceStub->OnNotifyConnectDone(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_OK); @@ -87,7 +86,7 @@ HWTEST_F(DataShareServiceStubTest, OnRemoteRequest002, TestSize.Level1) /** * @tc.name: OnInsert001 -* @tc.desc: test Insert Update Query Delete function of abnormal scene +* @tc.desc: test InsertEx UpdateEx Query DeleteEx function of abnormal scene * @tc.type: FUNC * @tc.require:SQL */ @@ -101,16 +100,16 @@ HWTEST_F(DataShareServiceStubTest, OnInsert001, TestSize.Level1) request.WriteBuffer(data, size); request.RewindRead(0); MessageParcel reply; - auto result = dataShareServiceStub->OnInsert(request, reply); + auto result = dataShareServiceStub->OnInsertEx(request, reply); EXPECT_EQ(result, IPC_STUB_INVALID_DATA_ERR); - result = dataShareServiceStub->OnUpdate(request, reply); + result = dataShareServiceStub->OnUpdateEx(request, reply); EXPECT_EQ(result, IPC_STUB_INVALID_DATA_ERR); result = dataShareServiceStub->OnQuery(request, reply); EXPECT_EQ(result, IPC_STUB_INVALID_DATA_ERR); - result = dataShareServiceStub->OnDelete(request, reply); + result = dataShareServiceStub->OnDeleteEx(request, reply); EXPECT_EQ(result, IPC_STUB_INVALID_DATA_ERR); } diff --git a/datamgr_service/services/distributeddataservice/service/test/data_share_subscriber_managers_test.cpp b/datamgr_service/services/distributeddataservice/service/test/data_share_subscriber_managers_test.cpp index bd34b243..eedf4ba1 100644 --- a/datamgr_service/services/distributeddataservice/service/test/data_share_subscriber_managers_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/data_share_subscriber_managers_test.cpp @@ -15,8 +15,8 @@ #define LOG_TAG "DataShareSubscriberManagersTest" #include +#include -#define private public #include "accesstoken_kit.h" #include "datashare_errno.h" #include "data_share_service_impl.h" diff --git a/datamgr_service/services/distributeddataservice/service/test/device_matrix_test.cpp b/datamgr_service/services/distributeddataservice/service/test/device_matrix_test.cpp index 975e45f0..f72ffc56 100644 --- a/datamgr_service/services/distributeddataservice/service/test/device_matrix_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/device_matrix_test.cpp @@ -55,8 +55,8 @@ protected: static inline std::vector> staticStores_ = { { "bundle0", "store0" }, { "bundle1", "store0" } }; - static inline std::vector> dynamicStores_ = { - { "distributeddata", "service_meta" }, { "bundle0", "store1" }, { "bundle3", "store0" } }; + static inline std::vector> dynamicStores_ = { { "bundle0", "store1" }, + { "bundle3", "store0" } }; static BlockData isFinished_; static std::shared_ptr dbStoreMock_; static uint32_t selfToken_; @@ -89,38 +89,12 @@ void DeviceMatrixTest::SetUpTestCase(void) } Bootstrap::GetInstance().LoadCheckers(); DeviceMatrix::GetInstance().Initialize(selfToken_, "service_meta"); - EventCenter::GetInstance().Subscribe(DeviceMatrix::MATRIX_ONLINE, [](const Event &event) { - auto &evt = static_cast(event); - auto data = evt.GetMatrixData(); - auto deviceId = evt.GetDeviceId(); - if ((data.dynamic & DeviceMatrix::META_STORE_MASK) != 0) { - auto onComplete = [deviceId](const std::map &) { - DeviceMatrix::GetInstance().OnExchanged(deviceId, DeviceMatrix::META_STORE_MASK); - }; - dbStoreMock_->Sync({ deviceId }, SYNC_MODE_PUSH_PULL, onComplete, false); - } -#ifdef TEST_ON_DEVICE - auto finEvent = std::make_unique(DeviceMatrix::MATRIX_META_FINISHED, deviceId, data); - EventCenter::GetInstance().PostEvent(std::move(finEvent)); -#endif - }); - - EventCenter::GetInstance().Subscribe(DeviceMatrix::MATRIX_META_FINISHED, [](const Event &event) { - auto &evt = static_cast(event); - Result result; - result.deviceId_ = evt.GetDeviceId(); - result.mask_ = evt.GetMatrixData().dynamic; - isFinished_.SetValue(result); - }); - mkdir("/data/service/el1/public/database/matrix_test", (S_IRWXU | S_IRWXG | S_IRWXO)); mkdir("/data/service/el1/public/database/matrix_test/kvdb", (S_IRWXU | S_IRWXG | S_IRWXO)); } void DeviceMatrixTest::TearDownTestCase(void) { - EventCenter::GetInstance().Unsubscribe(DeviceMatrix::MATRIX_ONLINE); - EventCenter::GetInstance().Unsubscribe(DeviceMatrix::MATRIX_META_FINISHED); EventCenter::GetInstance().Unsubscribe(DeviceMatrix::MATRIX_BROADCAST); } @@ -171,86 +145,6 @@ void DeviceMatrixTest::InitMetaData() localMeta_.policies = { std::move(value) }; } -/** -* @tc.name: FirstOnline -* @tc.desc: the first online time; -* @tc.type: FUNC -* @tc.require: -* @tc.author: blue sky -*/ -HWTEST_F(DeviceMatrixTest, FirstOnline, TestSize.Level0) -{ - DeviceMatrix::GetInstance().Online(TEST_DEVICE); - auto result = isFinished_.GetValue(); - ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0x7); -} - -/** -* @tc.name: OnlineAgainNoData -* @tc.desc: the second online with no data change; -* @tc.type: FUNC -* @tc.require: -* @tc.author: blue sky -*/ -HWTEST_F(DeviceMatrixTest, OnlineAgainNoData, TestSize.Level0) -{ - DeviceMatrix::GetInstance().Online(TEST_DEVICE); - auto result = isFinished_.GetValue(); - ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0x7); - isFinished_.Clear(Result()); - DeviceMatrix::GetInstance().Offline(TEST_DEVICE); - DeviceMatrix::GetInstance().Online(TEST_DEVICE); - result = isFinished_.GetValue(); - ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0x6); -} - -/** -* @tc.name: OnlineAgainWithData -* @tc.desc: the second online with sync data change; -* @tc.type: FUNC -* @tc.require: -* @tc.author: blue sky -*/ -HWTEST_F(DeviceMatrixTest, OnlineAgainWithData, TestSize.Level0) -{ - DeviceMatrix::GetInstance().Online(TEST_DEVICE); - auto result = isFinished_.GetValue(); - ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0x7); - isFinished_.Clear(Result()); - DeviceMatrix::GetInstance().Offline(TEST_DEVICE); - MetaDataManager::GetInstance().SaveMeta(metaData_.GetKey(), metaData_); - DeviceMatrix::GetInstance().Online(TEST_DEVICE); - result = isFinished_.GetValue(); - ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0x7); -} - -/** -* @tc.name: OnlineAgainWithLocal -* @tc.desc: the second online with local data change; -* @tc.type: FUNC -* @tc.require: -* @tc.author: blue sky -*/ -HWTEST_F(DeviceMatrixTest, OnlineAgainWithLocal, TestSize.Level0) -{ - DeviceMatrix::GetInstance().Online(TEST_DEVICE); - auto result = isFinished_.GetValue(); - ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0x7); - isFinished_.Clear(Result()); - DeviceMatrix::GetInstance().Offline(TEST_DEVICE); - MetaDataManager::GetInstance().SaveMeta(metaData_.GetKeyLocal(), localMeta_, true); - DeviceMatrix::GetInstance().Online(TEST_DEVICE); - result = isFinished_.GetValue(); - ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0x6); -} - /** * @tc.name: GetMetaStoreCode * @tc.desc: get the meta data store mask code; @@ -283,7 +177,7 @@ HWTEST_F(DeviceMatrixTest, GetAllCode, TestSize.Level0) for (size_t i = 0; i < dynamicStores_.size(); ++i) { meta.appId = dynamicStores_[i].first; meta.bundleName = dynamicStores_[i].first; - ASSERT_EQ(DeviceMatrix::GetInstance().GetCode(meta), 0x1 << i); + ASSERT_EQ(DeviceMatrix::GetInstance().GetCode(meta), 0x1 << (i + 1)); } } @@ -327,8 +221,8 @@ HWTEST_F(DeviceMatrixTest, BroadcastMeta, TestSize.Level0) HWTEST_F(DeviceMatrixTest, BroadcastFirst, TestSize.Level0) { StoreMetaData meta = metaData_; - meta.appId = dynamicStores_[1].first; - meta.bundleName = dynamicStores_[1].first; + meta.appId = dynamicStores_[0].first; + meta.bundleName = dynamicStores_[0].first; auto code = DeviceMatrix::GetInstance().GetCode(meta); ASSERT_EQ(code, 0x2); DeviceMatrix::DataLevel level = { @@ -371,13 +265,13 @@ HWTEST_F(DeviceMatrixTest, BroadcastAll, TestSize.Level0) auto mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level); ASSERT_EQ(mask.first, DeviceMatrix::META_STORE_MASK); StoreMetaData meta = metaData_; - for (size_t i = 1; i < dynamicStores_.size(); ++i) { + for (size_t i = 0; i < dynamicStores_.size(); ++i) { meta.appId = dynamicStores_[i].first; meta.bundleName = dynamicStores_[i].first; auto code = DeviceMatrix::GetInstance().GetCode(meta); level.dynamic = code; mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level); - ASSERT_EQ(mask.first, (0x1 << i) + 1); + ASSERT_EQ(mask.first, (0x1 << (i + 1)) + 1); DeviceMatrix::GetInstance().OnExchanged(TEST_DEVICE, code); } DeviceMatrix::GetInstance().OnExchanged(TEST_DEVICE, DeviceMatrix::META_STORE_MASK); @@ -405,7 +299,7 @@ HWTEST_F(DeviceMatrixTest, UpdateMatrixMeta, TestSize.Level0) metaData.dynamic = 0x1F; metaData.deviceId = TEST_DEVICE; metaData.origin = MatrixMetaData::Origin::REMOTE_RECEIVED; - metaData.dynamicInfo = { TEST_BUNDLE, dynamicStores_[1].first }; + metaData.dynamicInfo = { TEST_BUNDLE, dynamicStores_[0].first }; MetaDataManager::GetInstance().Subscribe(MatrixMetaData::GetPrefix({ TEST_DEVICE }), [](const std::string &, const std::string &value, int32_t flag) { if (flag != MetaDataManager::INSERT && flag != MetaDataManager::UPDATE) { diff --git a/datamgr_service/services/distributeddataservice/service/test/dump_helper_test.cpp b/datamgr_service/services/distributeddataservice/service/test/dump_helper_test.cpp new file mode 100644 index 00000000..86ce2efb --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/dump_helper_test.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2024 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 "DumpHelperTest " + +#include "gtest/gtest.h" +#include "log_print.h" +#include "dump_helper.h" +#include "dump/dump_manager.h" +#include "types.h" + +using namespace OHOS; +using namespace testing; +using namespace testing::ext; +using namespace OHOS::DistributedData; +namespace OHOS::Test { +namespace DistributedDataTest { +class DumpHelperTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(); + void TearDown(){}; +}; + +void DumpHelperTest::SetUp(void) +{ + DumpManager &dumpManager = DumpManager::GetInstance(); + DumpManager::Config config; + config.dumpName = "test_dump"; + config.fullCmd = "test_full_cmd"; + config.abbrCmd = "test_abbr_cmd"; + config.countPrintf = 1; + config.infoName = "test_info"; + config.minParamsNum = 2; //minParamsNum is 2 + config.maxParamsNum = 5; //maxParamsNum is 5 + config.parentNode = "test_parent"; + config.childNode = "test_child"; + config.dumpCaption = {"test_caption1", "test_caption2"}; + + dumpManager.AddConfig("111", config); + dumpManager.GetHandler(config.infoName); + DumpManager::Config result = dumpManager.GetConfig("111"); + ASSERT_EQ(result.dumpName, config.dumpName); +} + +/** +* @tc.name: GetInstanceTest +* @tc.desc: GetInstance test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(DumpHelperTest, GetInstanceTest, TestSize.Level0) +{ + DumpHelper &dumpHelper = DumpHelper::GetInstance(); + EXPECT_NE(&dumpHelper, nullptr); + + int fd = 1; + std::vector args; + EXPECT_TRUE(dumpHelper.Dump(fd, args)); + + args = {"COMMAND_A", "ARG_1", "ARG_2"}; + EXPECT_TRUE(dumpHelper.Dump(fd, args)); +} + +/** +* @tc.name: AddErrorInfoTest +* @tc.desc: AddErrorInfo test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(DumpHelperTest, AddErrorInfoTest, TestSize.Level0) +{ + DumpHelper &dumpHelper = DumpHelper::GetInstance(); + EXPECT_NE(&dumpHelper, nullptr); + int32_t errorCode = 1001; + std::string errorInfo = "Test error information"; + + dumpHelper.AddErrorInfo(errorCode, errorInfo); + + const OHOS::DistributedData::DumpHelper::ErrorInfo& lastError = dumpHelper.errorInfo_.back(); + EXPECT_EQ(lastError.errorCode, errorCode); + EXPECT_EQ(lastError.errorInfo, errorInfo); +} +} // namespace DistributedDataTest +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn index 2007179c..4f44b6a1 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/BUILD.gn @@ -75,6 +75,7 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/common/xcollie.cpp", "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/app_id_mapping_config.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", "${data_service_path}/service/config/src/model/cloud_config.cpp", diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/BUILD.gn index 485c816f..c495c98f 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/BUILD.gn @@ -99,6 +99,7 @@ ohos_fuzztest("CustomUtdInstallerFuzzTest") { "safwk:system_ability_fwk", "samgr:samgr_proxy", "udmf:udmf_client", + "udmf:utd_client", ] } diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn index 7e0a8249..83c0d398 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/BUILD.gn @@ -63,6 +63,7 @@ ohos_fuzztest("KvdbServiceStubFuzzTest") { "${data_service_path}/service/bootstrap/src/bootstrap.cpp", "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/app_id_mapping_config.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", "${data_service_path}/service/config/src/model/cloud_config.cpp", @@ -83,7 +84,6 @@ ohos_fuzztest("KvdbServiceStubFuzzTest") { "${data_service_path}/service/kvdb/query_helper.cpp", "${data_service_path}/service/kvdb/upgrade.cpp", "${data_service_path}/service/kvdb/user_delegate.cpp", - "${data_service_path}/service/matrix/src/auto_sync_matrix.cpp", "${data_service_path}/service/matrix/src/device_matrix.cpp", "${data_service_path}/service/matrix/src/matrix_event.cpp", "${data_service_path}/service/permission/src/permit_delegate.cpp", diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn index 9f310308..d268b6b6 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/BUILD.gn @@ -62,6 +62,7 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "${data_service_path}/service/common/common_types_utils.cpp", "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/app_id_mapping_config.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", "${data_service_path}/service/config/src/model/cloud_config.cpp", diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn index f45834ee..a6ffe6bb 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/BUILD.gn @@ -69,6 +69,7 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/common/xcollie.cpp", "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/app_id_mapping_config.cpp", "${data_service_path}/service/config/src/model/backup_config.cpp", "${data_service_path}/service/config/src/model/checker_config.cpp", "${data_service_path}/service/config/src/model/cloud_config.cpp", diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/BUILD.gn index 2c399378..82fe2b86 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/BUILD.gn @@ -56,7 +56,6 @@ ohos_fuzztest("UdmfServiceFuzzTest") { "bundle_framework:appexecfwk_core", "c_utils:utils", "hilog:libhilog", - "image_framework:image", "ipc:ipc_core", "kv_store:distributeddata_inner", "kv_store:distributeddata_mgr", diff --git a/datamgr_service/services/distributeddataservice/service/test/kvdb_general_store_test.cpp b/datamgr_service/services/distributeddataservice/service/test/kvdb_general_store_test.cpp index 23a555dd..557d62d5 100644 --- a/datamgr_service/services/distributeddataservice/service/test/kvdb_general_store_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/kvdb_general_store_test.cpp @@ -18,30 +18,38 @@ #include #include +#include #include "bootstrap.h" +#include "cloud/schema_meta.h" +#include "cloud/asset_loader.h" +#include "cloud/cloud_db.h" #include "crypto_manager.h" #include "kvdb_query.h" +#include "kv_store_nb_delegate_mock.h" #include "log_print.h" #include "metadata/meta_data_manager.h" #include "metadata/secret_key_meta_data.h" #include "metadata/store_meta_data.h" #include "metadata/store_meta_data_local.h" #include "mock/db_store_mock.h" +#include "mock/general_watcher_mock.h" using namespace testing::ext; +using namespace DistributedDB; +using namespace OHOS::DistributedData; using DBStoreMock = OHOS::DistributedData::DBStoreMock; using StoreMetaData = OHOS::DistributedData::StoreMetaData; - -namespace OHOS { -namespace DistributedKv { +using SecurityLevel = OHOS::DistributedKv::SecurityLevel; +using KVDBGeneralStore = OHOS::DistributedKv::KVDBGeneralStore; +namespace OHOS::Test { +namespace DistributedDataTest { class KVDBGeneralStoreTest : public testing::Test { public: static void SetUpTestCase(void); static void TearDownTestCase(void); void SetUp(); void TearDown(); - protected: static constexpr const char *bundleName = "test_distributeddata"; static constexpr const char *storeName = "test_service_meta"; @@ -64,7 +72,7 @@ void KVDBGeneralStoreTest::InitMetaData() metaData_.area = OHOS::DistributedKv::EL1; metaData_.instanceId = 0; metaData_.isAutoSync = true; - metaData_.storeType = KvStoreType::SINGLE_VERSION; + metaData_.storeType = DistributedKv::KvStoreType::SINGLE_VERSION; metaData_.storeId = storeName; metaData_.dataDir = "/data/service/el1/public/database/" + std::string(bundleName) + "/kvdb"; metaData_.securityLevel = SecurityLevel::S2; @@ -95,6 +103,48 @@ void KVDBGeneralStoreTest::SetUp() void KVDBGeneralStoreTest::TearDown() {} +class MockGeneralWatcher : public DistributedData::GeneralWatcher { +public: + int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) override + { + return GeneralError::E_OK; + } + + int32_t OnChange(const Origin &origin, const Fields &fields, ChangeData &&datas) override + { + return GeneralError::E_OK; + } +}; + +class MockKvStoreChangedData : public DistributedDB::KvStoreChangedData { +public: + MockKvStoreChangedData() {} + virtual ~MockKvStoreChangedData() {} + std::list entriesInserted = {}; + std::list entriesUpdated = {}; + std::list entriesDeleted = {}; + bool isCleared = true; + const std::list& GetEntriesInserted() const override + { + return entriesInserted; + } + + const std::list& GetEntriesUpdated() const override + { + return entriesUpdated; + } + + const std::list& GetEntriesDeleted() const override + { + return entriesDeleted; + } + + bool IsCleared() const override + { + return isCleared; + } +}; + /** * @tc.name: GetDBPasswordTest_001 * @tc.desc: GetDBPassword from meta. @@ -177,6 +227,11 @@ HWTEST_F(KVDBGeneralStoreTest, GetDBSecurityTest, TestSize.Level0) dbSecurity = KVDBGeneralStore::GetDBSecurity(SecurityLevel::S4); EXPECT_EQ(dbSecurity.securityLabel, DistributedDB::S4); EXPECT_EQ(dbSecurity.securityFlag, DistributedDB::ECE); + + auto action = static_cast(SecurityLevel::S4 + 1); + dbSecurity = KVDBGeneralStore::GetDBSecurity(action); + EXPECT_EQ(dbSecurity.securityLabel, DistributedDB::NOT_SET); + EXPECT_EQ(dbSecurity.securityFlag, DistributedDB::ECE); } /** @@ -206,7 +261,7 @@ HWTEST_F(KVDBGeneralStoreTest, GetDBOptionTest, TestSize.Level0) /** * @tc.name: CloseTest -* @tc.desc: Close kvdb general store. +* @tc.desc: Close kvdb general store and test the functionality of different branches. * @tc.type: FUNC * @tc.require: * @tc.author: Hollokin @@ -217,6 +272,36 @@ HWTEST_F(KVDBGeneralStoreTest, CloseTest, TestSize.Level0) ASSERT_NE(store, nullptr); auto ret = store->Close(); EXPECT_EQ(ret, GeneralError::E_OK); + + KvStoreNbDelegateMock mockDelegate; + mockDelegate.taskCountMock_ = 1; + store->delegate_ = &mockDelegate; + EXPECT_NE(store->delegate_, nullptr); + ret = store->Close(); + EXPECT_EQ(ret, GeneralError::E_BUSY); +} + +/** +* @tc.name: Close +* @tc.desc: RdbGeneralStore Close test +* @tc.type: FUNC +* @tc.require: +* @tc.author: shaoyuanzhao +*/ +HWTEST_F(KVDBGeneralStoreTest, BusyClose, TestSize.Level0) +{ + auto store = std::make_shared(metaData_); + ASSERT_NE(store, nullptr); + std::thread thread([store]() { + std::unique_lockrwMutex_)> lock(store->rwMutex_); + std::this_thread::sleep_for(std::chrono::seconds(1)); + }); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + auto ret = store->Close(); + EXPECT_EQ(ret, GeneralError::E_BUSY); + thread.join(); + ret = store->Close(); + EXPECT_EQ(ret, GeneralError::E_OK); } /** @@ -237,7 +322,7 @@ HWTEST_F(KVDBGeneralStoreTest, SyncTest, TestSize.Level0) uint32_t highMode = GeneralStore::HighMode::MANUAL_SYNC_MODE; auto mixMode = GeneralStore::MixMode(syncMode, highMode); std::string kvQuery = ""; - KVDBQuery query(kvQuery); + DistributedKv::KVDBQuery query(kvQuery); SyncParam syncParam{}; syncParam.mode = mixMode; auto ret = store->Sync( @@ -246,5 +331,396 @@ HWTEST_F(KVDBGeneralStoreTest, SyncTest, TestSize.Level0) ret = store->Close(); EXPECT_EQ(ret, GeneralError::E_OK); } + +/** +* @tc.name: BindTest +* @tc.desc: Bind test the functionality of different branches. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(KVDBGeneralStoreTest, BindTest, TestSize.Level0) +{ + auto store = new (std::nothrow) KVDBGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + DistributedData::Database database; + std::map bindInfos; + GeneralStore::CloudConfig config; + EXPECT_EQ(bindInfos.empty(), true); + auto ret = store->Bind(database, bindInfos, config); + EXPECT_EQ(ret, GeneralError::E_OK); + + std::shared_ptr db; + std::shared_ptr loader; + GeneralStore::BindInfo bindInfo1(db, loader); + uint32_t key = 1; + bindInfos[key] = bindInfo1; + ret = store->Bind(database, bindInfos, config); + EXPECT_EQ(ret, GeneralError::E_INVALID_ARGS); + std::shared_ptr dbs = std::make_shared(); + std::shared_ptr loaders = std::make_shared(); + GeneralStore::BindInfo bindInfo2(dbs, loaders); + bindInfos[key] = bindInfo2; + EXPECT_EQ(store->IsBound(), false); + ret = store->Bind(database, bindInfos, config); + EXPECT_EQ(ret, GeneralError::E_ALREADY_CLOSED); + + store->isBound_ = false; + KvStoreNbDelegateMock mockDelegate; + store->delegate_ = &mockDelegate; + EXPECT_NE(store->delegate_, nullptr); + EXPECT_EQ(store->IsBound(), false); + ret = store->Bind(database, bindInfos, config); + EXPECT_EQ(ret, GeneralError::E_OK); + + EXPECT_EQ(store->IsBound(), true); + ret = store->Bind(database, bindInfos, config); + EXPECT_EQ(ret, GeneralError::E_OK); +} + +/** +* @tc.name: GetDBSyncCompleteCB +* @tc.desc: GetDBSyncCompleteCB test the functionality of different branches. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(KVDBGeneralStoreTest, GetDBSyncCompleteCB, TestSize.Level0) +{ + auto store = new (std::nothrow) KVDBGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + GeneralStore::DetailAsync async; + EXPECT_EQ(async, nullptr); + KVDBGeneralStore::DBSyncCallback ret = store->GetDBSyncCompleteCB(async); + EXPECT_NE(ret, nullptr); + auto asyncs = [](const GenDetails &result) {}; + EXPECT_NE(asyncs, nullptr); + ret = store->GetDBSyncCompleteCB(asyncs); + EXPECT_NE(ret, nullptr); +} + +/** +* @tc.name: CloudSync +* @tc.desc: CloudSync test the functionality of different branches. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(KVDBGeneralStoreTest, CloudSync, TestSize.Level0) +{ + auto store = new (std::nothrow) KVDBGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + store->SetEqualIdentifier(bundleName, storeName); + KvStoreNbDelegateMock mockDelegate; + store->delegate_ = &mockDelegate; + std::vector devices = {"device1", "device2"}; + auto asyncs = [](const GenDetails &result) {}; + store->storeInfo_.user = 0; + auto cloudSyncMode = DistributedDB::SyncMode::SYNC_MODE_PUSH_ONLY; + store->SetEqualIdentifier(bundleName, storeName); + auto ret = store->CloudSync(devices, cloudSyncMode, asyncs, 0); + EXPECT_EQ(ret, DBStatus::OK); + + store->storeInfo_.user = 1; + cloudSyncMode = DistributedDB::SyncMode::SYNC_MODE_CLOUD_FORCE_PUSH; + ret = store->CloudSync(devices, cloudSyncMode, asyncs, 0); + EXPECT_EQ(ret, DBStatus::OK); +} + +/** +* @tc.name: Sync +* @tc.desc: Sync test the functionality of different branches. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(KVDBGeneralStoreTest, Sync, TestSize.Level0) +{ + mkdir(("/data/service/el1/public/database/" + std::string(bundleName)).c_str(), + (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); + auto store = new (std::nothrow) KVDBGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + uint32_t syncMode = GeneralStore::SyncMode::CLOUD_BEGIN; + uint32_t highMode = GeneralStore::HighMode::MANUAL_SYNC_MODE; + auto mixMode = GeneralStore::MixMode(syncMode, highMode); + std::string kvQuery = ""; + DistributedKv::KVDBQuery query(kvQuery); + SyncParam syncParam{}; + syncParam.mode = mixMode; + KvStoreNbDelegateMock mockDelegate; + store->delegate_ = &mockDelegate; + auto ret = store->Sync({}, query, [](const GenDetails &result) {}, syncParam); + EXPECT_EQ(ret, GeneralError::E_NOT_SUPPORT); + GeneralStore::StoreConfig storeConfig; + storeConfig.enableCloud_ = true; + store->SetConfig(storeConfig); + ret = store->Sync({}, query, [](const GenDetails &result) {}, syncParam); + EXPECT_EQ(ret, GeneralError::E_OK); + + syncMode = GeneralStore::SyncMode::NEARBY_END; + mixMode = GeneralStore::MixMode(syncMode, highMode); + syncParam.mode = mixMode; + ret = store->Sync({}, query, [](const GenDetails &result) {}, syncParam); + EXPECT_EQ(ret, GeneralError::E_INVALID_ARGS); + + std::vector devices = {"device1", "device2"}; + syncMode = GeneralStore::SyncMode::NEARBY_SUBSCRIBE_REMOTE; + mixMode = GeneralStore::MixMode(syncMode, highMode); + syncParam.mode = mixMode; + ret = store->Sync(devices, query, [](const GenDetails &result) {}, syncParam); + EXPECT_EQ(ret, GeneralError::E_OK); + + syncMode = GeneralStore::SyncMode::NEARBY_UNSUBSCRIBE_REMOTE; + mixMode = GeneralStore::MixMode(syncMode, highMode); + syncParam.mode = mixMode; + ret = store->Sync(devices, query, [](const GenDetails &result) {}, syncParam); + EXPECT_EQ(ret, GeneralError::E_OK); + + syncMode = GeneralStore::SyncMode::NEARBY_PULL_PUSH; + mixMode = GeneralStore::MixMode(syncMode, highMode); + syncParam.mode = mixMode; + ret = store->Sync(devices, query, [](const GenDetails &result) {}, syncParam); + EXPECT_EQ(ret, GeneralError::E_OK); + + syncMode = GeneralStore::SyncMode::MODE_BUTT; + mixMode = GeneralStore::MixMode(syncMode, highMode); + syncParam.mode = mixMode; + ret = store->Sync(devices, query, [](const GenDetails &result) {}, syncParam); + EXPECT_EQ(ret, GeneralError::E_ERROR); +} + +/** +* @tc.name: Clean +* @tc.desc: Clean test the functionality of different branches. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(KVDBGeneralStoreTest, Clean, TestSize.Level0) +{ + auto store = new (std::nothrow) KVDBGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::vector devices = {"device1", "device2"}; + std::string tableName = "tableName"; + auto ret = store->Clean(devices, -1, tableName); + EXPECT_EQ(ret, GeneralError::E_INVALID_ARGS); + ret = store->Clean(devices, 5, tableName); + EXPECT_EQ(ret, GeneralError::E_INVALID_ARGS); + ret = store->Clean(devices, GeneralStore::CleanMode::NEARBY_DATA, tableName); + EXPECT_EQ(ret, GeneralError::E_ALREADY_CLOSED); + + KvStoreNbDelegateMock mockDelegate; + store->delegate_ = &mockDelegate; + ret = store->Clean(devices, GeneralStore::CleanMode::CLOUD_INFO, tableName); + EXPECT_EQ(ret, GeneralError::E_OK); + + ret = store->Clean(devices, GeneralStore::CleanMode::CLOUD_DATA, tableName); + EXPECT_EQ(ret, GeneralError::E_OK); + + ret = store->Clean({}, GeneralStore::CleanMode::NEARBY_DATA, tableName); + EXPECT_EQ(ret, GeneralError::E_OK); + ret = store->Clean(devices, GeneralStore::CleanMode::NEARBY_DATA, tableName); + EXPECT_EQ(ret, GeneralError::E_OK); + + ret = store->Clean(devices, GeneralStore::CleanMode::LOCAL_DATA, tableName); + EXPECT_EQ(ret, GeneralError::E_ERROR); +} + +/** +* @tc.name: Watch +* @tc.desc: Watch and Unwatch test the functionality of different branches. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(KVDBGeneralStoreTest, Watch, TestSize.Level0) +{ + auto store = new (std::nothrow) KVDBGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + DistributedDataTest::MockGeneralWatcher watcher; + auto ret = store->Watch(GeneralWatcher::Origin::ORIGIN_CLOUD, watcher); + EXPECT_EQ(ret, GeneralError::E_INVALID_ARGS); + ret = store->Unwatch(GeneralWatcher::Origin::ORIGIN_CLOUD, watcher); + EXPECT_EQ(ret, GeneralError::E_INVALID_ARGS); + + ret = store->Watch(GeneralWatcher::Origin::ORIGIN_ALL, watcher); + EXPECT_EQ(ret, GeneralError::E_OK); + ret = store->Watch(GeneralWatcher::Origin::ORIGIN_ALL, watcher); + EXPECT_EQ(ret, GeneralError::E_INVALID_ARGS); + + ret = store->Unwatch(GeneralWatcher::Origin::ORIGIN_ALL, watcher); + EXPECT_EQ(ret, GeneralError::E_OK); + ret = store->Unwatch(GeneralWatcher::Origin::ORIGIN_ALL, watcher); + EXPECT_EQ(ret, GeneralError::E_INVALID_ARGS); +} + +/** +* @tc.name: Release +* @tc.desc: Release and AddRef test the functionality of different branches. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(KVDBGeneralStoreTest, Release, TestSize.Level0) +{ + auto store = new (std::nothrow) KVDBGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + auto ret = store->Release(); + EXPECT_EQ(ret, 0); + store = new (std::nothrow) KVDBGeneralStore(metaData_); + store->ref_ = 0; + ret = store->Release(); + EXPECT_EQ(ret, 0); + store->ref_ = 2; + ret = store->Release(); + EXPECT_EQ(ret, 1); + + ret = store->AddRef(); + EXPECT_EQ(ret, 2); + store->ref_ = 0; + ret = store->AddRef(); + EXPECT_EQ(ret, 0); +} + +/** +* @tc.name: ConvertStatus +* @tc.desc: ConvertStatus test the functionality of different branches. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(KVDBGeneralStoreTest, ConvertStatus, TestSize.Level0) +{ + auto store = new (std::nothrow) KVDBGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + auto ret = store->ConvertStatus(DBStatus::OK); + EXPECT_EQ(ret, GeneralError::E_OK); + ret = store->ConvertStatus(DBStatus::CLOUD_NETWORK_ERROR); + EXPECT_EQ(ret, GeneralError::E_NETWORK_ERROR); + ret = store->ConvertStatus(DBStatus::CLOUD_LOCK_ERROR); + EXPECT_EQ(ret, GeneralError::E_LOCKED_BY_OTHERS); + ret = store->ConvertStatus(DBStatus::CLOUD_FULL_RECORDS); + EXPECT_EQ(ret, GeneralError::E_RECODE_LIMIT_EXCEEDED); + ret = store->ConvertStatus(DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT); + EXPECT_EQ(ret, GeneralError::E_NO_SPACE_FOR_ASSET); + ret = store->ConvertStatus(DBStatus::CLOUD_SYNC_TASK_MERGED); + EXPECT_EQ(ret, GeneralError::E_SYNC_TASK_MERGED); + ret = store->ConvertStatus(DBStatus::DB_ERROR); + EXPECT_EQ(ret, GeneralError::E_ERROR); +} + +/** +* @tc.name: GetWaterVersion +* @tc.desc: GetWaterVersion test the functionality of different branches. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(KVDBGeneralStoreTest, GetWaterVersion, TestSize.Level0) +{ + auto store = new (std::nothrow) KVDBGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string deviceId = "deviceId"; + std::vector res = {}; + auto ret = store->GetWaterVersion(deviceId); + EXPECT_EQ(ret, res); + KvStoreNbDelegateMock mockDelegate; + store->delegate_ = &mockDelegate; + ret = store->GetWaterVersion(""); + EXPECT_EQ(ret, res); + ret = store->GetWaterVersion("test"); + EXPECT_EQ(ret, res); + ret = store->GetWaterVersion("device"); + EXPECT_EQ(ret, res); + res = {"deviceId"}; + ret = store->GetWaterVersion(deviceId); + EXPECT_EQ(ret, res); +} + +/** +* @tc.name: OnChange +* @tc.desc: OnChange test the functionality of different branches. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(KVDBGeneralStoreTest, OnChange, TestSize.Level0) +{ + auto store = new (std::nothrow) KVDBGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + DistributedDataTest::MockGeneralWatcher watcher; + DistributedDataTest::MockKvStoreChangedData data; + DistributedDB::ChangedData changedData; + store->observer_.OnChange(data); + store->observer_.OnChange(DistributedDB::Origin::ORIGIN_CLOUD, "originalId", std::move(changedData)); + auto result = store->Watch(GeneralWatcher::Origin::ORIGIN_ALL, watcher); + EXPECT_EQ(result, GeneralError::E_OK); + store->observer_.OnChange(data); + store->observer_.OnChange(DistributedDB::Origin::ORIGIN_CLOUD, "originalId", std::move(changedData)); + result = store->Unwatch(GeneralWatcher::Origin::ORIGIN_ALL, watcher); + EXPECT_EQ(result, GeneralError::E_OK); +} + +/** +* @tc.name: Delete +* @tc.desc: Delete test the function. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(KVDBGeneralStoreTest, Delete, TestSize.Level0) +{ + auto store = new (std::nothrow) KVDBGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + KvStoreNbDelegateMock mockDelegate; + store->delegate_ = &mockDelegate; + store->SetDBPushDataInterceptor(DistributedKv::KvStoreType::DEVICE_COLLABORATION); + store->SetDBReceiveDataInterceptor(DistributedKv::KvStoreType::DEVICE_COLLABORATION); + DistributedData::VBuckets values; + auto ret = store->Insert("table", std::move(values)); + EXPECT_EQ(ret, GeneralError::E_NOT_SUPPORT); + + DistributedData::Values args; + store->SetDBPushDataInterceptor(DistributedKv::KvStoreType::SINGLE_VERSION); + store->SetDBReceiveDataInterceptor(DistributedKv::KvStoreType::SINGLE_VERSION); + ret = store->Delete("table", "sql", std::move(args)); + EXPECT_EQ(ret, GeneralError::E_NOT_SUPPORT); +} + +/** +* @tc.name: Query001 +* @tc.desc: KVDBGeneralStoreTest Query function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(KVDBGeneralStoreTest, Query001, TestSize.Level1) +{ + auto store = new (std::nothrow) KVDBGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string table = "table"; + std::string sql = "sql"; + auto [errCode, result] = store->Query(table, sql, {}); + EXPECT_EQ(errCode, GeneralError::E_NOT_SUPPORT); + EXPECT_EQ(result, nullptr); +} + +/** +* @tc.name: Query002 +* @tc.desc: KVDBGeneralStoreTest Query function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(KVDBGeneralStoreTest, Query002, TestSize.Level1) +{ + auto store = new (std::nothrow) KVDBGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string table = "table"; + MockQuery query; + auto [errCode, result] = store->Query(table, query); + EXPECT_EQ(errCode, GeneralError::E_NOT_SUPPORT); + EXPECT_EQ(result, nullptr); +} } // namespace DistributedDataTest -} // namespace OHOS::Test +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/kvdb_service_impl_test.cpp b/datamgr_service/services/distributeddataservice/service/test/kvdb_service_impl_test.cpp index 6360e4cd..2fb8c186 100644 --- a/datamgr_service/services/distributeddataservice/service/test/kvdb_service_impl_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/kvdb_service_impl_test.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022 Huawei Device Co., Ltd. +* Copyright (c) 2024 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 @@ -16,32 +16,40 @@ #include #include "log_print.h" #include "accesstoken_kit.h" +#include "bootstrap.h" +#include "checker/checker_manager.h" +#include "distributed_kv_data_manager.h" +#include "device_manager_adapter.h" +#include "ipc_skeleton.h" #include "nativetoken_kit.h" - +#include "kvdb_service_impl.h" #include "kvdb_service_stub.h" -#include "checker/checker_manager.h" +#include "kvstore_death_recipient.h" +#include "kvstore_meta_manager.h" #include "utils/constant.h" #include "utils/anonymous.h" -#include "distributed_kv_data_manager.h" - -#include -#include "kvstore_death_recipient.h" +#include "token_setproc.h" #include "types.h" -#include "kvdb_service_impl.h" +#include using namespace testing::ext; using namespace OHOS::DistributedData; using namespace OHOS::Security::AccessToken; - -using Status = OHOS::DistributedKv::Status; +using Action = OHOS::DistributedData::MetaDataManager::Action; +using AppId = OHOS::DistributedKv::AppId; +using ChangeType = OHOS::DistributedData::DeviceMatrix::ChangeType; +using DistributedKvDataManager = OHOS::DistributedKv::DistributedKvDataManager; +using DBStatus = DistributedDB::DBStatus; +using DBMode = DistributedDB::SyncMode; using Options = OHOS::DistributedKv::Options; +using Status = OHOS::DistributedKv::Status; using SingleKvStore = OHOS::DistributedKv::SingleKvStore; -using DistributedKvDataManager = OHOS::DistributedKv::DistributedKvDataManager; -using UserId = OHOS::DistributedKv::UserId; - using StoreId = OHOS::DistributedKv::StoreId; -using AppId = OHOS::DistributedKv::AppId; using SyncInfo = OHOS::DistributedKv::KVDBService::SyncInfo; +using SyncMode = OHOS::DistributedKv::SyncMode; +using SyncAction = OHOS::DistributedKv::KVDBServiceImpl::SyncAction; +using SwitchState = OHOS::DistributedKv::SwitchState; +using UserId = OHOS::DistributedKv::UserId; static OHOS::DistributedKv::StoreId storeId = { "kvdb_test_storeid" }; static OHOS::DistributedKv::AppId appId = { "ohos.test.kvdb" }; @@ -90,7 +98,6 @@ void KvdbServiceImplTest::SetUpTestCase(void) { auto executors = std::make_shared(NUM_MAX, NUM_MIN); manager.SetExecutors(executors); - userId.userId = "kvdbserviceimpltest1"; appId.appId = "ohos.kvdbserviceimpl.test"; create.createIfMissing = true; @@ -128,6 +135,45 @@ void KvdbServiceImplTest::TearDown(void) KvdbServiceImplTest::KvdbServiceImplTest(void) {} +/** +* @tc.name: KvdbServiceImpl001 +* @tc.desc: KvdbServiceImplTest function test. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KvdbServiceImplTest, KvdbServiceImpl001, TestSize.Level0) +{ + std::string device = "OH_device_test"; + StoreId id1; + id1.storeId = "id1"; + Status status = manager.GetSingleKvStore(create, appId, id1, kvStore); + EXPECT_NE(kvStore, nullptr); + EXPECT_EQ(status, Status::SUCCESS); + int32_t result = kvdbServiceImpl_->OnInitialize(); + EXPECT_EQ(result, Status::SUCCESS); + FeatureSystem::Feature::BindInfo bindInfo; + result = kvdbServiceImpl_->OnBind(bindInfo); + EXPECT_EQ(result, Status::SUCCESS); + result = kvdbServiceImpl_->Online(device); + EXPECT_EQ(result, Status::SUCCESS); + status = kvdbServiceImpl_->SubscribeSwitchData(appId); + EXPECT_EQ(status, Status::SUCCESS); + SyncInfo syncInfo; + status = kvdbServiceImpl_->CloudSync(appId, id1, syncInfo); + EXPECT_EQ(status, Status::INVALID_ARGUMENT); + + DistributedKv::StoreConfig storeConfig; + status = kvdbServiceImpl_->SetConfig(appId, id1, storeConfig); + EXPECT_EQ(status, Status::SUCCESS); + status = kvdbServiceImpl_->NotifyDataChange(appId, id1, 0); + EXPECT_EQ(status, Status::INVALID_ARGUMENT); + + status = kvdbServiceImpl_->UnsubscribeSwitchData(appId); + EXPECT_EQ(status, Status::SUCCESS); + status = kvdbServiceImpl_->Close(appId, id1); + EXPECT_EQ(status, Status::SUCCESS); +} + /** * @tc.name: GetStoreIdsTest001 * @tc.desc: GetStoreIds @@ -536,6 +582,218 @@ HWTEST_F(KvdbServiceImplTest, OnReadyTest001, TestSize.Level0) auto status = kvdbServiceImpl_->OnReady(device); ZLOGI("OnReadyTest001 status = :%{public}d", status); ASSERT_EQ(status, Status::SUCCESS); + status = kvdbServiceImpl_->OnSessionReady(device); + ASSERT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: ResolveAutoLaunch +* @tc.desc: ResolveAutoLaunch function test. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KvdbServiceImplTest, ResolveAutoLaunch, TestSize.Level0) +{ + StoreId id1; + id1.storeId = "id1"; + Status status = manager.GetSingleKvStore(create, appId, id1, kvStore); + EXPECT_NE(kvStore, nullptr); + EXPECT_EQ(status, Status::SUCCESS); + std::string identifier = "identifier"; + DistributedKv::KVDBServiceImpl::DBLaunchParam launchParam; + auto result = kvdbServiceImpl_->ResolveAutoLaunch(identifier, launchParam); + EXPECT_EQ(result, Status::STORE_NOT_FOUND); + std::shared_ptr executors = std::make_shared(1, 0); + Bootstrap::GetInstance().LoadDirectory(); + Bootstrap::GetInstance().LoadCheckers(); + DistributedKv::KvStoreMetaManager::GetInstance().BindExecutor(executors); + DistributedKv::KvStoreMetaManager::GetInstance().InitMetaParameter(); + DistributedKv::KvStoreMetaManager::GetInstance().InitMetaListener(); + result = kvdbServiceImpl_->ResolveAutoLaunch(identifier, launchParam); + EXPECT_EQ(result, Status::SUCCESS); +} + +/** +* @tc.name: PutSwitch +* @tc.desc: PutSwitch function test. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KvdbServiceImplTest, PutSwitch, TestSize.Level0) +{ + StoreId id1; + id1.storeId = "id1"; + Status status = manager.GetSingleKvStore(create, appId, id1, kvStore); + ASSERT_NE(kvStore, nullptr); + ASSERT_EQ(status, Status::SUCCESS); + DistributedKv::SwitchData switchData; + status = kvdbServiceImpl_->PutSwitch(appId, switchData); + EXPECT_EQ(status, Status::INVALID_ARGUMENT); + switchData.value = DeviceMatrix::INVALID_VALUE; + switchData.length = DeviceMatrix::INVALID_LEVEL; + status = kvdbServiceImpl_->PutSwitch(appId, switchData); + EXPECT_EQ(status, Status::INVALID_ARGUMENT); + switchData.value = DeviceMatrix::INVALID_MASK; + switchData.length = DeviceMatrix::INVALID_LENGTH; + status = kvdbServiceImpl_->PutSwitch(appId, switchData); + EXPECT_EQ(status, Status::INVALID_ARGUMENT); + switchData.value = DeviceMatrix::INVALID_VALUE; + switchData.length = DeviceMatrix::INVALID_LENGTH; + status = kvdbServiceImpl_->PutSwitch(appId, switchData); + EXPECT_EQ(status, Status::INVALID_ARGUMENT); + switchData.value = DeviceMatrix::INVALID_MASK; + switchData.length = DeviceMatrix::INVALID_LEVEL; + status = kvdbServiceImpl_->PutSwitch(appId, switchData); + EXPECT_EQ(status, Status::SUCCESS); + std::string networkId = "networkId"; + status = kvdbServiceImpl_->GetSwitch(appId, networkId, switchData); + EXPECT_EQ(status, Status::INVALID_ARGUMENT); +} + +/** +* @tc.name: DoCloudSync +* @tc.desc: DoCloudSync error function test. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KvdbServiceImplTest, DoCloudSync, TestSize.Level0) +{ + StoreId id1; + id1.storeId = "id1"; + Status status = manager.GetSingleKvStore(create, appId, id1, kvStore); + ASSERT_NE(kvStore, nullptr); + ASSERT_EQ(status, Status::SUCCESS); + StoreMetaData metaData; + SyncInfo syncInfo; + status = kvdbServiceImpl_->DoCloudSync(metaData, syncInfo); + EXPECT_EQ(status, Status::NOT_SUPPORT); + syncInfo.devices = {"device1", "device2"}; + syncInfo.query = "query"; + metaData.enableCloud = true; + status = kvdbServiceImpl_->DoCloudSync(metaData, syncInfo); + EXPECT_EQ(status, Status::CLOUD_DISABLED); +} + +/** +* @tc.name: ConvertDbStatus +* @tc.desc: ConvertDbStatus test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KvdbServiceImplTest, ConvertDbStatus, TestSize.Level0) +{ + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::BUSY), Status::DB_ERROR); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::DB_ERROR), Status::DB_ERROR); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::OK), Status::SUCCESS); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::INVALID_ARGS), Status::INVALID_ARGUMENT); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::NOT_FOUND), Status::KEY_NOT_FOUND); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::INVALID_VALUE_FIELDS), Status::INVALID_VALUE_FIELDS); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::INVALID_FIELD_TYPE), Status::INVALID_FIELD_TYPE); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::CONSTRAIN_VIOLATION), Status::CONSTRAIN_VIOLATION); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::INVALID_FORMAT), Status::INVALID_FORMAT); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::INVALID_QUERY_FORMAT), Status::INVALID_QUERY_FORMAT); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::INVALID_QUERY_FIELD), Status::INVALID_QUERY_FIELD); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::NOT_SUPPORT), Status::NOT_SUPPORT); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::TIME_OUT), Status::TIME_OUT); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::OVER_MAX_LIMITS), Status::OVER_MAX_LIMITS); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::EKEYREVOKED_ERROR), Status::SECURITY_LEVEL_ERROR); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::SECURITY_OPTION_CHECK_ERROR), Status::SECURITY_LEVEL_ERROR); + EXPECT_EQ(kvdbServiceImpl_->ConvertDbStatus(DBStatus::SCHEMA_VIOLATE_VALUE), Status::ERROR); +} + +/** +* @tc.name: ConvertDBMode +* @tc.desc: ConvertDBMode test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KvdbServiceImplTest, ConvertDBMode, TestSize.Level0) +{ + auto status = kvdbServiceImpl_->ConvertDBMode(SyncMode::PUSH); + EXPECT_EQ(status, DBMode::SYNC_MODE_PUSH_ONLY); + status = kvdbServiceImpl_->ConvertDBMode(SyncMode::PULL); + EXPECT_EQ(status, DBMode::SYNC_MODE_PULL_ONLY); + status = kvdbServiceImpl_->ConvertDBMode(SyncMode::PUSH_PULL); + EXPECT_EQ(status, DBMode::SYNC_MODE_PUSH_PULL); +} + +/** +* @tc.name: ConvertGeneralSyncMode +* @tc.desc: ConvertGeneralSyncMode test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KvdbServiceImplTest, ConvertGeneralSyncMode, TestSize.Level0) +{ + auto status = kvdbServiceImpl_->ConvertGeneralSyncMode(SyncMode::PUSH, SyncAction::ACTION_SUBSCRIBE); + EXPECT_EQ(status, GeneralStore::SyncMode::NEARBY_SUBSCRIBE_REMOTE); + status = kvdbServiceImpl_->ConvertGeneralSyncMode(SyncMode::PUSH, SyncAction::ACTION_UNSUBSCRIBE); + EXPECT_EQ(status, GeneralStore::SyncMode::NEARBY_UNSUBSCRIBE_REMOTE); + status = kvdbServiceImpl_->ConvertGeneralSyncMode(SyncMode::PUSH, SyncAction::ACTION_SYNC); + EXPECT_EQ(status, GeneralStore::SyncMode::NEARBY_PUSH); + status = kvdbServiceImpl_->ConvertGeneralSyncMode(SyncMode::PULL, SyncAction::ACTION_SYNC); + EXPECT_EQ(status, GeneralStore::SyncMode::NEARBY_PULL); + status = kvdbServiceImpl_->ConvertGeneralSyncMode(SyncMode::PUSH_PULL, SyncAction::ACTION_SYNC); + EXPECT_EQ(status, GeneralStore::SyncMode::NEARBY_PULL_PUSH); + auto action = static_cast(SyncAction::ACTION_UNSUBSCRIBE + 1); + status = kvdbServiceImpl_->ConvertGeneralSyncMode(SyncMode::PUSH, action); + EXPECT_EQ(status, GeneralStore::SyncMode::NEARBY_END); +} + +/** +* @tc.name: ConvertType +* @tc.desc: ConvertType test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KvdbServiceImplTest, ConvertType, TestSize.Level0) +{ + auto status = kvdbServiceImpl_->ConvertType(SyncMode::PUSH); + EXPECT_EQ(status, ChangeType::CHANGE_LOCAL); + status = kvdbServiceImpl_->ConvertType(SyncMode::PULL); + EXPECT_EQ(status, ChangeType::CHANGE_REMOTE); + status = kvdbServiceImpl_->ConvertType(SyncMode::PUSH_PULL); + EXPECT_EQ(status, ChangeType::CHANGE_ALL); + auto action = static_cast(SyncMode::PUSH_PULL + 1); + status = kvdbServiceImpl_->ConvertType(action); + EXPECT_EQ(status, ChangeType::CHANGE_ALL); +} + +/** +* @tc.name: ConvertAction +* @tc.desc: ConvertAction test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KvdbServiceImplTest, ConvertAction, TestSize.Level0) +{ + auto status = kvdbServiceImpl_->ConvertAction(Action::INSERT); + EXPECT_EQ(status, SwitchState::INSERT); + status = kvdbServiceImpl_->ConvertAction(Action::UPDATE); + EXPECT_EQ(status, SwitchState::UPDATE); + status = kvdbServiceImpl_->ConvertAction(Action::DELETE); + EXPECT_EQ(status, SwitchState::DELETE); + auto action = static_cast(Action::DELETE + 1); + status = kvdbServiceImpl_->ConvertAction(action); + EXPECT_EQ(status, SwitchState::INSERT); +} + +/** +* @tc.name: GetSyncMode +* @tc.desc: GetSyncMode test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KvdbServiceImplTest, GetSyncMode, TestSize.Level0) +{ + auto status = kvdbServiceImpl_->GetSyncMode(true, true); + EXPECT_EQ(status, SyncMode::PUSH_PULL); + status = kvdbServiceImpl_->GetSyncMode(true, false); + EXPECT_EQ(status, SyncMode::PUSH); + status = kvdbServiceImpl_->GetSyncMode(false, true); + EXPECT_EQ(status, SyncMode::PULL); + status = kvdbServiceImpl_->GetSyncMode(false, false); + EXPECT_EQ(status, SyncMode::PUSH_PULL); } } // namespace DistributedDataTest -} // namespace OHOS::Test +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/kvdb_service_test.cpp b/datamgr_service/services/distributeddataservice/service/test/kvdb_service_test.cpp new file mode 100644 index 00000000..026b9c03 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/kvdb_service_test.cpp @@ -0,0 +1,685 @@ +/* +* Copyright (c) 2024 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 +#include "log_print.h" +#include "accesstoken_kit.h" +#include "auth_delegate.h" +#include "bootstrap.h" +#include "crypto_manager.h" +#include "device_manager_adapter.h" +#include "directory/directory_manager.h" +#include "metadata/meta_data_manager.h" +#include "metadata/secret_key_meta_data.h" +#include "metadata/store_meta_data.h" +#include "metadata/store_meta_data_local.h" +#include "query_helper.h" +#include "upgrade.h" +#include "user_delegate.h" +#include "kvdb_general_store.h" +#include "kvdb_watcher.h" +#include "kvdb_notifier_proxy.h" +#include "kvstore_sync_manager.h" +#include "kvstore_meta_manager.h" + +using namespace testing::ext; +using namespace DistributedDB; +using namespace OHOS::DistributedData; +using StoreMetaData = OHOS::DistributedData::StoreMetaData; +using DBPassword = DistributedDB::CipherPassword; +using DBStatus = DistributedDB::DBStatus; +using Status = OHOS::DistributedKv::Status; +using KVDBWatcher = OHOS::DistributedKv::KVDBWatcher; +using KVDBNotifierProxy = OHOS::DistributedKv::KVDBNotifierProxy; +using QueryHelper = OHOS::DistributedKv::QueryHelper; +namespace OHOS::Test { +namespace DistributedDataTest { +class UpgradeTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(); + void TearDown(){}; +protected: + static constexpr const char *bundleName = "test_upgrade"; + static constexpr const char *storeName = "test_upgrade_meta"; + void InitMetaData(); + StoreMetaData metaData_; +}; + +void UpgradeTest::InitMetaData() +{ + metaData_.bundleName = bundleName; + metaData_.appId = bundleName; + metaData_.user = "0"; + metaData_.area = OHOS::DistributedKv::EL1; + metaData_.instanceId = 0; + metaData_.isAutoSync = true; + metaData_.storeType = DistributedKv::KvStoreType::SINGLE_VERSION; + metaData_.storeId = storeName; + metaData_.dataDir = "/data/service/el1/public/database/" + std::string(bundleName) + "/kvdb/upgrade"; + metaData_.securityLevel = DistributedKv::SecurityLevel::S2; +} + +void UpgradeTest::SetUp() +{ + Bootstrap::GetInstance().LoadDirectory(); + InitMetaData(); +} + +class KvStoreSyncManagerTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +protected: +}; + +class KVDBWatcherTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +protected: +}; + +class UserDelegateTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +protected: +}; + +class QueryHelperTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +protected: +}; + +class AuthHandlerTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +protected: +}; + +/** +* @tc.name: UpdateStore +* @tc.desc: UpdateStore test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(UpgradeTest, UpdateStore, TestSize.Level0) +{ + DistributedKv::Upgrade upgrade; + StoreMetaData oldMeta = metaData_; + oldMeta.version = 1; + oldMeta.storeType = DistributedKv::KvStoreType::DEVICE_COLLABORATION; + oldMeta.dataDir = "/data/service/el1/public/database/" + std::string(bundleName) + "/kvdb/upgrade/old"; + std::vector password = {0x01, 0x02, 0x03}; + auto dbStatus = upgrade.UpdateStore(oldMeta, metaData_, password); + EXPECT_EQ(dbStatus, DBStatus::DB_ERROR); + + oldMeta.version = StoreMetaData::CURRENT_VERSION; + dbStatus = upgrade.UpdateStore(oldMeta, metaData_, password); + EXPECT_EQ(dbStatus, DBStatus::NOT_SUPPORT); + + oldMeta.storeType = DistributedKv::KvStoreType::SINGLE_VERSION; + DistributedKv::Upgrade::Exporter exporter = [](const StoreMetaData &, DBPassword &) { + return "testexporter"; + }; + upgrade.exporter_ = exporter; + dbStatus = upgrade.UpdateStore(oldMeta, metaData_, password); + EXPECT_EQ(dbStatus, DBStatus::NOT_SUPPORT); + + oldMeta.version = 1; + DistributedKv::Upgrade::Cleaner cleaner = [](const StoreMetaData &meta) -> DistributedKv::Status { + return DistributedKv::Status::SUCCESS; + }; + upgrade.cleaner_ = cleaner; + upgrade.exporter_ = nullptr; + upgrade.UpdatePassword(metaData_, password); + dbStatus = upgrade.UpdateStore(oldMeta, metaData_, password); + EXPECT_EQ(dbStatus, DBStatus::NOT_SUPPORT); + + metaData_.isEncrypt = true; + upgrade.UpdatePassword(metaData_, password); + EXPECT_TRUE(upgrade.RegisterExporter(oldMeta.version, exporter)); + EXPECT_TRUE(upgrade.RegisterCleaner(oldMeta.version, cleaner)); + dbStatus = upgrade.UpdateStore(oldMeta, metaData_, password); + EXPECT_EQ(dbStatus, DBStatus::DB_ERROR); + + StoreMetaData oldMetas = metaData_; + dbStatus = upgrade.UpdateStore(oldMetas, metaData_, password); + EXPECT_EQ(dbStatus, DBStatus::OK); +} + +/** +* @tc.name: ExportStore +* @tc.desc: ExportStore test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(UpgradeTest, ExportStore, TestSize.Level0) +{ + DistributedKv::Upgrade upgrade; + StoreMetaData oldMeta = metaData_; + auto dbStatus = upgrade.ExportStore(oldMeta, metaData_); + EXPECT_EQ(dbStatus, DBStatus::OK); + + oldMeta.dataDir = "/data/service/el1/public/database/" + std::string(bundleName) + "/kvdb/upgrade/old"; + dbStatus = upgrade.ExportStore(oldMeta, metaData_); + EXPECT_EQ(dbStatus, DBStatus::NOT_SUPPORT); + + DistributedKv::Upgrade::Exporter exporter = [](const StoreMetaData &, DBPassword &) { + return "testexporter"; + }; + EXPECT_TRUE(upgrade.RegisterExporter(oldMeta.version, exporter)); + dbStatus = upgrade.ExportStore(oldMeta, metaData_); + EXPECT_EQ(dbStatus, DBStatus::OK); + + DistributedKv::Upgrade::Exporter test = [](const StoreMetaData &, DBPassword &) { + return ""; + }; + EXPECT_TRUE(upgrade.RegisterExporter(oldMeta.version, test)); + dbStatus = upgrade.ExportStore(oldMeta, metaData_); + EXPECT_EQ(dbStatus, DBStatus::NOT_FOUND); +} + +/** +* @tc.name: GetEncryptedUuidByMeta +* @tc.desc: GetEncryptedUuidByMeta test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(UpgradeTest, GetEncryptedUuidByMeta, TestSize.Level0) +{ + DistributedKv::Upgrade upgrade; + auto dbStatus = upgrade.GetEncryptedUuidByMeta(metaData_); + EXPECT_EQ(dbStatus, metaData_.deviceId); + metaData_.appId = ""; + dbStatus = upgrade.GetEncryptedUuidByMeta(metaData_); + EXPECT_EQ(dbStatus, metaData_.appId); +} + +/** +* @tc.name: AddSyncOperation +* @tc.desc: AddSyncOperation test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KvStoreSyncManagerTest, AddSyncOperation, TestSize.Level0) +{ + DistributedKv::KvStoreSyncManager syncManager; + uintptr_t syncId = 0; + DistributedKv::KvStoreSyncManager::SyncFunc syncFunc = nullptr; + DistributedKv::KvStoreSyncManager::SyncEnd syncEnd = nullptr; + auto kvStatus = syncManager.AddSyncOperation(syncId, 0, syncFunc, syncEnd); + EXPECT_EQ(kvStatus, Status::INVALID_ARGUMENT); + syncId = 1; + kvStatus = syncManager.AddSyncOperation(syncId, 0, syncFunc, syncEnd); + EXPECT_EQ(kvStatus, Status::INVALID_ARGUMENT); + syncFunc = [](const DistributedKv::KvStoreSyncManager::SyncEnd &callback) -> Status { + std::map status_map = + {{"key1", DBStatus::OK}, {"key2", DBStatus::DB_ERROR}}; + callback(status_map); + return Status::SUCCESS; + }; + kvStatus = syncManager.AddSyncOperation(0, 0, syncFunc, syncEnd); + EXPECT_EQ(kvStatus, Status::INVALID_ARGUMENT); +} + +/** +* @tc.name: RemoveSyncOperation +* @tc.desc: RemoveSyncOperation test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KvStoreSyncManagerTest, RemoveSyncOperation, TestSize.Level0) +{ + DistributedKv::KvStoreSyncManager syncManager; + uintptr_t syncId = 0; + auto kvStatus = syncManager.RemoveSyncOperation(syncId); + EXPECT_EQ(kvStatus, Status::ERROR); +} + +/** +* @tc.name: DoRemoveSyncingOp +* @tc.desc: DoRemoveSyncingOp test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KvStoreSyncManagerTest, GetTimeoutSyncOps, TestSize.Level0) +{ + DistributedKv::KvStoreSyncManager syncManager; + DistributedKv::KvStoreSyncManager::TimePoint currentTime = std::chrono::steady_clock::now(); + DistributedKv::KvStoreSyncManager::KvSyncOperation syncOp; + syncOp.syncId = 1; + syncOp.beginTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(1); + std::list syncOps; + + EXPECT_TRUE(syncManager.realtimeSyncingOps_.empty()); + EXPECT_TRUE(syncManager.scheduleSyncOps_.empty()); + auto kvStatus = syncManager.GetTimeoutSyncOps(currentTime, syncOps); + EXPECT_EQ(kvStatus, false); + syncManager.realtimeSyncingOps_.push_back(syncOp); + kvStatus = syncManager.GetTimeoutSyncOps(currentTime, syncOps); + EXPECT_EQ(kvStatus, false); + syncManager.realtimeSyncingOps_ = syncOps; + syncManager.scheduleSyncOps_.insert(std::make_pair(syncOp.beginTime, syncOp)); + kvStatus = syncManager.GetTimeoutSyncOps(currentTime, syncOps); + EXPECT_EQ(kvStatus, false); + + syncManager.realtimeSyncingOps_.push_back(syncOp); + syncManager.scheduleSyncOps_.insert(std::make_pair(syncOp.beginTime, syncOp)); + EXPECT_TRUE(!syncManager.realtimeSyncingOps_.empty()); + EXPECT_TRUE(!syncManager.scheduleSyncOps_.empty()); + kvStatus = syncManager.GetTimeoutSyncOps(currentTime, syncOps); + EXPECT_EQ(kvStatus, true); +} + +/** +* @tc.name: KVDBWatcher +* @tc.desc: KVDBWatcher test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KVDBWatcherTest, KVDBWatcher, TestSize.Level0) +{ + GeneralWatcher::Origin origin; + GeneralWatcher::PRIFields primaryFields = {{"primaryFields1", "primaryFields2"}}; + GeneralWatcher::ChangeInfo values; + std::shared_ptr watcher = std::make_shared(); + sptr observer; + watcher->SetObserver(observer); + EXPECT_EQ(watcher->observer_, nullptr); + auto result = watcher->OnChange(origin, primaryFields, std::move(values)); + EXPECT_EQ(result, GeneralError::E_OK); + GeneralWatcher::Fields fields; + GeneralWatcher::ChangeData data; + result = watcher->OnChange(origin, fields, std::move(data)); + EXPECT_EQ(result, GeneralError::E_OK); +} + +/** +* @tc.name: ConvertToEntries +* @tc.desc: ConvertToEntries test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KVDBWatcherTest, ConvertToEntries, TestSize.Level0) +{ + std::vector values; + Values info1; + info1.emplace_back(Bytes({1, 2, 3})); + info1.emplace_back(Bytes({4, 5, 6})); + values.emplace_back(info1); + Values info2; + info2.emplace_back(Bytes({7, 8, 9})); + info2.emplace_back(Bytes({10, 11, 12})); + values.emplace_back(info2); + Values info3; + info3.emplace_back(Bytes({16, 17, 18})); + info3.emplace_back(int64_t(1)); + values.emplace_back(info3); + Values info4; + info4.emplace_back(int64_t(1)); + info4.emplace_back(Bytes({19, 20, 21})); + values.emplace_back(info4); + Values info5; + info5.emplace_back(int64_t(1)); + info5.emplace_back(int64_t(1)); + values.emplace_back(info5); + std::shared_ptr watcher = std::make_shared(); + auto result = watcher->ConvertToEntries(values); + EXPECT_EQ(result.size(), 2); + EXPECT_EQ(result[0].key, Bytes({1, 2, 3})); + EXPECT_EQ(result[0].value, Bytes({4, 5, 6})); + EXPECT_EQ(result[1].key, Bytes({7, 8, 9})); + EXPECT_EQ(result[1].value, Bytes({10, 11, 12})); +} + +/** +* @tc.name: ConvertToKeys +* @tc.desc: ConvertToKeys test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(KVDBWatcherTest, ConvertToKeys, TestSize.Level0) +{ + std::vector values = { "key1", 123, "key3", 456, "key5" }; + std::shared_ptr watcher = std::make_shared(); + auto result = watcher->ConvertToKeys(values); + EXPECT_EQ(result.size(), 3); + EXPECT_EQ(result[0], "key1"); + EXPECT_EQ(result[1], "key3"); + EXPECT_EQ(result[2], "key5"); +} + +/** +* @tc.name: UserDelegate +* @tc.desc: UserDelegate test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(UserDelegateTest, UserDelegate, TestSize.Level0) +{ + std::shared_ptr userDelegate = std::make_shared(); + auto result = userDelegate->GetLocalUserStatus(); + EXPECT_EQ(result.size(), 0); + std::string deviceId = ""; + result = userDelegate->GetRemoteUserStatus(deviceId); + EXPECT_TRUE(deviceId.empty()); + EXPECT_TRUE(result.empty()); + deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; + result = userDelegate->GetRemoteUserStatus(deviceId); + EXPECT_EQ(result.size(), 0); +} + +/** +* @tc.name: StringToDbQuery +* @tc.desc: StringToDbQuery test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(QueryHelperTest, StringToDbQuery, TestSize.Level0) +{ + std::shared_ptr queryHelper = std::make_shared(); + bool isSuccess = false; + std::string query = ""; + auto result = queryHelper->StringToDbQuery(query, isSuccess); + EXPECT_TRUE(isSuccess); + std::string querys(5 * 1024, 'a'); + query = "querys" + querys; + result = queryHelper->StringToDbQuery(query, isSuccess); + EXPECT_FALSE(isSuccess); + query = "query"; + result = queryHelper->StringToDbQuery(query, isSuccess); + EXPECT_FALSE(isSuccess); +} + +/** +* @tc.name: Handle001 +* @tc.desc: Handle test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(QueryHelperTest, Handle001, TestSize.Level0) +{ + std::shared_ptr queryHelper = std::make_shared(); + std::vector words = {"query0", "query1", "query2", "query3", "query4"}; + int pointer = 0; + int end = 1; + int ends = 4; + DistributedDB::Query dbQuery; + EXPECT_FALSE(queryHelper->Handle(words, pointer, end, dbQuery)); + EXPECT_FALSE(queryHelper->HandleExtra(words, pointer, end, dbQuery)); + EXPECT_FALSE(queryHelper->HandleEqualTo(words, pointer, end, dbQuery)); + EXPECT_FALSE(queryHelper->HandleNotEqualTo(words, pointer, end, dbQuery)); + EXPECT_FALSE(queryHelper->HandleNotEqualTo(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleGreaterThan(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleGreaterThan(words, pointer, end, dbQuery)); + EXPECT_FALSE(queryHelper->HandleLessThan(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleLessThan(words, pointer, end, dbQuery)); + EXPECT_FALSE(queryHelper->HandleGreaterThanOrEqualTo(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleGreaterThanOrEqualTo(words, pointer, end, dbQuery)); + EXPECT_FALSE(queryHelper->HandleLessThanOrEqualTo(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleLessThanOrEqualTo(words, pointer, end, dbQuery)); + + pointer = 0; + words = {"INTEGER", "LONG", "DOUBLE", "STRING"}; + EXPECT_FALSE(queryHelper->Handle(words, pointer, end, dbQuery)); + EXPECT_FALSE(queryHelper->HandleExtra(words, pointer, end, dbQuery)); + EXPECT_FALSE(queryHelper->HandleEqualTo(words, pointer, end, dbQuery)); + EXPECT_TRUE(queryHelper->HandleNotEqualTo(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleNotEqualTo(words, pointer, end, dbQuery)); + pointer = 0; + EXPECT_TRUE(queryHelper->HandleGreaterThan(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleGreaterThan(words, pointer, end, dbQuery)); + pointer = 0; + EXPECT_TRUE(queryHelper->HandleLessThan(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleLessThan(words, pointer, end, dbQuery)); + pointer = 0; + EXPECT_TRUE(queryHelper->HandleGreaterThanOrEqualTo(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleGreaterThanOrEqualTo(words, pointer, end, dbQuery)); + pointer = 0; + EXPECT_TRUE(queryHelper->HandleLessThanOrEqualTo(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleLessThanOrEqualTo(words, pointer, end, dbQuery)); +} + +/** +* @tc.name: Handle002 +* @tc.desc: Handle test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(QueryHelperTest, Handle002, TestSize.Level0) +{ + std::shared_ptr queryHelper = std::make_shared(); + std::vector words = {"query0", "query1", "query2", "query3", "query4"}; + int pointer = 1; + int end = 1; + int ends = 4; + DistributedDB::Query dbQuery; + EXPECT_TRUE(queryHelper->HandleIsNull(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleIsNull(words, pointer, end, dbQuery)); + pointer = 0; + EXPECT_TRUE(queryHelper->HandleIsNotNull(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleIsNotNull(words, pointer, end, dbQuery)); + pointer = 0; + EXPECT_TRUE(queryHelper->HandleLike(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleLike(words, pointer, end, dbQuery)); + pointer = 0; + EXPECT_TRUE(queryHelper->HandleNotLike(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleNotLike(words, pointer, end, dbQuery)); + pointer = 0; + EXPECT_TRUE(queryHelper->HandleOrderByAsc(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleOrderByAsc(words, pointer, end, dbQuery)); + pointer = 0; + EXPECT_TRUE(queryHelper->HandleOrderByDesc(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleOrderByDesc(words, pointer, end, dbQuery)); + pointer = 0; + EXPECT_TRUE(queryHelper->HandleOrderByWriteTime(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleOrderByWriteTime(words, pointer, end, dbQuery)); + pointer = 0; + EXPECT_TRUE(queryHelper->HandleLimit(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleLimit(words, pointer, end, dbQuery)); + pointer = 0; + EXPECT_TRUE(queryHelper->HandleKeyPrefix(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleKeyPrefix(words, pointer, end, dbQuery)); +} + +/** +* @tc.name: Handle003 +* @tc.desc: Handle test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(QueryHelperTest, Handle003, TestSize.Level0) +{ + std::shared_ptr queryHelper = std::make_shared(); + std::vector words = {"query0", "query1", "query2", "query3", "query4", "query5"}; + std::vector wordss = {"^NOT_IN", "INTEGER", "LONG", "^START", "STRING", "^END"}; + int pointer = 0; + int end = 1; + int ends = 5; + DistributedDB::Query dbQuery; + EXPECT_FALSE(queryHelper->HandleIn(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleIn(words, pointer, end, dbQuery)); + EXPECT_FALSE(queryHelper->HandleIn(wordss, pointer, end, dbQuery)); + EXPECT_TRUE(queryHelper->HandleIn(wordss, pointer, ends, dbQuery)); + pointer = 0; + EXPECT_FALSE(queryHelper->HandleNotIn(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleNotIn(words, pointer, end, dbQuery)); + EXPECT_FALSE(queryHelper->HandleNotIn(wordss, pointer, end, dbQuery)); + EXPECT_TRUE(queryHelper->HandleNotIn(wordss, pointer, ends, dbQuery)); +} + +/** +* @tc.name: Handle004 +* @tc.desc: Handle test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(QueryHelperTest, Handle004, TestSize.Level0) +{ + std::shared_ptr queryHelper = std::make_shared(); + std::vector words = {"query0", "query1", "query2", "query3", "query4", "query5"}; + std::vector wordss = {"^NOT_IN", "INTEGER", "LONG", "^START", "STRING", "^END"}; + int pointer = 2; + int end = 3; + int ends = 5; + DistributedDB::Query dbQuery; + EXPECT_FALSE(queryHelper->HandleInKeys(words, pointer, ends, dbQuery)); + EXPECT_FALSE(queryHelper->HandleInKeys(words, pointer, end, dbQuery)); + EXPECT_FALSE(queryHelper->HandleInKeys(wordss, pointer, end, dbQuery)); + EXPECT_TRUE(queryHelper->HandleInKeys(wordss, pointer, ends, dbQuery)); + pointer = 3; + EXPECT_FALSE(queryHelper->HandleSetSuggestIndex(wordss, pointer, end, dbQuery)); + EXPECT_TRUE(queryHelper->HandleSetSuggestIndex(wordss, pointer, ends, dbQuery)); + pointer = 3; + EXPECT_FALSE(queryHelper->HandleDeviceId(wordss, pointer, end, dbQuery)); + EXPECT_TRUE(queryHelper->HandleDeviceId(wordss, pointer, ends, dbQuery)); + queryHelper->hasPrefixKey_ = true; + pointer = 3; + EXPECT_TRUE(queryHelper->HandleDeviceId(wordss, pointer, ends, dbQuery)); +} + +/** +* @tc.name: StringTo +* @tc.desc: StringTo test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(QueryHelperTest, StringTo, TestSize.Level0) +{ + std::shared_ptr queryHelper = std::make_shared(); + std::string word = "true"; + EXPECT_TRUE(queryHelper->StringToBoolean(word)); + word = "false"; + EXPECT_FALSE(queryHelper->StringToBoolean(word)); + word = "BOOL"; + EXPECT_FALSE(queryHelper->StringToBoolean(word)); + + word = "^EMPTY_STRING"; + auto result = queryHelper->StringToString(word); + EXPECT_EQ(result, ""); + word = "START"; + result = queryHelper->StringToString(word); + EXPECT_EQ(result, "START"); + word = "START^^START"; + result = queryHelper->StringToString(word); + EXPECT_EQ(result, "START START"); + word = "START(^)START"; + result = queryHelper->StringToString(word); + EXPECT_EQ(result, "START^START"); +} + +/** +* @tc.name: Get +* @tc.desc: Get test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(QueryHelperTest, Get, TestSize.Level0) +{ + std::shared_ptr queryHelper = std::make_shared(); + std::vector words = {"1", "2", "3", "4", "5", "^END"}; + int elementPointer = 0; + int end = 5; + std::vector ret = {1, 2, 3, 4, 5}; + auto result = queryHelper->GetIntegerList(words, elementPointer, end); + EXPECT_EQ(result, ret); + elementPointer = 6; + ret = {}; + result = queryHelper->GetIntegerList(words, elementPointer, end); + EXPECT_EQ(result, ret); + + elementPointer = 0; + std::vector ret1 = {1, 2, 3, 4, 5}; + auto result1 = queryHelper->GetLongList(words, elementPointer, end); + EXPECT_EQ(result1, ret1); + elementPointer = 6; + ret1 = {}; + result1 = queryHelper->GetLongList(words, elementPointer, end); + EXPECT_EQ(result1, ret1); + + elementPointer = 0; + std::vector ret2 = {1, 2, 3, 4, 5}; + auto result2 = queryHelper->GetDoubleList(words, elementPointer, end); + EXPECT_EQ(result2, ret2); + elementPointer = 6; + ret2 = {}; + result2 = queryHelper->GetDoubleList(words, elementPointer, end); + EXPECT_EQ(result2, ret2); + + std::vector words1 = {"^NOT_IN", "INTEGER", "LONG", "^START", "STRING", "^END"}; + elementPointer = 0; + std::vector ret3 = { "^NOT_IN", "INTEGER", "LONG", "^START", "STRING" }; + auto result3 = queryHelper->GetStringList(words1, elementPointer, end); + EXPECT_EQ(result3, ret3); + elementPointer = 6; + ret3 = {}; + result3 = queryHelper->GetStringList(words1, elementPointer, end); + EXPECT_EQ(result3, ret3); +} + +/** +* @tc.name: AuthHandler +* @tc.desc: AuthHandler test the return result of input with different values. +* @tc.type: FUNC +* @tc.author: SQL +*/ +HWTEST_F(AuthHandlerTest, AuthHandler, TestSize.Level0) +{ + int localUserId = 0; + int peerUserId = 0; + std::string peerDeviceId = ""; + int32_t authType = static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT); + bool isSend = false; + auto result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); + EXPECT_FALSE(result); + authType = static_cast(DistributedKv::AuthType::DEFAULT); + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); + EXPECT_TRUE(result); + + authType = static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT); + peerDeviceId = "peerDeviceId"; + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); + EXPECT_FALSE(result); + + authType = static_cast(DistributedKv::AuthType::DEFAULT); + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); + EXPECT_TRUE(result); + + localUserId = 1; + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); + EXPECT_FALSE(result); + + peerUserId = 1; + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); + EXPECT_FALSE(result); +} +} // namespace DistributedDataTest +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/mock/BUILD.gn index 4a458579..2feaaa79 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/mock/BUILD.gn @@ -37,6 +37,7 @@ ohos_static_library("distributeddata_mock_static") { "db_change_data_mock.cpp", "db_store_mock.cpp", "general_store_mock.cpp", + "kv_store_nb_delegate_mock.cpp", ] external_deps = [ diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.cpp b/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.cpp index acb05513..6466dd56 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.cpp @@ -17,6 +17,10 @@ namespace OHOS { namespace DistributedData { using namespace DistributedDB; +DBStatus DBStoreMock::Reset() +{ + return OK; +} DBStatus DBStoreMock::Get(const Key &key, Value &value) const { return Get(entries_, key, value); @@ -263,7 +267,7 @@ DBStatus DBStoreMock::GetEntries(ConcurrentMap &store, const Key &ke store.ForEach([&entries, &keyPrefix](const Key &key, Value &value) { auto it = std::search(key.begin(), key.end(), keyPrefix.begin(), keyPrefix.end()); if (it == key.begin()) { - entries.push_back({key, value}); + entries.push_back({key, value}); } return false; }); @@ -356,12 +360,13 @@ std::pair> DBStoreMock::GetCloudVer { return { NOT_SUPPORT, {} }; } -DBStatus DBStoreMock::SetReceiveDataInterceptor(const DataInterceptor &interceptor) + +DBStatus DBStoreMock::SetCloudSyncConfig(const CloudSyncConfig &config) { return NOT_SUPPORT; } -DBStatus DBStoreMock::SetCloudSyncConfig(const CloudSyncConfig &config) +DBStatus DBStoreMock::SetReceiveDataInterceptor(const DataInterceptor &interceptor) { return NOT_SUPPORT; } @@ -370,9 +375,15 @@ DBStatus DBStoreMock::GetDeviceEntries(const std::string &device, std::vector &entries) const override; DBStatus GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const override; @@ -107,10 +111,11 @@ public: int32_t GetTaskCount() override; void SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback) override; std::pair> GetCloudVersion(const std::string &device) override; - DBStatus SetReceiveDataInterceptor(const DataInterceptor &interceptor) override; DBStatus SetCloudSyncConfig(const CloudSyncConfig &config) override; + DBStatus SetReceiveDataInterceptor(const DataInterceptor &interceptor) override; DBStatus GetDeviceEntries(const std::string &device, std::vector &entries) const override; - DBStatus Reset(); + DBStatus Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess) override; + DBStatus CancelSync(uint32_t syncId) override; private: static const uint32_t DEFAULT_SIZE = 0; DBStatus Get(ConcurrentMap &store, const Key &key, Value &value) const; diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp index 748c0224..a3d3b7f9 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.cpp @@ -74,9 +74,9 @@ int32_t GeneralStoreMock::Delete(const std::string &table, const std::string &sq return 0; } -std::shared_ptr GeneralStoreMock::Query(const std::string &table, GenQuery &query) +std::pair> GeneralStoreMock::Query(const std::string &table, GenQuery &query) { - return nullptr; + return {GeneralError::E_NOT_SUPPORT, nullptr}; } int32_t GeneralStoreMock::Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) @@ -84,9 +84,9 @@ int32_t GeneralStoreMock::Sync(const Devices &devices, GenQuery &query, DetailAs return 0; } -std::shared_ptr GeneralStoreMock::PreSharing(GenQuery &query) +std::pair> GeneralStoreMock::PreSharing(GenQuery &query) { - return nullptr; + return {GeneralError::E_NOT_SUPPORT, nullptr}; } int32_t GeneralStoreMock::Clean(const std::vector &devices, int32_t mode, const std::string &tableName) @@ -114,17 +114,7 @@ int32_t GeneralStoreMock::UnregisterDetailProgressObserver() return 0; } -int32_t GeneralStoreMock::OnChange(const GeneralWatcher::Origin& origin, const GeneralWatcher::PRIFields& primaries, - GeneralWatcher::ChangeInfo&& changeInfo) -{ - if (watcher_ != nullptr) { - watcher_->OnChange(origin, primaries, std::move(changeInfo)); - return GeneralError::E_OK; - } - return GeneralError::E_ERROR; -} - -int32_t GeneralStoreMock::Close() +int32_t GeneralStoreMock::Close(bool isForce) { return 0; } @@ -149,9 +139,10 @@ int32_t GeneralStoreMock::MergeMigratedData(const std::string &tableName, VBucke return 0; } -std::shared_ptr GeneralStoreMock::Query(const std::string &table, const std::string &sql, Values &&args) +std::pair> GeneralStoreMock::Query(const std::string &table, const std::string &sql, + Values &&args) { - return cursor_; + return {GeneralError::E_OK, cursor_}; } std::vector GeneralStoreMock::GetWaterVersion(const std::string &deviceId) @@ -164,6 +155,26 @@ void GeneralStoreMock::MakeCursor(const std::map &entry) auto resultSet = std::make_shared(1, entry); cursor_ = std::make_shared(resultSet); } + +std::pair GeneralStoreMock::LockCloudDB() +{ + return { E_OK, 0 }; +} + +int32_t GeneralStoreMock::UnLockCloudDB() +{ + return E_OK; +} + +void GeneralStoreMock::SetExecutor(std::shared_ptr executor) +{ + return; +} +int32_t GeneralStoreMock::OnChange(const GeneralWatcher::Origin &origin, const GeneralWatcher::PRIFields &primaries, + GeneralWatcher::ChangeInfo &&changeInfo) +{ + return 0; +} GeneralStoreMock::GeneralStoreMock() {} } // namespace DistributedData } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h index 45773e34..bf16a2c8 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h +++ b/datamgr_service/services/distributeddataservice/service/test/mock/general_store_mock.h @@ -47,22 +47,26 @@ public: Values &&conditions) override; int32_t Replace(const std::string &table, VBucket &&value) override; int32_t Delete(const std::string &table, const std::string &sql, Values &&args) override; - std::shared_ptr Query(const std::string &table, const std::string &sql, Values &&args) override; - std::shared_ptr Query(const std::string &table, GenQuery &query) override; + std::pair> Query(const std::string &table, const std::string &sql, + Values &&args) override; + std::pair> Query(const std::string &table, GenQuery &query) override; int32_t Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) override; - std::shared_ptr PreSharing(GenQuery &query) override; + std::pair> PreSharing(GenQuery &query) override; int32_t Clean(const std::vector &devices, int32_t mode, const std::string &tableName) override; int32_t Watch(int32_t origin, Watcher &watcher) override; int32_t Unwatch(int32_t origin, Watcher &watcher) override; int32_t RegisterDetailProgressObserver(DetailAsync async) override; int32_t UnregisterDetailProgressObserver() override; - int32_t Close() override; + int32_t Close(bool isForce) override; int32_t AddRef() override; int32_t Release() override; int32_t BindSnapshots(std::shared_ptr>> bindAssets) override; int32_t MergeMigratedData(const std::string &tableName, VBuckets &&values) override; std::vector GetWaterVersion(const std::string &deviceId) override; + void SetExecutor(std::shared_ptr executor) override; void MakeCursor(const std::map &entry); + std::pair LockCloudDB() override; + int32_t UnLockCloudDB() override; int32_t OnChange(const GeneralWatcher::Origin &origin, const GeneralWatcher::PRIFields &primaries, GeneralWatcher::ChangeInfo &&changeInfo); @@ -70,7 +74,7 @@ public: private: std::shared_ptr cursor_ = nullptr; - Watcher* watcher_ = nullptr; + Watcher* watcher_ = nullptr; }; } // namespace DistributedData } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/general_watcher_mock.cpp b/datamgr_service/services/distributeddataservice/service/test/mock/general_watcher_mock.cpp new file mode 100644 index 00000000..e4ec970b --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/mock/general_watcher_mock.cpp @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2024 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 "general_watcher_mock.h" + +namespace OHOS::DistributedData { +bool MockQuery::IsEqual(uint64_t tid) +{ + return (tid == TYPE_ID) && lastResult; +} + +std::vector MockQuery::GetTables() +{ + return tables_; +} + +int32_t MockGeneralWatcher::OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) +{ + return GeneralError::E_OK; +} + +int32_t MockGeneralWatcher::OnChange(const Origin &origin, const Fields &fields, ChangeData &&datas) +{ + return GeneralError::E_OK; +} +} // OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/general_watcher_mock.h b/datamgr_service/services/distributeddataservice/service/test/mock/general_watcher_mock.h new file mode 100644 index 00000000..27748455 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/mock/general_watcher_mock.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 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_DISTRIBUTEDDATA_SERVICE_TEST_GENERAL_WATCH_MOCK_H +#define OHOS_DISTRIBUTEDDATA_SERVICE_TEST_GENERAL_WATCH_MOCK_H + +#include "store/general_value.h" +#include "store/general_watcher.h" + +namespace OHOS::DistributedData { +class MockQuery : public GenQuery { +public: + ~MockQuery() = default; + static constexpr uint64_t TYPE_ID = 0x20000001; + std::vector tables_; + bool lastResult = false; + bool IsEqual(uint64_t tid) override; + + std::vector GetTables() override; +}; + +class MockGeneralWatcher : public DistributedData::GeneralWatcher { +public: + int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) override; + + int32_t OnChange(const Origin &origin, const Fields &fields, ChangeData &&datas) override; +}; +} // OHOS::DistributedData +#endif \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.cpp b/datamgr_service/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.cpp new file mode 100644 index 00000000..8c402f96 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.cpp @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2024 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 "kv_store_nb_delegate_mock.h" +#include "store_types.h" +namespace DistributedDB { +DBStatus KvStoreNbDelegateMock::Get(const Key &key, Value &value) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::GetEntries(const Key &keyPrefix, std::vector &entries) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::GetEntries(const Query &query, std::vector &entries) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::GetEntries(const Query &query, KvStoreResultSet *&resultSet) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::GetCount(const Query &query, int &count) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::CloseResultSet(KvStoreResultSet *&resultSet) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::Put(const Key &key, const Value &value) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::PutBatch(const std::vector &entries) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::DeleteBatch(const std::vector &keys) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::Delete(const Key &key) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::GetLocal(const Key &key, Value &value) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::GetLocalEntries(const Key &keyPrefix, std::vector &entries) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::PutLocal(const Key &key, const Value &value) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::DeleteLocal(const Key &key) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::PublishLocal(const Key &key, bool deleteLocal, bool updateTimestamp, + const KvStoreNbPublishOnConflict &onConflict) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::UnpublishToLocal(const Key &key, bool deletePublic, bool updateTimestamp) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::RegisterObserver(const Key &key, unsigned int mode, + KvStoreObserver *observer) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::UnRegisterObserver(const KvStoreObserver *observer) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::RemoveDeviceData(const std::string &device) +{ + return DBStatus::OK; +} + +std::string KvStoreNbDelegateMock::GetStoreId() const +{ + return "ok"; +} + +DBStatus KvStoreNbDelegateMock::Sync(const std::vector &devices, SyncMode mode, + const std::function &devicesMap)> &onComplete, + bool wait) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::Pragma(PragmaCmd cmd, PragmaData ¶mData) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::SetConflictNotifier(int conflictType, + const KvStoreNbConflictNotifier ¬ifier) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::Rekey(const CipherPassword &password) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::Export(const std::string &filePath, + const CipherPassword &passwd, bool force) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::Import(const std::string &filePath, const CipherPassword &passwd) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::StartTransaction() +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::Commit() +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::Rollback() +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::PutLocalBatch(const std::vector &entries) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::DeleteLocalBatch(const std::vector &keys) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::GetSecurityOption(SecurityOption &option) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::SetRemotePushFinishedNotify(const RemotePushFinishedNotifier ¬ifier) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::Sync(const std::vector &devices, SyncMode mode, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::CheckIntegrity() const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::SetEqualIdentifier(const std::string &identifier, + const std::vector &targets) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::SetPushDataInterceptor(const PushDataInterceptor &interceptor) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::SubscribeRemoteQuery(const std::vector &devices, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::UnSubscribeRemoteQuery(const std::vector &devices, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::RemoveDeviceData() +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::GetKeys(const Key &keyPrefix, std::vector &keys) const +{ + return DBStatus::OK; +} + +size_t KvStoreNbDelegateMock::GetSyncDataSize(const std::string &device) const +{ + size_t size = 0; + return size; +} + +DBStatus KvStoreNbDelegateMock::UpdateKey(const UpdateKeyCallback &callback) +{ + return DBStatus::OK; +} + +std::pair KvStoreNbDelegateMock::GetWatermarkInfo(const std::string &device) +{ + std::pair ret; + return ret; +} + +DBStatus KvStoreNbDelegateMock::Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::SetCloudDB(const std::map> &cloudDBs) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::SetCloudDbSchema(const std::map &schema) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::RemoveDeviceData(const std::string &device, ClearMode mode) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::RemoveDeviceData(const std::string &device, const std::string &user, ClearMode mode) +{ + return DBStatus::OK; +} + +int32_t KvStoreNbDelegateMock::GetTaskCount() +{ + int32_t taskCount = taskCountMock_; + return taskCount; +} + +void KvStoreNbDelegateMock::SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback) +{ + auto callback_ = callback; +} + +std::pair> KvStoreNbDelegateMock::GetCloudVersion( + const std::string &device) +{ + if (device.empty()) { + return { DBStatus::OK, {} }; + } else if (device == "test") { + return { DBStatus::DB_ERROR, {} }; + } else if (device == "device") { + return { DBStatus::DB_ERROR, {{device, device}} }; + } else { + return { DBStatus::OK, {{device, device}} }; + } +} + +DBStatus KvStoreNbDelegateMock::SetReceiveDataInterceptor(const DataInterceptor &interceptor) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::SetCloudSyncConfig(const CloudSyncConfig &config) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::GetDeviceEntries(const std::string &device, std::vector &entries) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateMock::CancelSync(uint32_t syncId) +{ + return DBStatus::OK; +} +} // namespace DistributedDB \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.h b/datamgr_service/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.h new file mode 100644 index 00000000..83d935fb --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_mock.h @@ -0,0 +1,111 @@ +/* + * 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 KV_STORE_NB_DELEGATE_H_MOCK +#define KV_STORE_NB_DELEGATE_H_MOCK + +#include +#include +#include + +#include "cloud/cloud_store_types.h" +#include "cloud/icloud_db.h" +#include "intercepted_data.h" +#include "iprocess_system_api_adapter.h" +#include "kv_store_nb_delegate.h" +#include "kv_store_nb_conflict_data.h" +#include "kv_store_observer.h" +#include "kv_store_result_set.h" +#include "query.h" +#include "store_types.h" + +namespace DistributedDB { +class KvStoreNbDelegateMock : public DistributedDB::KvStoreNbDelegate { +public: + int32_t taskCountMock_ = 0; + ~KvStoreNbDelegateMock() = default; + DBStatus Get(const Key &key, Value &value) const; + DBStatus GetEntries(const Key &keyPrefix, std::vector &entries) const; + DBStatus GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const; + DBStatus GetEntries(const Query &query, std::vector &entries) const; + DBStatus GetEntries(const Query &query, KvStoreResultSet *&resultSet) const; + DBStatus GetCount(const Query &query, int &count) const; + DBStatus CloseResultSet(KvStoreResultSet *&resultSet); + DBStatus Put(const Key &key, const Value &value); + DBStatus PutBatch(const std::vector &entries); + DBStatus DeleteBatch(const std::vector &keys); + DBStatus Delete(const Key &key); + DBStatus GetLocal(const Key &key, Value &value) const; + DBStatus GetLocalEntries(const Key &keyPrefix, std::vector &entries) const; + DBStatus PutLocal(const Key &key, const Value &value); + DBStatus DeleteLocal(const Key &key); + DBStatus PublishLocal(const Key &key, bool deleteLocal, bool updateTimestamp, + const KvStoreNbPublishOnConflict &onConflict); + DBStatus UnpublishToLocal(const Key &key, bool deletePublic, bool updateTimestamp); + DBStatus RegisterObserver(const Key &key, unsigned int mode, KvStoreObserver *observer); + DBStatus UnRegisterObserver(const KvStoreObserver *observer); + DBStatus RemoveDeviceData(const std::string &device); + std::string GetStoreId() const; + DBStatus Sync(const std::vector &devices, SyncMode mode, + const std::function &devicesMap)> &onComplete, + bool wait = false); + DBStatus Pragma(PragmaCmd cmd, PragmaData ¶mData); + DBStatus SetConflictNotifier(int conflictType, + const KvStoreNbConflictNotifier ¬ifier); + DBStatus Rekey(const CipherPassword &password); + DBStatus Export(const std::string &filePath, const CipherPassword &passwd, bool force = false); + DBStatus Import(const std::string &filePath, const CipherPassword &passwd); + DBStatus StartTransaction(); + DBStatus Commit(); + DBStatus Rollback(); + DBStatus PutLocalBatch(const std::vector &entries); + DBStatus DeleteLocalBatch(const std::vector &keys); + DBStatus GetSecurityOption(SecurityOption &option) const; + DBStatus SetRemotePushFinishedNotify(const RemotePushFinishedNotifier ¬ifier); + DBStatus Sync(const std::vector &devices, SyncMode mode, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait); + DBStatus CheckIntegrity() const; + DBStatus SetEqualIdentifier(const std::string &identifier, + const std::vector &targets); + DBStatus SetPushDataInterceptor(const PushDataInterceptor &interceptor); + DBStatus SubscribeRemoteQuery(const std::vector &devices, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait); + DBStatus UnSubscribeRemoteQuery(const std::vector &devices, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait); + DBStatus RemoveDeviceData(); + DBStatus GetKeys(const Key &keyPrefix, std::vector &keys) const; + size_t GetSyncDataSize(const std::string &device) const; + DBStatus UpdateKey(const UpdateKeyCallback &callback); + std::pair GetWatermarkInfo(const std::string &device); + DBStatus Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess); + DBStatus SetCloudDB(const std::map> &cloudDBs); + DBStatus SetCloudDbSchema(const std::map &schema); + DBStatus RemoveDeviceData(const std::string &device, ClearMode mode); + DBStatus RemoveDeviceData(const std::string &device, const std::string &user, ClearMode mode); + int32_t GetTaskCount(); + void SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback); + std::pair> GetCloudVersion( + const std::string &device); + DBStatus SetReceiveDataInterceptor(const DataInterceptor &interceptor); + DBStatus SetCloudSyncConfig(const CloudSyncConfig &config); + DBStatus GetDeviceEntries(const std::string &device, std::vector &entries) const; + DBStatus Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess); + DBStatus CancelSync(uint32_t syncId); +}; +} // namespace DistributedDB +#endif // KV_STORE_NB_DELEGATE_H_MOCK \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/object_asset_loader_test.cpp b/datamgr_service/services/distributeddataservice/service/test/object_asset_loader_test.cpp new file mode 100644 index 00000000..ab444492 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/object_asset_loader_test.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2024 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 "ObjectAssetLoaderTest" + +#include "object_asset_loader.h" +#include +#include "snapshot/machine_status.h" +#include "executor_pool.h" + +using namespace testing::ext; +using namespace OHOS::DistributedObject; +using namespace OHOS::DistributedData; +namespace OHOS::Test { + +class ObjectAssetLoaderTest : public testing::Test { +public: + void SetUp(); + void TearDown(); + +protected: + Asset asset_; + std::string uri_; + int32_t userId_ = 1; + std::string bundleName_ = "test_bundleName_1"; + std::string deviceId_ = "test_deviceId__1"; +}; + +void ObjectAssetLoaderTest::SetUp() +{ + uri_ = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset1.jpg"; + Asset asset{ + .name = "test_name", + .uri = uri_, + .modifyTime = "modifyTime", + .size = "size", + .hash = "modifyTime_size", + }; + asset_ = asset; +} + +void ObjectAssetLoaderTest::TearDown() {} + +/** +* @tc.name: UploadTest001 +* @tc.desc: Transfer test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, UploadTest001, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + auto result = assetLoader->Transfer(userId_, bundleName_, deviceId_, asset_); + ASSERT_EQ(result, false); +} + +/** +* @tc.name: TransferAssetsAsync001 +* @tc.desc: TransferAssetsAsync test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, TransferAssetsAsync001, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + std::function lambdaFunc = [](bool success) { + if (success) {} + }; + std::vector assets{ asset_ }; + ASSERT_EQ(assetLoader->executors_, nullptr); + assetLoader->TransferAssetsAsync(userId_, bundleName_, deviceId_, assets, lambdaFunc); +} + +/** +* @tc.name: TransferAssetsAsync002 +* @tc.desc: TransferAssetsAsync test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, TransferAssetsAsync002, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + std::function lambdaFunc = [](bool success) { + if (success) {} + }; + std::vector assets{ asset_ }; + std::shared_ptr executors = std::make_shared(5, 3); + ASSERT_NE(executors, nullptr); + assetLoader->SetThreadPool(executors); + ASSERT_NE(assetLoader->executors_, nullptr); + assetLoader->TransferAssetsAsync(userId_, bundleName_, deviceId_, assets, lambdaFunc); +} + +/** +* @tc.name: FinishTask001 +* @tc.desc: FinishTask test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, FinishTask001, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + ASSERT_NE(assetLoader, nullptr); + TransferTask task; + task.downloadAssets.insert(uri_); + assetLoader->FinishTask(asset_.uri, true); + ASSERT_TRUE(assetLoader->tasks_.Empty()); + assetLoader->FinishTask(asset_.uri, false); + ASSERT_TRUE(assetLoader->tasks_.Empty()); +} + +/** +* @tc.name: IsDownloading001 +* @tc.desc: IsDownloading test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, IsDownloading001, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + assetLoader->downloading_.InsertOrAssign(asset_.uri, asset_.hash); + auto result = assetLoader->IsDownloading(asset_); + ASSERT_EQ(result, true); + assetLoader->downloading_.Erase(asset_.uri); + result = assetLoader->IsDownloading(asset_); + ASSERT_EQ(result, false); +} + +/** +* @tc.name: IsDownloaded001 +* @tc.desc: IsDownloaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, IsDownloaded001, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + auto result = assetLoader->IsDownloaded(asset_); + ASSERT_EQ(result, false); + assetLoader->downloaded_.Insert(asset_.uri, "modifyTime_size"); + result = assetLoader->IsDownloaded(asset_); + ASSERT_EQ(result, true); +} + +/** +* @tc.name: UpdateDownloaded001 +* @tc.desc: UpdateDownloaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, UpdateDownloaded001, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + ASSERT_NE(assetLoader, nullptr); + while (!assetLoader->assetQueue_.empty()) { + assetLoader->assetQueue_.pop(); + } + assetLoader->UpdateDownloaded(asset_); + auto [success, hash] = assetLoader->downloaded_.Find(asset_.uri); + ASSERT_TRUE(success); + EXPECT_EQ(hash, asset_.hash); +} + +/** +* @tc.name: UpdateDownloaded002 +* @tc.desc: UpdateDownloaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectAssetLoaderTest, UpdateDownloaded002, TestSize.Level0) +{ + auto assetLoader = ObjectAssetLoader::GetInstance(); + ASSERT_NE(assetLoader, nullptr); + while (!assetLoader->assetQueue_.empty()) { + assetLoader->assetQueue_.pop(); + } + for (int i = 0; i <= assetLoader->LAST_DOWNLOAD_ASSET_SIZE; i++) { + assetLoader->assetQueue_.push(asset_.uri); + } + assetLoader->UpdateDownloaded(asset_); + EXPECT_NE(assetLoader->assetQueue_.size(), ObjectAssetLoader::LAST_DOWNLOAD_ASSET_SIZE); + EXPECT_EQ(assetLoader->assetQueue_.size(), ObjectAssetLoader::LAST_DOWNLOAD_ASSET_SIZE + 1); + auto [success, hash] = assetLoader->downloaded_.Find(asset_.uri); + EXPECT_EQ(success, false); + EXPECT_EQ(hash, ""); +} +} // namespace OHOS::Test diff --git a/datamgr_service/services/distributeddataservice/service/test/object_asset_machine_test.cpp b/datamgr_service/services/distributeddataservice/service/test/object_asset_machine_test.cpp index 96912249..c6e34358 100644 --- a/datamgr_service/services/distributeddataservice/service/test/object_asset_machine_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/object_asset_machine_test.cpp @@ -82,37 +82,12 @@ void ObjectAssetMachineTest::TearDown() {} /** * @tc.name: StatusTransfer001 -* @tc.desc: Transfer event. -* @tc.type: FUNC -* @tc.require: -* @tc.author: whj -*/ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer001, TestSize.Level0) -{ - auto machine = std::make_shared(); - Asset asset{ - .name = "test_name", - .uri = uri_, - .modifyTime = "modifyTime1", - .size = "size1", - .hash = "modifyTime1_size1", - }; - std::pair changedAsset{ "device_1", asset }; - changedAssets_[uri_].status = STATUS_STABLE; - machine->DFAPostEvent(REMOTE_CHANGED, changedAssets_[uri_], asset, changedAsset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_TRANSFERRING); - ASSERT_EQ(changedAssets_[uri_].deviceId, changedAsset.first); - ASSERT_EQ(changedAssets_[uri_].asset.hash, asset.hash); -} - -/** -* @tc.name: StatusTransfer002 * @tc.desc: Remote changed when transferring. * @tc.type: FUNC * @tc.require: * @tc.author: whj */ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer002, TestSize.Level0) +HWTEST_F(ObjectAssetMachineTest, StatusTransfer001, TestSize.Level0) { auto machine = std::make_shared(); Asset asset{ @@ -131,40 +106,13 @@ HWTEST_F(ObjectAssetMachineTest, StatusTransfer002, TestSize.Level0) } /** -* @tc.name: StatusTransfer003 -* @tc.desc: Compensate transfer in conflict scenario. -* @tc.type: FUNC -* @tc.require: -* @tc.author: whj -*/ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer003, TestSize.Level0) -{ - auto machine = std::make_shared(); - Asset asset{ - .name = "test_name", - .uri = uri_, - .modifyTime = "modifyTime1", - .size = "size1", - .hash = "modifyTime1_size1", - }; - std::pair changedAsset{ "device_1", asset }; - changedAssets_[uri_].status = STATUS_WAIT_TRANSFER; - changedAssets_[uri_].deviceId = "device_2"; - changedAssets_[uri_].asset.hash = "modifyTime2_size2"; - machine->DFAPostEvent(TRANSFER_FINISHED, changedAssets_[uri_], asset, changedAsset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_TRANSFERRING); - ASSERT_EQ(changedAssets_[uri_].deviceId, "device_2"); - ASSERT_EQ(changedAssets_[uri_].asset.hash, "modifyTime2_size2"); -} - -/** -* @tc.name: StatusTransfer004 +* @tc.name: StatusTransfer002 * @tc.desc: Transfer finished. * @tc.type: FUNC * @tc.require: * @tc.author: whj */ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer004, TestSize.Level0) +HWTEST_F(ObjectAssetMachineTest, StatusTransfer002, TestSize.Level0) { auto machine = std::make_shared(); Asset asset{ @@ -181,13 +129,13 @@ HWTEST_F(ObjectAssetMachineTest, StatusTransfer004, TestSize.Level0) } /** -* @tc.name: StatusTransfer005 +* @tc.name: StatusTransfer003 * @tc.desc: Transfer event * @tc.type: FUNC * @tc.require: * @tc.author: nhj */ -HWTEST_F(ObjectAssetMachineTest, StatusTransfer005, TestSize.Level0) +HWTEST_F(ObjectAssetMachineTest, StatusTransfer003, TestSize.Level0) { auto machine = std::make_shared(); Asset asset{ @@ -270,46 +218,33 @@ HWTEST_F(ObjectAssetMachineTest, StatusDownload001, TestSize.Level0) { auto machine = std::make_shared(); Asset asset{ - .name = "test_name", - .uri = uri_, - .modifyTime = "modifyTime1", - .size = "size1", - .hash = "modifyTime1_size1", + .name = "name_006", + .uri = "uri_006", + .modifyTime = "modifyTime_006", + .size = "size_006", + .hash = "modifyTime_006_size_006", }; - std::pair changedAsset{ "device_1", asset }; - machine->DFAPostEvent(DOWNLOAD, changedAssets_[uri_], asset, changedAsset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_DOWNLOADING); - - machine->DFAPostEvent(DOWNLOAD_FINISHED, changedAssets_[uri_], asset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_STABLE); -} - -/** -* @tc.name: StatusDownload002 -* @tc.desc: Conflict scenario: Download before transfer. -* @tc.type: FUNC -* @tc.require: -* @tc.author: nhj -*/ -HWTEST_F(ObjectAssetMachineTest, StatusDownload002, TestSize.Level0) -{ - auto machine = std::make_shared(); - Asset asset{ - .name = "test_name", - .uri = uri_, - .modifyTime = "modifyTime1", - .size = "size1", - .hash = "modifyTime1_size1", + AssetBindInfo AssetBindInfo{ + .storeName = "store_006", + .tableName = "table_006", + .primaryKey = {{ "006", "006" }}, + .field = "attachment_006", + .assetName = "asset_006.jpg", }; - std::pair changedAsset{ "device_1", asset }; - machine->DFAPostEvent(DOWNLOAD, changedAssets_[uri_], asset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_DOWNLOADING); + StoreInfo storeInfo { + .tokenId = 600, + .bundleName = "bundleName_006", + .storeName = "store_006", + .instanceId = 600, + .user = 600, + }; + ChangedAssetInfo changedAssetInfo(asset, AssetBindInfo, storeInfo); + std::pair changedAsset{ "device_006", asset }; - machine->DFAPostEvent(REMOTE_CHANGED, changedAssets_[uri_], asset, changedAsset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_WAIT_TRANSFER); - ASSERT_EQ(changedAssets_[uri_].asset.hash, asset.hash); + machine->DFAPostEvent(DOWNLOAD, changedAssetInfo, asset, changedAsset); + ASSERT_EQ(changedAssetInfo.status, STATUS_DOWNLOADING); - machine->DFAPostEvent(DOWNLOAD_FINISHED, changedAssets_[uri_], asset); - ASSERT_EQ(changedAssets_[uri_].status, STATUS_TRANSFERRING); + machine->DFAPostEvent(DOWNLOAD_FINISHED, changedAssetInfo, asset); + ASSERT_EQ(changedAssetInfo.status, STATUS_STABLE); } } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/object_manager_test.cpp b/datamgr_service/services/distributeddataservice/service/test/object_manager_test.cpp new file mode 100644 index 00000000..bccbc22e --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/object_manager_test.cpp @@ -0,0 +1,893 @@ +/* + * Copyright (c) 2024 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 "ObjectManagerTest" + +#include "object_manager.h" +#include +#include "snapshot/machine_status.h" +#include "executor_pool.h" +#include "object_types.h" +#include "kv_store_nb_delegate_mock.h" +#include + +using namespace testing::ext; +using namespace OHOS::DistributedObject; +using AssetValue = OHOS::CommonType::AssetValue; +using RestoreStatus = OHOS::DistributedObject::ObjectStoreManager::RestoreStatus; +namespace OHOS::Test { + +class ObjectManagerTest : public testing::Test { +public: + void SetUp(); + void TearDown(); + +protected: + Asset asset_; + std::string uri_; + std::string appId_ = "objectManagerTest_appid_1"; + std::string sessionId_ = "123"; + std::vector data_; + std::string deviceId_ = "7001005458323933328a258f413b3900"; + uint64_t sequenceId_ = 10; + uint64_t sequenceId_2 = 20; + uint64_t sequenceId_3 = 30; + std::string userId_ = "100"; + std::string bundleName_ = "com.examples.hmos.notepad"; + OHOS::ObjectStore::AssetBindInfo assetBindInfo_; + pid_t pid_ = 10; + uint32_t tokenId_ = 100; + AssetValue assetValue_; +}; + +void ObjectManagerTest::SetUp() +{ + uri_ = "file:://com.examples.hmos.notepad/data/storage/el2/distributedfiles/dir/asset1.jpg"; + Asset asset{ + .name = "test_name", + .uri = uri_, + .modifyTime = "modifyTime", + .size = "size", + .hash = "modifyTime_size", + }; + asset_ = asset; + + AssetValue assetValue{ + .id = "test_name", + .name = uri_, + .uri = uri_, + .createTime = "2024.07.23", + .modifyTime = "modifyTime", + .size = "size", + .hash = "modifyTime_size", + .path = "/data/storage/el2", + }; + assetValue_ = assetValue; + + data_.push_back(10); // 10 is for testing + data_.push_back(20); // 20 is for testing + data_.push_back(30); // 30 is for testing + + OHOS::ObjectStore::AssetBindInfo AssetBindInfo{ + .storeName = "store_test", + .tableName = "table_test", + .field = "attachment", + .assetName = "asset1.jpg", + }; + assetBindInfo_ = AssetBindInfo; +} + +void ObjectManagerTest::TearDown() {} + +/** +* @tc.name: DeleteNotifier001 +* @tc.desc: DeleteNotifier test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, DeleteNotifier001, TestSize.Level0) +{ + auto syncManager = SequenceSyncManager::GetInstance(); + auto result = syncManager->DeleteNotifier(sequenceId_, userId_); + ASSERT_EQ(result, SequenceSyncManager::ERR_SID_NOT_EXIST); +} + +/** +* @tc.name: Process001 +* @tc.desc: Process test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, Process001, TestSize.Level0) +{ + auto syncManager = SequenceSyncManager::GetInstance(); + std::map results; + results = {{ "test_cloud", DistributedDB::DBStatus::OK }}; + + std::function &results)> func; + func = [](const std::map &results) { + return results; + }; + auto result = syncManager->Process(sequenceId_, results, userId_); + ASSERT_EQ(result, SequenceSyncManager::ERR_SID_NOT_EXIST); + syncManager->seqIdCallbackRelations_.emplace(sequenceId_, func); + result = syncManager->Process(sequenceId_, results, userId_); + ASSERT_EQ(result, SequenceSyncManager::SUCCESS_USER_HAS_FINISHED); +} + +/** +* @tc.name: DeleteNotifierNoLock001 +* @tc.desc: DeleteNotifierNoLock test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, DeleteNotifierNoLock001, TestSize.Level0) +{ + auto syncManager = SequenceSyncManager::GetInstance(); + std::function &results)> func; + func = [](const std::map &results) { + return results; + }; + syncManager->seqIdCallbackRelations_.emplace(sequenceId_, func); + std::vector seqIds = {sequenceId_, sequenceId_2, sequenceId_3}; + std::string userId = "user_1"; + auto result = syncManager->DeleteNotifierNoLock(sequenceId_, userId_); + ASSERT_EQ(result, SequenceSyncManager::SUCCESS_USER_HAS_FINISHED); + syncManager->userIdSeqIdRelations_[userId] = seqIds; + result = syncManager->DeleteNotifierNoLock(sequenceId_, userId_); + ASSERT_EQ(result, SequenceSyncManager::SUCCESS_USER_IN_USE); +} + +/** +* @tc.name: Clear001 +* @tc.desc: Clear test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, Clear001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + auto result = manager->Clear(); + ASSERT_EQ(result, OHOS::DistributedObject::OBJECT_STORE_NOT_FOUND); +} + +/** +* @tc.name: registerAndUnregisterRemoteCallback001 +* @tc.desc: test RegisterRemoteCallback and UnregisterRemoteCallback. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, registerAndUnregisterRemoteCallback001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + sptr callback; + manager->RegisterRemoteCallback(bundleName_, sessionId_, pid_, tokenId_, callback); + ObjectStoreManager::CallbackInfo callbackInfo = manager->callbacks_.Find(tokenId_).second; + std::string prefix = bundleName_ + sessionId_; + ASSERT_NE(callbackInfo.observers_.find(prefix), callbackInfo.observers_.end()); + manager->UnregisterRemoteCallback(bundleName_, pid_, tokenId_, sessionId_); + callbackInfo = manager->callbacks_.Find(tokenId_).second; + ASSERT_EQ(callbackInfo.observers_.find(prefix), callbackInfo.observers_.end()); +} + +/** +* @tc.name: registerAndUnregisterRemoteCallback002 +* @tc.desc: abnormal use cases. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, registerAndUnregisterRemoteCallback002, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + sptr callback; + uint32_t tokenId = 101; + manager->RegisterRemoteCallback("", sessionId_, pid_, tokenId, callback); + manager->RegisterRemoteCallback(bundleName_, "", pid_, tokenId, callback); + manager->RegisterRemoteCallback("", "", pid_, tokenId, callback); + ASSERT_EQ(manager->callbacks_.Find(tokenId).first, false); + manager->UnregisterRemoteCallback("", pid_, tokenId, sessionId_); +} + +/** +* @tc.name: NotifyDataChanged001 +* @tc.desc: NotifyDataChanged test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, NotifyDataChanged001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::string bundleName1_ = "com.examples.ophm.notepad"; + std::string objectKey = bundleName1_ + sessionId_; + std::map>> data; + std::map> data1; + std::vector data1_; + data1_.push_back(RestoreStatus::DATA_READY); + data1_.push_back(RestoreStatus::ASSETS_READY); + data1_.push_back(RestoreStatus::ALL_READY); + data1 = {{ "objectKey", data1_ }}; + data = {{ objectKey, data1 }}; + std::shared_ptr executors = std::make_shared(5, 3); // executor pool + manager->SetThreadPool(executors); + ASSERT_EQ(manager->restoreStatus_.Find(objectKey).first, false); + manager->NotifyDataChanged(data, {}); + ASSERT_EQ(manager->restoreStatus_.Find(objectKey).second, RestoreStatus::DATA_READY); +} + +/** +* @tc.name: NotifyAssetsReady001 +* @tc.desc: NotifyAssetsReady test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, NotifyAssetsReady001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::string objectKey = bundleName_ + sessionId_; + std::string srcNetworkId = "1"; + ASSERT_EQ(manager->restoreStatus_.Find(objectKey).first, false); + manager->NotifyAssetsReady(objectKey, srcNetworkId); + ASSERT_EQ(manager->restoreStatus_.Find(objectKey).second, RestoreStatus::ASSETS_READY); + manager->restoreStatus_.Clear(); + manager->restoreStatus_.Insert(objectKey, RestoreStatus::DATA_READY); + manager->NotifyAssetsReady(objectKey, srcNetworkId); + ASSERT_EQ(manager->restoreStatus_.Find(objectKey).second, RestoreStatus::ALL_READY); +} + +/** + * @tc.name: NotifyAssetsReady002 + * @tc.desc: NotifyAssetsReady test. + * @tc.type: FUNC + */ +HWTEST_F(ObjectManagerTest, NotifyAssetsReady002, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::string objectKey="com.example.myapplicaiton123456"; + std::string srcNetworkId = "654321"; + + manager->restoreStatus_.Clear(); + manager->NotifyAssetsStart(objectKey, srcNetworkId); + auto [has0, value0] = manager->restoreStatus_.Find(objectKey); + EXPECT_TRUE(has0); + EXPECT_EQ(value0, RestoreStatus::NONE); + + manager->restoreStatus_.Clear(); + manager->NotifyAssetsReady(objectKey, srcNetworkId); + auto [has1, value1] = manager->restoreStatus_.Find(objectKey); + EXPECT_TRUE(has1); + EXPECT_EQ(value1, RestoreStatus::ASSETS_READY); + + manager->restoreStatus_.Clear(); + manager->restoreStatus_.Insert(objectKey, RestoreStatus::DATA_NOTIFIED); + manager->NotifyAssetsReady(objectKey, srcNetworkId); + auto [has2, value2] = manager->restoreStatus_.Find(objectKey); + EXPECT_TRUE(has2); + EXPECT_EQ(value2, RestoreStatus::ALL_READY); + + manager->restoreStatus_.Clear(); + manager->restoreStatus_.Insert(objectKey, RestoreStatus::DATA_READY); + manager->NotifyAssetsReady(objectKey, srcNetworkId); + auto [has3, value3] = manager->restoreStatus_.Find(objectKey); + EXPECT_TRUE(has3); + EXPECT_EQ(value3, RestoreStatus::ALL_READY); + manager->restoreStatus_.Clear(); +} + +/** +* @tc.name: NotifyChange001 +* @tc.desc: NotifyChange test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, NotifyChange001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::map> data; + std::map> data1; + std::vector data1_; + data1_.push_back(RestoreStatus::DATA_READY); + data_.push_back(RestoreStatus::ALL_READY); + data = {{ "test_cloud", data_ }}; + data1 = {{ "p_###SAVEINFO###001", data1_ }}; + manager->NotifyChange(data1); + manager->NotifyChange(data); +} + +/** + * @tc.name: NotifyChange002 + * @tc.desc: NotifyChange test. + * @tc.type: FUNC + */ +HWTEST_F(ObjectManagerTest, NotifyChange002, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::shared_ptr executor = std::make_shared(1, 0); + manager->SetThreadPool(executor); + std::map> data{}; + std::vector value{0}; + std::string bundleName = "com.example.myapplication"; + std::string sessionId = "123456"; + std::string source = "source"; + std::string target = "target"; + std::string timestamp = "1234567890"; + ObjectStoreManager::SaveInfo saveInfo(bundleName, sessionId, source, target, timestamp); + std::string saveInfoStr = DistributedData::Serializable::Marshall(saveInfo); + auto saveInfoValue = std::vector(saveInfoStr.begin(), saveInfoStr.end()); + std::string prefix = saveInfo.ToPropertyPrefix(); + std::string assetPrefix = prefix + "p_asset"; + data.insert_or_assign(prefix + "p_###SAVEINFO###", saveInfoValue); + data.insert_or_assign(prefix + "p_data", value); + data.insert_or_assign(assetPrefix + ObjectStore::NAME_SUFFIX, value); + data.insert_or_assign(assetPrefix + ObjectStore::URI_SUFFIX, value); + data.insert_or_assign(assetPrefix + ObjectStore::PATH_SUFFIX, value); + data.insert_or_assign(assetPrefix + ObjectStore::CREATE_TIME_SUFFIX, value); + data.insert_or_assign(assetPrefix + ObjectStore::MODIFY_TIME_SUFFIX, value); + data.insert_or_assign(assetPrefix + ObjectStore::SIZE_SUFFIX, value); + data.insert_or_assign("testkey", value); + manager->NotifyChange(data); + EXPECT_TRUE(manager->restoreStatus_.Contains(bundleName+sessionId)); + auto [has, taskId] = manager->objectTimer_.Find(bundleName+sessionId); + EXPECT_TRUE(has); + manager->restoreStatus_.Clear(); + manager->executors_->Remove(taskId); + manager->objectTimer_.Clear(); +} + +/** + * @tc.name: ComputeStatus001 + * @tc.desc: ComputeStatus.test + * @tc.type: FUNC + */ +HWTEST_F(ObjectManagerTest, ComputeStatus001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::shared_ptr executor = std::make_shared(1, 0); + manager->SetThreadPool(executor); + std::string objectKey="com.example.myapplicaiton123456"; + std::map>> data{}; + manager->restoreStatus_.Clear(); + manager->ComputeStatus(objectKey, {}, data); + auto [has0, value0] = manager->restoreStatus_.Find(objectKey); + EXPECT_TRUE(has0); + EXPECT_EQ(value0, RestoreStatus::DATA_READY); + auto [has1, taskId1] = manager->objectTimer_.Find(objectKey); + EXPECT_TRUE(has1); + manager->executors_->Remove(taskId1); + manager->objectTimer_.Clear(); + manager->restoreStatus_.Clear(); + + manager->restoreStatus_.Insert(objectKey, RestoreStatus::ASSETS_READY); + manager->ComputeStatus(objectKey, {}, data); + auto [has2, value2] = manager->restoreStatus_.Find(objectKey); + EXPECT_TRUE(has2); + EXPECT_EQ(value2, RestoreStatus::ALL_READY); + auto [has3, taskId3] = manager->objectTimer_.Find(objectKey); + EXPECT_FALSE(has3); + manager->restoreStatus_.Clear(); +} + +/** +* @tc.name: Open001 +* @tc.desc: Open test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, Open001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + manager->kvStoreDelegateManager_ = nullptr; + auto result = manager->Open(); + ASSERT_EQ(result, DistributedObject::OBJECT_INNER_ERROR); + std::string dataDir = "/data/app/el2/100/database"; + manager->SetData(dataDir, userId_); + manager->delegate_ = nullptr; + result = manager->Open(); + ASSERT_EQ(result, DistributedObject::OBJECT_SUCCESS); + manager->delegate_ = manager->OpenObjectKvStore(); + result = manager->Open(); + ASSERT_EQ(result, DistributedObject::OBJECT_SUCCESS); +} + +/** +* @tc.name: OnAssetChanged001 +* @tc.desc: OnAssetChanged test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, OnAssetChanged001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::shared_ptr snapshot = std::make_shared(); + auto snapshotKey = appId_ + "_" + sessionId_; + auto result = manager->OnAssetChanged(tokenId_, appId_, sessionId_, deviceId_, assetValue_); + ASSERT_EQ(result, DistributedObject::OBJECT_INNER_ERROR); + manager->snapshots_.Insert(snapshotKey, snapshot); + result = manager->OnAssetChanged(tokenId_, appId_, sessionId_, deviceId_, assetValue_); + ASSERT_EQ(result, DistributedObject::OBJECT_SUCCESS); +} + +/** +* @tc.name: DeleteSnapshot001 +* @tc.desc: DeleteSnapshot test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, DeleteSnapshot001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::shared_ptr snapshot = std::make_shared(); + auto snapshotKey = bundleName_ + "_" + sessionId_; + auto snapshots = manager->snapshots_.Find(snapshotKey).second; + ASSERT_EQ(snapshots, nullptr); + manager->DeleteSnapshot(bundleName_, sessionId_); + + manager->snapshots_.Insert(snapshotKey, snapshot); + snapshots = manager->snapshots_.Find(snapshotKey).second; + ASSERT_NE(snapshots, nullptr); + manager->DeleteSnapshot(bundleName_, sessionId_); +} + +/** +* @tc.name: OpenObjectKvStore001 +* @tc.desc: OpenObjectKvStore test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, OpenObjectKvStore001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + manager->objectDataListener_ = nullptr; + ASSERT_EQ(manager->objectDataListener_, nullptr); + manager->OpenObjectKvStore(); + ASSERT_NE(manager->objectDataListener_, nullptr); + manager->OpenObjectKvStore(); +} + +/** +* @tc.name: FlushClosedStore001 +* @tc.desc: FlushClosedStore test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, FlushClosedStore001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + manager->isSyncing_ = true; + manager->syncCount_ = 10; // test syncCount_ + manager->delegate_ = nullptr; + manager->FlushClosedStore(); + manager->isSyncing_ = false; + manager->FlushClosedStore(); + manager->syncCount_ = 0; // test syncCount_ + manager->FlushClosedStore(); + manager->delegate_ = manager->OpenObjectKvStore(); + manager->FlushClosedStore(); +} + +/** +* @tc.name: Close001 +* @tc.desc: Close test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, Close001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + manager->syncCount_ = 1; // test syncCount_ + manager->Close(); + ASSERT_EQ(manager->syncCount_, 1); // 1 is for testing + manager->delegate_ = manager->OpenObjectKvStore(); + manager->Close(); + ASSERT_EQ(manager->syncCount_, 0); // 0 is for testing +} + +/** +* @tc.name: SyncOnStore001 +* @tc.desc: SyncOnStore test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, SyncOnStore001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::function &results)> func; + func = [](const std::map &results) { + return results; + }; + std::string prefix = "ObjectManagerTest"; + std::vector deviceList; + deviceList.push_back("local"); + deviceList.push_back("local1"); + auto result = manager->SyncOnStore(prefix, deviceList, func); + ASSERT_EQ(result, OBJECT_SUCCESS); +} + +/** +* @tc.name: RevokeSaveToStore001 +* @tc.desc: RetrieveFromStore test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, RevokeSaveToStore001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + DistributedDB::KvStoreNbDelegateMock mockDelegate; + manager->delegate_ = &mockDelegate; + std::vector id; + id.push_back(1); // for testing + id.push_back(2); // for testing + std::map> results; + results = {{ "test_cloud", id }}; + auto result = manager->RetrieveFromStore(appId_, sessionId_, results); + ASSERT_EQ(result, OBJECT_SUCCESS); +} + +/** +* @tc.name: SyncCompleted001 +* @tc.desc: SyncCompleted test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, SyncCompleted001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + auto syncManager = SequenceSyncManager::GetInstance(); + std::map results; + results = {{ "test_cloud", DistributedDB::DBStatus::OK }}; + std::function &results)> func; + func = [](const std::map &results) { + return results; + }; + manager->userId_ = "99"; + std::vector userId; + userId.push_back(99); + userId.push_back(100); + manager->SyncCompleted(results, sequenceId_); + syncManager->userIdSeqIdRelations_ = {{ "test_cloud", userId }}; + manager->SyncCompleted(results, sequenceId_); + userId.clear(); + syncManager->seqIdCallbackRelations_.emplace(sequenceId_, func); + manager->SyncCompleted(results, sequenceId_); + userId.push_back(99); + userId.push_back(100); + manager->SyncCompleted(results, sequenceId_); +} + +/** +* @tc.name: SplitEntryKey001 +* @tc.desc: SplitEntryKey test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, SplitEntryKey001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::string key1 = ""; + std::string key2 = "ObjectManagerTest"; + auto result = manager->SplitEntryKey(key1); + ASSERT_EQ(result.empty(), true); + result = manager->SplitEntryKey(key2); + ASSERT_EQ(result.empty(), true); +} + +/** +* @tc.name: SplitEntryKey002 +* @tc.desc: SplitEntryKey test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerTest, SplitEntryKey002, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::string key1 = "com.example.myapplication_sessionId_source_target_1234567890_p_propertyName"; + auto res = manager->SplitEntryKey(key1); + EXPECT_EQ(res[0], "com.example.myapplication"); + EXPECT_EQ(res[1], "sessionId"); + EXPECT_EQ(res[2], "source"); + EXPECT_EQ(res[3], "target"); + EXPECT_EQ(res[4], "1234567890"); + EXPECT_EQ(res[5], "p_propertyName"); + + std::string key2 = "com.example.myapplication_sessionId_source_target_000_p_propertyName"; + res = manager->SplitEntryKey(key2); + EXPECT_TRUE(res.empty()); + + std::string key3 = "com.example.myapplicationsessionIdsourcetarget_1234567890_p_propertyName"; + res = manager->SplitEntryKey(key3); + EXPECT_TRUE(res.empty()); + + std::string key4 = "com.example.myapplicationsessionIdsource_target_1234567890_p_propertyName"; + res = manager->SplitEntryKey(key4); + EXPECT_TRUE(res.empty()); + + std::string key5 = "com.example.myapplicationsessionId_source_target_1234567890_p_propertyName"; + res = manager->SplitEntryKey(key5); + EXPECT_TRUE(res.empty()); +} + +/** +* @tc.name: ProcessOldEntry001 +* @tc.desc: ProcessOldEntry test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, ProcessOldEntry001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + manager->delegate_ = manager->OpenObjectKvStore(); + std::vector entries; + auto status = manager->delegate_->GetEntries(std::vector(appId_.begin(), appId_.end()), entries); + ASSERT_EQ(status, DistributedDB::DBStatus::NOT_FOUND); + manager->ProcessOldEntry(appId_); + + DistributedDB::KvStoreNbDelegateMock mockDelegate; + manager->delegate_ = &mockDelegate; + status = manager->delegate_->GetEntries(std::vector(appId_.begin(), appId_.end()), entries); + ASSERT_EQ(status, DistributedDB::DBStatus::OK); + manager->ProcessOldEntry(appId_); +} + +/** +* @tc.name: ProcessSyncCallback001 +* @tc.desc: ProcessSyncCallback test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, ProcessSyncCallback001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::map results; + manager->ProcessSyncCallback(results, appId_, sessionId_, deviceId_); + results.insert({"local", 1}); // for testing + ASSERT_EQ(results.empty(), false); + ASSERT_NE(results.find("local"), results.end()); + manager->ProcessSyncCallback(results, appId_, sessionId_, deviceId_); +} + +/** +* @tc.name: IsAssetComplete001 +* @tc.desc: IsAssetComplete test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, IsAssetComplete001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::map> results; + std::vector completes; + completes.push_back(1); // for testing + completes.push_back(2); // for testing + std::string assetPrefix = "IsAssetComplete_test"; + results.insert({assetPrefix, completes}); + auto result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, false); + results.insert({assetPrefix + ObjectStore::NAME_SUFFIX, completes}); + result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, false); + results.insert({assetPrefix + ObjectStore::URI_SUFFIX, completes}); + result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, false); + results.insert({assetPrefix + ObjectStore::PATH_SUFFIX, completes}); + result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, false); + results.insert({assetPrefix + ObjectStore::CREATE_TIME_SUFFIX, completes}); + result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, false); + results.insert({assetPrefix + ObjectStore::MODIFY_TIME_SUFFIX, completes}); + result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, false); + results.insert({assetPrefix + ObjectStore::SIZE_SUFFIX, completes}); + result = manager->IsAssetComplete(results, assetPrefix); + ASSERT_EQ(result, true); +} + +/** +* @tc.name: GetAssetsFromDBRecords001 +* @tc.desc: GetAssetsFromDBRecords test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, GetAssetsFromDBRecords001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::map> results; + std::vector completes; + completes.push_back(1); // for testing + completes.push_back(2); // for testing + std::string assetPrefix = "IsAssetComplete_test"; + results.insert({assetPrefix, completes}); + results.insert({assetPrefix + ObjectStore::NAME_SUFFIX, completes}); + results.insert({assetPrefix + ObjectStore::URI_SUFFIX, completes}); + results.insert({assetPrefix + ObjectStore::MODIFY_TIME_SUFFIX, completes}); + results.insert({assetPrefix + ObjectStore::SIZE_SUFFIX, completes}); + auto result = manager->GetAssetsFromDBRecords(results); + ASSERT_EQ(result.empty(), false); +} + +/** +* @tc.name: GetAssetsFromDBRecords002 +* @tc.desc: GetAssetsFromDBRecords test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerTest, GetAssetsFromDBRecords002, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::map> result; + + std::vector value0{0}; + std::string data0 = "[STRING]test"; + value0.insert(value0.end(), data0.begin(), data0.end()); + + std::vector value1{0}; + std::string data1 = "(string)test"; + value1.insert(value1.end(), data1.begin(), data1.end()); + + std::string prefix = "bundleName_sessionId_source_target_timestamp"; + std::string dataKey = prefix + "_p_data"; + std::string assetPrefix0 = prefix + "_p_asset0"; + std::string assetPrefix1 = prefix + "_p_asset1"; + + result.insert({dataKey, value0}); + auto assets = manager->GetAssetsFromDBRecords(result); + EXPECT_TRUE(assets.empty()); + + result.clear(); + result.insert({assetPrefix0 + ObjectStore::URI_SUFFIX, value0}); + assets = manager->GetAssetsFromDBRecords(result); + EXPECT_TRUE(assets.empty()); + + result.clear(); + result.insert({assetPrefix1 + ObjectStore::NAME_SUFFIX, value1}); + assets = manager->GetAssetsFromDBRecords(result); + EXPECT_TRUE(assets.empty()); + + result.clear(); + result.insert({assetPrefix0 + ObjectStore::NAME_SUFFIX, value0}); + result.insert({assetPrefix0 + ObjectStore::URI_SUFFIX, value0}); + result.insert({assetPrefix0 + ObjectStore::MODIFY_TIME_SUFFIX, value0}); + result.insert({assetPrefix0 + ObjectStore::SIZE_SUFFIX, value0}); + assets = manager->GetAssetsFromDBRecords(result); + ASSERT_EQ(assets.size(), 1); + EXPECT_EQ(assets[0].name, "test"); + EXPECT_EQ(assets[0].uri, "test"); + EXPECT_EQ(assets[0].modifyTime, "test"); + EXPECT_EQ(assets[0].size, "test"); + EXPECT_EQ(assets[0].hash, "test_test"); + + result.clear(); + result.insert({assetPrefix1 + ObjectStore::NAME_SUFFIX, value1}); + result.insert({assetPrefix1 + ObjectStore::URI_SUFFIX, value1}); + result.insert({assetPrefix1 + ObjectStore::MODIFY_TIME_SUFFIX, value1}); + result.insert({assetPrefix1 + ObjectStore::SIZE_SUFFIX, value1}); + assets = manager->GetAssetsFromDBRecords(result); + ASSERT_EQ(assets.size(), 1); + EXPECT_EQ(assets[0].name, "(string)test"); + EXPECT_EQ(assets[0].uri, "(string)test"); + EXPECT_EQ(assets[0].modifyTime, "(string)test"); + EXPECT_EQ(assets[0].size, "(string)test"); + EXPECT_EQ(assets[0].hash, "(string)test_(string)test"); +} + +/** +* @tc.name: RegisterAssetsLister001 +* @tc.desc: RegisterAssetsLister test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, RegisterAssetsLister001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + manager->objectAssetsSendListener_ = nullptr; + manager->objectAssetsRecvListener_ = nullptr; + auto result = manager->RegisterAssetsLister(); + ASSERT_EQ(result, true); + manager->objectAssetsSendListener_ = new ObjectAssetsSendListener(); + manager->objectAssetsRecvListener_ = new ObjectAssetsRecvListener();; + result = manager->RegisterAssetsLister(); + ASSERT_EQ(result, true); +} + +/** +* @tc.name: RegisterAssetsLister001 +* @tc.desc: PushAssets test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectManagerTest, PushAssets001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::map> data; + std::string assetPrefix = "PushAssets_test"; + std::vector completes; + completes.push_back(1); // for testing + completes.push_back(2); // for testing + data.insert({assetPrefix, completes}); + auto result = manager->PushAssets(100, appId_, sessionId_, data, deviceId_); + ASSERT_EQ(result, DistributedObject::OBJECT_SUCCESS); +} + +/** +* @tc.name: AddNotifier001 +* @tc.desc: AddNotifie and DeleteNotifier test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerTest, AddNotifier001, TestSize.Level0) +{ + auto syncManager = SequenceSyncManager::GetInstance(); + std::function &results)> func; + func = [](const std::map &results) { + return results; + }; + auto sequenceId_ = syncManager->AddNotifier(userId_, func); + auto result = syncManager->DeleteNotifier(sequenceId_, userId_); + ASSERT_EQ(result, SequenceSyncManager::SUCCESS_USER_HAS_FINISHED); +} + +/** +* @tc.name: AddNotifier002 +* @tc.desc: AddNotifie and DeleteNotifier test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerTest, AddNotifier002, TestSize.Level0) +{ + auto syncManager = SequenceSyncManager::GetInstance(); + std::function &results)> func; + func = [](const std::map &results) { + return results; + }; + auto sequenceId = syncManager->AddNotifier(userId_, func); + ASSERT_NE(sequenceId, sequenceId_); + auto result = syncManager->DeleteNotifier(sequenceId_, userId_); + ASSERT_EQ(result, SequenceSyncManager::ERR_SID_NOT_EXIST); +} + +/** +* @tc.name: BindAsset 001 +* @tc.desc: BindAsset test. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerTest, BindAsset001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::string bundleName = "BindAsset"; + uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); + auto result = manager->BindAsset(tokenId, bundleName, sessionId_, assetValue_, assetBindInfo_); + ASSERT_EQ(result, DistributedObject::OBJECT_DBSTATUS_ERROR); +} +} // namespace OHOS::Test diff --git a/datamgr_service/services/distributeddataservice/service/test/object_snapshot_test.cpp b/datamgr_service/services/distributeddataservice/service/test/object_snapshot_test.cpp new file mode 100644 index 00000000..90cdc9da --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/object_snapshot_test.cpp @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2024 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 "ObjectSnapshotTest" + +#include "object_snapshot.h" +#include +#include "snapshot/machine_status.h" +#include "executor_pool.h" + +using namespace testing::ext; +using namespace OHOS::DistributedObject; +using namespace OHOS::DistributedData; +namespace OHOS::Test { + +class ObjectSnapshotTest : public testing::Test { +public: + void SetUp(); + void TearDown(); + +protected: + AssetBindInfo AssetBindInfo_; + Asset asset_; + std::string uri_; + StoreInfo storeInfo_; +}; + +void ObjectSnapshotTest::SetUp() +{ + uri_ = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset1.jpg"; + Asset asset{ + .name = "test_name", + .uri = uri_, + .modifyTime = "modifyTime", + .size = "size", + .hash = "modifyTime_size", + }; + asset_ = asset; + + VBucket vBucket{ { "11", 111 } }; + AssetBindInfo AssetBindInfo{ + .storeName = "store_test", + .tableName = "table_test", + .primaryKey = vBucket, + .field = "attachment", + .assetName = "asset1.jpg", + }; + AssetBindInfo_ = AssetBindInfo; + StoreInfo storeInfo { + .tokenId = 0, + .bundleName = "bundleName_test", + .storeName = "store_test", + .instanceId = 1, + .user = 100, + }; + storeInfo_ = storeInfo; + ChangedAssetInfo changedAssetInfo(asset, AssetBindInfo, storeInfo); +} + +void ObjectSnapshotTest::TearDown() {} + +/** +* @tc.name: UploadTest001 +* @tc.desc: Upload test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, UploadTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->Upload(asset); + ASSERT_EQ(upload, 0); +} + +/** +* @tc.name: UploadTest002 +* @tc.desc: Upload test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, UploadTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->Upload(asset_); + ASSERT_EQ(upload, 0); +} + +/** +* @tc.name: DownloadTest001 +* @tc.desc: Download test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, DownloadTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->Download(asset); + ASSERT_EQ(upload, 0); +} + +/** +* @tc.name: DownloadTest002 +* @tc.desc: Download test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, DownloadTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->Download(asset_); + ASSERT_EQ(upload, 0); +} + +/** +* @tc.name: GetAssetStatusTest001 +* @tc.desc: GetAssetStatus test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, GetAssetStatusTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->GetAssetStatus(asset); + ASSERT_EQ(upload, STATUS_BUTT); +} + +/** +* @tc.name: GetAssetStatusTest002 +* @tc.desc: GetAssetStatus test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, GetAssetStatusTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->GetAssetStatus(asset_); + ASSERT_EQ(upload, STATUS_STABLE); +} + +/** +* @tc.name: UploadedTest001 +* @tc.desc: Uploaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, UploadedTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->Uploaded(asset); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: UploadedTest002 +* @tc.desc: Uploaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, UploadedTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->Uploaded(asset_); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: DownloadedTest001 +* @tc.desc: Downloaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, DownloadedTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->Downloaded(asset); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: DownloadedTest002 +* @tc.desc: Downloaded test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, DownloadedTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->Downloaded(asset_); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: TransferredTest001 +* @tc.desc: Transferred test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, TransferredTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->Transferred(asset); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: TransferredTest002 +* @tc.desc: Transferred test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, TransferredTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->Transferred(asset_); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: OnDataChangedTest001 +* @tc.desc: OnDataChanged test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, OnDataChangedTest001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + std::string deviceId = "object_snapshot_test_1"; + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + auto upload = snapshot->OnDataChanged(asset, deviceId); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: OnDataChangedTest002 +* @tc.desc: OnDataChanged test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, OnDataChangedTest002, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + std::string deviceId = "object_snapshot_test_1"; + snapshot->BindAsset(asset_, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset_), true); + auto upload = snapshot->OnDataChanged(asset_, deviceId); + ASSERT_EQ(upload, E_OK); +} + +/** +* @tc.name: BindAsset001 +* @tc.desc: BindAsset test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: wangbin +*/ +HWTEST_F(ObjectSnapshotTest, BindAsset001, TestSize.Level0) +{ + auto snapshot = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = "file:://com.example.hmos.notepad/data/storage/el2/distributedfiles/dir/asset2.jpg", + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + ASSERT_EQ(snapshot->IsBoundAsset(asset), false); + snapshot->BindAsset(asset, AssetBindInfo_, storeInfo_); + ASSERT_EQ(snapshot->IsBoundAsset(asset), true); + snapshot->BindAsset(asset, AssetBindInfo_, storeInfo_); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_asset_loader_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_asset_loader_test.cpp index 9ab9c95e..91b54fb4 100644 --- a/datamgr_service/services/distributeddataservice/service/test/rdb_asset_loader_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_asset_loader_test.cpp @@ -17,8 +17,11 @@ #include "gtest/gtest.h" #include "log_print.h" #include "rdb_asset_loader.h" +#include "rdb_notifier_proxy.h" +#include "rdb_watcher.h" #include "store/cursor.h" - +#include "store/general_value.h" +#include "store/general_watcher.h" using namespace OHOS; using namespace testing; using namespace testing::ext; @@ -61,6 +64,14 @@ public: } }; +class RdbWatcherTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + /** * @tc.name: Download * @tc.desc: RdbAssetLoader download test. @@ -121,5 +132,25 @@ HWTEST_F(RdbAssetLoaderTest, PostEvent, TestSize.Level0) auto result = rdbAssetLoader.Download(tableName, groupId, prefix, assets); EXPECT_EQ(result, DistributedDB::DBStatus::CLOUD_ERROR); } + +/** +* @tc.name: RdbWatcher +* @tc.desc: RdbWatcher function test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbWatcherTest, RdbWatcher, TestSize.Level0) +{ + GeneralWatcher::Origin origin; + GeneralWatcher::PRIFields primaryFields = {{"primaryFields1", "primaryFields2"}}; + GeneralWatcher::ChangeInfo values; + std::shared_ptr watcher = std::make_shared(); + sptr notifier; + watcher->SetNotifier(notifier); + EXPECT_EQ(watcher->notifier_, nullptr); + auto result = watcher->OnChange(origin, primaryFields, std::move(values)); + EXPECT_EQ(result, GeneralError::E_NOT_INIT); +} } // namespace DistributedRDBTest } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_cloud_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_cloud_test.cpp index 3be6d2d0..0646e6ff 100644 --- a/datamgr_service/services/distributeddataservice/service/test/rdb_cloud_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_cloud_test.cpp @@ -14,9 +14,10 @@ */ #define LOG_TAG "RdbCloudTest" +#include "rdb_cloud.h" + #include "gtest/gtest.h" #include "log_print.h" -#include "rdb_cloud.h" #include "rdb_cloud_data_translate.h" using namespace testing::ext; @@ -56,7 +57,7 @@ HWTEST_F(RdbCloudTest, RdbCloudTest001, TestSize.Level1) { BindAssets bindAssets; Bytes bytes; - std::shared_ptr cloudDB = std::make_shared(); + std::shared_ptr cloudDB = std::make_shared(); RdbCloud rdbCloud(cloudDB, &bindAssets); std::string tableName = "testTable"; auto result = rdbCloud.BatchInsert(tableName, std::move(g_DBVBucket), g_DBVBucket); @@ -77,7 +78,7 @@ HWTEST_F(RdbCloudTest, RdbCloudTest001, TestSize.Level1) HWTEST_F(RdbCloudTest, RdbCloudTest002, TestSize.Level1) { BindAssets bindAssets; - std::shared_ptr cloudDB = std::make_shared(); + std::shared_ptr cloudDB = std::make_shared(); RdbCloud rdbCloud(cloudDB, &bindAssets); std::string tableName = "testTable"; rdbCloud.Lock(); @@ -113,7 +114,7 @@ HWTEST_F(RdbCloudTest, RdbCloudTest003, TestSize.Level1) { BindAssets bindAssets; bindAssets.bindAssets = nullptr; - std::shared_ptr cloudDB = std::make_shared(); + std::shared_ptr cloudDB = std::make_shared(); RdbCloud rdbCloud(cloudDB, &bindAssets); std::string tableName = "testTable"; DBVBucket extends = { @@ -151,7 +152,7 @@ HWTEST_F(RdbCloudTest, RdbCloudTest003, TestSize.Level1) HWTEST_F(RdbCloudTest, ConvertStatus, TestSize.Level1) { BindAssets bindAssets; - std::shared_ptr cloudDB = std::make_shared(); + std::shared_ptr cloudDB = std::make_shared(); RdbCloud rdbCloud(cloudDB, &bindAssets); auto result = rdbCloud.ConvertStatus(GeneralError::E_OK); EXPECT_EQ(result, DBStatus::OK); diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_cursor_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_cursor_test.cpp index d8aa4815..02f36f3c 100644 --- a/datamgr_service/services/distributeddataservice/service/test/rdb_cursor_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_cursor_test.cpp @@ -16,7 +16,6 @@ #include "gtest/gtest.h" #include "log_print.h" -#define private public #include "rdb_cursor.h" #include "result_set.h" #include "store/general_value.h" diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_general_store_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_general_store_test.cpp index a0a1794c..6697dae2 100644 --- a/datamgr_service/services/distributeddataservice/service/test/rdb_general_store_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_general_store_test.cpp @@ -14,19 +14,20 @@ */ #define LOG_TAG "RdbGeneralStoreTest" +#include "rdb_general_store.h" #include +#include #include "bootstrap.h" #include "cloud/schema_meta.h" #include "gtest/gtest.h" -#define private public -#include "rdb_general_store.h" #include "log_print.h" #include "metadata/meta_data_manager.h" #include "metadata/secret_key_meta_data.h" #include "metadata/store_meta_data.h" #include "metadata/store_meta_data_local.h" +#include "mock/general_watcher_mock.h" #include "rdb_query.h" #include "store/general_store.h" #include "types.h" @@ -230,42 +231,13 @@ protected: } }; -class MockQuery : public GenQuery { -public: - ~MockQuery() = default; - static constexpr uint64_t TYPE_ID = 0x20000001; - std::vector tables_; - bool lastResult = false; - bool IsEqual(uint64_t tid) override - { - return (tid == TYPE_ID) && lastResult; - } - - std::vector GetTables() override - { - return tables_; - } -}; - -class MockGeneralWatcher : public DistributedData::GeneralWatcher { -public: - int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) override - { - return GeneralError::E_OK; - } - - int32_t OnChange(const Origin &origin, const Fields &fields, ChangeData &&datas) override - { - return GeneralError::E_OK; - } -}; - class MockStoreChangedData : public DistributedDB::StoreChangedData { public: std::string GetDataChangeDevice() const override { return "DataChangeDevice"; } + void GetStoreProperty(DistributedDB::StoreProperty &storeProperty) const override { return; @@ -433,6 +405,29 @@ HWTEST_F(RdbGeneralStoreTest, Close, TestSize.Level1) EXPECT_EQ(ret, GeneralError::E_BUSY); } +/** +* @tc.name: Close +* @tc.desc: RdbGeneralStore Close test +* @tc.type: FUNC +* @tc.require: +* @tc.author: shaoyuanzhao +*/ +HWTEST_F(RdbGeneralStoreTest, BusyClose, TestSize.Level1) +{ + auto store = std::make_shared(metaData_); + ASSERT_NE(store, nullptr); + std::thread thread([store]() { + std::unique_lockrwMutex_)> lock(store->rwMutex_); + std::this_thread::sleep_for(std::chrono::seconds(1)); + }); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + auto ret = store->Close(); + EXPECT_EQ(ret, GeneralError::E_BUSY); + thread.join(); + ret = store->Close(); + EXPECT_EQ(ret, GeneralError::E_OK); +} + /** * @tc.name: Execute * @tc.desc: RdbGeneralStore Execute function test @@ -658,13 +653,15 @@ HWTEST_F(RdbGeneralStoreTest, Query001, TestSize.Level1) ASSERT_NE(store, nullptr); std::string table = "table"; std::string sql = "sql"; - auto result = store->Query(table, sql, std::move(g_RdbValues)); - EXPECT_EQ(result, nullptr); + auto [err1, result1] = store->Query(table, sql, std::move(g_RdbValues)); + EXPECT_EQ(err1, GeneralError::E_ALREADY_CLOSED); + EXPECT_EQ(result1, nullptr); MockRelationalStoreDelegate mockDelegate; store->delegate_ = &mockDelegate; - result = store->Query(table, sql, std::move(g_RdbValues)); - EXPECT_NE(result, nullptr); + auto [err2, result2] = store->Query(table, sql, std::move(g_RdbValues)); + EXPECT_EQ(err2, GeneralError::E_OK); + EXPECT_NE(result2, nullptr); } /** @@ -681,12 +678,14 @@ HWTEST_F(RdbGeneralStoreTest, Query002, TestSize.Level1) std::string table = "table"; std::string sql = "sql"; MockQuery query; - auto result = store->Query(table, query); - EXPECT_EQ(result, nullptr); + auto [err1, result1] = store->Query(table, query); + EXPECT_EQ(err1, GeneralError::E_INVALID_ARGS); + EXPECT_EQ(result1, nullptr); query.lastResult = true; - result = store->Query(table, query); - EXPECT_EQ(result, nullptr); + auto [err2, result2] = store->Query(table, query); + EXPECT_EQ(err2, GeneralError::E_ALREADY_CLOSED); + EXPECT_EQ(result2, nullptr); } /** @@ -747,7 +746,8 @@ HWTEST_F(RdbGeneralStoreTest, PreSharing, TestSize.Level1) auto store = new (std::nothrow) RdbGeneralStore(metaData_); ASSERT_NE(store, nullptr); MockQuery query; - auto result = store->PreSharing(query); + auto [errCode, result] = store->PreSharing(query); + EXPECT_NE(errCode, GeneralError::E_OK); EXPECT_EQ(result, nullptr); } @@ -867,7 +867,7 @@ HWTEST_F(RdbGeneralStoreTest, OnChange, TestSize.Level1) /** * @tc.name: Release -* @tc.desc: RdbGeneralStore Release function test +* @tc.desc: RdbGeneralStore Release and AddRef function test * @tc.type: FUNC * @tc.require: * @tc.author: SQL @@ -878,6 +878,8 @@ HWTEST_F(RdbGeneralStoreTest, Release, TestSize.Level1) ASSERT_NE(store, nullptr); auto result = store->Release(); EXPECT_EQ(result, 0); + store = new (std::nothrow) RdbGeneralStore(metaData_); + store->ref_ = 0; result = store->Release(); EXPECT_EQ(result, 0); store->ref_ = 2; @@ -1009,10 +1011,13 @@ HWTEST_F(RdbGeneralStoreTest, QuerySql, TestSize.Level1) ASSERT_NE(store, nullptr); MockRelationalStoreDelegate mockDelegate; store->delegate_ = &mockDelegate; - auto result = store->QuerySql("", std::move(g_RdbValues)); - EXPECT_TRUE(result.empty()); - result = store->QuerySql("sql", std::move(g_RdbValues)); - EXPECT_TRUE(result.empty()); + auto [err1, result1] = store->QuerySql("", std::move(g_RdbValues)); + EXPECT_EQ(err1, GeneralError::E_ERROR); + EXPECT_TRUE(result1.empty()); + + auto [err2, result2] = store->QuerySql("sql", std::move(g_RdbValues)); + EXPECT_EQ(err1, GeneralError::E_ERROR); + EXPECT_TRUE(result2.empty()); } } // namespace DistributedRDBTest } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/value_proxy_test.cpp b/datamgr_service/services/distributeddataservice/service/test/value_proxy_test.cpp index dba39e9d..327e2e49 100644 --- a/datamgr_service/services/distributeddataservice/service/test/value_proxy_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/value_proxy_test.cpp @@ -13,14 +13,14 @@ * limitations under the License. */ -#define LOG_TAG "CloudDataTest" +#define LOG_TAG "ValueProxyServiceTest" #include #include "log_print.h" #include "value_proxy.h" -namespace Test { +namespace OHOS::Test { using namespace testing::ext; using namespace OHOS::DistributedData; -class ValueProxyTest : public testing::Test { +class ValueProxyServiceTest : public testing::Test { }; /** @@ -30,7 +30,7 @@ class ValueProxyTest : public testing::Test { * @tc.require: * @tc.author: ht */ -HWTEST_F(ValueProxyTest, VBucketsNormal2GaussDB, TestSize.Level0) +HWTEST_F(ValueProxyServiceTest, VBucketsNormal2GaussDB, TestSize.Level0) { std::vector dbVBuckets; OHOS::DistributedData::VBuckets extends = { @@ -48,7 +48,7 @@ HWTEST_F(ValueProxyTest, VBucketsNormal2GaussDB, TestSize.Level0) * @tc.require: * @tc.author: ht */ -HWTEST_F(ValueProxyTest, VBucketsGaussDB2Normal, TestSize.Level0) +HWTEST_F(ValueProxyServiceTest, VBucketsGaussDB2Normal, TestSize.Level0) { std::vector dbVBuckets = { {{"#gid", {"0000000"}}, {"#flag", {true }}, {"#value", {int64_t(100)}}, {"#float", {double(100)}}}, @@ -66,7 +66,7 @@ HWTEST_F(ValueProxyTest, VBucketsGaussDB2Normal, TestSize.Level0) * @tc.require: * @tc.author: ht */ -HWTEST_F(ValueProxyTest, VBucketsNormal2Rdb, TestSize.Level0) +HWTEST_F(ValueProxyServiceTest, VBucketsNormal2Rdb, TestSize.Level0) { using RdbBucket = OHOS::NativeRdb::ValuesBucket; std::vector rdbVBuckets; @@ -85,7 +85,7 @@ HWTEST_F(ValueProxyTest, VBucketsNormal2Rdb, TestSize.Level0) * @tc.require: * @tc.author: ht */ -HWTEST_F(ValueProxyTest, VBucketsRdb2Normal, TestSize.Level0) +HWTEST_F(ValueProxyServiceTest, VBucketsRdb2Normal, TestSize.Level0) { using RdbBucket = OHOS::NativeRdb::ValuesBucket; using RdbValue = OHOS::NativeRdb::ValueObject; @@ -112,7 +112,7 @@ HWTEST_F(ValueProxyTest, VBucketsRdb2Normal, TestSize.Level0) * @tc.require: * @tc.author: ht */ -HWTEST_F(ValueProxyTest, ConvertIntMapTest, TestSize.Level0) +HWTEST_F(ValueProxyServiceTest, ConvertIntMapTest, TestSize.Level0) { std::map testMap = { { "name", 1 }, { "school", 2 }, { "address", 3 } }; auto res = ValueProxy::Convert(testMap); @@ -130,7 +130,7 @@ HWTEST_F(ValueProxyTest, ConvertIntMapTest, TestSize.Level0) * @tc.require: * @tc.author: ht */ -HWTEST_F(ValueProxyTest, ConvertAssetMapGaussDB2NormalTest, TestSize.Level0) +HWTEST_F(ValueProxyServiceTest, ConvertAssetMapGaussDB2NormalTest, TestSize.Level0) { DistributedDB::Asset dbAsset0 { .name = "dbname", .uri = "dburi" }; DistributedDB::Asset dbAsset1 { .name = "dbname", .uri = "dburi" }; @@ -157,7 +157,7 @@ HWTEST_F(ValueProxyTest, ConvertAssetMapGaussDB2NormalTest, TestSize.Level0) * @tc.require: * @tc.author: ht */ -HWTEST_F(ValueProxyTest, ConvertAssetMapNormal2GaussDBTest, TestSize.Level0) +HWTEST_F(ValueProxyServiceTest, ConvertAssetMapNormal2GaussDBTest, TestSize.Level0) { using NormalAsset = OHOS::DistributedData::Asset; using NormalAssets = OHOS::DistributedData::Assets; @@ -186,7 +186,7 @@ HWTEST_F(ValueProxyTest, ConvertAssetMapNormal2GaussDBTest, TestSize.Level0) * @tc.require: * @tc.author: ht */ -HWTEST_F(ValueProxyTest, ConvertAssetMapRdb2NormalTest, TestSize.Level0) +HWTEST_F(ValueProxyServiceTest, ConvertAssetMapRdb2NormalTest, TestSize.Level0) { using RdbAsset = OHOS::NativeRdb::AssetValue; using RdbAssets = std::vector; @@ -215,7 +215,7 @@ HWTEST_F(ValueProxyTest, ConvertAssetMapRdb2NormalTest, TestSize.Level0) * @tc.require: * @tc.author: ht */ -HWTEST_F(ValueProxyTest, ConvertAssetMapNormal2RdbTest, TestSize.Level0) +HWTEST_F(ValueProxyServiceTest, ConvertAssetMapNormal2RdbTest, TestSize.Level0) { using RdbAsset = OHOS::NativeRdb::AssetValue; using RdbAssets = std::vector; @@ -244,4 +244,121 @@ HWTEST_F(ValueProxyTest, ConvertAssetMapNormal2RdbTest, TestSize.Level0) auto dataAsset = rdbAssets.begin(); ASSERT_EQ(dataAsset->name, "name"); } -} // namespace Test + +/** +* @tc.name: AssetConvertToDataStatus +* @tc.desc: Asset::ConvertToDataStatus function test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ValueProxyServiceTest, AssetConvertToDataStatus, TestSize.Level0) +{ + DistributedDB::Asset asset; + asset.status = static_cast(DistributedDB::AssetStatus::DOWNLOADING); + asset.flag = static_cast(DistributedDB::AssetOpType::DELETE); + auto result = ValueProxy::Asset::ConvertToDataStatus(asset); + EXPECT_EQ(result, DistributedData::Asset::STATUS_DELETE); + + asset.flag = static_cast(DistributedDB::AssetOpType::NO_CHANGE); + result = ValueProxy::Asset::ConvertToDataStatus(asset); + EXPECT_EQ(result, DistributedData::Asset::STATUS_DOWNLOADING); + + asset.status = static_cast(DistributedDB::AssetStatus::ABNORMAL); + result = ValueProxy::Asset::ConvertToDataStatus(asset); + EXPECT_EQ(result, DistributedData::Asset::STATUS_ABNORMAL); + + asset.status = static_cast(DistributedDB::AssetStatus::NORMAL); + asset.flag = static_cast(DistributedDB::AssetOpType::INSERT); + result = ValueProxy::Asset::ConvertToDataStatus(asset); + EXPECT_EQ(result, DistributedData::Asset::STATUS_INSERT); + + asset.flag = static_cast(DistributedDB::AssetOpType::UPDATE); + result = ValueProxy::Asset::ConvertToDataStatus(asset); + EXPECT_EQ(result, DistributedData::Asset::STATUS_UPDATE); + + asset.flag = static_cast(DistributedDB::AssetOpType::DELETE); + result = ValueProxy::Asset::ConvertToDataStatus(asset); + EXPECT_EQ(result, DistributedData::Asset::STATUS_DELETE); + + asset.flag = static_cast(DistributedDB::AssetOpType::NO_CHANGE); + result = ValueProxy::Asset::ConvertToDataStatus(asset); + EXPECT_EQ(result, DistributedData::Asset::STATUS_NORMAL); +} + +/** +* @tc.name: AssetConvertToDBStatus +* @tc.desc: Asset::ConvertToDBStatus function test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ValueProxyServiceTest, AssetConvertToDBStatus, TestSize.Level0) +{ + uint32_t status = static_cast(DistributedData::Asset::STATUS_NORMAL); + auto result = ValueProxy::Asset::ConvertToDBStatus(status); + EXPECT_EQ(result, DistributedDB::AssetStatus::NORMAL); + + status = static_cast(DistributedData::Asset::STATUS_ABNORMAL); + result = ValueProxy::Asset::ConvertToDBStatus(status); + EXPECT_EQ(result, DistributedDB::AssetStatus::ABNORMAL); + + status = static_cast(DistributedData::Asset::STATUS_INSERT); + result = ValueProxy::Asset::ConvertToDBStatus(status); + EXPECT_EQ(result, DistributedDB::AssetStatus::INSERT); + + status = static_cast(DistributedData::Asset::STATUS_UPDATE); + result = ValueProxy::Asset::ConvertToDBStatus(status); + EXPECT_EQ(result, DistributedDB::AssetStatus::UPDATE); + + status = static_cast(DistributedData::Asset::STATUS_DELETE); + result = ValueProxy::Asset::ConvertToDBStatus(status); + EXPECT_EQ(result, DistributedDB::AssetStatus::DELETE); + + status = static_cast(DistributedData::Asset::STATUS_DOWNLOADING); + result = ValueProxy::Asset::ConvertToDBStatus(status); + EXPECT_EQ(result, DistributedDB::AssetStatus::DOWNLOADING); + + status = static_cast(DistributedData::Asset::STATUS_UNKNOWN); + result = ValueProxy::Asset::ConvertToDBStatus(status); + EXPECT_EQ(result, DistributedDB::AssetStatus::NORMAL); +} + +/** +* @tc.name: TempAssetConvertToDataStatus +* @tc.desc: TempAsset::ConvertToDataStatus function test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ValueProxyServiceTest, TempAssetConvertToDataStatus, TestSize.Level0) +{ + uint32_t status = static_cast(DistributedDB::AssetStatus::NORMAL); + auto result = ValueProxy::TempAsset::ConvertToDataStatus(status); + EXPECT_EQ(result, DistributedData::Asset::STATUS_NORMAL); + + status = static_cast(DistributedDB::AssetStatus::ABNORMAL); + result = ValueProxy::TempAsset::ConvertToDataStatus(status); + EXPECT_EQ(result, DistributedData::Asset::STATUS_ABNORMAL); + + status = static_cast(DistributedDB::AssetStatus::INSERT); + result = ValueProxy::TempAsset::ConvertToDataStatus(status); + EXPECT_EQ(result, DistributedData::Asset::STATUS_INSERT); + + status = static_cast(DistributedDB::AssetStatus::UPDATE); + result = ValueProxy::TempAsset::ConvertToDataStatus(status); + EXPECT_EQ(result, DistributedData::Asset::STATUS_UPDATE); + + status = static_cast(DistributedDB::AssetStatus::DELETE); + result = ValueProxy::TempAsset::ConvertToDataStatus(status); + EXPECT_EQ(result, DistributedData::Asset::STATUS_DELETE); + + status = static_cast(DistributedDB::AssetStatus::DOWNLOADING); + result = ValueProxy::TempAsset::ConvertToDataStatus(status); + EXPECT_EQ(result, DistributedData::Asset::STATUS_DOWNLOADING); + + status = static_cast(DistributedDB::AssetStatus::DOWNLOAD_WITH_NULL); + result = ValueProxy::TempAsset::ConvertToDataStatus(status); + EXPECT_NE(result, DistributedData::Asset::STATUS_NORMAL); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn b/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn index e64eb69f..65d462e1 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn @@ -19,6 +19,7 @@ config("module_public_config") { include_dirs = [ "${data_service_path}/framework/include", "${data_service_path}/adapter/include/communicator", + "${data_service_path}/adapter/include/account", "${data_service_path}/adapter/include/dfx", "${data_service_path}/service/udmf/lifecycle", "${data_service_path}/service/udmf/permission", @@ -55,6 +56,7 @@ ohos_shared_library("udmf_server") { "permission/uri_permission_manager.cpp", "preprocess/preprocess_utils.cpp", "store/runtime_store.cpp", + "store/store_account_observer.cpp", "store/store_cache.cpp", "udmf_service_impl.cpp", "udmf_service_stub.cpp", @@ -80,12 +82,12 @@ ohos_shared_library("udmf_server") { "c_utils:utils", "hilog:libhilog", "hisysevent:libhisysevent", - "image_framework:image", "ipc:ipc_core", "kv_store:distributeddb", "safwk:system_ability_fwk", "samgr:samgr_proxy", "udmf:udmf_client", + "udmf:utd_client", ] cflags_cc = [ "-fvisibility=hidden" ] subsystem_name = "distributeddatamgr" diff --git a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp index f628847d..c7560122 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_manager.cpp @@ -26,6 +26,7 @@ namespace UDMF { using CleanAfterGet = LifeCyclePolicy; std::unordered_map> LifeCycleManager::intentionPolicy_ = { { UD_INTENTION_MAP.at(UD_INTENTION_DRAG), std::make_shared() }, + { UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB), std::make_shared() } }; LifeCycleManager &LifeCycleManager::GetInstance() diff --git a/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.cpp b/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.cpp index c6215277..4d528143 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.cpp @@ -31,7 +31,7 @@ UriPermissionManager &UriPermissionManager::GetInstance() } Status UriPermissionManager::GrantUriPermission( - const std::vector &allUri, uint32_t tokenId, const std::string &queryKey) + const std::vector &allUri, uint32_t tokenId, const std::string &queryKey, uint32_t &completeCount) { std::string bundleName; if (!PreProcessUtils::GetHapBundleNameByToken(tokenId, bundleName)) { @@ -57,9 +57,11 @@ Status UriPermissionManager::GrantUriPermission( status, queryKey.c_str(), instIndex); return E_NO_PERMISSION; } + completeCount = std::min(allUri.size(), index + GRANT_URI_PERMISSION_MAX_SIZE); auto time = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL); std::for_each(uriLst.begin(), uriLst.end(), [&](const Uri &uri) { - uriTimeout_[std::make_pair(uri.ToString(), tokenId)] = time; + auto times = std::make_pair(uri.ToString(), tokenId); + uriTimeout_.Insert(times, time); }); } ZLOGI("GrantUriPermission end, url size:%{public}zu, queryKey:%{public}s.", allUri.size(), queryKey.c_str()); @@ -75,7 +77,7 @@ Status UriPermissionManager::GrantUriPermission( void UriPermissionManager::RevokeUriPermission() { auto current = std::chrono::steady_clock::now(); - uriTimeout_.EraseIf([&](auto &key, Time &time) { + uriTimeout_.EraseIf([&](const auto &key, const Time &time) { if (time > current) { return false; } diff --git a/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.h b/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.h index 87be83cd..61dacb66 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.h @@ -30,7 +30,8 @@ class UriPermissionManager { public: using Time = std::chrono::steady_clock::time_point; static UriPermissionManager &GetInstance(); - Status GrantUriPermission(const std::vector &allUri, uint32_t tokenId, const std::string &queryKey); + Status GrantUriPermission(const std::vector &allUri, uint32_t tokenId, + const std::string &queryKey, uint32_t &completeCount); void SetThreadPool(std::shared_ptr executors); private: diff --git a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp index 64885ff0..b89ab80f 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp @@ -37,7 +37,8 @@ namespace UDMF { static constexpr int ID_LEN = 32; static constexpr int MINIMUM = 48; static constexpr int MAXIMUM = 121; -const char SPECIAL = '^'; +constexpr char SPECIAL = '^'; +constexpr const char *FILE_SCHEME = "file"; static constexpr uint32_t VERIFY_URI_PERMISSION_MAX_SIZE = 500; using namespace Security::AccessToken; using namespace OHOS::AppFileService::ModuleRemoteFileShare; @@ -170,8 +171,10 @@ int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data) continue; } Uri uri(file->GetUri()); - if (uri.GetAuthority().empty()) { - ZLOGW("Get uri authority empty."); + std::string scheme = uri.GetScheme(); + std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower); + if (uri.GetAuthority().empty() || scheme != FILE_SCHEME) { + ZLOGW("Get uri authority empty or uri scheme not equals to file."); continue; } uris.push_back(file->GetUri()); @@ -181,14 +184,17 @@ int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data) if (!CheckUriAuthorization(uris, tokenId)) { ZLOGE("CheckUriAuthorization failed, bundleName:%{public}s, tokenId: %{public}d, uris size:%{public}zu.", data.GetRuntime()->createPackage.c_str(), tokenId, uris.size()); - RADAR_REPORT(BizScene::SET_DATA, SetDataStage::VERIFY_SHARE_PERMISSIONS, StageRes::FAILED, - ERROR_CODE, E_NO_PERMISSION); + RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), + BizScene::SET_DATA, SetDataStage::VERIFY_SHARE_PERMISSIONS, StageRes::FAILED, E_NO_PERMISSION); return E_NO_PERMISSION; } + if (!IsNetworkingEnabled()) { + return E_OK; + } int ret = GetDfsUrisFromLocal(uris, userId, data); if (ret != E_OK) { - RADAR_REPORT(BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::FAILED, - ERROR_CODE, E_FS_ERROR); + RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), + BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::FAILED, E_FS_ERROR); ZLOGE("Get remoteUri failed, ret = %{public}d, userId: %{public}d, uri size:%{public}zu.", ret, userId, uris.size()); return E_FS_ERROR; @@ -248,5 +254,16 @@ bool PreProcessUtils::GetInstIndex(uint32_t tokenId, int32_t &instIndex) instIndex = tokenInfo.instIndex; return true; } + +bool PreProcessUtils::IsNetworkingEnabled() +{ + std::vector devInfos = + DistributedData::DeviceManagerAdapter::GetInstance().GetRemoteDevices(); + ZLOGI("DM remote devices count is %{public}u.", static_cast(devInfos.size())); + if (devInfos.empty()) { + return false; + } + return true; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h index 70e9c6ee..11ecccbb 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h @@ -38,6 +38,7 @@ public: static bool IsFileType(UDType udType); static int32_t SetRemoteUri(uint32_t tokenId, UnifiedData &data); static bool GetInstIndex(uint32_t tokenId, int32_t &instIndex); + static bool IsNetworkingEnabled(); private: static bool CheckUriAuthorization(const std::vector& uris, uint32_t tokenId); static int32_t GetDfsUrisFromLocal(const std::vector &uris, int32_t userId, UnifiedData &data); diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp index d6dd6a0d..e75733df 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -40,7 +40,7 @@ using namespace DistributedDB; using Anonymous = OHOS::DistributedData::Anonymous; using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; -const std::string TEMP_UNIFIED_DATA_FLAG = "temp_udmf_file_flag"; +constexpr const char *TEMP_UNIFIED_DATA_FLAG = "temp_udmf_file_flag"; static constexpr size_t TEMP_UDATA_RECORD_SIZE = 1; RuntimeStore::RuntimeStore(const std::string &storeId) : storeId_(storeId) @@ -277,23 +277,82 @@ Status RuntimeStore::Sync(const std::vector &devices) } } if (dbStatus != DBStatus::OK) { - RADAR_REPORT(BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, ERROR_CODE, dbStatus); + RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), + BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, dbStatus); } else { - RADAR_REPORT(BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::SUCCESS, - BIZ_STATE, BizState::DFX_NORMAL_END); + RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__), + BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::SUCCESS, BizState::DFX_NORMAL_END); } ZLOGI("sync complete, %{public}s, status:%{public}d.", Anonymous::Change(storeId_).c_str(), dbStatus); }; DBStatus status = kvStore_->Sync(syncDevices, SyncMode::SYNC_MODE_PULL_ONLY, onComplete); if (status != DBStatus::OK) { - RADAR_REPORT(BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, ERROR_CODE, status); + RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), + BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, status); ZLOGE("Sync kvStore failed, status: %{public}d.", status); return E_DB_ERROR; } return E_OK; } +Status RuntimeStore::Sync(const std::vector &devices, ProcessCallback callback) +{ + UpdateTime(); + if (devices.empty()) { + ZLOGE("devices empty, no need sync."); + return E_INVALID_PARAMETERS; + } + std::vector syncDevices = DmAdapter::ToUUID(devices); + DevNameMap deviceNameMap; + for (const auto &device : devices) { + std::string deviceUuid = DmAdapter::GetInstance().ToUUID(device); + std::string deviceName = DmAdapter::GetInstance().GetDeviceInfo(device).deviceName; + deviceNameMap.emplace(deviceUuid, deviceName); + } + auto progressCallback = [this, callback, deviceNameMap](const DevSyncProcessMap &processMap) { + this->NotifySyncProcss(processMap, callback, deviceNameMap); + }; + + DistributedDB::DeviceSyncOption option; + option.devices = syncDevices; + option.isWait = false; + DBStatus status = kvStore_->Sync(option, progressCallback); + if (status != DBStatus::OK) { + RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), + BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, status); + ZLOGE("Sync kvStore failed, status: %{public}d.", status); + return E_DB_ERROR; + } + return E_OK; +} + +void RuntimeStore::NotifySyncProcss(const DevSyncProcessMap &processMap, ProcessCallback callback, + const DevNameMap &deviceNameMap) +{ + AsyncProcessInfo processInfo{ASYNC_IDLE, ASYNC_IDLE, "", 0, 0, 0, 0, 0}; + for (const auto &[originDeviceId, syncProcess] : processMap) { // only one device + processInfo.srcDevName = deviceNameMap.at(originDeviceId); + processInfo.syncId = syncProcess.syncId; + processInfo.syncFinished = syncProcess.pullInfo.finishedCount; + processInfo.syncTotal = syncProcess.pullInfo.total; + if (syncProcess.process != DistributedDB::ProcessStatus::FINISHED) { + processInfo.syncStatus = ASYNC_RUNNING; + continue; + } + if (syncProcess.errCode == DBStatus::OK) { + processInfo.syncStatus = ASYNC_SUCCESS; + RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__), + BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::SUCCESS, BizState::DFX_NORMAL_END); + } else { + processInfo.syncStatus = ASYNC_FAILURE; + RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), + BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, syncProcess.errCode); + } + } + callback(processInfo); +} + Status RuntimeStore::Clear() { UpdateTime(); @@ -415,7 +474,12 @@ bool RuntimeStore::SaveMetaData() } int foregroundUserId = 0; - DistributedKv::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); + bool ret = DistributedKv::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); + if (!ret) { + ZLOGE("QueryForegroundUserId failed."); + return false; + } + saveMeta.dataDir.append("/").append(std::to_string(foregroundUserId)); if (!DistributedData::DirectoryManager::GetInstance().CreateDirectory(saveMeta.dataDir)) { ZLOGE("Create directory error"); diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.h b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.h index 303b4b08..e01d6e2d 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.h @@ -23,6 +23,8 @@ namespace OHOS { namespace UDMF { +using DevNameMap = std::map; +using DevSyncProcessMap = std::map; class API_EXPORT RuntimeStore final : public Store { public: explicit RuntimeStore(const std::string &storeId); @@ -34,6 +36,7 @@ public: Status Delete(const std::string &key) override; Status DeleteBatch(const std::vector &unifiedKeys) override; Status Sync(const std::vector &devices) override; + Status Sync(const std::vector &devices, ProcessCallback callback) override; Status Clear() override; Status GetBatchData(const std::string &dataPrefix, std::vector &unifiedDataSet) override; Status PutLocal(const std::string &key, const std::string &value) override; @@ -60,6 +63,8 @@ private: bool GetDetailsFromUData(UnifiedData &data, UDDetails &details); Status GetSummaryFromDetails(const UDDetails &details, Summary &summary); bool BuildMetaDataParam(DistributedData::StoreMetaData &metaData); + void NotifySyncProcss(const DevSyncProcessMap &processMap, ProcessCallback callback, + const DevNameMap &deviceNameMap); }; } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/store.h b/datamgr_service/services/distributeddataservice/service/udmf/store/store.h index 11a41da5..76471ef5 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/store.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/store.h @@ -27,6 +27,7 @@ namespace OHOS { namespace UDMF { +using ProcessCallback = std::function; class Store { public: using Time = std::chrono::steady_clock::time_point; @@ -37,6 +38,7 @@ public: virtual Status Delete(const std::string &key) = 0; virtual Status DeleteBatch(const std::vector &unifiedKeys) = 0; virtual Status Sync(const std::vector &devices) = 0; + virtual Status Sync(const std::vector &devices, ProcessCallback callback) = 0; virtual Status Clear() = 0; virtual Status GetBatchData(const std::string &dataPrefix, std::vector &unifiedDataSet) = 0; virtual Status PutLocal(const std::string &key, const std::string &value) = 0; diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/store_account_observer.cpp b/datamgr_service/services/distributeddataservice/service/udmf/store/store_account_observer.cpp new file mode 100644 index 00000000..1fa4c362 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/store_account_observer.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024 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 "RuntimeStoreAccountObserver" + +#include "store_account_observer.h" +#include "runtime_store.h" +#include "log_print.h" +#include "directory/directory_manager.h" +#include "account/account_delegate.h" +#include "bootstrap.h" +#include "ipc_skeleton.h" + +namespace OHOS { +namespace UDMF { +using namespace DistributedKv; +using namespace DistributedData; +void RuntimeStoreAccountObserver::OnAccountChanged(const DistributedKv::AccountEventInfo &eventInfo) +{ + ZLOGI("account event begin. status is %{public}d.", eventInfo.status); + if (eventInfo.status == DistributedKv::AccountStatus::DEVICE_ACCOUNT_DELETE) { + DistributedData::StoreMetaData metaData; + uint32_t token = IPCSkeleton::GetSelfTokenID(); + metaData.bundleName = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); + metaData.appId = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); + metaData.user = eventInfo.userId; + metaData.tokenId = token; + metaData.securityLevel = DistributedKv::SecurityLevel::S1; + metaData.area = DistributedKv::Area::EL1; + metaData.storeType = DistributedKv::KvStoreType::SINGLE_VERSION; + metaData.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(metaData); + std::string userPath = metaData.dataDir.append("/").append(eventInfo.userId); + DistributedData::DirectoryManager::GetInstance().DeleteDirectory(userPath.c_str()); + } +} + +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/store_account_observer.h b/datamgr_service/services/distributeddataservice/service/udmf/store/store_account_observer.h new file mode 100644 index 00000000..c352fd9c --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/store_account_observer.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 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 STORE_ACCOUNT_OBSERVER_H +#define STORE_ACCOUNT_OBSERVER_H + +#include "account_delegate.h" +namespace OHOS { +namespace UDMF { +class RuntimeStoreAccountObserver : public DistributedKv::AccountDelegate::Observer { + void OnAccountChanged(const DistributedKv::AccountEventInfo &eventInfo) override; + // must specify unique name for observer + std::string Name() override + { + return "UdmfRuntimeStore"; + } + + LevelType GetLevel() override + { + return LevelType::LOW; + } +}; + +} // namespace UDMF +} // namespace OHOS + +#endif // STORE_ACCOUNT_OBSERVER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.cpp b/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.cpp index 9d4d9014..f4c11ac5 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.cpp @@ -34,7 +34,11 @@ std::shared_ptr StoreCache::GetStore(std::string intention) { std::shared_ptr store; int foregroundUserId = 0; - DistributedKv::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); + bool ret = DistributedKv::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); + if (!ret) { + ZLOGE("QueryForegroundUserId failed."); + return nullptr; + } std::string key = intention; key.append(std::to_string(foregroundUserId)); diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index ec9febfc..2a6356b7 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -33,6 +33,11 @@ #include "uri.h" #include "utd/custom_utd_installer.h" #include "udmf_radar_reporter.h" +#include "securec.h" +#include "unified_types.h" +#include "device_manager_adapter.h" +#include "store_account_observer.h" + namespace OHOS { namespace UDMF { @@ -41,8 +46,10 @@ using FeatureSystem = DistributedData::FeatureSystem; using UdmfBehaviourMsg = OHOS::DistributedDataDfx::UdmfBehaviourMsg; using Reporter = OHOS::DistributedDataDfx::Reporter; using namespace RadarReporter; +using namespace DistributedKv; constexpr const char *DRAG_AUTHORIZED_PROCESSES[] = {"msdp_sa", "collaboration_service"}; constexpr const char *DATA_PREFIX = "udmf://"; +constexpr const char *FILE_SCHEME = "file"; constexpr const char *PRIVILEGE_READ_AND_KEEP = "readAndKeep"; __attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_; UdmfServiceImpl::Factory::Factory() @@ -56,6 +63,8 @@ UdmfServiceImpl::Factory::Factory() }, FeatureSystem::BIND_NOW); staticActs_ = std::make_shared(); FeatureSystem::GetInstance().RegisterStaticActs("udmf", staticActs_); + auto observer = std::make_shared(); + DistributedKv::AccountDelegate::GetInstance()->Subscribe(observer); } UdmfServiceImpl::Factory::~Factory() @@ -198,8 +207,8 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni return E_DB_ERROR; } if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info) && !IsPermissionInCache(query)) { - RADAR_REPORT(BizScene::GET_DATA, GetDataStage::VERIFY_PRIVILEGE, StageRes::FAILED, - ERROR_CODE, E_NO_PERMISSION); + RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), + BizScene::GET_DATA, GetDataStage::VERIFY_PRIVILEGE, StageRes::FAILED, E_NO_PERMISSION); return E_NO_PERMISSION; } @@ -277,16 +286,21 @@ int32_t UdmfServiceImpl::ProcessUri(const QueryOption &query, UnifiedData &unifi continue; } Uri uri(file->GetUri()); - if (uri.GetAuthority().empty()) { - ZLOGW("Get authority is empty, key=%{public}s.", query.key.c_str()); + std::string scheme = uri.GetScheme(); + std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower); + if (uri.GetAuthority().empty() || scheme != FILE_SCHEME) { + ZLOGW("Get authority is empty or uri scheme not equals to file, key=%{public}s.", query.key.c_str()); continue; } allUri.push_back(uri); } } - if (UriPermissionManager::GetInstance().GrantUriPermission(allUri, query.tokenId, query.key) != E_OK) { - RADAR_REPORT(BizScene::GET_DATA, GetDataStage::GRANT_URI_PERMISSION, StageRes::FAILED, - ERROR_CODE, E_NO_PERMISSION); + asyncProcessInfo_.permStatus = ASYNC_RUNNING; + asyncProcessInfo_.permTotal = allUri.size(); + if (UriPermissionManager::GetInstance().GrantUriPermission(allUri, query.tokenId, query.key, + asyncProcessInfo_.permFnished) != E_OK) { + RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), + BizScene::GET_DATA, GetDataStage::GRANT_URI_PERMISSION, StageRes::FAILED, E_NO_PERMISSION); ZLOGE("GrantUriPermission fail, bundleName=%{public}s, key=%{public}s.", bundleName.c_str(), query.key.c_str()); return E_NO_PERMISSION; @@ -332,23 +346,26 @@ int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vectorGet(query.key, data); if (res != E_OK) { @@ -363,6 +380,10 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi if (runtime == nullptr) { return E_DB_ERROR; } + if (runtime->tokenId != query.tokenId) { + ZLOGE("update data failed, query option tokenId not equals data's tokenId"); + return E_INVALID_PARAMETERS; + } runtime->lastModifiedTime = PreProcessUtils::GetTimestamp(); unifiedData.SetRuntime(*runtime); for (auto &record : unifiedData.GetRecords()) { @@ -396,9 +417,16 @@ int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vectorkey.key); + if (runtime->tokenId == query.tokenId) { + unifiedDataSet.push_back(data); + deleteKeys.push_back(runtime->key.key); + } + } + if (deleteKeys.empty()) { + ZLOGE("Delete nothing. There is no data belonging to this application"); + return E_OK; } + ZLOGI("Delete data start. size: %{public}zu.", deleteKeys.size()); if (store->DeleteBatch(deleteKeys) != E_OK) { ZLOGE("Remove data failed."); return E_DB_ERROR; @@ -484,7 +512,8 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector &devices) { ZLOGD("start"); - RADAR_REPORT(BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::IDLE, BIZ_STATE, BizState::DFX_BEGIN); + RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__), + BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::IDLE, BizState::DFX_BEGIN); UnifiedKey key(query.key); if (!key.IsValid()) { ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); @@ -496,14 +525,32 @@ int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vectorSync(devices) != E_OK) { + syncingData_ = true; + if (devices.size() > 0) { + syncingDevName_ = DistributedData::DeviceManagerAdapter::GetInstance().GetDeviceInfo(devices[0]).deviceName; + } + auto callback = [this](AsyncProcessInfo &syncInfo) { + asyncProcessInfo_.syncId = syncInfo.syncId; + asyncProcessInfo_.syncStatus = syncInfo.syncStatus; + asyncProcessInfo_.syncTotal = syncInfo.syncTotal; + asyncProcessInfo_.syncFinished = syncInfo.syncFinished; + asyncProcessInfo_.srcDevName = syncInfo.srcDevName; + if (asyncProcessInfo_.syncStatus != ASYNC_RUNNING) { + syncingData_ = false; + } + ZLOGD("store.Sync: name=%{public}s, id=%{public}u, status=%{public}u, total=%{public}u, finish=%{public}u", + syncInfo.srcDevName.c_str(), syncInfo.syncId, syncInfo.syncStatus, + syncInfo.syncTotal, syncInfo.syncFinished); + }; + if (store->Sync(devices, callback) != E_OK) { + syncingData_ = false; ZLOGE("Store sync failed, intention: %{public}s.", key.intention.c_str()); - RADAR_REPORT(BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, ERROR_CODE, E_DB_ERROR, - BIZ_STATE, BizState::DFX_ABNORMAL_END); + RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), + BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, E_DB_ERROR, BizState::DFX_ABNORMAL_END); return E_DB_ERROR; } - RADAR_REPORT(BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::SUCCESS); + RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__), + BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::SUCCESS, BizState::DFX_NORMAL_END); return E_OK; } @@ -711,5 +758,21 @@ int32_t UdmfServiceImpl::UdmfStatic::OnAppUninstall(const std::string &bundleNam } return status; } + +int32_t UdmfServiceImpl::ObtainAsynProcess(AsyncProcessInfo &processInfo) +{ + processInfo = asyncProcessInfo_; + if (syncingData_ && processInfo.syncStatus != ASYNC_RUNNING) { + processInfo.syncStatus = ASYNC_RUNNING; + processInfo.srcDevName = syncingDevName_; + } + return E_OK; +} + +int32_t UdmfServiceImpl::ClearAsynProcess() +{ + (void)memset_s(&asyncProcessInfo_, sizeof(asyncProcessInfo_), 0, sizeof(asyncProcessInfo_)); + return E_OK; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h index e172fe22..ca9a1107 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -51,6 +51,8 @@ public: int32_t RemoveAppShareOption(const std::string &intention) override; int32_t OnInitialize() override; int32_t OnBind(const BindInfo &bindInfo) override; + int32_t ObtainAsynProcess(AsyncProcessInfo &processInfo) override; + int32_t ClearAsynProcess() override; private: int32_t SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key); @@ -81,6 +83,10 @@ private: static Factory factory_; std::map privilegeCache_; std::shared_ptr executors_; + + AsyncProcessInfo asyncProcessInfo_{}; + bool syncingData_{false}; + std::string syncingDevName_; }; } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp index c71b3572..2523b196 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp @@ -263,5 +263,29 @@ int32_t UdmfServiceStub::OnRemoveAppShareOption(MessageParcel &data, MessageParc } return E_OK; } + +int32_t UdmfServiceStub::OnObtainAsynProcess(MessageParcel &data, MessageParcel &reply) +{ + ZLOGD("start"); + AsyncProcessInfo processInfo; + int32_t status = ObtainAsynProcess(processInfo); + if (!ITypesUtil::Marshal(reply, status, processInfo)) { + ZLOGE("Marshal status or processInfo failed, status: %{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnClearAsynProcess(MessageParcel &data, MessageParcel &reply) +{ + ZLOGD("start"); + int32_t status = ClearAsynProcess(); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status failed, status: %{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h index 0cd2879f..e3a66a58 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h @@ -48,6 +48,8 @@ private: int32_t OnSetAppShareOption(MessageParcel &data, MessageParcel &reply); int32_t OnGetAppShareOption(MessageParcel &data, MessageParcel &reply); int32_t OnRemoveAppShareOption(MessageParcel &data, MessageParcel &reply); + int32_t OnObtainAsynProcess(MessageParcel &data, MessageParcel &reply); + int32_t OnClearAsynProcess(MessageParcel &data, MessageParcel &reply); using Handler = int32_t (UdmfServiceStub::*)(MessageParcel &data, MessageParcel &reply); static constexpr Handler HANDLERS[static_cast(UdmfServiceInterfaceCode::CODE_BUTT)] = { @@ -62,7 +64,9 @@ private: &UdmfServiceStub::OnIsRemoteData, &UdmfServiceStub::OnSetAppShareOption, &UdmfServiceStub::OnGetAppShareOption, - &UdmfServiceStub::OnRemoveAppShareOption + &UdmfServiceStub::OnRemoveAppShareOption, + &UdmfServiceStub::OnObtainAsynProcess, + &UdmfServiceStub::OnClearAsynProcess }; }; } // namespace UDMF diff --git a/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.cpp b/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.cpp index 3a41a383..4101a168 100644 --- a/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.cpp @@ -17,14 +17,14 @@ #include "checker/checker_manager.h" #include "cloud/cloud_sync_finished_event.h" -#include "device_matrix.h" -#include "store/auto_cache.h" #include "device_manager_adapter.h" +#include "device_matrix.h" #include "eventcenter/event_center.h" #include "log_print.h" #include "metadata/matrix_meta_data.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" +#include "store/auto_cache.h" #include "utils/anonymous.h" #include "utils/constant.h" @@ -39,7 +39,7 @@ WaterVersionManager &WaterVersionManager::GetInstance() } WaterVersionManager::WaterVersionManager() : waterVersions_(BUTT) { - for (int i = 0; i < BUTT; ++i) { + for (int i = 0; i < static_cast(BUTT); ++i) { waterVersions_[i].SetType(static_cast(i)); } } @@ -58,7 +58,7 @@ void WaterVersionManager::Init() } MetaDataManager::GetInstance().LoadMeta(WaterVersionMetaData::GetPrefix(), metas, true); for (auto &meta : metas) { - if (meta.type < 0 || meta.type > BUTT) { + if (meta.type < BEGIN || meta.type > BUTT) { ZLOGW("error meta:%{public}s", meta.ToAnonymousString().c_str()); continue; } @@ -90,7 +90,7 @@ std::string WaterVersionManager::GenerateWaterVersion(const std::string &bundleN if (CheckerManager::GetInstance().IsStatic(info)) { type = STATIC; } - if (type < 0 || type >= BUTT || bundleName.empty() || storeName.empty()) { + if (type < BEGIN || type >= BUTT || bundleName.empty() || storeName.empty()) { ZLOGE("invalid args. bundleName:%{public}s, storeName:%{public}s, type:%{public}d", bundleName.c_str(), Anonymous::Change(storeName).c_str(), type); return ""; @@ -111,7 +111,7 @@ std::string WaterVersionManager::GetWaterVersion(const std::string &bundleName, if (CheckerManager::GetInstance().IsStatic(info)) { type = STATIC; } - if (type < 0 || type >= BUTT || bundleName.empty() || storeName.empty()) { + if (type < BEGIN || type >= BUTT || bundleName.empty() || storeName.empty()) { ZLOGE("invalid args. bundleName:%{public}s, storeName:%{public}s, type:%{public}d", bundleName.c_str(), Anonymous::Change(storeName).c_str(), type); return ""; @@ -137,7 +137,7 @@ std::string WaterVersionManager::GetWaterVersion(const std::string &bundleName, std::pair WaterVersionManager::GetVersion(const std::string &deviceId, WaterVersionManager::Type type) { - if (type < 0 || type >= BUTT || deviceId.empty()) { + if (type < BEGIN || type >= BUTT || deviceId.empty()) { ZLOGE("invalid args, type:%{public}d", type); return { false, 0 }; } @@ -147,7 +147,7 @@ std::pair WaterVersionManager::GetVersion(const std::string &dev std::string WaterVersionManager::GetWaterVersion(const std::string &deviceId, WaterVersionManager::Type type) { - if (type < 0 || type >= BUTT || deviceId.empty()) { + if (type < BEGIN || type >= BUTT || deviceId.empty()) { ZLOGE("invalid args, type:%{public}d", type); return { false, 0 }; } @@ -181,7 +181,7 @@ bool WaterVersionManager::DelWaterVersion(const std::string &deviceId) bool WaterVersionManager::InitMeta(WaterVersionMetaData &metaData) { - metaData.waterVersion = 0; + metaData.waterVersion = WaterVersionMetaData::DEFAULT_VERSION; std::string uuid = DMAdapter::GetInstance().GetLocalDevice().uuid; for (size_t i = 0; i < metaData.keys.size(); ++i) { auto key = metaData.keys[i]; @@ -326,7 +326,7 @@ bool WaterVersionMetaData::Unmarshal(const Serializable::json &node) GetValue(node, GET_NAME(waterVersion), waterVersion); int32_t tmp = -1; GetValue(node, GET_NAME(type), tmp); - if (tmp < 0 || tmp >= BUTT) { + if (tmp < BEGIN || tmp >= BUTT) { return false; } type = static_cast(tmp); @@ -360,7 +360,7 @@ std::string WaterVersionMetaData::GetPrefix() bool WaterVersionMetaData::IsValid() { - if (type < 0 || type >= BUTT) { + if (type < BEGIN || type >= BUTT) { return false; } if (keys.size() != infos.size()) { diff --git a/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.h b/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.h index bdf83e9f..7e77513f 100644 --- a/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.h +++ b/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.h @@ -25,7 +25,8 @@ namespace DistributedData { class WaterVersionManager { public: enum Type { - DYNAMIC, + BEGIN, + DYNAMIC = BEGIN, STATIC, BUTT }; diff --git a/googletest/BUILD.bazel b/googletest/BUILD.bazel index 965c518d..ac62251e 100644 --- a/googletest/BUILD.bazel +++ b/googletest/BUILD.bazel @@ -30,19 +30,32 @@ # # Bazel Build for Google C++ Testing Framework(Google Test) -load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") - package(default_visibility = ["//visibility:public"]) licenses(["notice"]) exports_files(["LICENSE"]) +config_setting( + name = "qnx", + constraint_values = ["@platforms//os:qnx"], +) + config_setting( name = "windows", constraint_values = ["@platforms//os:windows"], ) +config_setting( + name = "freebsd", + constraint_values = ["@platforms//os:freebsd"], +) + +config_setting( + name = "openbsd", + constraint_values = ["@platforms//os:openbsd"], +) + config_setting( name = "msvc_compiler", flag_values = { @@ -86,6 +99,7 @@ cc_library( "googlemock/include/gmock/*.h", ]), copts = select({ + ":qnx": [], ":windows": [], "//conditions:default": ["-pthread"], }), @@ -104,7 +118,16 @@ cc_library( "googletest/include", ], linkopts = select({ + ":qnx": ["-lregex"], ":windows": [], + ":freebsd": [ + "-lm", + "-pthread", + ], + ":openbsd": [ + "-lm", + "-pthread", + ], "//conditions:default": ["-pthread"], }), deps = select({ @@ -112,10 +135,15 @@ cc_library( "@com_google_absl//absl/debugging:failure_signal_handler", "@com_google_absl//absl/debugging:stacktrace", "@com_google_absl//absl/debugging:symbolize", + "@com_google_absl//absl/flags:flag", + "@com_google_absl//absl/flags:parse", + "@com_google_absl//absl/flags:reflection", + "@com_google_absl//absl/flags:usage", "@com_google_absl//absl/strings", "@com_google_absl//absl/types:any", "@com_google_absl//absl/types:optional", "@com_google_absl//absl/types:variant", + "@com_googlesource_code_re2//:re2", ], "//conditions:default": [], }), diff --git a/googletest/BUILD.gn b/googletest/BUILD.gn index f890da31..ec835ee7 100644 --- a/googletest/BUILD.gn +++ b/googletest/BUILD.gn @@ -7,68 +7,100 @@ config("gtest_private_config") { include_dirs = [ "googletest" ] } +config("gtest_private_config_rtti") { + visibility = [ ":*" ] + include_dirs = [ "googletest" ] + cflags = [ "-frtti" ] + cflags_objcc = [ "-frtti" ] + cflags_cc = [ "-frtti" ] +} + config("gtest_config") { include_dirs = [ "googletest/include" ] + cflags_cc = [ + "-std=c++17", + "-Wno-float-equal", + "-Wno-sign-compare", + "-Wno-reorder-init-list", + ] if (is_mingw) { - cflags_cc = [ + cflags_cc += [ "-Wno-unused-const-variable", "-Wno-unused-private-field", ] } } +sources_files = [ + "googletest/include/gtest/gtest-death-test.h", + "googletest/include/gtest/gtest-matchers.h", + "googletest/include/gtest/gtest-message.h", + "googletest/include/gtest/gtest-param-test.h", + "googletest/include/gtest/gtest-printers.h", + "googletest/include/gtest/gtest-test-part.h", + "googletest/include/gtest/gtest-typed-test.h", + "googletest/include/gtest/gtest_pred_impl.h", + "googletest/include/gtest/gtest_prod.h", + "googletest/include/gtest/hwext/gtest-ext.h", + "googletest/include/gtest/hwext/gtest-filter.h", + "googletest/include/gtest/hwext/gtest-multithread.h", + "googletest/include/gtest/hwext/gtest-tag.h", + "googletest/include/gtest/hwext/utils.h", + "googletest/include/gtest/internal/custom/gtest-port.h", + "googletest/include/gtest/internal/custom/gtest-printers.h", + "googletest/include/gtest/internal/custom/gtest.h", + "googletest/include/gtest/internal/gtest-death-test-internal.h", + "googletest/include/gtest/internal/gtest-filepath.h", + "googletest/include/gtest/internal/gtest-internal.h", + "googletest/include/gtest/internal/gtest-param-util.h", + "googletest/include/gtest/internal/gtest-port-arch.h", + "googletest/include/gtest/internal/gtest-port.h", + "googletest/include/gtest/internal/gtest-string.h", + "googletest/include/gtest/internal/gtest-type-util.h", + "googletest/src/gtest-all.cc", + "googletest/src/gtest-assertion-result.cc", + "googletest/src/gtest-death-test.cc", + "googletest/src/gtest-filepath.cc", + "googletest/src/gtest-internal-inl.h", + "googletest/src/gtest-matchers.cc", + "googletest/src/gtest-port.cc", + "googletest/src/gtest-printers.cc", + "googletest/src/gtest-test-part.cc", + "googletest/src/gtest-typed-test.cc", + "googletest/src/gtest.cc", + "googletest/src/hwext/gtest-ext.cc", + "googletest/src/hwext/gtest-filter.cc", + "googletest/src/hwext/gtest-multithread.cpp", + "googletest/src/hwext/gtest-tag.cc", + "googletest/src/hwext/gtest-utils.cc", +] + static_library("gtest") { testonly = true public = [ "googletest/include/gtest/gtest-spi.h", "googletest/include/gtest/gtest.h", ] - sources = [ - "googletest/include/gtest/gtest-death-test.h", - "googletest/include/gtest/gtest-matchers.h", - "googletest/include/gtest/gtest-message.h", - "googletest/include/gtest/gtest-param-test.h", - "googletest/include/gtest/gtest-printers.h", - "googletest/include/gtest/gtest-test-part.h", - "googletest/include/gtest/gtest-typed-test.h", - "googletest/include/gtest/gtest_pred_impl.h", - "googletest/include/gtest/gtest_prod.h", - "googletest/include/gtest/hwext/gtest-ext.h", - "googletest/include/gtest/hwext/gtest-filter.h", - "googletest/include/gtest/hwext/gtest-tag.h", - "googletest/include/gtest/hwext/utils.h", - "googletest/include/gtest/internal/custom/gtest-port.h", - "googletest/include/gtest/internal/custom/gtest-printers.h", - "googletest/include/gtest/internal/custom/gtest.h", - "googletest/include/gtest/internal/gtest-death-test-internal.h", - "googletest/include/gtest/internal/gtest-filepath.h", - "googletest/include/gtest/internal/gtest-internal.h", - "googletest/include/gtest/internal/gtest-param-util.h", - "googletest/include/gtest/internal/gtest-port-arch.h", - "googletest/include/gtest/internal/gtest-port.h", - "googletest/include/gtest/internal/gtest-string.h", - "googletest/include/gtest/internal/gtest-type-util.h", - "googletest/src/gtest-all.cc", - "googletest/src/gtest-death-test.cc", - "googletest/src/gtest-filepath.cc", - "googletest/src/gtest-internal-inl.h", - "googletest/src/gtest-matchers.cc", - "googletest/src/gtest-port.cc", - "googletest/src/gtest-printers.cc", - "googletest/src/gtest-test-part.cc", - "googletest/src/gtest-typed-test.cc", - "googletest/src/gtest.cc", - "googletest/src/hwext/gtest-ext.cc", - "googletest/src/hwext/gtest-filter.cc", - "googletest/src/hwext/gtest-tag.cc", - "googletest/src/hwext/gtest-utils.cc", - ] + sources = sources_files sources -= [ "googletest/src/gtest-all.cc" ] public_configs = [ ":gtest_config" ] configs += [ ":gtest_private_config" ] configs -= [ "//build/config/coverage:default_coverage" ] } +static_library("gtest_rtti") { + testonly = true + public = [ + "googletest/include/gtest/gtest-spi.h", + "googletest/include/gtest/gtest.h", + ] + sources = sources_files + sources -= [ "googletest/src/gtest-all.cc" ] + public_configs = [ ":gtest_config" ] + configs += [ ":gtest_private_config_rtti" ] + configs -= [ "//build/config/coverage:default_coverage" ] +} + static_library("gtest_main") { testonly = true sources = [ "googletest/src/gtest_main.cc" ] @@ -81,6 +113,14 @@ config("gmock_private_config") { include_dirs = [ "googlemock" ] } +config("gmock_private_config_rtti") { + visibility = [ ":*" ] + include_dirs = [ "googlemock/include" ] + cflags = [ "-frtti" ] + cflags_objcc = [ "-frtti" ] + cflags_cc = [ "-frtti" ] +} + config("gmock_config") { include_dirs = [ "googlemock/include" ] @@ -94,31 +134,33 @@ config("gmock_config") { ] } +gmock_sources_files = [ + "googlemock/include/gmock/gmock-actions.h", + "googlemock/include/gmock/gmock-cardinalities.h", + "googlemock/include/gmock/gmock-function-mocker.h", + "googlemock/include/gmock/gmock-matchers.h", + "googlemock/include/gmock/gmock-more-actions.h", + "googlemock/include/gmock/gmock-more-matchers.h", + "googlemock/include/gmock/gmock-nice-strict.h", + "googlemock/include/gmock/gmock-spec-builders.h", + "googlemock/include/gmock/internal/custom/gmock-generated-actions.h", + "googlemock/include/gmock/internal/custom/gmock-matchers.h", + "googlemock/include/gmock/internal/custom/gmock-port.h", + "googlemock/include/gmock/internal/gmock-internal-utils.h", + "googlemock/include/gmock/internal/gmock-port.h", + "googlemock/include/gmock/internal/gmock-pp.h", + "googlemock/src/gmock-all.cc", + "googlemock/src/gmock-cardinalities.cc", + "googlemock/src/gmock-internal-utils.cc", + "googlemock/src/gmock-matchers.cc", + "googlemock/src/gmock-spec-builders.cc", + "googlemock/src/gmock.cc", +] + static_library("gmock") { testonly = true public = [ "googlemock/include/gmock/gmock.h" ] - sources = [ - "googlemock/include/gmock/gmock-actions.h", - "googlemock/include/gmock/gmock-cardinalities.h", - "googlemock/include/gmock/gmock-function-mocker.h", - "googlemock/include/gmock/gmock-matchers.h", - "googlemock/include/gmock/gmock-more-actions.h", - "googlemock/include/gmock/gmock-more-matchers.h", - "googlemock/include/gmock/gmock-nice-strict.h", - "googlemock/include/gmock/gmock-spec-builders.h", - "googlemock/include/gmock/internal/custom/gmock-generated-actions.h", - "googlemock/include/gmock/internal/custom/gmock-matchers.h", - "googlemock/include/gmock/internal/custom/gmock-port.h", - "googlemock/include/gmock/internal/gmock-internal-utils.h", - "googlemock/include/gmock/internal/gmock-port.h", - "googlemock/include/gmock/internal/gmock-pp.h", - "googlemock/src/gmock-all.cc", - "googlemock/src/gmock-cardinalities.cc", - "googlemock/src/gmock-internal-utils.cc", - "googlemock/src/gmock-matchers.cc", - "googlemock/src/gmock-spec-builders.cc", - "googlemock/src/gmock.cc", - ] + sources = gmock_sources_files sources -= [ "googlemock/src/gmock-all.cc" ] public_configs = [ ":gmock_config" ] configs += [ ":gmock_private_config" ] @@ -126,6 +168,17 @@ static_library("gmock") { deps = [ ":gtest" ] } +static_library("gmock_rtti") { + testonly = true + public = [ "googlemock/include/gmock/gmock.h" ] + sources = gmock_sources_files + sources -= [ "googlemock/src/gmock-all.cc" ] + public_configs = [ ":gmock_config" ] + configs += [ ":gmock_private_config_rtti" ] + configs -= [ "//build/config/coverage:default_coverage" ] + deps = [ ":gtest_rtti" ] +} + static_library("gmock_main") { testonly = true sources = [ "googlemock/src/gmock_main.cc" ] diff --git a/googletest/CMakeLists.txt b/googletest/CMakeLists.txt index ea81ab12..6af41437 100644 --- a/googletest/CMakeLists.txt +++ b/googletest/CMakeLists.txt @@ -1,19 +1,25 @@ # Note: CMake support is community-based. The maintainers do not use CMake # internally. -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.5) if (POLICY CMP0048) cmake_policy(SET CMP0048 NEW) endif (POLICY CMP0048) +if (POLICY CMP0069) + cmake_policy(SET CMP0069 NEW) +endif (POLICY CMP0069) + +if (POLICY CMP0077) + cmake_policy(SET CMP0077 NEW) +endif (POLICY CMP0077) + project(googletest-distribution) -set(GOOGLETEST_VERSION 1.11.0) +set(GOOGLETEST_VERSION 1.13.0) -if (CMAKE_VERSION VERSION_GREATER "3.0.2") - if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX) - set(CMAKE_CXX_EXTENSIONS OFF) - endif() +if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX) + set(CMAKE_CXX_EXTENSIONS OFF) endif() enable_testing() @@ -24,6 +30,7 @@ include(GNUInstallDirs) #Note that googlemock target already builds googletest option(BUILD_GMOCK "Builds the googlemock subproject" ON) option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" ON) +option(GTEST_HAS_ABSL "Use Abseil and RE2. Requires Abseil and RE2 to be separately added to the build." OFF) if(BUILD_GMOCK) add_subdirectory( googlemock ) diff --git a/googletest/CONTRIBUTING.md b/googletest/CONTRIBUTING.md index da45e445..de14c815 100644 --- a/googletest/CONTRIBUTING.md +++ b/googletest/CONTRIBUTING.md @@ -21,8 +21,8 @@ accept your pull requests. ## Are you a Googler? -If you are a Googler, please make an attempt to submit an internal change rather -than a GitHub Pull Request. If you are not able to submit an internal change a +If you are a Googler, please make an attempt to submit an internal contribution +rather than a GitHub Pull Request. If you are not able to submit internally, a PR is acceptable as an alternative. ## Contributing A Patch @@ -36,7 +36,8 @@ PR is acceptable as an alternative. This ensures that work isn't being duplicated and communicating your plan early also generally leads to better patches. 4. If your proposed change is accepted, and you haven't already done so, sign a - Contributor License Agreement (see details above). + Contributor License Agreement + ([see details above](#contributor-license-agreements)). 5. Fork the desired repo, develop and test your code changes. 6. Ensure that your code adheres to the existing style in the sample to which you are contributing. @@ -79,8 +80,8 @@ fairly rigid coding style, as defined by the [google-styleguide](https://github.com/google/styleguide) project. All patches will be expected to conform to the style outlined [here](https://google.github.io/styleguide/cppguide.html). Use -[.clang-format](https://github.com/google/googletest/blob/master/.clang-format) -to check your formatting. +[.clang-format](https://github.com/google/googletest/blob/main/.clang-format) to +check your formatting. ## Requirements for Contributors diff --git a/googletest/CONTRIBUTORS b/googletest/CONTRIBUTORS index 76db0b40..77397a5b 100644 --- a/googletest/CONTRIBUTORS +++ b/googletest/CONTRIBUTORS @@ -34,6 +34,7 @@ Manuel Klimek Mario Tanev Mark Paskin Markus Heule +Martijn Vels Matthew Simmons Mika Raento Mike Bland @@ -55,6 +56,7 @@ Russ Rufer Sean Mcafee Sigurður Ásgeirsson Sverre Sundsdal +Szymon Sobik Takeshi Yoshino Tracy Bialik Vadim Berman diff --git a/googletest/OAT.xml b/googletest/OAT.xml index 79905db4..c876d65f 100644 --- a/googletest/OAT.xml +++ b/googletest/OAT.xml @@ -64,12 +64,9 @@ Note:If the text contains special characters, please escape them according to th - - - - - - + + + \ No newline at end of file diff --git a/googletest/README.OpenSource b/googletest/README.OpenSource index b7b7997f..625a7c02 100644 --- a/googletest/README.OpenSource +++ b/googletest/README.OpenSource @@ -3,9 +3,9 @@ "Name": "googletest", "License": "BSD 3-Clause License", "License File": "LICENSE", - "Version Number": "1.11.0", - "Owner": "zhangchunbao@huawei.com", - "Upstream URL": "https://github.com/google/googletest/releases/tag/release-1.11.0", - "Description": "The 1.11.x is the last release supporting pre-C++11 compilers. The 1.11.x will not accept any requests for any new features and any bugfix requests will only be accepted if proven critical" + "Version Number": "1.13.0", + "Owner": "", + "Upstream URL": "https://github.com/google/googletest/archive/refs/tags/v1.13.0.tar.gz", + "Description": "The 1.13.x only supports compilers above C++14. The 1.13.x will not accept any requests for any new features and any bugfix requests will only be accepted if proven critical" } -] +] \ No newline at end of file diff --git a/googletest/README.md b/googletest/README.md index 7d872a57..cd89abb2 100644 --- a/googletest/README.md +++ b/googletest/README.md @@ -6,7 +6,8 @@ GoogleTest now follows the [Abseil Live at Head philosophy](https://abseil.io/about/philosophy#upgrade-support). -We recommend using the latest commit in the `master` branch in your projects. +We recommend +[updating to the latest commit in the `main` branch as often as possible](https://github.com/abseil/abseil-cpp/blob/master/FAQ.md#what-is-live-at-head-and-how-do-i-do-it). #### Documentation Updates @@ -14,11 +15,14 @@ Our documentation is now live on GitHub Pages at https://google.github.io/googletest/. We recommend browsing the documentation on GitHub Pages rather than directly in the repository. -#### Release 1.10.x +#### Release 1.12.1 -[Release 1.10.x](https://github.com/google/googletest/releases/tag/release-1.10.0) +[Release 1.12.1](https://github.com/google/googletest/releases/tag/release-1.12.1) is now available. +The 1.12.x branch will be the last to support C++11. Future releases will +require at least C++14. + #### Coming Soon * We are planning to take a dependency on @@ -55,39 +59,12 @@ More information about building GoogleTest can be found at ## Supported Platforms -GoogleTest requires a codebase and compiler compliant with the C++11 standard or -newer. - -The GoogleTest code is officially supported on the following platforms. -Operating systems or tools not listed below are community-supported. For -community-supported platforms, patches that do not complicate the code may be -considered. - -If you notice any problems on your platform, please file an issue on the -[GoogleTest GitHub Issue Tracker](https://github.com/google/googletest/issues). -Pull requests containing fixes are welcome! - -### Operating Systems - -* Linux -* macOS -* Windows - -### Compilers - -* gcc 5.0+ -* clang 5.0+ -* MSVC 2015+ - -**macOS users:** Xcode 9.3+ provides clang 5.0+. - -### Build Systems - -* [Bazel](https://bazel.build/) -* [CMake](https://cmake.org/) - -**Note:** Bazel is the build system used by the team internally and in tests. -CMake is supported on a best-effort basis and by the community. +GoogleTest follows Google's +[Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support). +See +[this table](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md) +for a list of currently supported versions compilers, platforms, and build +tools. ## Who Is Using GoogleTest? @@ -109,8 +86,8 @@ Windows and Linux platforms. [GoogleTest UI](https://github.com/ospector/gtest-gbar) is a test runner that runs your test binary, allows you to track its progress via a progress bar, and -displays a list of test failures. Clicking on one shows failure text. Google -Test UI is written in C#. +displays a list of test failures. Clicking on one shows failure text. GoogleTest +UI is written in C#. [GTest TAP Listener](https://github.com/kinow/gtest-tap-listener) is an event listener for GoogleTest that implements the @@ -121,11 +98,11 @@ result output. If your test runner understands TAP, you may find it useful. runs tests from your binary in parallel to provide significant speed-up. [GoogleTest Adapter](https://marketplace.visualstudio.com/items?itemName=DavidSchuldenfrei.gtest-adapter) -is a VS Code extension allowing to view GoogleTest in a tree view, and run/debug +is a VS Code extension allowing to view GoogleTest in a tree view and run/debug your tests. [C++ TestMate](https://github.com/matepek/vscode-catch2-test-adapter) is a VS -Code extension allowing to view GoogleTest in a tree view, and run/debug your +Code extension allowing to view GoogleTest in a tree view and run/debug your tests. [Cornichon](https://pypi.org/project/cornichon/) is a small Gherkin DSL parser @@ -134,7 +111,7 @@ that generates stub code for GoogleTest. ## Contributing Changes Please read -[`CONTRIBUTING.md`](https://github.com/google/googletest/blob/master/CONTRIBUTING.md) +[`CONTRIBUTING.md`](https://github.com/google/googletest/blob/main/CONTRIBUTING.md) for details on how to contribute to this project. Happy testing! diff --git a/googletest/WORKSPACE b/googletest/WORKSPACE index 614f5577..0f10a6a9 100644 --- a/googletest/WORKSPACE +++ b/googletest/WORKSPACE @@ -3,22 +3,38 @@ workspace(name = "com_google_googletest") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( - name = "com_google_absl", - urls = ["https://github.com/abseil/abseil-cpp/archive/7971fb358ae376e016d2d4fc9327aad95659b25e.zip"], # 2021-05-20T02:59:16Z - strip_prefix = "abseil-cpp-7971fb358ae376e016d2d4fc9327aad95659b25e", - sha256 = "aeba534f7307e36fe084b452299e49b97420667a8d28102cf9a0daeed340b859", + name = "com_google_absl", # 2023-01-10T21:08:25Z + sha256 = "f9a4e749f42c386a32a90fddf0e2913ed408d10c42f7f33ccf4c59ac4f0d1d05", + strip_prefix = "abseil-cpp-52835439ca90d86b27bf8cd1708296e95604d724", + urls = ["https://github.com/abseil/abseil-cpp/archive/52835439ca90d86b27bf8cd1708296e95604d724.zip"], ) +# Note this must use a commit from the `abseil` branch of the RE2 project. +# https://github.com/google/re2/tree/abseil http_archive( - name = "rules_cc", - urls = ["https://github.com/bazelbuild/rules_cc/archive/68cb652a71e7e7e2858c50593e5a9e3b94e5b9a9.zip"], # 2021-05-14T14:51:14Z - strip_prefix = "rules_cc-68cb652a71e7e7e2858c50593e5a9e3b94e5b9a9", - sha256 = "1e19e9a3bc3d4ee91d7fcad00653485ee6c798efbbf9588d40b34cbfbded143d", + name = "com_googlesource_code_re2", # 2022-12-21T14:29:10Z + sha256 = "b9ce3a51beebb38534d11d40f8928d40509b9e18a735f6a4a97ad3d014c87cb5", + strip_prefix = "re2-d0b1f8f2ecc2ea74956c7608b6f915175314ff0e", + urls = ["https://github.com/google/re2/archive/d0b1f8f2ecc2ea74956c7608b6f915175314ff0e.zip"], ) http_archive( - name = "rules_python", - urls = ["https://github.com/bazelbuild/rules_python/archive/ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2.zip"], # 2021-05-17T00:24:16Z - strip_prefix = "rules_python-ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2", - sha256 = "98b3c592faea9636ac8444bfd9de7f3fb4c60590932d6e6ac5946e3f8dbd5ff6", + name = "rules_python", # 2023-01-10T22:00:51Z + sha256 = "5de54486a60ad8948dabe49605bb1c08053e04001a431ab3e96745b4d97a4419", + strip_prefix = "rules_python-70cce26432187a60b4e950118791385e6fb3c26f", + urls = ["https://github.com/bazelbuild/rules_python/archive/70cce26432187a60b4e950118791385e6fb3c26f.zip"], +) + +http_archive( + name = "bazel_skylib", # 2022-11-16T18:29:32Z + sha256 = "a22290c26d29d3ecca286466f7f295ac6cbe32c0a9da3a91176a90e0725e3649", + strip_prefix = "bazel-skylib-5bfcb1a684550626ce138fe0fe8f5f702b3764c3", + urls = ["https://github.com/bazelbuild/bazel-skylib/archive/5bfcb1a684550626ce138fe0fe8f5f702b3764c3.zip"], +) + +http_archive( + name = "platforms", # 2022-11-09T19:18:22Z + sha256 = "b4a3b45dc4202e2b3e34e3bc49d2b5b37295fc23ea58d88fb9e01f3642ad9b55", + strip_prefix = "platforms-3fbc687756043fb58a407c2ea8c944bc2fe1d922", + urls = ["https://github.com/bazelbuild/platforms/archive/3fbc687756043fb58a407c2ea8c944bc2fe1d922.zip"], ) diff --git a/googletest/bundle.json b/googletest/bundle.json index 002bd1d6..a82e37e2 100644 --- a/googletest/bundle.json +++ b/googletest/bundle.json @@ -10,11 +10,14 @@ "dirs": {}, "scripts": {}, "component": { - "name": "thirdparty_googletest", - "subsystem": "", + "name": "googletest", + "subsystem": "thirdparty", "syscap": [], "features": [], - "adapted_system_type": [], + "adapted_system_type": [ + "small", + "standard" + ], "rom": "", "ram": "", "deps": { @@ -23,8 +26,24 @@ }, "build": { "sub_component": [], - "inner_kits": [], + "inner_kits": [ + { + "name": "//third_party/googletest:gtest" + }, + { + "name": "//third_party/googletest:gmock" + }, + { + "name": "//third_party/googletest:gtest_main" + }, + { + "name": "//third_party/googletest:gmock_main" + }, + { + "name": "//third_party/googletest:gtest_rtti" + } + ], "test": [] } } -} \ No newline at end of file +} diff --git a/googletest/ci/linux-presubmit.sh b/googletest/ci/linux-presubmit.sh index 6bea1cde..4eb5bbe4 100644 --- a/googletest/ci/linux-presubmit.sh +++ b/googletest/ci/linux-presubmit.sh @@ -31,15 +31,15 @@ set -euox pipefail -readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20210525" -readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20201015" +readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20220217" +readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20220621" if [[ -z ${GTEST_ROOT:-} ]]; then GTEST_ROOT="$(realpath $(dirname ${0})/..)" fi if [[ -z ${STD:-} ]]; then - STD="c++11 c++14 c++17 c++20" + STD="c++14 c++17 c++20" fi # Test the CMake build @@ -55,7 +55,7 @@ for cc in /usr/local/bin/gcc /opt/llvm/clang/bin/clang; do ${LINUX_LATEST_CONTAINER} \ /bin/bash -c " cmake /src \ - -DCMAKE_CXX_STANDARD=11 \ + -DCMAKE_CXX_STANDARD=14 \ -Dgtest_build_samples=ON \ -Dgtest_build_tests=ON \ -Dgmock_build_tests=ON \ @@ -72,11 +72,15 @@ time docker run \ --workdir="/src" \ --rm \ --env="CC=/usr/local/bin/gcc" \ + --env="BAZEL_CXXOPTS=-std=c++14" \ ${LINUX_GCC_FLOOR_CONTAINER} \ /usr/local/bin/bazel test ... \ --copt="-Wall" \ --copt="-Werror" \ + --copt="-Wuninitialized" \ --copt="-Wno-error=pragmas" \ + --distdir="/bazel-distdir" \ + --features=external_include_paths \ --keep_going \ --show_timestamps \ --test_output=errors @@ -94,8 +98,10 @@ for std in ${STD}; do /usr/local/bin/bazel test ... \ --copt="-Wall" \ --copt="-Werror" \ + --copt="-Wuninitialized" \ --define="absl=${absl}" \ --distdir="/bazel-distdir" \ + --features=external_include_paths \ --keep_going \ --show_timestamps \ --test_output=errors @@ -116,8 +122,10 @@ for std in ${STD}; do --copt="--gcc-toolchain=/usr/local" \ --copt="-Wall" \ --copt="-Werror" \ + --copt="-Wuninitialized" \ --define="absl=${absl}" \ --distdir="/bazel-distdir" \ + --features=external_include_paths \ --keep_going \ --linkopt="--gcc-toolchain=/usr/local" \ --show_timestamps \ diff --git a/googletest/ci/macos-presubmit.sh b/googletest/ci/macos-presubmit.sh index d6423faa..8f35df58 100644 --- a/googletest/ci/macos-presubmit.sh +++ b/googletest/ci/macos-presubmit.sh @@ -40,7 +40,7 @@ for cmake_off_on in OFF ON; do BUILD_DIR=$(mktemp -d build_dir.XXXXXXXX) cd ${BUILD_DIR} time cmake ${GTEST_ROOT} \ - -DCMAKE_CXX_STANDARD=11 \ + -DCMAKE_CXX_STANDARD=14 \ -Dgtest_build_samples=ON \ -Dgtest_build_tests=ON \ -Dgmock_build_tests=ON \ @@ -53,7 +53,7 @@ done # Test the Bazel build # If we are running on Kokoro, check for a versioned Bazel binary. -KOKORO_GFILE_BAZEL_BIN="bazel-3.7.0-darwin-x86_64" +KOKORO_GFILE_BAZEL_BIN="bazel-5.1.1-darwin-x86_64" if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f ${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN} ]]; then BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}" chmod +x ${BAZEL_BIN} @@ -66,7 +66,9 @@ for absl in 0 1; do ${BAZEL_BIN} test ... \ --copt="-Wall" \ --copt="-Werror" \ + --cxxopt="-std=c++14" \ --define="absl=${absl}" \ + --features=external_include_paths \ --keep_going \ --show_timestamps \ --test_output=errors diff --git a/googletest/ci/windows-presubmit.bat b/googletest/ci/windows-presubmit.bat new file mode 100644 index 00000000..0c822d5e --- /dev/null +++ b/googletest/ci/windows-presubmit.bat @@ -0,0 +1,71 @@ +@echo off +@rem Copyright 2024 googletest authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. + +SETLOCAL ENABLEDELAYEDEXPANSION + +SET BAZEL_EXE=%KOKORO_GFILE_DIR%\bazel-5.1.1-windows-x86_64.exe + +SET PATH=C:\Python37;%PATH% +SET BAZEL_PYTHON=C:\python37\python.exe +SET BAZEL_SH=C:\tools\msys64\usr\bin\bash.exe +SET CMAKE_BIN="C:\Program Files\CMake\bin\cmake.exe" +SET CTEST_BIN="C:\Program Files\CMake\bin\ctest.exe" +SET CTEST_OUTPUT_ON_FAILURE=1 + +IF EXIST git\googletest ( + CD git\googletest +) ELSE IF EXIST github\googletest ( + CD github\googletest +) + +IF %errorlevel% neq 0 EXIT /B 1 + +:: ---------------------------------------------------------------------------- +:: CMake Visual Studio 15 2017 Win64 +MKDIR cmake_msvc2017 +CD cmake_msvc2017 + +%CMAKE_BIN% .. ^ + -G "Visual Studio 15 2017 Win64" ^ + -DPYTHON_EXECUTABLE:FILEPATH=c:\python37\python.exe ^ + -DPYTHON_INCLUDE_DIR:PATH=c:\python37\include ^ + -DPYTHON_LIBRARY:FILEPATH=c:\python37\lib\site-packages\pip ^ + -Dgtest_build_samples=ON ^ + -Dgtest_build_tests=ON ^ + -Dgmock_build_tests=ON +IF %errorlevel% neq 0 EXIT /B 1 + +%CMAKE_BIN% --build . --target ALL_BUILD --config Debug -- -maxcpucount +IF %errorlevel% neq 0 EXIT /B 1 + +%CTEST_BIN% -C Debug --timeout 600 +IF %errorlevel% neq 0 EXIT /B 1 + +CD .. +RMDIR /S /Q cmake_msvc2017 + +:: ---------------------------------------------------------------------------- +:: Bazel Visual Studio 15 2017 Win64 + +SET BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC +%BAZEL_EXE% test ... ^ + --compilation_mode=dbg ^ + --copt=/std:c++14 ^ + --copt=/WX ^ + --features=external_include_paths ^ + --keep_going ^ + --test_output=errors ^ + --test_tag_filters=-no_test_msvc2017 +IF %errorlevel% neq 0 EXIT /B 1 diff --git a/googletest/docs/_layouts/default.html b/googletest/docs/_layouts/default.html index dcb42d91..c7f331b8 100644 --- a/googletest/docs/_layouts/default.html +++ b/googletest/docs/_layouts/default.html @@ -48,7 +48,7 @@ diff --git a/googletest/docs/advanced.md b/googletest/docs/advanced.md index 8dff5ba1..f16382fe 100644 --- a/googletest/docs/advanced.md +++ b/googletest/docs/advanced.md @@ -157,8 +157,11 @@ that can be used in the predicate assertion macro example: ```c++ -EXPECT_PRED_FORMAT2(testing::FloatLE, val1, val2); -EXPECT_PRED_FORMAT2(testing::DoubleLE, val1, val2); +using ::testing::FloatLE; +using ::testing::DoubleLE; +... +EXPECT_PRED_FORMAT2(FloatLE, val1, val2); +EXPECT_PRED_FORMAT2(DoubleLE, val1, val2); ``` The above code verifies that `val1` is less than, or approximately equal to, @@ -202,10 +205,9 @@ You can call the function to assert that types `T1` and `T2` are the same. The function does nothing if the assertion is satisfied. If the types are different, the function call will -fail to compile, the compiler error message will say that -`T1 and T2 are not the same type` and most likely (depending on the compiler) -show you the actual values of `T1` and `T2`. This is mainly useful inside -template code. +fail to compile, the compiler error message will say that `T1 and T2 are not the +same type` and most likely (depending on the compiler) show you the actual +values of `T1` and `T2`. This is mainly useful inside template code. **Caveat**: When used inside a member function of a class template or a function template, `StaticAssertTypeEq()` is effective only if the function is @@ -383,10 +385,10 @@ EXPECT_TRUE(IsCorrectBarIntVector(bar_ints)) ## Death Tests In many applications, there are assertions that can cause application failure if -a condition is not met. These sanity checks, which ensure that the program is in -a known good state, are there to fail at the earliest possible time after some -program state is corrupted. If the assertion checks the wrong condition, then -the program may proceed in an erroneous state, which could lead to memory +a condition is not met. These consistency checks, which ensure that the program +is in a known good state, are there to fail at the earliest possible time after +some program state is corrupted. If the assertion checks the wrong condition, +then the program may proceed in an erroneous state, which could lead to memory corruption, security holes, or worse. Hence it is vitally important to test that such assertion statements work as expected. @@ -480,10 +482,12 @@ TEST_F(FooDeathTest, DoesThat) { ### Regular Expression Syntax -On POSIX systems (e.g. Linux, Cygwin, and Mac), googletest uses the +When built with Bazel and using Abseil, googletest uses the +[RE2](https://github.com/google/re2/wiki/Syntax) syntax. Otherwise, for POSIX +systems (Linux, Cygwin, Mac), googletest uses the [POSIX extended regular expression](http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_04) -syntax. To learn about this syntax, you may want to read this -[Wikipedia entry](http://en.wikipedia.org/wiki/Regular_expression#POSIX_Extended_Regular_Expressions). +syntax. To learn about POSIX syntax, you may want to read this +[Wikipedia entry](http://en.wikipedia.org/wiki/Regular_expression#POSIX_extended). On Windows, googletest uses its own simple regular expression implementation. It lacks many features. For example, we don't support union (`"x|y"`), grouping @@ -558,7 +562,7 @@ The automated testing framework does not set the style flag. You can choose a particular style of death tests by setting the flag programmatically: ```c++ -testing::FLAGS_gtest_death_test_style="threadsafe" +GTEST_FLAG_SET(death_test_style, "threadsafe") ``` You can do this in `main()` to set the style for all death tests in the binary, @@ -568,12 +572,12 @@ restored afterwards, so you need not do that yourself. For example: ```c++ int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); - testing::FLAGS_gtest_death_test_style = "fast"; + GTEST_FLAG_SET(death_test_style, "fast"); return RUN_ALL_TESTS(); } TEST(MyDeathTest, TestOne) { - testing::FLAGS_gtest_death_test_style = "threadsafe"; + GTEST_FLAG_SET(death_test_style, "threadsafe"); // This test is run in the "threadsafe" style: ASSERT_DEATH(ThisShouldDie(), ""); } @@ -610,15 +614,14 @@ Despite the improved thread safety afforded by the "threadsafe" style of death test, thread problems such as deadlock are still possible in the presence of handlers registered with `pthread_atfork(3)`. - ## Using Assertions in Sub-routines {: .callout .note} Note: If you want to put a series of test assertions in a subroutine to check for a complex condition, consider using -[a custom GMock matcher](gmock_cook_book.md#NewMatchers) -instead. This lets you provide a more readable error message in case of failure -and avoid all of the issues described below. +[a custom GMock matcher](gmock_cook_book.md#NewMatchers) instead. This lets you +provide a more readable error message in case of failure and avoid all of the +issues described below. ### Adding Traces to Assertions @@ -631,6 +634,7 @@ the `SCOPED_TRACE` macro or the `ScopedTrace` utility: ```c++ SCOPED_TRACE(message); ``` + ```c++ ScopedTrace trace("file_path", line_number, message); ``` @@ -837,7 +841,7 @@ will output XML like this: ```xml ... - + ... ``` @@ -888,6 +892,12 @@ preceding or following another. Also, the tests must either not modify the state of any shared resource, or, if they do modify the state, they must restore the state to its original value before passing control to the next test. +Note that `SetUpTestSuite()` may be called multiple times for a test fixture +class that has derived classes, so you should not expect code in the function +body to be run only once. Also, derived classes still have access to shared +resources defined as static members, so careful consideration is needed when +managing shared resources to avoid memory leaks. + Here's an example of per-test-suite set-up and tear-down: ```c++ @@ -897,7 +907,10 @@ class FooTest : public testing::Test { // Called before the first test in this test suite. // Can be omitted if not needed. static void SetUpTestSuite() { - shared_resource_ = new ...; + // Avoid reallocating static objects if called in subclasses of FooTest. + if (shared_resource_ == nullptr) { + shared_resource_ = new ...; + } } // Per-test-suite tear-down. @@ -1082,6 +1095,11 @@ instantiation of the test suite. The next argument is the name of the test pattern, and the last is the [parameter generator](reference/testing.md#param-generators). +The parameter generator expression is not evaluated until GoogleTest is +initialized (via `InitGoogleTest()`). Any prior initialization done in the +`main` function will be accessible from the parameter generator, for example, +the results of flag parsing. + You can instantiate a test pattern more than once, so to distinguish different instances of the pattern, the instantiation name is added as a prefix to the actual test suite name. Remember to pick unique prefixes for different @@ -1129,8 +1147,8 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FooTest); You can see [sample7_unittest.cc] and [sample8_unittest.cc] for more examples. -[sample7_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample7_unittest.cc "Parameterized Test example" -[sample8_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample8_unittest.cc "Parameterized Test example with multiple parameters" +[sample7_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample7_unittest.cc "Parameterized Test example" +[sample8_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample8_unittest.cc "Parameterized Test example with multiple parameters" ### Creating Value-Parameterized Abstract Tests @@ -1281,7 +1299,7 @@ TYPED_TEST(FooTest, HasPropertyA) { ... } You can see [sample6_unittest.cc] for a complete example. -[sample6_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample6_unittest.cc "Typed Test example" +[sample6_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample6_unittest.cc "Typed Test example" ## Type-Parameterized Tests @@ -1302,6 +1320,7 @@ First, define a fixture class template, as we did with typed tests: ```c++ template class FooTest : public testing::Test { + void DoSomethingInteresting(); ... }; ``` @@ -1319,6 +1338,9 @@ this as many times as you want: TYPED_TEST_P(FooTest, DoesBlah) { // Inside a test, refer to TypeParam to get the type parameter. TypeParam n = 0; + + // You will need to use `this` explicitly to refer to fixture members. + this->DoSomethingInteresting() ... } @@ -1481,8 +1503,8 @@ In frameworks that report a failure by throwing an exception, you could catch the exception and assert on it. But googletest doesn't use exceptions, so how do we test that a piece of code generates an expected failure? -`"gtest/gtest-spi.h"` contains some constructs to do this. After #including this header, -you can use +`"gtest/gtest-spi.h"` contains some constructs to do this. +After #including this header, you can use ```c++ EXPECT_FATAL_FAILURE(statement, substring); @@ -1586,12 +1608,14 @@ void RegisterMyTests(const std::vector& values) { } ... int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); std::vector values_to_test = LoadValuesFromConfig(); RegisterMyTests(values_to_test); ... return RUN_ALL_TESTS(); } ``` + ## Getting the Current Test's Name Sometimes a function may need to know the name of the currently running test. @@ -1714,7 +1738,7 @@ You can do so by adding one line: Now, sit back and enjoy a completely different output from your tests. For more details, see [sample9_unittest.cc]. -[sample9_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample9_unittest.cc "Event listener example" +[sample9_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample9_unittest.cc "Event listener example" You may append more than one listener to the list. When an `On*Start()` or `OnTestPartResult()` event is fired, the listeners will receive it in the order @@ -1741,7 +1765,7 @@ by the former. See [sample10_unittest.cc] for an example of a failure-raising listener. -[sample10_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample10_unittest.cc "Failure-raising listener example" +[sample10_unittest.cc]: https://github.com/google/googletest/blob/main/googletest/samples/sample10_unittest.cc "Failure-raising listener example" ## Running Test Programs: Advanced Options @@ -1816,8 +1840,7 @@ By default, a googletest program runs all tests the user has defined. In some cases (e.g. iterative test development & execution) it may be desirable stop test execution upon first failure (trading improved latency for completeness). If `GTEST_FAIL_FAST` environment variable or `--gtest_fail_fast` flag is set, -the test runner will stop execution as soon as the first test failure is -found. +the test runner will stop execution as soon as the first test failure is found. #### Temporarily Disabling Tests @@ -1890,8 +1913,12 @@ Repeat the tests whose name matches the filter 1000 times. If your test program contains [global set-up/tear-down](#global-set-up-and-tear-down) code, it will be -repeated in each iteration as well, as the flakiness may be in it. You can also -specify the repeat count by setting the `GTEST_REPEAT` environment variable. +repeated in each iteration as well, as the flakiness may be in it. To avoid +repeating global set-up/tear-down, specify +`--gtest_recreate_environments_when_repeating=false`{.nowrap}. + +You can also specify the repeat count by setting the `GTEST_REPEAT` environment +variable. ### Shuffling the Tests @@ -1911,6 +1938,58 @@ time. If you combine this with `--gtest_repeat=N`, googletest will pick a different random seed and re-shuffle the tests in each iteration. +### Distributing Test Functions to Multiple Machines + +If you have more than one machine you can use to run a test program, you might +want to run the test functions in parallel and get the result faster. We call +this technique *sharding*, where each machine is called a *shard*. + +GoogleTest is compatible with test sharding. To take advantage of this feature, +your test runner (not part of GoogleTest) needs to do the following: + +1. Allocate a number of machines (shards) to run the tests. +1. On each shard, set the `GTEST_TOTAL_SHARDS` environment variable to the total + number of shards. It must be the same for all shards. +1. On each shard, set the `GTEST_SHARD_INDEX` environment variable to the index + of the shard. Different shards must be assigned different indices, which + must be in the range `[0, GTEST_TOTAL_SHARDS - 1]`. +1. Run the same test program on all shards. When GoogleTest sees the above two + environment variables, it will select a subset of the test functions to run. + Across all shards, each test function in the program will be run exactly + once. +1. Wait for all shards to finish, then collect and report the results. + +Your project may have tests that were written without GoogleTest and thus don't +understand this protocol. In order for your test runner to figure out which test +supports sharding, it can set the environment variable `GTEST_SHARD_STATUS_FILE` +to a non-existent file path. If a test program supports sharding, it will create +this file to acknowledge that fact; otherwise it will not create it. The actual +contents of the file are not important at this time, although we may put some +useful information in it in the future. + +Here's an example to make it clear. Suppose you have a test program `foo_test` +that contains the following 5 test functions: + +``` +TEST(A, V) +TEST(A, W) +TEST(B, X) +TEST(B, Y) +TEST(B, Z) +``` + +Suppose you have 3 machines at your disposal. To run the test functions in +parallel, you would set `GTEST_TOTAL_SHARDS` to 3 on all machines, and set +`GTEST_SHARD_INDEX` to 0, 1, and 2 on the machines respectively. Then you would +run the same `foo_test` on each machine. + +GoogleTest reserves the right to change how the work is distributed across the +shards, but here's one possible scenario: + +* Machine #0 runs `A.V` and `B.X`. +* Machine #1 runs `A.W` and `B.Y`. +* Machine #2 runs `B.Z`. + ### Controlling Test Output #### Colored Terminal Output @@ -1965,8 +2044,6 @@ text because, for example, you don't have an UTF-8 compatible output medium, run the test program with `--gtest_print_utf8=0` or set the `GTEST_PRINT_UTF8` environment variable to `0`. - - #### Generating an XML Report googletest can emit a detailed XML report to a file in addition to its normal @@ -2020,15 +2097,15 @@ could generate this report: - + ... ... - + - + @@ -2046,6 +2123,9 @@ Things to note: * The `timestamp` attribute records the local date and time of the test execution. +* The `file` and `line` attributes record the source file location, where the + test was defined. + * Each `` element corresponds to a single failed googletest assertion. @@ -2085,6 +2165,8 @@ The report format conforms to the following JSON Schema: "type": "object", "properties": { "name": { "type": "string" }, + "file": { "type": "string" }, + "line": { "type": "integer" }, "status": { "type": "string", "enum": ["RUN", "NOTRUN"] @@ -2162,6 +2244,8 @@ message TestCase { message TestInfo { string name = 1; + string file = 6; + int32 line = 7; enum Status { RUN = 0; NOTRUN = 1; @@ -2205,6 +2289,8 @@ could generate this report: "testsuite": [ { "name": "Addition", + "file": "test.cpp", + "line": 1, "status": "RUN", "time": "0.007s", "classname": "", @@ -2221,6 +2307,8 @@ could generate this report: }, { "name": "Subtraction", + "file": "test.cpp", + "line": 2, "status": "RUN", "time": "0.005s", "classname": "" @@ -2236,6 +2324,8 @@ could generate this report: "testsuite": [ { "name": "NonContradiction", + "file": "test.cpp", + "line": 3, "status": "RUN", "time": "0.005s", "classname": "" @@ -2253,12 +2343,11 @@ IMPORTANT: The exact format of the JSON document is subject to change. #### Detecting Test Premature Exit -Google Test implements the _premature-exit-file_ protocol for test runners -to catch any kind of unexpected exits of test programs. Upon start, -Google Test creates the file which will be automatically deleted after -all work has been finished. Then, the test runner can check if this file -exists. In case the file remains undeleted, the inspected test has exited -prematurely. +Google Test implements the _premature-exit-file_ protocol for test runners to +catch any kind of unexpected exits of test programs. Upon start, Google Test +creates the file which will be automatically deleted after all work has been +finished. Then, the test runner can check if this file exists. In case the file +remains undeleted, the inspected test has exited prematurely. This feature is enabled only if the `TEST_PREMATURE_EXIT_FILE` environment variable has been set. diff --git a/googletest/docs/faq.md b/googletest/docs/faq.md index 9042da1e..19280972 100644 --- a/googletest/docs/faq.md +++ b/googletest/docs/faq.md @@ -1,9 +1,9 @@ -# Googletest FAQ +# GoogleTest FAQ ## Why should test suite names and test names not contain underscore? {: .callout .note} -Note: Googletest reserves underscore (`_`) for special purpose keywords, such as +Note: GoogleTest reserves underscore (`_`) for special purpose keywords, such as [the `DISABLED_` prefix](advanced.md#temporarily-disabling-tests), in addition to the following rationale. @@ -50,15 +50,15 @@ Now, the two `TEST`s will both generate the same class So for simplicity, we just ask the users to avoid `_` in `TestSuiteName` and `TestName`. The rule is more constraining than necessary, but it's simple and -easy to remember. It also gives googletest some wiggle room in case its +easy to remember. It also gives GoogleTest some wiggle room in case its implementation needs to change in the future. If you violate the rule, there may not be immediate consequences, but your test may (just may) break with a new compiler (or a new version of the compiler you -are using) or with a new version of googletest. Therefore it's best to follow +are using) or with a new version of GoogleTest. Therefore it's best to follow the rule. -## Why does googletest support `EXPECT_EQ(NULL, ptr)` and `ASSERT_EQ(NULL, ptr)` but not `EXPECT_NE(NULL, ptr)` and `ASSERT_NE(NULL, ptr)`? +## Why does GoogleTest support `EXPECT_EQ(NULL, ptr)` and `ASSERT_EQ(NULL, ptr)` but not `EXPECT_NE(NULL, ptr)` and `ASSERT_NE(NULL, ptr)`? First of all, you can use `nullptr` with each of these macros, e.g. `EXPECT_EQ(ptr, nullptr)`, `EXPECT_NE(ptr, nullptr)`, `ASSERT_EQ(ptr, nullptr)`, @@ -68,7 +68,7 @@ because `nullptr` does not have the type problems that `NULL` does. Due to some peculiarity of C++, it requires some non-trivial template meta programming tricks to support using `NULL` as an argument of the `EXPECT_XX()` and `ASSERT_XX()` macros. Therefore we only do it where it's most needed -(otherwise we make the implementation of googletest harder to maintain and more +(otherwise we make the implementation of GoogleTest harder to maintain and more error-prone than necessary). Historically, the `EXPECT_EQ()` macro took the *expected* value as its first @@ -162,7 +162,7 @@ methods, the parent process will think the calls have never occurred. Therefore, you may want to move your `EXPECT_CALL` statements inside the `EXPECT_DEATH` macro. -## EXPECT_EQ(htonl(blah), blah_blah) generates weird compiler errors in opt mode. Is this a googletest bug? +## EXPECT_EQ(htonl(blah), blah_blah) generates weird compiler errors in opt mode. Is this a GoogleTest bug? Actually, the bug is in `htonl()`. @@ -199,7 +199,7 @@ const int Foo::kBar; // No initializer here. ``` Otherwise your code is **invalid C++**, and may break in unexpected ways. In -particular, using it in googletest comparison assertions (`EXPECT_EQ`, etc) will +particular, using it in GoogleTest comparison assertions (`EXPECT_EQ`, etc) will generate an "undefined reference" linker error. The fact that "it used to work" doesn't mean it's valid. It just means that you were lucky. :-) @@ -225,7 +225,7 @@ cases may want to use the same or slightly different fixtures. For example, you may want to make sure that all of a GUI library's test suites don't leak important system resources like fonts and brushes. -In googletest, you share a fixture among test suites by putting the shared logic +In GoogleTest, you share a fixture among test suites by putting the shared logic in a base test fixture, then deriving from that base a separate fixture for each test suite that wants to use this common logic. You then use `TEST_F()` to write tests using each derived fixture. @@ -264,10 +264,10 @@ TEST_F(FooTest, Baz) { ... } ``` If necessary, you can continue to derive test fixtures from a derived fixture. -googletest has no limit on how deep the hierarchy can be. +GoogleTest has no limit on how deep the hierarchy can be. For a complete example using derived test fixtures, see -[sample5_unittest.cc](https://github.com/google/googletest/blob/master/googletest/samples/sample5_unittest.cc). +[sample5_unittest.cc](https://github.com/google/googletest/blob/main/googletest/samples/sample5_unittest.cc). ## My compiler complains "void value not ignored as it ought to be." What does this mean? @@ -278,7 +278,7 @@ disabled by our build system. Please see more details ## My death test hangs (or seg-faults). How do I fix it? -In googletest, death tests are run in a child process and the way they work is +In GoogleTest, death tests are run in a child process and the way they work is delicate. To write death tests you really need to understand how they work—see the details at [Death Assertions](reference/assertions.md#death) in the Assertions Reference. @@ -305,8 +305,8 @@ bullet - sorry! ## Should I use the constructor/destructor of the test fixture or SetUp()/TearDown()? {#CtorVsSetUp} -The first thing to remember is that googletest does **not** reuse the same test -fixture object across multiple tests. For each `TEST_F`, googletest will create +The first thing to remember is that GoogleTest does **not** reuse the same test +fixture object across multiple tests. For each `TEST_F`, GoogleTest will create a **fresh** test fixture object, immediately call `SetUp()`, run the test body, call `TearDown()`, and then delete the test fixture object. @@ -328,7 +328,7 @@ You may still want to use `SetUp()/TearDown()` in the following cases: * C++ does not allow virtual function calls in constructors and destructors. You can call a method declared as virtual, but it will not use dynamic - dispatch, it will use the definition from the class the constructor of which + dispatch. It will use the definition from the class the constructor of which is currently executing. This is because calling a virtual method before the derived class constructor has a chance to run is very dangerous - the virtual method might operate on uninitialized data. Therefore, if you need @@ -345,11 +345,11 @@ You may still want to use `SetUp()/TearDown()` in the following cases: that many standard libraries (like STL) may throw when exceptions are enabled in the compiler. Therefore you should prefer `TearDown()` if you want to write portable tests that work with or without exceptions. -* The googletest team is considering making the assertion macros throw on +* The GoogleTest team is considering making the assertion macros throw on platforms where exceptions are enabled (e.g. Windows, Mac OS, and Linux client-side), which will eliminate the need for the user to propagate failures from a subroutine to its caller. Therefore, you shouldn't use - googletest assertions in a destructor if your code could run on such a + GoogleTest assertions in a destructor if your code could run on such a platform. ## The compiler complains "no matching function to call" when I use ASSERT_PRED*. How do I fix it? @@ -375,7 +375,7 @@ they write This is **wrong and dangerous**. The testing services needs to see the return value of `RUN_ALL_TESTS()` in order to determine if a test has passed. If your `main()` function ignores it, your test will be considered successful even if it -has a googletest assertion failure. Very bad. +has a GoogleTest assertion failure. Very bad. We have decided to fix this (thanks to Michael Chastain for the idea). Now, your code will no longer be able to ignore `RUN_ALL_TESTS()` when compiled with @@ -410,7 +410,6 @@ C++ is case-sensitive. Did you spell it as `Setup()`? Similarly, sometimes people spell `SetUpTestSuite()` as `SetupTestSuite()` and wonder why it's never called. - ## I have several test suites which share the same test fixture logic, do I have to define a new test fixture class for each of them? This seems pretty tedious. You don't have to. Instead of @@ -441,14 +440,14 @@ TEST_F(BarTest, Abc) { ... } TEST_F(BarTest, Def) { ... } ``` -## googletest output is buried in a whole bunch of LOG messages. What do I do? +## GoogleTest output is buried in a whole bunch of LOG messages. What do I do? -The googletest output is meant to be a concise and human-friendly report. If -your test generates textual output itself, it will mix with the googletest +The GoogleTest output is meant to be a concise and human-friendly report. If +your test generates textual output itself, it will mix with the GoogleTest output, making it hard to read. However, there is an easy solution to this problem. -Since `LOG` messages go to stderr, we decided to let googletest output go to +Since `LOG` messages go to stderr, we decided to let GoogleTest output go to stdout. This way, you can easily separate the two using redirection. For example: @@ -521,7 +520,7 @@ TEST(MyDeathTest, CompoundStatement) { ## I have a fixture class `FooTest`, but `TEST_F(FooTest, Bar)` gives me error ``"no matching function for call to `FooTest::FooTest()'"``. Why? -Googletest needs to be able to create objects of your test fixture class, so it +GoogleTest needs to be able to create objects of your test fixture class, so it must have a default constructor. Normally the compiler will define one for you. However, there are cases where you have to define your own: @@ -546,11 +545,11 @@ The new NPTL thread library doesn't suffer from this problem, as it doesn't create a manager thread. However, if you don't control which machine your test runs on, you shouldn't depend on this. -## Why does googletest require the entire test suite, instead of individual tests, to be named *DeathTest when it uses ASSERT_DEATH? +## Why does GoogleTest require the entire test suite, instead of individual tests, to be named *DeathTest when it uses ASSERT_DEATH? -googletest does not interleave tests from different test suites. That is, it +GoogleTest does not interleave tests from different test suites. That is, it runs all tests in one test suite first, and then runs all tests in the next test -suite, and so on. googletest does this because it needs to set up a test suite +suite, and so on. GoogleTest does this because it needs to set up a test suite before the first test in it is run, and tear it down afterwards. Splitting up the test case would require multiple set-up and tear-down processes, which is inefficient and makes the semantics unclean. @@ -589,11 +588,11 @@ TEST_F(FooDeathTest, Uvw) { ... EXPECT_DEATH(...) ... } TEST_F(FooDeathTest, Xyz) { ... ASSERT_DEATH(...) ... } ``` -## googletest prints the LOG messages in a death test's child process only when the test fails. How can I see the LOG messages when the death test succeeds? +## GoogleTest prints the LOG messages in a death test's child process only when the test fails. How can I see the LOG messages when the death test succeeds? Printing the LOG messages generated by the statement inside `EXPECT_DEATH()` makes it harder to search for real problems in the parent's log. Therefore, -googletest only prints them when the death test has failed. +GoogleTest only prints them when the death test has failed. If you really need to see such LOG messages, a workaround is to temporarily break the death test (e.g. by changing the regex pattern it is expected to @@ -612,7 +611,7 @@ needs to be defined in the *same* name space. See ## How do I suppress the memory leak messages on Windows? -Since the statically initialized googletest singleton requires allocations on +Since the statically initialized GoogleTest singleton requires allocations on the heap, the Visual C++ memory leak detector will report memory leaks at the end of the program run. The easiest way to avoid this is to use the `_CrtMemCheckpoint` and `_CrtMemDumpAllObjectsSince` calls to not report any @@ -626,7 +625,7 @@ things accordingly, you are leaking test-only logic into production code and there is no easy way to ensure that the test-only code paths aren't run by mistake in production. Such cleverness also leads to [Heisenbugs](https://en.wikipedia.org/wiki/Heisenbug). Therefore we strongly -advise against the practice, and googletest doesn't provide a way to do it. +advise against the practice, and GoogleTest doesn't provide a way to do it. In general, the recommended way to cause the code to behave differently under test is [Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection). You can inject @@ -673,7 +672,7 @@ TEST(CoolTest, DoSomething) { ``` However, the following code is **not allowed** and will produce a runtime error -from googletest because the test methods are using different test fixture +from GoogleTest because the test methods are using different test fixture classes with the same test suite name. ```c++ diff --git a/googletest/docs/gmock_cheat_sheet.md b/googletest/docs/gmock_cheat_sheet.md index 17ed7a54..2fb0403e 100644 --- a/googletest/docs/gmock_cheat_sheet.md +++ b/googletest/docs/gmock_cheat_sheet.md @@ -8,7 +8,7 @@ Given ```cpp class Foo { - ... + public: virtual ~Foo(); virtual int GetSize() const = 0; virtual string Describe(const char* name) = 0; @@ -23,7 +23,7 @@ class Foo { #include "gmock/gmock.h" class MockFoo : public Foo { - ... + public: MOCK_METHOD(int, GetSize, (), (const, override)); MOCK_METHOD(string, Describe, (const char* name), (override)); MOCK_METHOD(string, Describe, (int type), (override)); @@ -58,7 +58,7 @@ To mock ```cpp template class StackInterface { - ... + public: virtual ~StackInterface(); virtual int GetSize() const = 0; virtual void Push(const Elem& x) = 0; @@ -71,7 +71,7 @@ class StackInterface { ```cpp template class MockStack : public StackInterface { - ... + public: MOCK_METHOD(int, GetSize, (), (const, override)); MOCK_METHOD(void, Push, (const Elem& x), (override)); }; @@ -140,7 +140,7 @@ To customize the default action for functions with return type `T`, use // Sets the default action for return type std::unique_ptr to // creating a new Buzz every time. DefaultValue>::SetFactory( - [] { return MakeUnique(AccessLevel::kInternal); }); + [] { return std::make_unique(AccessLevel::kInternal); }); // When this fires, the default action of MakeBuzz() will run, which // will return a new Buzz object. @@ -230,7 +230,7 @@ class MockFunction { }; ``` -See this [recipe](gmock_cook_book.md#using-check-points) for one application of +See this [recipe](gmock_cook_book.md#UsingCheckPoints) for one application of it. ## Flags diff --git a/googletest/docs/gmock_cook_book.md b/googletest/docs/gmock_cook_book.md index c08958eb..fc7db35b 100644 --- a/googletest/docs/gmock_cook_book.md +++ b/googletest/docs/gmock_cook_book.md @@ -392,8 +392,7 @@ Old macros and their new equivalents: If a mock method has no `EXPECT_CALL` spec but is called, we say that it's an "uninteresting call", and the default action (which can be specified using `ON_CALL()`) of the method will be taken. Currently, an uninteresting call will -also by default cause gMock to print a warning. (In the future, we might remove -this warning by default.) +also by default cause gMock to print a warning. However, sometimes you may want to ignore these uninteresting calls, and sometimes you may want to treat them as errors. gMock lets you make the decision @@ -905,7 +904,7 @@ using ::testing::Contains; using ::testing::Property; inline constexpr auto HasFoo = [](const auto& f) { - return Property(&MyClass::foo, Contains(f)); + return Property("foo", &MyClass::foo, Contains(f)); }; ... EXPECT_THAT(x, HasFoo("blah")); @@ -1084,7 +1083,7 @@ using ::testing::Lt; ``` says that `Blah` will be called with arguments `x`, `y`, and `z` where `x < y < -z`. Note that in this example, it wasn't necessary specify the positional +z`. Note that in this example, it wasn't necessary to specify the positional matchers. As a convenience and example, gMock provides some matchers for 2-tuples, @@ -1159,7 +1158,7 @@ int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; } ``` Note that the predicate function / functor doesn't have to return `bool`. It -works as long as the return value can be used as the condition in in statement +works as long as the return value can be used as the condition in the statement `if (condition) ...`. ### Matching Arguments that Are Not Copyable @@ -1300,23 +1299,27 @@ What if you have a pointer to pointer? You guessed it - you can use nested `Pointee(Pointee(Lt(3)))` matches a pointer that points to a pointer that points to a number less than 3 (what a mouthful...). -### Testing a Certain Property of an Object +### Defining a Custom Matcher Class {#CustomMatcherClass} -Sometimes you want to specify that an object argument has a certain property, -but there is no existing matcher that does this. If you want good error -messages, you should [define a matcher](#NewMatchers). If you want to do it -quick and dirty, you could get away with writing an ordinary function. +Most matchers can be simply defined using [the MATCHER* macros](#NewMatchers), +which are terse and flexible, and produce good error messages. However, these +macros are not very explicit about the interfaces they create and are not always +suitable, especially for matchers that will be widely reused. -Let's say you have a mock function that takes an object of type `Foo`, which has -an `int bar()` method and an `int baz()` method, and you want to constrain that -the argument's `bar()` value plus its `baz()` value is a given number. Here's -how you can define a matcher to do it: +For more advanced cases, you may need to define your own matcher class. A custom +matcher allows you to test a specific invariant property of that object. Let's +take a look at how to do so. -```cpp -using ::testing::Matcher; +Imagine you have a mock function that takes an object of type `Foo`, which has +an `int bar()` method and an `int baz()` method. You want to constrain that the +argument's `bar()` value plus its `baz()` value is a given number. (This is an +invariant.) Here's how we can write and use a matcher class to do so: +```cpp class BarPlusBazEqMatcher { public: + using is_gtest_matcher = void; + explicit BarPlusBazEqMatcher(int expected_sum) : expected_sum_(expected_sum) {} @@ -1325,23 +1328,24 @@ class BarPlusBazEqMatcher { return (foo.bar() + foo.baz()) == expected_sum_; } - void DescribeTo(std::ostream& os) const { - os << "bar() + baz() equals " << expected_sum_; + void DescribeTo(std::ostream* os) const { + *os << "bar() + baz() equals " << expected_sum_; } - void DescribeNegationTo(std::ostream& os) const { - os << "bar() + baz() does not equal " << expected_sum_; + void DescribeNegationTo(std::ostream* os) const { + *os << "bar() + baz() does not equal " << expected_sum_; } private: const int expected_sum_; }; -Matcher BarPlusBazEq(int expected_sum) { +::testing::Matcher BarPlusBazEq(int expected_sum) { return BarPlusBazEqMatcher(expected_sum); } ... - EXPECT_CALL(..., DoThis(BarPlusBazEq(5)))...; + Foo foo; + EXPECT_THAT(foo, BarPlusBazEq(5))...; ``` ### Matching Containers @@ -1420,11 +1424,12 @@ Use `Pair` when comparing maps or other associative containers. {% raw %} ```cpp -using testing::ElementsAre; -using testing::Pair; +using ::testing::UnorderedElementsAre; +using ::testing::Pair; ... - std::map m = {{"a", 1}, {"b", 2}, {"c", 3}}; - EXPECT_THAT(m, ElementsAre(Pair("a", 1), Pair("b", 2), Pair("c", 3))); + absl::flat_hash_map m = {{"a", 1}, {"b", 2}, {"c", 3}}; + EXPECT_THAT(m, UnorderedElementsAre( + Pair("a", 1), Pair("b", 2), Pair("c", 3))); ``` {% endraw %} @@ -1441,8 +1446,8 @@ using testing::Pair; * If the container is passed by pointer instead of by reference, just write `Pointee(ElementsAre*(...))`. * The order of elements *matters* for `ElementsAre*()`. If you are using it - with containers whose element order are undefined (e.g. `hash_map`) you - should use `WhenSorted` around `ElementsAre`. + with containers whose element order are undefined (such as a + `std::unordered_map`) you should use `UnorderedElementsAre`. ### Sharing Matchers @@ -1452,7 +1457,7 @@ the pointer is copied. When the last matcher that references the implementation object dies, the implementation object will be deleted. Therefore, if you have some complex matcher that you want to use again and -again, there is no need to build it everytime. Just assign it to a matcher +again, there is no need to build it every time. Just assign it to a matcher variable and use that variable repeatedly! For example, ```cpp @@ -1754,7 +1759,7 @@ specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> C -> D`): | A ---| | - +---> C ---> D + +---> C ---> D ``` This means that A must occur before B and C, and C must occur before D. There's @@ -1899,7 +1904,7 @@ using testing::ReturnPointee; ### Combining Actions Want to do more than one thing when a function is called? That's fine. `DoAll()` -allow you to do sequence of actions every time. Only the return value of the +allows you to do a sequence of actions every time. Only the return value of the last action in the sequence will be used. ```cpp @@ -1980,6 +1985,7 @@ If the mock method also needs to return a value as well, you can chain ```cpp using ::testing::_; +using ::testing::DoAll; using ::testing::Return; using ::testing::SetArgPointee; @@ -2033,10 +2039,7 @@ class MockRolodex : public Rolodex { } ... MockRolodex rolodex; - vector names; - names.push_back("George"); - names.push_back("John"); - names.push_back("Thomas"); + vector names = {"George", "John", "Thomas"}; EXPECT_CALL(rolodex, GetNames(_)) .WillOnce(SetArrayArgument<0>(names.begin(), names.end())); ``` @@ -2604,7 +2607,7 @@ efficient. When the last action that references the implementation object dies, the implementation object will be deleted. If you have some complex action that you want to use again and again, you may -not have to build it from scratch everytime. If the action doesn't have an +not have to build it from scratch every time. If the action doesn't have an internal state (i.e. if it always does the same thing no matter how many times it has been called), you can assign it to an action variable and use that variable repeatedly. For example: @@ -2781,7 +2784,7 @@ If you just need to return a pre-defined move-only value, you can use the // When this fires, the unique_ptr<> specified by ByMove(...) will // be returned. EXPECT_CALL(mock_buzzer_, MakeBuzz("world")) - .WillOnce(Return(ByMove(MakeUnique(AccessLevel::kInternal)))); + .WillOnce(Return(ByMove(std::make_unique(AccessLevel::kInternal)))); EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("world")); ``` @@ -2802,7 +2805,7 @@ pretty much anything you want: ```cpp EXPECT_CALL(mock_buzzer_, MakeBuzz("x")) .WillRepeatedly([](StringPiece text) { - return MakeUnique(AccessLevel::kInternal); + return std::make_unique(AccessLevel::kInternal); }); EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x")); @@ -2821,7 +2824,7 @@ can always use `Return`, or a [lambda or functor](#FunctionsAsActions): using ::testing::Unused; EXPECT_CALL(mock_buzzer_, ShareBuzz(NotNull(), _)).WillOnce(Return(true)); - EXPECT_TRUE(mock_buzzer_.ShareBuzz(MakeUnique(AccessLevel::kInternal)), + EXPECT_TRUE(mock_buzzer_.ShareBuzz(std::make_unique(AccessLevel::kInternal)), 0); EXPECT_CALL(mock_buzzer_, ShareBuzz(_, _)).WillOnce( @@ -2865,7 +2868,7 @@ method: // When one calls ShareBuzz() on the MockBuzzer like this, the call is // forwarded to DoShareBuzz(), which is mocked. Therefore this statement // will trigger the above EXPECT_CALL. - mock_buzzer_.ShareBuzz(MakeUnique(AccessLevel::kInternal), 0); + mock_buzzer_.ShareBuzz(std::make_unique(AccessLevel::kInternal), 0); ``` ### Making the Compilation Faster @@ -3809,22 +3812,19 @@ Cardinality EvenNumber() { .Times(EvenNumber()); ``` -### Writing New Actions Quickly {#QuickNewActions} +### Writing New Actions {#QuickNewActions} If the built-in actions don't work for you, you can easily define your own one. -Just define a functor class with a (possibly templated) call operator, matching -the signature of your action. +All you need is a call operator with a signature compatible with the mocked +function. So you can use a lambda: -```cpp -struct Increment { - template - T operator()(T* arg) { - return ++(*arg); - } -} +``` +MockFunction mock; +EXPECT_CALL(mock, Call).WillOnce([](const int input) { return input * 7; }); +EXPECT_EQ(14, mock.AsStdFunction()(2)); ``` -The same approach works with stateful functors (or any callable, really): +Or a struct with a call operator (even a templated one): ``` struct MultiplyBy { @@ -3832,12 +3832,54 @@ struct MultiplyBy { T operator()(T arg) { return arg * multiplier; } int multiplier; -} +}; // Then use: // EXPECT_CALL(...).WillOnce(MultiplyBy{7}); ``` +It's also fine for the callable to take no arguments, ignoring the arguments +supplied to the mock function: + +``` +MockFunction mock; +EXPECT_CALL(mock, Call).WillOnce([] { return 17; }); +EXPECT_EQ(17, mock.AsStdFunction()(0)); +``` + +When used with `WillOnce`, the callable can assume it will be called at most +once and is allowed to be a move-only type: + +``` +// An action that contains move-only types and has an &&-qualified operator, +// demanding in the type system that it be called at most once. This can be +// used with WillOnce, but the compiler will reject it if handed to +// WillRepeatedly. +struct MoveOnlyAction { + std::unique_ptr move_only_state; + std::unique_ptr operator()() && { return std::move(move_only_state); } +}; + +MockFunction()> mock; +EXPECT_CALL(mock, Call).WillOnce(MoveOnlyAction{std::make_unique(17)}); +EXPECT_THAT(mock.AsStdFunction()(), Pointee(Eq(17))); +``` + +More generally, to use with a mock function whose signature is `R(Args...)` the +object can be anything convertible to `OnceAction` or +`Action. The difference between the two is that `OnceAction` has +weaker requirements (`Action` requires a copy-constructible input that can be +called repeatedly whereas `OnceAction` requires only move-constructible and +supports `&&`-qualified call operators), but can be used only with `WillOnce`. +`OnceAction` is typically relevant only when supporting move-only types or +actions that want a type-system guarantee that they will be called at most once. + +Typically the `OnceAction` and `Action` templates need not be referenced +directly in your actions: a struct or class with a call operator is sufficient, +as in the examples above. But fancier polymorphic actions that need to know the +specific return type of the mock function can define templated conversion +operators to make that possible. See `gmock-actions.h` for examples. + #### Legacy macro-based Actions Before C++11, the functor-based actions were not supported; the old way of @@ -4191,7 +4233,7 @@ This implementation class does *not* need to inherit from any particular class. What matters is that it must have a `Perform()` method template. This method template takes the mock function's arguments as a tuple in a **single** argument, and returns the result of the action. It can be either `const` or not, -but must be invokable with exactly one template argument, which is the result +but must be invocable with exactly one template argument, which is the result type. In other words, you must be able to call `Perform(args)` where `R` is the mock function's return type and `args` is its arguments in a tuple. diff --git a/googletest/docs/gmock_faq.md b/googletest/docs/gmock_faq.md index 2cd9b3f3..8f220bf7 100644 --- a/googletest/docs/gmock_faq.md +++ b/googletest/docs/gmock_faq.md @@ -369,8 +369,8 @@ Usually, if your action is for a particular function type, defining it using different types (e.g. if you are defining `Return(*value*)`), `MakePolymorphicAction()` is easiest. Sometimes you want precise control on what types of functions the action can be used in, and implementing `ActionInterface` -is the way to go here. See the implementation of `Return()` in -`testing/base/public/gmock-actions.h` for an example. +is the way to go here. See the implementation of `Return()` in `gmock-actions.h` +for an example. ### I use SetArgPointee() in WillOnce(), but gcc complains about "conflicting return type specified". What does it mean? diff --git a/googletest/docs/gmock_for_dummies.md b/googletest/docs/gmock_for_dummies.md index 1f4cc246..b7264d35 100644 --- a/googletest/docs/gmock_for_dummies.md +++ b/googletest/docs/gmock_for_dummies.md @@ -190,10 +190,10 @@ Some people put it in a `_test.cc`. This is fine when the interface being mocked `Foo` changes it, your test could break. (You can't really expect `Foo`'s maintainer to fix every test that uses `Foo`, can you?) -So, the rule of thumb is: if you need to mock `Foo` and it's owned by others, -define the mock class in `Foo`'s package (better, in a `testing` sub-package -such that you can clearly separate production code and testing utilities), put -it in a `.h` and a `cc_library`. Then everyone can reference them from their +Generally, you should not mock classes you don't own. If you must mock such a +class owned by others, define the mock class in `Foo`'s Bazel package (usually +the same directory or a `testing` sub-directory), and put it in a `.h` and a +`cc_library` with `testonly=True`. Then everyone can reference them from their tests. If `Foo` ever changes, there is only one copy of `MockFoo` to change, and only tests that depend on the changed methods need to be fixed. @@ -480,8 +480,8 @@ the *default* action for the function every time (unless, of course, you have a `WillRepeatedly()`.). What can we do inside `WillOnce()` besides `Return()`? You can return a -reference using `ReturnRef(*variable*)`, or invoke a pre-defined function, among -[others](gmock_cook_book.md#using-actions). +reference using `ReturnRef(`*`variable`*`)`, or invoke a pre-defined function, +among [others](gmock_cook_book.md#using-actions). **Important note:** The `EXPECT_CALL()` statement evaluates the action clause only once, even though the action may be performed many times. Therefore you diff --git a/googletest/docs/pkgconfig.md b/googletest/docs/pkgconfig.md index 768e9b4c..18a2546a 100644 --- a/googletest/docs/pkgconfig.md +++ b/googletest/docs/pkgconfig.md @@ -105,7 +105,7 @@ includedir=/usr/include Name: gtest Description: GoogleTest (without main() function) -Version: 1.10.0 +Version: 1.11.0 URL: https://github.com/google/googletest Libs: -L${libdir} -lgtest -lpthread Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1 -lpthread diff --git a/googletest/docs/primer.md b/googletest/docs/primer.md index 6d8fdf44..2ffbf53b 100644 --- a/googletest/docs/primer.md +++ b/googletest/docs/primer.md @@ -162,9 +162,9 @@ TEST(TestSuiteName, TestName) { `TEST()` arguments go from general to specific. The *first* argument is the name of the test suite, and the *second* argument is the test's name within the test -suite. Both names must be valid C++ identifiers, and they should not contain -any underscores (`_`). A test's *full name* consists of its containing test suite and -its individual name. Tests from different test suites can have the same +suite. Both names must be valid C++ identifiers, and they should not contain any +underscores (`_`). A test's *full name* consists of its containing test suite +and its individual name. Tests from different test suites can have the same individual name. For example, let's take a simple integer function: @@ -245,8 +245,8 @@ Also, you must first define a test fixture class before using it in a declaration`". For each test defined with `TEST_F()`, googletest will create a *fresh* test -fixture at runtime, immediately initialize it via `SetUp()`, run the test, -clean up by calling `TearDown()`, and then delete the test fixture. Note that +fixture at runtime, immediately initialize it via `SetUp()`, run the test, clean +up by calling `TearDown()`, and then delete the test fixture. Note that different tests in the same test suite have different test fixture objects, and googletest always deletes a test fixture before it creates the next one. googletest does **not** reuse the same test fixture for multiple tests. Any @@ -274,6 +274,7 @@ First, define a fixture class. By convention, you should give it the name class QueueTest : public ::testing::Test { protected: void SetUp() override { + // q0_ remains empty q1_.Enqueue(1); q2_.Enqueue(2); q2_.Enqueue(3); @@ -342,8 +343,8 @@ your defined tests in order to run them. After defining your tests, you can run them with `RUN_ALL_TESTS()`, which returns `0` if all the tests are successful, or `1` otherwise. Note that -`RUN_ALL_TESTS()` runs *all tests* in your link unit--they can be from -different test suites, or even different source files. +`RUN_ALL_TESTS()` runs *all tests* in your link unit--they can be from different +test suites, or even different source files. When invoked, the `RUN_ALL_TESTS()` macro: @@ -456,8 +457,8 @@ int main(int argc, char **argv) { The `::testing::InitGoogleTest()` function parses the command line for googletest flags, and removes all recognized flags. This allows the user to -control a test program's behavior via various flags, which we'll cover in -the [AdvancedGuide](advanced.md). You **must** call this function before calling +control a test program's behavior via various flags, which we'll cover in the +[AdvancedGuide](advanced.md). You **must** call this function before calling `RUN_ALL_TESTS()`, or the flags won't be properly initialized. On Windows, `InitGoogleTest()` also works with wide strings, so it can be used diff --git a/googletest/docs/quickstart-bazel.md b/googletest/docs/quickstart-bazel.md index 362ee6d0..15c27a22 100644 --- a/googletest/docs/quickstart-bazel.md +++ b/googletest/docs/quickstart-bazel.md @@ -9,7 +9,7 @@ we recommend this tutorial as a starting point. To complete this tutorial, you'll need: * A compatible operating system (e.g. Linux, macOS, Windows). -* A compatible C++ compiler that supports at least C++11. +* A compatible C++ compiler that supports at least C++14. * [Bazel](https://bazel.build/), the preferred build system used by the GoogleTest team. @@ -17,16 +17,15 @@ See [Supported Platforms](platforms.md) for more information about platforms compatible with GoogleTest. If you don't already have Bazel installed, see the -[Bazel installation guide](https://docs.bazel.build/versions/master/install.html). +[Bazel installation guide](https://bazel.build/install). -{: .callout .note} -Note: The terminal commands in this tutorial show a Unix shell prompt, but the -commands work on the Windows command line as well. +{: .callout .note} Note: The terminal commands in this tutorial show a Unix +shell prompt, but the commands work on the Windows command line as well. ## Set up a Bazel workspace A -[Bazel workspace](https://docs.bazel.build/versions/master/build-ref.html#workspace) +[Bazel workspace](https://docs.bazel.build/versions/main/build-ref.html#workspace) is a directory on your filesystem that you use to manage source files for the software you want to build. Each workspace directory has a text file named `WORKSPACE` which may be empty, or may contain references to external @@ -40,9 +39,9 @@ $ mkdir my_workspace && cd my_workspace Next, you’ll create the `WORKSPACE` file to specify dependencies. A common and recommended way to depend on GoogleTest is to use a -[Bazel external dependency](https://docs.bazel.build/versions/master/external.html) +[Bazel external dependency](https://docs.bazel.build/versions/main/external.html) via the -[`http_archive` rule](https://docs.bazel.build/versions/master/repo/http.html#http_archive). +[`http_archive` rule](https://docs.bazel.build/versions/main/repo/http.html#http_archive). To do this, in the root directory of your workspace (`my_workspace/`), create a file named `WORKSPACE` with the following contents: @@ -51,28 +50,16 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "com_google_googletest", - urls = ["https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip"], - strip_prefix = "googletest-609281088cfefc76f9d0ce82e1ff6c30cc3591e5", + urls = ["https://github.com/google/googletest/archive/5ab508a01f9eb089207ee87fd547d290da39d015.zip"], + strip_prefix = "googletest-5ab508a01f9eb089207ee87fd547d290da39d015", ) ``` The above configuration declares a dependency on GoogleTest which is downloaded as a ZIP archive from GitHub. In the above example, -`609281088cfefc76f9d0ce82e1ff6c30cc3591e5` is the Git commit hash of the +`5ab508a01f9eb089207ee87fd547d290da39d015` is the Git commit hash of the GoogleTest version to use; we recommend updating the hash often to point to the -latest version. - -Bazel also needs a dependency on the -[`rules_cc` repository](https://github.com/bazelbuild/rules_cc) to build C++ -code, so add the following to the `WORKSPACE` file: - -``` -http_archive( - name = "rules_cc", - urls = ["https://github.com/bazelbuild/rules_cc/archive/40548a2974f1aea06215272d9c2b47a14a24e556.zip"], - strip_prefix = "rules_cc-40548a2974f1aea06215272d9c2b47a14a24e556", -) -``` +latest version. Use a recent hash on the `main` branch. Now you're ready to build C++ code that uses GoogleTest. @@ -104,8 +91,6 @@ To build the code, create a file named `BUILD` in the same directory with the following contents: ``` -load("@rules_cc//cc:defs.bzl", "cc_test") - cc_test( name = "hello_test", size = "small", @@ -118,7 +103,7 @@ This `cc_test` rule declares the C++ test binary you want to build, and links to GoogleTest (`//:gtest_main`) using the prefix you specified in the `WORKSPACE` file (`@com_google_googletest`). For more information about Bazel `BUILD` files, see the -[Bazel C++ Tutorial](https://docs.bazel.build/versions/master/tutorial/cpp.html). +[Bazel C++ Tutorial](https://docs.bazel.build/versions/main/tutorial/cpp.html). Now you can build and run your test: diff --git a/googletest/docs/quickstart-cmake.md b/googletest/docs/quickstart-cmake.md index 420f1d3a..5abe5044 100644 --- a/googletest/docs/quickstart-cmake.md +++ b/googletest/docs/quickstart-cmake.md @@ -10,7 +10,7 @@ this tutorial as a starting point. If your project uses Bazel, see the To complete this tutorial, you'll need: * A compatible operating system (e.g. Linux, macOS, Windows). -* A compatible C++ compiler that supports at least C++11. +* A compatible C++ compiler that supports at least C++14. * [CMake](https://cmake.org/) and a compatible build tool for building the project. * Compatible build tools include @@ -52,13 +52,13 @@ To do this, in your project directory (`my_project`), create a file named cmake_minimum_required(VERSION 3.14) project(my_project) -# GoogleTest requires at least C++11 -set(CMAKE_CXX_STANDARD 11) +# GoogleTest requires at least C++14 +set(CMAKE_CXX_STANDARD 14) include(FetchContent) FetchContent_Declare( googletest - URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip + URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip ) # For Windows: Prevent overriding the parent project's compiler/linker settings set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) @@ -66,7 +66,7 @@ FetchContent_MakeAvailable(googletest) ``` The above configuration declares a dependency on GoogleTest which is downloaded -from GitHub. In the above example, `609281088cfefc76f9d0ce82e1ff6c30cc3591e5` is +from GitHub. In the above example, `03597a01ee50ed33e9dfd640b249b4be3799d395` is the Git commit hash of the GoogleTest version to use; we recommend updating the hash often to point to the latest version. @@ -108,7 +108,7 @@ add_executable( ) target_link_libraries( hello_test - gtest_main + GTest::gtest_main ) include(GoogleTest) diff --git a/googletest/docs/reference/actions.md b/googletest/docs/reference/actions.md index 166d2a89..ab81a129 100644 --- a/googletest/docs/reference/actions.md +++ b/googletest/docs/reference/actions.md @@ -6,7 +6,7 @@ provided by GoogleTest. All actions are defined in the `::testing` namespace. ## Returning a Value -| | | +| Action | Description | | :-------------------------------- | :-------------------------------------------- | | `Return()` | Return from a `void` mock function. | | `Return(value)` | Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type at the time the expectation is set, not when the action is executed. | @@ -20,7 +20,7 @@ provided by GoogleTest. All actions are defined in the `::testing` namespace. ## Side Effects -| | | +| Action | Description | | :--------------------------------- | :-------------------------------------- | | `Assign(&variable, value)` | Assign `value` to variable. | | `DeleteArg()` | Delete the `N`-th (0-based) argument, which must be a pointer. | @@ -38,9 +38,9 @@ provided by GoogleTest. All actions are defined in the `::testing` namespace. In the following, by "callable" we mean a free function, `std::function`, functor, or lambda. -| | | +| Action | Description | | :---------------------------------- | :------------------------------------- | -| `f` | Invoke f with the arguments passed to the mock function, where f is a callable. | +| `f` | Invoke `f` with the arguments passed to the mock function, where `f` is a callable. | | `Invoke(f)` | Invoke `f` with the arguments passed to the mock function, where `f` can be a global/static function or a functor. | | `Invoke(object_pointer, &class::method)` | Invoke the method on the object with the arguments passed to the mock function. | | `InvokeWithoutArgs(f)` | Invoke `f`, which can be a global/static function or a functor. `f` must take no arguments. | @@ -86,7 +86,7 @@ value, and `foo` by reference. ## Default Action -| Matcher | Description | +| Action | Description | | :------------ | :----------------------------------------------------- | | `DoDefault()` | Do the default action (specified by `ON_CALL()` or the built-in one). | @@ -96,7 +96,7 @@ composite action - trying to do so will result in a run-time error. ## Composite Actions -| | | +| Action | Description | | :----------------------------- | :------------------------------------------ | | `DoAll(a1, a2, ..., an)` | Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void and will receive a readonly view of the arguments. | | `IgnoreResult(a)` | Perform action `a` and ignore its result. `a` must not return void. | @@ -106,7 +106,7 @@ composite action - trying to do so will result in a run-time error. ## Defining Actions -| | | +| Macro | Description | | :--------------------------------- | :-------------------------------------- | | `ACTION(Sum) { return arg0 + arg1; }` | Defines an action `Sum()` to return the sum of the mock function's argument #0 and #1. | | `ACTION_P(Plus, n) { return arg0 + n; }` | Defines an action `Plus(n)` to return the sum of the mock function's argument #0 and `n`. | diff --git a/googletest/docs/reference/matchers.md b/googletest/docs/reference/matchers.md index 9e40cab7..9fb15927 100644 --- a/googletest/docs/reference/matchers.md +++ b/googletest/docs/reference/matchers.md @@ -8,9 +8,13 @@ A **matcher** matches a *single* argument. You can use it inside `ON_CALL()` or | `EXPECT_THAT(actual_value, matcher)` | Asserts that `actual_value` matches `matcher`. | | `ASSERT_THAT(actual_value, matcher)` | The same as `EXPECT_THAT(actual_value, matcher)`, except that it generates a **fatal** failure. | -{: .callout .note} -**Note:** Although equality matching via `EXPECT_THAT(actual_value, -expected_value)` is supported, prefer to make the comparison explicit via +{: .callout .warning} +**WARNING:** Equality matching via `EXPECT_THAT(actual_value, expected_value)` +is supported, however note that implicit conversions can cause surprising +results. For example, `EXPECT_THAT(some_bool, "some string")` will compile and +may pass unintentionally. + +**BEST PRACTICE:** Prefer to make the comparison explicit via `EXPECT_THAT(actual_value, Eq(expected_value))` or `EXPECT_EQ(actual_value, expected_value)`. @@ -88,16 +92,17 @@ The `argument` can be either a C string or a C++ string object: | Matcher | Description | | :---------------------- | :------------------------------------------------- | -| `ContainsRegex(string)` | `argument` matches the given regular expression. | -| `EndsWith(suffix)` | `argument` ends with string `suffix`. | -| `HasSubstr(string)` | `argument` contains `string` as a sub-string. | -| `IsEmpty()` | `argument` is an empty string. | -| `MatchesRegex(string)` | `argument` matches the given regular expression with the match starting at the first character and ending at the last character. | -| `StartsWith(prefix)` | `argument` starts with string `prefix`. | -| `StrCaseEq(string)` | `argument` is equal to `string`, ignoring case. | -| `StrCaseNe(string)` | `argument` is not equal to `string`, ignoring case. | -| `StrEq(string)` | `argument` is equal to `string`. | -| `StrNe(string)` | `argument` is not equal to `string`. | +| `ContainsRegex(string)` | `argument` matches the given regular expression. | +| `EndsWith(suffix)` | `argument` ends with string `suffix`. | +| `HasSubstr(string)` | `argument` contains `string` as a sub-string. | +| `IsEmpty()` | `argument` is an empty string. | +| `MatchesRegex(string)` | `argument` matches the given regular expression with the match starting at the first character and ending at the last character. | +| `StartsWith(prefix)` | `argument` starts with string `prefix`. | +| `StrCaseEq(string)` | `argument` is equal to `string`, ignoring case. | +| `StrCaseNe(string)` | `argument` is not equal to `string`, ignoring case. | +| `StrEq(string)` | `argument` is equal to `string`. | +| `StrNe(string)` | `argument` is not equal to `string`. | +| `WhenBase64Unescaped(m)` | `argument` is a base-64 escaped string whose unescaped string matches `m`. | `ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They use the regular expression syntax defined @@ -116,6 +121,7 @@ messages, you can use: | `BeginEndDistanceIs(m)` | `argument` is a container whose `begin()` and `end()` iterators are separated by a number of increments matching `m`. E.g. `BeginEndDistanceIs(2)` or `BeginEndDistanceIs(Lt(2))`. For containers that define a `size()` method, `SizeIs(m)` may be more efficient. | | `ContainerEq(container)` | The same as `Eq(container)` except that the failure message also includes which elements are in one container but not the other. | | `Contains(e)` | `argument` contains an element that matches `e`, which can be either a value or a matcher. | +| `Contains(e).Times(n)` | `argument` contains elements that match `e`, which can be either a value or a matcher, and the number of matches is `n`, which can be either a value or a matcher. Unlike the plain `Contains` and `Each` this allows to check for arbitrary occurrences including testing for absence with `Contains(e).Times(0)`. | | `Each(e)` | `argument` is a container where *every* element matches `e`, which can be either a value or a matcher. | | `ElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, where the *i*-th element matches `ei`, which can be a value or a matcher. | | `ElementsAreArray({e0, e1, ..., en})`, `ElementsAreArray(a_container)`, `ElementsAreArray(begin, end)`, `ElementsAreArray(array)`, or `ElementsAreArray(array, count)` | The same as `ElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. | @@ -146,7 +152,6 @@ messages, you can use: one might write: ```cpp - using ::std::get; MATCHER(FooEq, "") { return std::get<0>(arg).Equals(std::get<1>(arg)); } @@ -193,6 +198,7 @@ messages, you can use: | Matcher | Description | | :--------------- | :------------------------------------------------ | | `ResultOf(f, m)` | `f(argument)` matches matcher `m`, where `f` is a function or functor. | +| `ResultOf(result_description, f, m)` | The same as the two-parameter version, but provides a better error message. ## Pointer Matchers @@ -237,6 +243,7 @@ You can make a matcher from one or more other matchers: | `AnyOf(m1, m2, ..., mn)` | `argument` matches at least one of the matchers `m1` to `mn`. | | `AnyOfArray({m0, m1, ..., mn})`, `AnyOfArray(a_container)`, `AnyOfArray(begin, end)`, `AnyOfArray(array)`, or `AnyOfArray(array, count)` | The same as `AnyOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. | | `Not(m)` | `argument` doesn't match matcher `m`. | +| `Conditional(cond, m1, m2)` | Matches matcher `m1` if `cond` evaluates to true, else matches `m2`.| ## Adapters for Matchers @@ -259,7 +266,7 @@ which must be a permanent callback. ## Defining Matchers -| Matcher | Description | +| Macro | Description | | :----------------------------------- | :------------------------------------ | | `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. | | `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a matcher `IsDivisibleBy(n)` to match a number divisible by `n`. | diff --git a/googletest/docs/reference/mocking.md b/googletest/docs/reference/mocking.md index c29f7160..e414ffbd 100644 --- a/googletest/docs/reference/mocking.md +++ b/googletest/docs/reference/mocking.md @@ -248,7 +248,9 @@ EXPECT_CALL(my_mock, GetNumber()) .WillOnce(Return(3)); ``` -The `WillOnce` clause can be used any number of times on an expectation. +The `WillOnce` clause can be used any number of times on an expectation. Unlike +`WillRepeatedly`, the action fed to each `WillOnce` call will be called at most +once, so may be a move-only type and/or have an `&&`-qualified call operator. #### WillRepeatedly {#EXPECT_CALL.WillRepeatedly} diff --git a/googletest/docs/reference/testing.md b/googletest/docs/reference/testing.md index 554d6c95..62cdcc1c 100644 --- a/googletest/docs/reference/testing.md +++ b/googletest/docs/reference/testing.md @@ -109,7 +109,7 @@ namespace: | `ValuesIn(container)` or `ValuesIn(begin,end)` | Yields values from a C-style array, an STL-style container, or an iterator range `[begin, end)`. | | `Bool()` | Yields sequence `{false, true}`. | | `Combine(g1, g2, ..., gN)` | Yields as `std::tuple` *n*-tuples all combinations (Cartesian product) of the values generated by the given *n* generators `g1`, `g2`, ..., `gN`. | - +| `ConvertGenerator(g)` | Yields values generated by generator `g`, `static_cast` to `T`. | The optional last argument *`name_generator`* is a function or functor that generates custom test name suffixes based on the test parameters. The function must accept an argument of type @@ -518,8 +518,8 @@ Logs a property for the current test, test suite, or entire invocation of the test program. Only the last value for a given key is logged. The key must be a valid XML attribute name, and cannot conflict with the ones -already used by GoogleTest (`name`, `status`, `time`, `classname`, `type_param`, -and `value_param`). +already used by GoogleTest (`name`, `file`, `line`, `status`, `time`, +`classname`, `type_param`, and `value_param`). `RecordProperty` is `public static` so it can be called from utility functions that are not members of the test fixture. diff --git a/googletest/docs/samples.md b/googletest/docs/samples.md index 2d97ca55..dedc5909 100644 --- a/googletest/docs/samples.md +++ b/googletest/docs/samples.md @@ -1,7 +1,7 @@ # Googletest Samples If you're like us, you'd like to look at -[googletest samples.](https://github.com/google/googletest/tree/master/googletest/samples) +[googletest samples.](https://github.com/google/googletest/blob/main/googletest/samples) The sample directory has a number of well-commented samples showing how to use a variety of googletest features. diff --git a/googletest/googlemock/CMakeLists.txt b/googletest/googlemock/CMakeLists.txt index aedbaa38..5c1f0daf 100644 --- a/googletest/googlemock/CMakeLists.txt +++ b/googletest/googlemock/CMakeLists.txt @@ -94,7 +94,6 @@ if (MSVC) src/gmock-all.cc src/gmock_main.cc) else() - cxx_library(gmock "${cxx_strict}" src/gmock-all.cc) target_link_libraries(gmock PUBLIC gtest) set_target_properties(gmock PROPERTIES VERSION ${GOOGLETEST_VERSION}) @@ -106,11 +105,12 @@ endif() # to the targets for when we are part of a parent build (ie being pulled # in via add_subdirectory() rather than being a standalone build). if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11") + string(REPLACE ";" "$" dirs "${gmock_build_include_dirs}") target_include_directories(gmock SYSTEM INTERFACE - "$" + "$" "$/${CMAKE_INSTALL_INCLUDEDIR}>") target_include_directories(gmock_main SYSTEM INTERFACE - "$" + "$" "$/${CMAKE_INSTALL_INCLUDEDIR}>") endif() @@ -151,7 +151,10 @@ if (gmock_build_tests) cxx_test(gmock_ex_test gmock_main) cxx_test(gmock-function-mocker_test gmock_main) cxx_test(gmock-internal-utils_test gmock_main) - cxx_test(gmock-matchers_test gmock_main) + cxx_test(gmock-matchers-arithmetic_test gmock_main) + cxx_test(gmock-matchers-comparisons_test gmock_main) + cxx_test(gmock-matchers-containers_test gmock_main) + cxx_test(gmock-matchers-misc_test gmock_main) cxx_test(gmock-more-actions_test gmock_main) cxx_test(gmock-nice-strict_test gmock_main) cxx_test(gmock-port_test gmock_main) diff --git a/googletest/googlemock/README.md b/googletest/googlemock/README.md index ead68832..7da60655 100644 --- a/googletest/googlemock/README.md +++ b/googletest/googlemock/README.md @@ -35,10 +35,6 @@ Details and examples can be found here: * [gMock Cookbook](https://google.github.io/googletest/gmock_cook_book.html) * [gMock Cheat Sheet](https://google.github.io/googletest/gmock_cheat_sheet.html) -Please note that code under scripts/generator/ is from the -[cppclean project](http://code.google.com/p/cppclean/) and under the Apache -License, which is different from GoogleMock's license. - GoogleMock is a part of [GoogleTest C++ testing framework](http://github.com/google/googletest/) and a subject to the same requirements. diff --git a/googletest/googlemock/include/gmock/gmock-actions.h b/googletest/googlemock/include/gmock/gmock-actions.h index f2393bd3..aad07d51 100644 --- a/googletest/googlemock/include/gmock/gmock-actions.h +++ b/googletest/googlemock/include/gmock/gmock-actions.h @@ -27,7 +27,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - // Google Mock - a framework for writing C++ mock classes. // // The ACTION* family of macros can be used in a namespace scope to @@ -123,15 +122,16 @@ // MORE INFORMATION: // // To learn more about using these macros, please search for 'ACTION' on -// https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md +// https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md -// GOOGLETEST_CM0002 DO NOT DELETE +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ #ifndef _WIN32_WCE -# include +#include #endif #include @@ -147,8 +147,8 @@ #include "gmock/internal/gmock-pp.h" #ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable:4100) +#pragma warning(push) +#pragma warning(disable : 4100) #endif namespace testing { @@ -196,9 +196,7 @@ class BuiltInDefaultValue { public: // This function returns true if and only if type T has a built-in default // value. - static bool Exists() { - return ::std::is_default_constructible::value; - } + static bool Exists() { return ::std::is_default_constructible::value; } static T Get() { return BuiltInDefaultValueGetter< @@ -227,11 +225,11 @@ class BuiltInDefaultValue { // The following specializations define the default values for // specific types we care about. #define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \ - template <> \ - class BuiltInDefaultValue { \ - public: \ - static bool Exists() { return true; } \ - static type Get() { return value; } \ + template <> \ + class BuiltInDefaultValue { \ + public: \ + static bool Exists() { return true; } \ + static type Get() { return value; } \ } GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, ); // NOLINT @@ -255,21 +253,309 @@ GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U); // NOLINT GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0); // NOLINT GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U); GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0); -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL); // NOLINT -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L); // NOLINT GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long long, 0); // NOLINT -GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long long, 0); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long long, 0); // NOLINT GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0); GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0); #undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_ -// Simple two-arg form of std::disjunction. -template -using disjunction = typename ::std::conditional::type; +// Partial implementations of metaprogramming types from the standard library +// not available in C++11. + +template +struct negation + // NOLINTNEXTLINE + : std::integral_constant {}; + +// Base case: with zero predicates the answer is always true. +template +struct conjunction : std::true_type {}; + +// With a single predicate, the answer is that predicate. +template +struct conjunction : P1 {}; + +// With multiple predicates the answer is the first predicate if that is false, +// and we recurse otherwise. +template +struct conjunction + : std::conditional, P1>::type {}; + +template +struct disjunction : std::false_type {}; + +template +struct disjunction : P1 {}; + +template +struct disjunction + // NOLINTNEXTLINE + : std::conditional, P1>::type {}; + +template +using void_t = void; + +// Detects whether an expression of type `From` can be implicitly converted to +// `To` according to [conv]. In C++17, [conv]/3 defines this as follows: +// +// An expression e can be implicitly converted to a type T if and only if +// the declaration T t=e; is well-formed, for some invented temporary +// variable t ([dcl.init]). +// +// [conv]/2 implies we can use function argument passing to detect whether this +// initialization is valid. +// +// Note that this is distinct from is_convertible, which requires this be valid: +// +// To test() { +// return declval(); +// } +// +// In particular, is_convertible doesn't give the correct answer when `To` and +// `From` are the same non-moveable type since `declval` will be an rvalue +// reference, defeating the guaranteed copy elision that would otherwise make +// this function work. +// +// REQUIRES: `From` is not cv void. +template +struct is_implicitly_convertible { + private: + // A function that accepts a parameter of type T. This can be called with type + // U successfully only if U is implicitly convertible to T. + template + static void Accept(T); + + // A function that creates a value of type T. + template + static T Make(); + + // An overload be selected when implicit conversion from T to To is possible. + template (Make()))> + static std::true_type TestImplicitConversion(int); + + // A fallback overload selected in all other cases. + template + static std::false_type TestImplicitConversion(...); + + public: + using type = decltype(TestImplicitConversion(0)); + static constexpr bool value = type::value; +}; + +// Like std::invoke_result_t from C++17, but works only for objects with call +// operators (not e.g. member function pointers, which we don't need specific +// support for in OnceAction because std::function deals with them). +template +using call_result_t = decltype(std::declval()(std::declval()...)); + +template +struct is_callable_r_impl : std::false_type {}; + +// Specialize the struct for those template arguments where call_result_t is +// well-formed. When it's not, the generic template above is chosen, resulting +// in std::false_type. +template +struct is_callable_r_impl>, R, F, Args...> + : std::conditional< + std::is_void::value, // + std::true_type, // + is_implicitly_convertible, R>>::type {}; + +// Like std::is_invocable_r from C++17, but works only for objects with call +// operators. See the note on call_result_t. +template +using is_callable_r = is_callable_r_impl; + +// Like std::as_const from C++17. +template +typename std::add_const::type& as_const(T& t) { + return t; +} } // namespace internal +// Specialized for function types below. +template +class OnceAction; + +// An action that can only be used once. +// +// This is accepted by WillOnce, which doesn't require the underlying action to +// be copy-constructible (only move-constructible), and promises to invoke it as +// an rvalue reference. This allows the action to work with move-only types like +// std::move_only_function in a type-safe manner. +// +// For example: +// +// // Assume we have some API that needs to accept a unique pointer to some +// // non-copyable object Foo. +// void AcceptUniquePointer(std::unique_ptr foo); +// +// // We can define an action that provides a Foo to that API. Because It +// // has to give away its unique pointer, it must not be called more than +// // once, so its call operator is &&-qualified. +// struct ProvideFoo { +// std::unique_ptr foo; +// +// void operator()() && { +// AcceptUniquePointer(std::move(Foo)); +// } +// }; +// +// // This action can be used with WillOnce. +// EXPECT_CALL(mock, Call) +// .WillOnce(ProvideFoo{std::make_unique(...)}); +// +// // But a call to WillRepeatedly will fail to compile. This is correct, +// // since the action cannot correctly be used repeatedly. +// EXPECT_CALL(mock, Call) +// .WillRepeatedly(ProvideFoo{std::make_unique(...)}); +// +// A less-contrived example would be an action that returns an arbitrary type, +// whose &&-qualified call operator is capable of dealing with move-only types. +template +class OnceAction final { + private: + // True iff we can use the given callable type (or lvalue reference) directly + // via StdFunctionAdaptor. + template + using IsDirectlyCompatible = internal::conjunction< + // It must be possible to capture the callable in StdFunctionAdaptor. + std::is_constructible::type, Callable>, + // The callable must be compatible with our signature. + internal::is_callable_r::type, + Args...>>; + + // True iff we can use the given callable type via StdFunctionAdaptor once we + // ignore incoming arguments. + template + using IsCompatibleAfterIgnoringArguments = internal::conjunction< + // It must be possible to capture the callable in a lambda. + std::is_constructible::type, Callable>, + // The callable must be invocable with zero arguments, returning something + // convertible to Result. + internal::is_callable_r::type>>; + + public: + // Construct from a callable that is directly compatible with our mocked + // signature: it accepts our function type's arguments and returns something + // convertible to our result type. + template ::type>>, + IsDirectlyCompatible> // + ::value, + int>::type = 0> + OnceAction(Callable&& callable) // NOLINT + : function_(StdFunctionAdaptor::type>( + {}, std::forward(callable))) {} + + // As above, but for a callable that ignores the mocked function's arguments. + template ::type>>, + // Exclude callables for which the overload above works. + // We'd rather provide the arguments if possible. + internal::negation>, + IsCompatibleAfterIgnoringArguments>::value, + int>::type = 0> + OnceAction(Callable&& callable) // NOLINT + // Call the constructor above with a callable + // that ignores the input arguments. + : OnceAction(IgnoreIncomingArguments::type>{ + std::forward(callable)}) {} + + // We are naturally copyable because we store only an std::function, but + // semantically we should not be copyable. + OnceAction(const OnceAction&) = delete; + OnceAction& operator=(const OnceAction&) = delete; + OnceAction(OnceAction&&) = default; + + // Invoke the underlying action callable with which we were constructed, + // handing it the supplied arguments. + Result Call(Args... args) && { + return function_(std::forward(args)...); + } + + private: + // An adaptor that wraps a callable that is compatible with our signature and + // being invoked as an rvalue reference so that it can be used as an + // StdFunctionAdaptor. This throws away type safety, but that's fine because + // this is only used by WillOnce, which we know calls at most once. + // + // Once we have something like std::move_only_function from C++23, we can do + // away with this. + template + class StdFunctionAdaptor final { + public: + // A tag indicating that the (otherwise universal) constructor is accepting + // the callable itself, instead of e.g. stealing calls for the move + // constructor. + struct CallableTag final {}; + + template + explicit StdFunctionAdaptor(CallableTag, F&& callable) + : callable_(std::make_shared(std::forward(callable))) {} + + // Rather than explicitly returning Result, we return whatever the wrapped + // callable returns. This allows for compatibility with existing uses like + // the following, when the mocked function returns void: + // + // EXPECT_CALL(mock_fn_, Call) + // .WillOnce([&] { + // [...] + // return 0; + // }); + // + // Such a callable can be turned into std::function. If we use an + // explicit return type of Result here then it *doesn't* work with + // std::function, because we'll get a "void function should not return a + // value" error. + // + // We need not worry about incompatible result types because the SFINAE on + // OnceAction already checks this for us. std::is_invocable_r_v itself makes + // the same allowance for void result types. + template + internal::call_result_t operator()( + ArgRefs&&... args) const { + return std::move(*callable_)(std::forward(args)...); + } + + private: + // We must put the callable on the heap so that we are copyable, which + // std::function needs. + std::shared_ptr callable_; + }; + + // An adaptor that makes a callable that accepts zero arguments callable with + // our mocked arguments. + template + struct IgnoreIncomingArguments { + internal::call_result_t operator()(Args&&...) { + return std::move(callable)(); + } + + Callable callable; + }; + + std::function function_; +}; + // When an unexpected function call is encountered, Google Mock will // let it return a default value if the user has specified one for its // return type, or if the return type has a built-in default value; @@ -339,7 +625,8 @@ class DefaultValue { private: const T value_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(FixedValueProducer); + FixedValueProducer(const FixedValueProducer&) = delete; + FixedValueProducer& operator=(const FixedValueProducer&) = delete; }; class FactoryValueProducer : public ValueProducer { @@ -350,7 +637,8 @@ class DefaultValue { private: const FactoryFunction factory_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(FactoryValueProducer); + FactoryValueProducer(const FactoryValueProducer&) = delete; + FactoryValueProducer& operator=(const FactoryValueProducer&) = delete; }; static ValueProducer* producer_; @@ -424,28 +712,34 @@ class ActionInterface { virtual Result Perform(const ArgumentTuple& args) = 0; private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionInterface); + ActionInterface(const ActionInterface&) = delete; + ActionInterface& operator=(const ActionInterface&) = delete; }; -// An Action is a copyable and IMMUTABLE (except by assignment) -// object that represents an action to be taken when a mock function -// of type F is called. The implementation of Action is just a -// std::shared_ptr to const ActionInterface. Don't inherit from Action! -// You can view an object implementing ActionInterface as a -// concrete action (including its current state), and an Action -// object as a handle to it. template -class Action { +class Action; + +// An Action is a copyable and IMMUTABLE (except by assignment) +// object that represents an action to be taken when a mock function of type +// R(Args...) is called. The implementation of Action is just a +// std::shared_ptr to const ActionInterface. Don't inherit from Action! You +// can view an object implementing ActionInterface as a concrete action +// (including its current state), and an Action object as a handle to it. +template +class Action { + private: + using F = R(Args...); + // Adapter class to allow constructing Action from a legacy ActionInterface. // New code should create Actions from functors instead. struct ActionAdapter { // Adapter must be copyable to satisfy std::function requirements. ::std::shared_ptr> impl_; - template - typename internal::Function::Result operator()(Args&&... args) { + template + typename internal::Function::Result operator()(InArgs&&... args) { return impl_->Perform( - ::std::forward_as_tuple(::std::forward(args)...)); + ::std::forward_as_tuple(::std::forward(args)...)); } }; @@ -480,7 +774,8 @@ class Action { // Action, as long as F's arguments can be implicitly converted // to Func's and Func's return type can be implicitly converted to F's. template - explicit Action(const Action& action) : fun_(action.fun_) {} + Action(const Action& action) // NOLINT + : fun_(action.fun_) {} // Returns true if and only if this is the DoDefault() action. bool IsDoDefault() const { return fun_ == nullptr; } @@ -498,6 +793,24 @@ class Action { return internal::Apply(fun_, ::std::move(args)); } + // An action can be used as a OnceAction, since it's obviously safe to call it + // once. + operator OnceAction() const { // NOLINT + // Return a OnceAction-compatible callable that calls Perform with the + // arguments it is provided. We could instead just return fun_, but then + // we'd need to handle the IsDoDefault() case separately. + struct OA { + Action action; + + R operator()(Args... args) && { + return action.Perform( + std::forward_as_tuple(std::forward(args)...)); + } + }; + + return OA{*this}; + } + private: template friend class Action; @@ -514,8 +827,8 @@ class Action { template struct IgnoreArgs { - template - Result operator()(const Args&...) const { + template + Result operator()(const InArgs&...) const { return function_impl(); } @@ -606,118 +919,198 @@ struct ByMoveWrapper { T payload; }; -// Implements the polymorphic Return(x) action, which can be used in -// any function that returns the type of x, regardless of the argument -// types. -// -// Note: The value passed into Return must be converted into -// Function::Result when this action is cast to Action rather than -// when that action is performed. This is important in scenarios like -// -// MOCK_METHOD1(Method, T(U)); -// ... -// { -// Foo foo; -// X x(&foo); -// EXPECT_CALL(mock, Method(_)).WillOnce(Return(x)); -// } -// -// In the example above the variable x holds reference to foo which leaves -// scope and gets destroyed. If copying X just copies a reference to foo, -// that copy will be left with a hanging reference. If conversion to T -// makes a copy of foo, the above code is safe. To support that scenario, we -// need to make sure that the type conversion happens inside the EXPECT_CALL -// statement, and conversion of the result of Return to Action is a -// good place for that. -// -// The real life example of the above scenario happens when an invocation -// of gtl::Container() is passed into Return. -// +// The general implementation of Return(R). Specializations follow below. template -class ReturnAction { +class ReturnAction final { public: - // Constructs a ReturnAction object from the value to be returned. - // 'value' is passed by value instead of by const reference in order - // to allow Return("string literal") to compile. - explicit ReturnAction(R value) : value_(new R(std::move(value))) {} + explicit ReturnAction(R value) : value_(std::move(value)) {} + + template >, // + negation>, // + std::is_convertible, // + std::is_move_constructible>::value>::type> + operator OnceAction() && { // NOLINT + return Impl(std::move(value_)); + } - // This template type conversion operator allows Return(x) to be - // used in ANY function that returns x's type. - template - operator Action() const { // NOLINT - // Assert statement belongs here because this is the best place to verify - // conditions on F. It produces the clearest error messages - // in most compilers. - // Impl really belongs in this scope as a local class but can't - // because MSVC produces duplicate symbols in different translation units - // in this case. Until MS fixes that bug we put Impl into the class scope - // and put the typedef both here (for use in assert statement) and - // in the Impl class. But both definitions must be the same. - typedef typename Function::Result Result; - GTEST_COMPILE_ASSERT_( - !std::is_reference::value, - use_ReturnRef_instead_of_Return_to_return_a_reference); - static_assert(!std::is_void::value, - "Can't use Return() on an action expected to return `void`."); - return Action(new Impl(value_)); + template >, // + negation>, // + std::is_convertible, // + std::is_copy_constructible>::value>::type> + operator Action() const { // NOLINT + return Impl(value_); } private: - // Implements the Return(x) action for a particular function type F. - template - class Impl : public ActionInterface { + // Implements the Return(x) action for a mock function that returns type U. + template + class Impl final { public: - typedef typename Function::Result Result; - typedef typename Function::ArgumentTuple ArgumentTuple; + // The constructor used when the return value is allowed to move from the + // input value (i.e. we are converting to OnceAction). + explicit Impl(R&& input_value) + : state_(new State(std::move(input_value))) {} - // The implicit cast is necessary when Result has more than one - // single-argument constructor (e.g. Result is std::vector) and R - // has a type conversion operator template. In that case, value_(value) - // won't compile as the compiler doesn't known which constructor of - // Result to call. ImplicitCast_ forces the compiler to convert R to - // Result without considering explicit constructors, thus resolving the - // ambiguity. value_ is then initialized using its copy constructor. - explicit Impl(const std::shared_ptr& value) - : value_before_cast_(*value), - value_(ImplicitCast_(value_before_cast_)) {} + // The constructor used when the return value is not allowed to move from + // the input value (i.e. we are converting to Action). + explicit Impl(const R& input_value) : state_(new State(input_value)) {} - Result Perform(const ArgumentTuple&) override { return value_; } + U operator()() && { return std::move(state_->value); } + U operator()() const& { return state_->value; } private: - GTEST_COMPILE_ASSERT_(!std::is_reference::value, - Result_cannot_be_a_reference_type); - // We save the value before casting just in case it is being cast to a - // wrapper type. - R value_before_cast_; - Result value_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); + // We put our state on the heap so that the compiler-generated copy/move + // constructors work correctly even when U is a reference-like type. This is + // necessary only because we eagerly create State::value (see the note on + // that symbol for details). If we instead had only the input value as a + // member then the default constructors would work fine. + // + // For example, when R is std::string and U is std::string_view, value is a + // reference to the string backed by input_value. The copy constructor would + // copy both, so that we wind up with a new input_value object (with the + // same contents) and a reference to the *old* input_value object rather + // than the new one. + struct State { + explicit State(const R& input_value_in) + : input_value(input_value_in), + // Make an implicit conversion to Result before initializing the U + // object we store, avoiding calling any explicit constructor of U + // from R. + // + // This simulates the language rules: a function with return type U + // that does `return R()` requires R to be implicitly convertible to + // U, and uses that path for the conversion, even U Result has an + // explicit constructor from R. + value(ImplicitCast_(internal::as_const(input_value))) {} + + // As above, but for the case where we're moving from the ReturnAction + // object because it's being used as a OnceAction. + explicit State(R&& input_value_in) + : input_value(std::move(input_value_in)), + // For the same reason as above we make an implicit conversion to U + // before initializing the value. + // + // Unlike above we provide the input value as an rvalue to the + // implicit conversion because this is a OnceAction: it's fine if it + // wants to consume the input value. + value(ImplicitCast_(std::move(input_value))) {} + + // A copy of the value originally provided by the user. We retain this in + // addition to the value of the mock function's result type below in case + // the latter is a reference-like type. See the std::string_view example + // in the documentation on Return. + R input_value; + + // The value we actually return, as the type returned by the mock function + // itself. + // + // We eagerly initialize this here, rather than lazily doing the implicit + // conversion automatically each time Perform is called, for historical + // reasons: in 2009-11, commit a070cbd91c (Google changelist 13540126) + // made the Action conversion operator eagerly convert the R value to + // U, but without keeping the R alive. This broke the use case discussed + // in the documentation for Return, making reference-like types such as + // std::string_view not safe to use as U where the input type R is a + // value-like type such as std::string. + // + // The example the commit gave was not very clear, nor was the issue + // thread (https://github.com/google/googlemock/issues/86), but it seems + // the worry was about reference-like input types R that flatten to a + // value-like type U when being implicitly converted. An example of this + // is std::vector::reference, which is often a proxy type with an + // reference to the underlying vector: + // + // // Helper method: have the mock function return bools according + // // to the supplied script. + // void SetActions(MockFunction& mock, + // const std::vector& script) { + // for (size_t i = 0; i < script.size(); ++i) { + // EXPECT_CALL(mock, Call(i)).WillOnce(Return(script[i])); + // } + // } + // + // TEST(Foo, Bar) { + // // Set actions using a temporary vector, whose operator[] + // // returns proxy objects that references that will be + // // dangling once the call to SetActions finishes and the + // // vector is destroyed. + // MockFunction mock; + // SetActions(mock, {false, true}); + // + // EXPECT_FALSE(mock.AsStdFunction()(0)); + // EXPECT_TRUE(mock.AsStdFunction()(1)); + // } + // + // This eager conversion helps with a simple case like this, but doesn't + // fully make these types work in general. For example the following still + // uses a dangling reference: + // + // TEST(Foo, Baz) { + // MockFunction()> mock; + // + // // Return the same vector twice, and then the empty vector + // // thereafter. + // auto action = Return(std::initializer_list{ + // "taco", "burrito", + // }); + // + // EXPECT_CALL(mock, Call) + // .WillOnce(action) + // .WillOnce(action) + // .WillRepeatedly(Return(std::vector{})); + // + // EXPECT_THAT(mock.AsStdFunction()(), + // ElementsAre("taco", "burrito")); + // EXPECT_THAT(mock.AsStdFunction()(), + // ElementsAre("taco", "burrito")); + // EXPECT_THAT(mock.AsStdFunction()(), IsEmpty()); + // } + // + U value; + }; + + const std::shared_ptr state_; }; - // Partially specialize for ByMoveWrapper. This version of ReturnAction will - // move its contents instead. - template - class Impl, F> : public ActionInterface { - public: - typedef typename Function::Result Result; - typedef typename Function::ArgumentTuple ArgumentTuple; + R value_; +}; + +// A specialization of ReturnAction when R is ByMoveWrapper for some T. +// +// This version applies the type system-defeating hack of moving from T even in +// the const call operator, checking at runtime that it isn't called more than +// once, since the user has declared their intent to do so by using ByMove. +template +class ReturnAction> final { + public: + explicit ReturnAction(ByMoveWrapper wrapper) + : state_(new State(std::move(wrapper.payload))) {} - explicit Impl(const std::shared_ptr& wrapper) - : performed_(false), wrapper_(wrapper) {} + T operator()() const { + GTEST_CHECK_(!state_->called) + << "A ByMove() action must be performed at most once."; - Result Perform(const ArgumentTuple&) override { - GTEST_CHECK_(!performed_) - << "A ByMove() action should only be performed once."; - performed_ = true; - return std::move(wrapper_->payload); - } + state_->called = true; + return std::move(state_->value); + } - private: - bool performed_; - const std::shared_ptr wrapper_; + private: + // We store our state on the heap so that we are copyable as required by + // Action, despite the fact that we are stateful and T may not be copyable. + struct State { + explicit State(T&& value_in) : value(std::move(value_in)) {} + + T value; + bool called = false; }; - const std::shared_ptr value_; + const std::shared_ptr state_; }; // Implements the ReturnNull() action. @@ -759,8 +1152,8 @@ class ReturnRefAction { // Asserts that the function return type is a reference. This // catches the user error of using ReturnRef(x) when Return(x) // should be used, and generates some helpful error message. - GTEST_COMPILE_ASSERT_(std::is_reference::value, - use_Return_instead_of_ReturnRef_to_return_a_value); + static_assert(std::is_reference::value, + "use Return instead of ReturnRef to return a value"); return Action(new Impl(ref_)); } @@ -801,9 +1194,8 @@ class ReturnRefOfCopyAction { // Asserts that the function return type is a reference. This // catches the user error of using ReturnRefOfCopy(x) when Return(x) // should be used, and generates some helpful error message. - GTEST_COMPILE_ASSERT_( - std::is_reference::value, - use_Return_instead_of_ReturnRefOfCopy_to_return_a_value); + static_assert(std::is_reference::value, + "use Return instead of ReturnRefOfCopy to return a value"); return Action(new Impl(value_)); } @@ -839,7 +1231,7 @@ class ReturnRoundRobinAction { template T operator()(Args&&...) const { - return state_->Next(); + return state_->Next(); } private: @@ -862,7 +1254,9 @@ class DoDefaultAction { // This template type conversion operator allows DoDefault() to be // used in any function. template - operator Action() const { return Action(); } // NOLINT + operator Action() const { + return Action(); + } // NOLINT }; // Implements the Assign action to set a given pointer referent to a @@ -890,8 +1284,7 @@ template class SetErrnoAndReturnAction { public: SetErrnoAndReturnAction(int errno_value, T result) - : errno_(errno_value), - result_(result) {} + : errno_(errno_value), result_(result) {} template Result Perform(const ArgumentTuple& /* args */) const { errno = errno_; @@ -1002,8 +1395,8 @@ class IgnoreResultAction { private: // Type OriginalFunction is the same as F except that its return // type is IgnoredValue. - typedef typename internal::Function::MakeResultIgnoredValue - OriginalFunction; + typedef + typename internal::Function::MakeResultIgnoredValue OriginalFunction; const Action action_; }; @@ -1013,55 +1406,243 @@ class IgnoreResultAction { template struct WithArgsAction { - InnerAction action; + InnerAction inner_action; - // The inner action could be anything convertible to Action. - // We use the conversion operator to detect the signature of the inner Action. + // The signature of the function as seen by the inner action, given an out + // action with the given result and argument types. template + using InnerSignature = + R(typename std::tuple_element>::type...); + + // Rather than a call operator, we must define conversion operators to + // particular action types. This is necessary for embedded actions like + // DoDefault(), which rely on an action conversion operators rather than + // providing a call operator because even with a particular set of arguments + // they don't have a fixed return type. + + template >...)>>::value, + int>::type = 0> + operator OnceAction() && { // NOLINT + struct OA { + OnceAction> inner_action; + + R operator()(Args&&... args) && { + return std::move(inner_action) + .Call(std::get( + std::forward_as_tuple(std::forward(args)...))...); + } + }; + + return OA{std::move(inner_action)}; + } + + template >...)>>::value, + int>::type = 0> operator Action() const { // NOLINT - using TupleType = std::tuple; - Action::type...)> - converted(action); + Action> converted(inner_action); - return [converted](Args... args) -> R { + return [converted](Args&&... args) -> R { return converted.Perform(std::forward_as_tuple( - std::get(std::forward_as_tuple(std::forward(args)...))...)); + std::get(std::forward_as_tuple(std::forward(args)...))...)); }; } }; template -struct DoAllAction { - private: +class DoAllAction; + +// Base case: only a single action. +template +class DoAllAction { + public: + struct UserConstructorTag {}; + template - using NonFinalType = - typename std::conditional::value, T, const T&>::type; + explicit DoAllAction(UserConstructorTag, T&& action) + : final_action_(std::forward(action)) {} + + // Rather than a call operator, we must define conversion operators to + // particular action types. This is necessary for embedded actions like + // DoDefault(), which rely on an action conversion operators rather than + // providing a call operator because even with a particular set of arguments + // they don't have a fixed return type. + + template >::value, + int>::type = 0> + operator OnceAction() && { // NOLINT + return std::move(final_action_); + } - template - std::vector Convert(IndexSequence) const { - return {ActionT(std::get(actions))...}; + template < + typename R, typename... Args, + typename std::enable_if< + std::is_convertible>::value, + int>::type = 0> + operator Action() const { // NOLINT + return final_action_; } + private: + FinalAction final_action_; +}; + +// Recursive case: support N actions by calling the initial action and then +// calling through to the base class containing N-1 actions. +template +class DoAllAction + : private DoAllAction { + private: + using Base = DoAllAction; + + // The type of reference that should be provided to an initial action for a + // mocked function parameter of type T. + // + // There are two quirks here: + // + // * Unlike most forwarding functions, we pass scalars through by value. + // This isn't strictly necessary because an lvalue reference would work + // fine too and be consistent with other non-reference types, but it's + // perhaps less surprising. + // + // For example if the mocked function has signature void(int), then it + // might seem surprising for the user's initial action to need to be + // convertible to Action. This is perhaps less + // surprising for a non-scalar type where there may be a performance + // impact, or it might even be impossible, to pass by value. + // + // * More surprisingly, `const T&` is often not a const reference type. + // By the reference collapsing rules in C++17 [dcl.ref]/6, if T refers to + // U& or U&& for some non-scalar type U, then InitialActionArgType is + // U&. In other words, we may hand over a non-const reference. + // + // So for example, given some non-scalar type Obj we have the following + // mappings: + // + // T InitialActionArgType + // ------- ----------------------- + // Obj const Obj& + // Obj& Obj& + // Obj&& Obj& + // const Obj const Obj& + // const Obj& const Obj& + // const Obj&& const Obj& + // + // In other words, the initial actions get a mutable view of an non-scalar + // argument if and only if the mock function itself accepts a non-const + // reference type. They are never given an rvalue reference to an + // non-scalar type. + // + // This situation makes sense if you imagine use with a matcher that is + // designed to write through a reference. For example, if the caller wants + // to fill in a reference argument and then return a canned value: + // + // EXPECT_CALL(mock, Call) + // .WillOnce(DoAll(SetArgReferee<0>(17), Return(19))); + // + template + using InitialActionArgType = + typename std::conditional::value, T, const T&>::type; + public: - std::tuple actions; + struct UserConstructorTag {}; + + template + explicit DoAllAction(UserConstructorTag, T&& initial_action, + U&&... other_actions) + : Base({}, std::forward(other_actions)...), + initial_action_(std::forward(initial_action)) {} + + template ...)>>, + std::is_convertible>>::value, + int>::type = 0> + operator OnceAction() && { // NOLINT + // Return an action that first calls the initial action with arguments + // filtered through InitialActionArgType, then forwards arguments directly + // to the base class to deal with the remaining actions. + struct OA { + OnceAction...)> initial_action; + OnceAction remaining_actions; + + R operator()(Args... args) && { + std::move(initial_action) + .Call(static_cast>(args)...); + + return std::move(remaining_actions).Call(std::forward(args)...); + } + }; - template + return OA{ + std::move(initial_action_), + std::move(static_cast(*this)), + }; + } + + template < + typename R, typename... Args, + typename std::enable_if< + conjunction< + // Both the initial action and the rest must support conversion to + // Action. + std::is_convertible...)>>, + std::is_convertible>>::value, + int>::type = 0> operator Action() const { // NOLINT - struct Op { - std::vector...)>> converted; - Action last; + // Return an action that first calls the initial action with arguments + // filtered through InitialActionArgType, then forwards arguments directly + // to the base class to deal with the remaining actions. + struct OA { + Action...)> initial_action; + Action remaining_actions; + R operator()(Args... args) const { - auto tuple_args = std::forward_as_tuple(std::forward(args)...); - for (auto& a : converted) { - a.Perform(tuple_args); - } - return last.Perform(std::move(tuple_args)); + initial_action.Perform(std::forward_as_tuple( + static_cast>(args)...)); + + return remaining_actions.Perform( + std::forward_as_tuple(std::forward(args)...)); } }; - return Op{Convert...)>>( - MakeIndexSequence()), - std::get(actions)}; + + return OA{ + initial_action_, + static_cast(*this), + }; } + + private: + InitialAction initial_action_; }; template @@ -1078,10 +1659,11 @@ struct ReturnNewAction { template struct ReturnArgAction { - template - auto operator()(const Args&... args) const -> - typename std::tuple_element>::type { - return std::get(std::tie(args...)); + template ::type> + auto operator()(Args&&... args) const -> decltype(std::get( + std::forward_as_tuple(std::forward(args)...))) { + return std::get(std::forward_as_tuple(std::forward(args)...)); } }; @@ -1203,7 +1785,8 @@ typedef internal::IgnoredValue Unused; template internal::DoAllAction::type...> DoAll( Action&&... action) { - return {std::forward_as_tuple(std::forward(action)...)}; + return internal::DoAllAction::type...>( + {}, std::forward(action)...); } // WithArg(an_action) creates an action that passes the k-th @@ -1212,8 +1795,8 @@ internal::DoAllAction::type...> DoAll( // multiple arguments. For convenience, we also provide // WithArgs(an_action) (defined below) as a synonym. template -internal::WithArgsAction::type, k> -WithArg(InnerAction&& action) { +internal::WithArgsAction::type, k> WithArg( + InnerAction&& action) { return {std::forward(action)}; } @@ -1232,14 +1815,35 @@ WithArgs(InnerAction&& action) { // argument. In other words, it adapts an action accepting no // argument to one that accepts (and ignores) arguments. template -internal::WithArgsAction::type> -WithoutArgs(InnerAction&& action) { +internal::WithArgsAction::type> WithoutArgs( + InnerAction&& action) { return {std::forward(action)}; } -// Creates an action that returns 'value'. 'value' is passed by value -// instead of const reference - otherwise Return("string literal") -// will trigger a compiler error about using array as initializer. +// Creates an action that returns a value. +// +// The returned type can be used with a mock function returning a non-void, +// non-reference type U as follows: +// +// * If R is convertible to U and U is move-constructible, then the action can +// be used with WillOnce. +// +// * If const R& is convertible to U and U is copy-constructible, then the +// action can be used with both WillOnce and WillRepeatedly. +// +// The mock expectation contains the R value from which the U return value is +// constructed (a move/copy of the argument to Return). This means that the R +// value will survive at least until the mock object's expectations are cleared +// or the mock object is destroyed, meaning that U can safely be a +// reference-like type such as std::string_view: +// +// // The mock function returns a view of a copy of the string fed to +// // Return. The view is valid even after the action is performed. +// MockFunction mock; +// EXPECT_CALL(mock, Call).WillOnce(Return(std::string("taco"))); +// const std::string_view result = mock.AsStdFunction()(); +// EXPECT_EQ("taco", result); +// template internal::ReturnAction Return(R value) { return internal::ReturnAction(std::move(value)); @@ -1273,6 +1877,8 @@ inline internal::ReturnRefOfCopyAction ReturnRefOfCopy(const R& x) { return internal::ReturnRefOfCopyAction(x); } +// DEPRECATED: use Return(x) directly with WillOnce. +// // Modifies the parent action (a Return() action) to perform a move of the // argument instead of a copy. // Return(ByMove()) actions can only be executed once and will assert this @@ -1319,7 +1925,7 @@ internal::SetArgumentPointeeAction SetArgumentPointee(T value) { // Creates an action that sets a pointer referent to a given value. template -PolymorphicAction > Assign(T1* ptr, T2 val) { +PolymorphicAction> Assign(T1* ptr, T2 val) { return MakePolymorphicAction(internal::AssignAction(ptr, val)); } @@ -1327,8 +1933,8 @@ PolymorphicAction > Assign(T1* ptr, T2 val) { // Creates an action that sets errno and returns the appropriate error. template -PolymorphicAction > -SetErrnoAndReturn(int errval, T result) { +PolymorphicAction> SetErrnoAndReturn( + int errval, T result) { return MakePolymorphicAction( internal::SetErrnoAndReturnAction(errval, result)); } @@ -1482,7 +2088,8 @@ struct ExcessiveArg {}; // Builds an implementation of an Action<> for some particular signature, using // a class defined by an ACTION* macro. -template struct ActionImpl; +template +struct ActionImpl; template struct ImplBase { @@ -1502,7 +2109,7 @@ struct ActionImpl : ImplBase::type { using args_type = std::tuple; ActionImpl() = default; // Only defined if appropriate for Base. - explicit ActionImpl(std::shared_ptr impl) : Base{std::move(impl)} { } + explicit ActionImpl(std::shared_ptr impl) : Base{std::move(impl)} {} R operator()(Args&&... arg) const { static constexpr size_t kMaxArgs = @@ -1521,12 +2128,14 @@ struct ActionImpl : ImplBase::type { // args_type get passed, followed by a dummy of unspecified type for the // remainder up to 10 explicit args. static constexpr ExcessiveArg kExcessArg{}; - return static_cast(*this).template gmock_PerformImpl< - /*function_type=*/function_type, /*return_type=*/R, - /*args_type=*/args_type, - /*argN_type=*/typename std::tuple_element::type...>( - /*args=*/args, std::get(args)..., - ((void)excess_id, kExcessArg)...); + return static_cast(*this) + .template gmock_PerformImpl< + /*function_type=*/function_type, /*return_type=*/R, + /*args_type=*/args_type, + /*argN_type=*/ + typename std::tuple_element::type...>( + /*args=*/args, std::get(args)..., + ((void)excess_id, kExcessArg)...); } }; @@ -1545,7 +2154,7 @@ template #define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \ , const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_ -#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \ +#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \ const args_type& args GTEST_ATTRIBUTE_UNUSED_ GMOCK_PP_REPEAT( \ GMOCK_INTERNAL_ARG_UNUSED, , 10) @@ -1584,42 +2193,47 @@ template #define GMOCK_ACTION_FIELD_PARAMS_(params) \ GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_FIELD_PARAM, , params) -#define GMOCK_INTERNAL_ACTION(name, full_name, params) \ - template \ - class full_name { \ - public: \ - explicit full_name(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \ - : impl_(std::make_shared( \ - GMOCK_ACTION_GVALUE_PARAMS_(params))) { } \ - full_name(const full_name&) = default; \ - full_name(full_name&&) noexcept = default; \ - template \ - operator ::testing::Action() const { \ - return ::testing::internal::MakeAction(impl_); \ - } \ - private: \ - class gmock_Impl { \ - public: \ - explicit gmock_Impl(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \ - : GMOCK_ACTION_INIT_PARAMS_(params) {} \ - template \ - return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ - GMOCK_ACTION_FIELD_PARAMS_(params) \ - }; \ - std::shared_ptr impl_; \ - }; \ - template \ - inline full_name name( \ - GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \ - return full_name( \ - GMOCK_ACTION_GVALUE_PARAMS_(params)); \ - } \ - template \ - template \ - return_type full_name::gmock_Impl:: \ - gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const +#define GMOCK_INTERNAL_ACTION(name, full_name, params) \ + template \ + class full_name { \ + public: \ + explicit full_name(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \ + : impl_(std::make_shared( \ + GMOCK_ACTION_GVALUE_PARAMS_(params))) {} \ + full_name(const full_name&) = default; \ + full_name(full_name&&) noexcept = default; \ + template \ + operator ::testing::Action() const { \ + return ::testing::internal::MakeAction(impl_); \ + } \ + \ + private: \ + class gmock_Impl { \ + public: \ + explicit gmock_Impl(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \ + : GMOCK_ACTION_INIT_PARAMS_(params) {} \ + template \ + return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ + GMOCK_ACTION_FIELD_PARAMS_(params) \ + }; \ + std::shared_ptr impl_; \ + }; \ + template \ + inline full_name name( \ + GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) GTEST_MUST_USE_RESULT_; \ + template \ + inline full_name name( \ + GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \ + return full_name( \ + GMOCK_ACTION_GVALUE_PARAMS_(params)); \ + } \ + template \ + template \ + return_type \ + full_name::gmock_Impl::gmock_PerformImpl( \ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const } // namespace internal @@ -1627,12 +2241,13 @@ template #define ACTION(name) \ class name##Action { \ public: \ - explicit name##Action() noexcept {} \ - name##Action(const name##Action&) noexcept {} \ + explicit name##Action() noexcept {} \ + name##Action(const name##Action&) noexcept {} \ template \ operator ::testing::Action() const { \ return ::testing::internal::MakeAction(); \ } \ + \ private: \ class gmock_Impl { \ public: \ @@ -1681,7 +2296,7 @@ template } // namespace testing #ifdef _MSC_VER -# pragma warning(pop) +#pragma warning(pop) #endif #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ diff --git a/googletest/googlemock/include/gmock/gmock-cardinalities.h b/googletest/googlemock/include/gmock/gmock-cardinalities.h index fc7f803a..b6ab648e 100644 --- a/googletest/googlemock/include/gmock/gmock-cardinalities.h +++ b/googletest/googlemock/include/gmock/gmock-cardinalities.h @@ -27,21 +27,23 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - // Google Mock - a framework for writing C++ mock classes. // // This file implements some commonly used cardinalities. More // cardinalities can be defined by the user implementing the // CardinalityInterface interface if necessary. -// GOOGLETEST_CM0002 DO NOT DELETE +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ #include + #include #include // NOLINT + #include "gmock/internal/gmock-port.h" #include "gtest/gtest.h" @@ -116,7 +118,7 @@ class GTEST_API_ Cardinality { // cardinality, i.e. exceed the maximum number of allowed calls. bool IsOverSaturatedByCallCount(int call_count) const { return impl_->IsSaturatedByCallCount(call_count) && - !impl_->IsSatisfiedByCallCount(call_count); + !impl_->IsSatisfiedByCallCount(call_count); } // Describes self to an ostream diff --git a/googletest/googlemock/include/gmock/gmock-function-mocker.h b/googletest/googlemock/include/gmock/gmock-function-mocker.h index 0fc6f6f3..9edfd9d5 100644 --- a/googletest/googlemock/include/gmock/gmock-function-mocker.h +++ b/googletest/googlemock/include/gmock/gmock-function-mocker.h @@ -31,10 +31,11 @@ // // This file implements MOCK_METHOD. -// GOOGLETEST_CM0002 DO NOT DELETE +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* -#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT -#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_ #include // IWYU pragma: keep #include // IWYU pragma: keep @@ -64,6 +65,39 @@ struct ThisRefAdjuster { } }; +constexpr bool PrefixOf(const char* a, const char* b) { + return *a == 0 || (*a == *b && internal::PrefixOf(a + 1, b + 1)); +} + +template +constexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) { + return N <= M && internal::PrefixOf(prefix, str); +} + +template +constexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) { + return N <= M && internal::PrefixOf(suffix, str + M - N); +} + +template +constexpr bool Equals(const char (&a)[N], const char (&b)[M]) { + return N == M && internal::PrefixOf(a, b); +} + +template +constexpr bool ValidateSpec(const char (&spec)[N]) { + return internal::Equals("const", spec) || + internal::Equals("override", spec) || + internal::Equals("final", spec) || + internal::Equals("noexcept", spec) || + (internal::StartsWith("noexcept(", spec) && + internal::EndsWith(")", spec)) || + internal::Equals("ref(&)", spec) || + internal::Equals("ref(&&)", spec) || + (internal::StartsWith("Calltype(", spec) && + internal::EndsWith(")", spec)); +} + } // namespace internal // The style guide prohibits "using" statements in a namespace scope @@ -74,8 +108,11 @@ struct ThisRefAdjuster { using internal::FunctionMocker; } // namespace testing -#define MOCK_METHOD(...) \ - GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__) +#define MOCK_METHOD(...) \ + GMOCK_INTERNAL_WARNING_PUSH() \ + GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-member-function") \ + GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__) \ + GMOCK_INTERNAL_WARNING_POP() #define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \ GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) @@ -86,17 +123,18 @@ using internal::FunctionMocker; #define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \ GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ()) -#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \ - GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \ - GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \ - GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \ - GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \ - GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \ - GMOCK_INTERNAL_MOCK_METHOD_IMPL( \ - GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \ - GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \ - GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \ - GMOCK_INTERNAL_GET_CALLTYPE(_Spec), GMOCK_INTERNAL_GET_REF_SPEC(_Spec), \ +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \ + GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \ + GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \ + GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \ + GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \ + GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \ + GMOCK_INTERNAL_MOCK_METHOD_IMPL( \ + GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \ + GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \ + GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \ + GMOCK_INTERNAL_GET_CALLTYPE_SPEC(_Spec), \ + GMOCK_INTERNAL_GET_REF_SPEC(_Spec), \ (GMOCK_INTERNAL_SIGNATURE(_Ret, _Args))) #define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \ @@ -166,11 +204,11 @@ using internal::FunctionMocker; GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \ } \ mutable ::testing::FunctionMocker \ - GMOCK_MOCKER_(_N, _Constness, _MethodName) + GMOCK_MOCKER_(_N, _Constness, _MethodName) #define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__ -// Five Valid modifiers. +// Valid modifiers. #define GMOCK_INTERNAL_HAS_CONST(_Tuple) \ GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple)) @@ -189,6 +227,14 @@ using internal::FunctionMocker; GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)), \ _elem, ) +#define GMOCK_INTERNAL_GET_CALLTYPE_SPEC(_Tuple) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE, ~, _Tuple) + +#define GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE(_i, _, _elem) \ + GMOCK_PP_IF( \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem)), \ + GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), ) + #define GMOCK_INTERNAL_GET_REF_SPEC(_Tuple) \ GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_REF_SPEC_IF_REF, ~, _Tuple) @@ -196,19 +242,25 @@ using internal::FunctionMocker; GMOCK_PP_IF(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)), \ GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), ) -#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \ - GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple) - -#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \ - static_assert( \ - (GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \ - GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \ - GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \ - GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \ - GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) + \ - GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \ - GMOCK_PP_STRINGIZE( \ +#ifdef GMOCK_INTERNAL_STRICT_SPEC_ASSERT +#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \ + static_assert( \ + ::testing::internal::ValidateSpec(GMOCK_PP_STRINGIZE(_elem)), \ + "Token \'" GMOCK_PP_STRINGIZE( \ + _elem) "\' cannot be recognized as a valid specification " \ + "modifier. Is a ',' missing?"); +#else +#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \ + static_assert( \ + (GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem))) == 1, \ + GMOCK_PP_STRINGIZE( \ _elem) " cannot be recognized as a valid specification modifier."); +#endif // GMOCK_INTERNAL_STRICT_SPEC_ASSERT // Modifiers implementation. #define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \ @@ -238,26 +290,12 @@ using internal::FunctionMocker; #define GMOCK_INTERNAL_UNPACK_ref(x) x -#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \ - GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \ - GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \ - (_elem) - -// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and -// GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows -// maybe they can be simplified somehow. -#define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \ - GMOCK_INTERNAL_IS_CALLTYPE_I( \ - GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg)) -#define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg) +#define GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CALLTYPE_I_, _elem) -#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \ - GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \ - GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg)) -#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \ - GMOCK_PP_IDENTITY _arg +#define GMOCK_INTERNAL_DETECT_CALLTYPE_I_Calltype , -#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype +#define GMOCK_INTERNAL_UNPACK_Calltype(...) __VA_ARGS__ // Note: The use of `identity_t` here allows _Ret to represent return types that // would normally need to be specified in a different way. For example, a method @@ -326,6 +364,8 @@ using internal::FunctionMocker; #define MOCK_METHOD9(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 9, __VA_ARGS__) #define MOCK_METHOD10(m, ...) \ GMOCK_INTERNAL_MOCK_METHODN(, , m, 10, __VA_ARGS__) +#define MOCK_METHOD11(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, , m, 11, __VA_ARGS__) #define MOCK_CONST_METHOD0(m, ...) \ GMOCK_INTERNAL_MOCK_METHODN(const, , m, 0, __VA_ARGS__) @@ -476,4 +516,4 @@ using internal::FunctionMocker; #define GMOCK_MOCKER_(arity, constness, Method) \ GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) -#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_ diff --git a/googletest/googlemock/include/gmock/gmock-matchers.h b/googletest/googlemock/include/gmock/gmock-matchers.h index 86be9c17..9e634f7f 100644 --- a/googletest/googlemock/include/gmock/gmock-matchers.h +++ b/googletest/googlemock/include/gmock/gmock-matchers.h @@ -27,7 +27,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - // Google Mock - a framework for writing C++ mock classes. // // The MATCHER* family of macros can be used in a namespace scope to @@ -241,7 +240,7 @@ // // To learn more about using these macros, please search for 'MATCHER' // on -// https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md +// https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md // // This file also implements some commonly used argument matchers. More // matchers can be defined by the user implementing the @@ -250,7 +249,8 @@ // See googletest/include/gtest/gtest-matchers.h for the definition of class // Matcher, class MatcherInterface, and others. -// GOOGLETEST_CM0002 DO NOT DELETE +// IWYU pragma: private, include "gmock/gmock.h" +// IWYU pragma: friend gmock/.* #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ @@ -258,6 +258,7 @@ #include #include #include +#include #include #include #include @@ -313,7 +314,9 @@ class StringMatchResultListener : public MatchResultListener { private: ::std::stringstream ss_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(StringMatchResultListener); + StringMatchResultListener(const StringMatchResultListener&) = delete; + StringMatchResultListener& operator=(const StringMatchResultListener&) = + delete; }; // Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION @@ -396,7 +399,7 @@ class MatcherCastImpl { // is already a Matcher. This only compiles when type T can be // statically converted to type U. template -class MatcherCastImpl > { +class MatcherCastImpl> { public: static Matcher Cast(const Matcher& source_matcher) { return Matcher(new Impl(source_matcher)); @@ -450,7 +453,7 @@ class MatcherCastImpl > { // This even more specialized version is used for efficiently casting // a matcher to its own type. template -class MatcherCastImpl > { +class MatcherCastImpl> { public: static Matcher Cast(const Matcher& matcher) { return matcher; } }; @@ -533,19 +536,18 @@ inline Matcher SafeMatcherCast(const Matcher& matcher) { "T must be implicitly convertible to U"); // Enforce that we are not converting a non-reference type T to a reference // type U. - GTEST_COMPILE_ASSERT_( - std::is_reference::value || !std::is_reference::value, - cannot_convert_non_reference_arg_to_reference); + static_assert(std::is_reference::value || !std::is_reference::value, + "cannot convert non reference arg to reference"); // In case both T and U are arithmetic types, enforce that the // conversion is not lossy. typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT; typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU; constexpr bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; constexpr bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; - GTEST_COMPILE_ASSERT_( + static_assert( kTIsOther || kUIsOther || - (internal::LosslessArithmeticConvertible::value), - conversion_of_arithmetic_types_must_be_lossless); + (internal::LosslessArithmeticConvertible::value), + "conversion of arithmetic types must be lossless"); return MatcherCast(matcher); } @@ -678,9 +680,9 @@ bool TupleMatches(const MatcherTuple& matcher_tuple, const ValueTuple& value_tuple) { // Makes sure that matcher_tuple and value_tuple have the same // number of fields. - GTEST_COMPILE_ASSERT_(std::tuple_size::value == - std::tuple_size::value, - matcher_and_value_have_different_numbers_of_fields); + static_assert(std::tuple_size::value == + std::tuple_size::value, + "matcher and value have different numbers of fields"); return TuplePrefix::value>::Matches(matcher_tuple, value_tuple); } @@ -689,8 +691,7 @@ bool TupleMatches(const MatcherTuple& matcher_tuple, // is no failure, nothing will be streamed to os. template void ExplainMatchFailureTupleTo(const MatcherTuple& matchers, - const ValueTuple& values, - ::std::ostream* os) { + const ValueTuple& values, ::std::ostream* os) { TuplePrefix::value>::ExplainMatchFailuresTo( matchers, values, os); } @@ -714,14 +715,14 @@ class TransformTupleValuesHelper { private: template struct IterateOverTuple { - OutIter operator() (Func f, const Tup& t, OutIter out) const { + OutIter operator()(Func f, const Tup& t, OutIter out) const { *out++ = f(::std::get(t)); return IterateOverTuple()(f, t, out); } }; template struct IterateOverTuple { - OutIter operator() (Func /* f */, const Tup& /* t */, OutIter out) const { + OutIter operator()(Func /* f */, const Tup& /* t */, OutIter out) const { return out; } }; @@ -767,9 +768,7 @@ class IsNullMatcher { } void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } - void DescribeNegationTo(::std::ostream* os) const { - *os << "isn't NULL"; - } + void DescribeNegationTo(::std::ostream* os) const { *os << "isn't NULL"; } }; // Implements the polymorphic NotNull() matcher, which matches any raw or smart @@ -783,9 +782,7 @@ class NotNullMatcher { } void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; } - void DescribeNegationTo(::std::ostream* os) const { - *os << "is NULL"; - } + void DescribeNegationTo(::std::ostream* os) const { *os << "is NULL"; } }; // Ref(variable) matches any argument that is a reference to @@ -871,8 +868,7 @@ inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs, // String comparison for narrow or wide strings that can have embedded NUL // characters. template -bool CaseInsensitiveStringEquals(const StringType& s1, - const StringType& s2) { +bool CaseInsensitiveStringEquals(const StringType& s1, const StringType& s2) { // Are the heads equal? if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) { return false; @@ -933,8 +929,8 @@ class StrEqualityMatcher { bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { const StringType s2(s); - const bool eq = case_sensitive_ ? s2 == string_ : - CaseInsensitiveStringEquals(s2, string_); + const bool eq = case_sensitive_ ? s2 == string_ + : CaseInsensitiveStringEquals(s2, string_); return expect_eq_ == eq; } @@ -1021,8 +1017,7 @@ class HasSubstrMatcher { template class StartsWithMatcher { public: - explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { - } + explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {} #if GTEST_INTERNAL_HAS_STRING_VIEW bool MatchAndExplain(const internal::StringView& s, @@ -1053,7 +1048,7 @@ class StartsWithMatcher { MatchResultListener* /* listener */) const { const StringType& s2(s); return s2.length() >= prefix_.length() && - s2.substr(0, prefix_.length()) == prefix_; + s2.substr(0, prefix_.length()) == prefix_; } void DescribeTo(::std::ostream* os) const { @@ -1107,7 +1102,7 @@ class EndsWithMatcher { MatchResultListener* /* listener */) const { const StringType& s2(s); return s2.length() >= suffix_.length() && - s2.substr(s2.length() - suffix_.length()) == suffix_; + s2.substr(s2.length() - suffix_.length()) == suffix_; } void DescribeTo(::std::ostream* os) const { @@ -1124,6 +1119,45 @@ class EndsWithMatcher { const StringType suffix_; }; +// Implements the polymorphic WhenBase64Unescaped(matcher) matcher, which can be +// used as a Matcher as long as T can be converted to a string. +class WhenBase64UnescapedMatcher { + public: + using is_gtest_matcher = void; + + explicit WhenBase64UnescapedMatcher( + const Matcher& internal_matcher) + : internal_matcher_(internal_matcher) {} + + // Matches anything that can convert to std::string. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* listener) const { + const std::string s2(s); // NOLINT (needed for working with string_view). + std::string unescaped; + if (!internal::Base64Unescape(s2, &unescaped)) { + if (listener != nullptr) { + *listener << "is not a valid base64 escaped string"; + } + return false; + } + return MatchPrintAndExplain(unescaped, internal_matcher_, listener); + } + + void DescribeTo(::std::ostream* os) const { + *os << "matches after Base64Unescape "; + internal_matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "does not match after Base64Unescape "; + internal_matcher_.DescribeTo(os); + } + + private: + const Matcher internal_matcher_; +}; + // Implements a matcher that compares the two fields of a 2-tuple // using one of the ==, <=, <, etc, operators. The two fields being // compared don't have to have the same type. @@ -1197,8 +1231,7 @@ class Ge2Matcher : public PairMatchBase { template class NotMatcherImpl : public MatcherInterface { public: - explicit NotMatcherImpl(const Matcher& matcher) - : matcher_(matcher) {} + explicit NotMatcherImpl(const Matcher& matcher) : matcher_(matcher) {} bool MatchAndExplain(const T& x, MatchResultListener* listener) const override { @@ -1242,7 +1275,7 @@ class NotMatcher { template class AllOfMatcherImpl : public MatcherInterface { public: - explicit AllOfMatcherImpl(std::vector > matchers) + explicit AllOfMatcherImpl(std::vector> matchers) : matchers_(std::move(matchers)) {} void DescribeTo(::std::ostream* os) const override { @@ -1293,7 +1326,7 @@ class AllOfMatcherImpl : public MatcherInterface { } private: - const std::vector > matchers_; + const std::vector> matchers_; }; // VariadicMatcher is used for the variadic implementation of @@ -1316,14 +1349,14 @@ class VariadicMatcher { // all of the provided matchers (Matcher1, Matcher2, ...) can match. template operator Matcher() const { - std::vector > values; + std::vector> values; CreateVariadicMatcher(&values, std::integral_constant()); return Matcher(new CombiningMatcher(std::move(values))); } private: template - void CreateVariadicMatcher(std::vector >* values, + void CreateVariadicMatcher(std::vector>* values, std::integral_constant) const { values->push_back(SafeMatcherCast(std::get(matchers_))); CreateVariadicMatcher(values, std::integral_constant()); @@ -1331,7 +1364,7 @@ class VariadicMatcher { template void CreateVariadicMatcher( - std::vector >*, + std::vector>*, std::integral_constant) const {} std::tuple matchers_; @@ -1347,7 +1380,7 @@ using AllOfMatcher = VariadicMatcher; template class AnyOfMatcherImpl : public MatcherInterface { public: - explicit AnyOfMatcherImpl(std::vector > matchers) + explicit AnyOfMatcherImpl(std::vector> matchers) : matchers_(std::move(matchers)) {} void DescribeTo(::std::ostream* os) const override { @@ -1398,13 +1431,35 @@ class AnyOfMatcherImpl : public MatcherInterface { } private: - const std::vector > matchers_; + const std::vector> matchers_; }; // AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...). template using AnyOfMatcher = VariadicMatcher; +// ConditionalMatcher is the implementation of Conditional(cond, m1, m2) +template +class ConditionalMatcher { + public: + ConditionalMatcher(bool condition, MatcherTrue matcher_true, + MatcherFalse matcher_false) + : condition_(condition), + matcher_true_(std::move(matcher_true)), + matcher_false_(std::move(matcher_false)) {} + + template + operator Matcher() const { // NOLINT(runtime/explicit) + return condition_ ? SafeMatcherCast(matcher_true_) + : SafeMatcherCast(matcher_false_); + } + + private: + bool condition_; + MatcherTrue matcher_true_; + MatcherFalse matcher_false_; +}; + // Wrapper for implementation of Any/AllOfArray(). template